Production deploy: Caddy reverse proxy, ports 3055/8055, nomadweb.nomadro.com live
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
da3c3eb016
commit
aba3f7e2ec
10
.gitignore
vendored
10
.gitignore
vendored
@ -26,3 +26,13 @@ Thumbs.db
|
|||||||
# IDE
|
# IDE
|
||||||
.idea/
|
.idea/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
|
||||||
|
# Deploy scripts with credentials (local only)
|
||||||
|
scripts/remote_deploy.py
|
||||||
|
scripts/redeploy_server.py
|
||||||
|
scripts/upload_and_deploy.py
|
||||||
|
scripts/check_server.py
|
||||||
|
scripts/check_ports.py
|
||||||
|
scripts/find_caddy.py
|
||||||
|
scripts/read_caddy.py
|
||||||
|
scripts/verify_site.py
|
||||||
|
|||||||
50
README.md
50
README.md
@ -173,10 +173,52 @@ NEXT_PUBLIC_API_URL=http://localhost:8000/api/v1
|
|||||||
|
|
||||||
## 部署
|
## 部署
|
||||||
|
|
||||||
|
### 生产环境(已上线)
|
||||||
|
|
||||||
|
| 项目 | 地址 |
|
||||||
|
|------|------|
|
||||||
|
| 网站 | https://nomadweb.nomadro.com |
|
||||||
|
| API 健康检查 | https://nomadweb.nomadro.com/api/v1/health |
|
||||||
|
| API 文档 | https://nomadweb.nomadro.com/docs |
|
||||||
|
| Git 仓库 | https://gitea.dsx2020.com/eric/nomadweb |
|
||||||
|
|
||||||
|
**服务器架构:**
|
||||||
|
- 服务器:`107.173.30.245`
|
||||||
|
- 反向代理:Caddy(自动 HTTPS)
|
||||||
|
- 前端容器:`127.0.0.1:3055` → Next.js
|
||||||
|
- 后端容器:`127.0.0.1:8055` → FastAPI
|
||||||
|
- 数据库:PocketBase(Docker 内部网络)
|
||||||
|
|
||||||
|
**更新部署:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# SSH 登录服务器后
|
||||||
|
cd /opt/nomadweb
|
||||||
|
git pull origin main
|
||||||
|
export DOMAIN=nomadweb.nomadro.com
|
||||||
|
export NEXT_PUBLIC_API_URL=https://nomadweb.nomadro.com/api/v1
|
||||||
|
export CORS_ORIGINS=https://nomadweb.nomadro.com
|
||||||
|
bash scripts/deploy-production.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
或使用 Docker Compose 生产配置:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f docker-compose.prod.yml up -d --build
|
||||||
|
cp deploy/caddy/nomadweb.caddy /etc/caddy/sites/nomadweb.caddy
|
||||||
|
systemctl reload caddy
|
||||||
|
```
|
||||||
|
|
||||||
|
### 本地 Docker Compose
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
```
|
||||||
|
|
||||||
### 前端 → Vercel
|
### 前端 → Vercel
|
||||||
|
|
||||||
1. 导入 `frontend/` 目录
|
1. 导入 `frontend/` 目录
|
||||||
2. 环境变量:`NEXT_PUBLIC_API_URL=https://your-api.example.com/api/v1`
|
2. 环境变量:`NEXT_PUBLIC_API_URL=https://nomadweb.nomadro.com/api/v1`
|
||||||
3. 自动构建部署
|
3. 自动构建部署
|
||||||
|
|
||||||
### 后端 → Railway
|
### 后端 → Railway
|
||||||
@ -185,12 +227,6 @@ NEXT_PUBLIC_API_URL=http://localhost:8000/api/v1
|
|||||||
2. 配置 `POCKETBASE_URL`、`CORS_ORIGINS`
|
2. 配置 `POCKETBASE_URL`、`CORS_ORIGINS`
|
||||||
3. 读取 `railway.toml` 自动部署
|
3. 读取 `railway.toml` 自动部署
|
||||||
|
|
||||||
### 全栈 → Docker Compose
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker compose up -d
|
|
||||||
```
|
|
||||||
|
|
||||||
## 快捷键
|
## 快捷键
|
||||||
|
|
||||||
| 按键 | 功能 |
|
| 按键 | 功能 |
|
||||||
|
|||||||
19
deploy/caddy/nomadweb.caddy
Normal file
19
deploy/caddy/nomadweb.caddy
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
nomadweb.nomadro.com {
|
||||||
|
encode gzip
|
||||||
|
|
||||||
|
handle /api/* {
|
||||||
|
reverse_proxy 127.0.0.1:8055
|
||||||
|
}
|
||||||
|
|
||||||
|
handle /docs* {
|
||||||
|
reverse_proxy 127.0.0.1:8055
|
||||||
|
}
|
||||||
|
|
||||||
|
handle /openapi.json {
|
||||||
|
reverse_proxy 127.0.0.1:8055
|
||||||
|
}
|
||||||
|
|
||||||
|
handle {
|
||||||
|
reverse_proxy 127.0.0.1:3055
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -5,7 +5,7 @@ server {
|
|||||||
client_max_body_size 20M;
|
client_max_body_size 20M;
|
||||||
|
|
||||||
location /api/ {
|
location /api/ {
|
||||||
proxy_pass http://127.0.0.1:8020/api/;
|
proxy_pass http://127.0.0.1:8055/api/;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
@ -14,18 +14,18 @@ server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
location /docs {
|
location /docs {
|
||||||
proxy_pass http://127.0.0.1:8020/docs;
|
proxy_pass http://127.0.0.1:8055/docs;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
location /openapi.json {
|
location /openapi.json {
|
||||||
proxy_pass http://127.0.0.1:8020/openapi.json;
|
proxy_pass http://127.0.0.1:8055/openapi.json;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
}
|
}
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
proxy_pass http://127.0.0.1:3020;
|
proxy_pass http://127.0.0.1:3055;
|
||||||
proxy_http_version 1.1;
|
proxy_http_version 1.1;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
|||||||
@ -15,7 +15,7 @@ services:
|
|||||||
build: ./backend
|
build: ./backend
|
||||||
container_name: nomadflow-api
|
container_name: nomadflow-api
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:8020:8000"
|
- "127.0.0.1:8055:8000"
|
||||||
environment:
|
environment:
|
||||||
- POCKETBASE_URL=http://pocketbase:8090
|
- POCKETBASE_URL=http://pocketbase:8090
|
||||||
- POCKETBASE_ADMIN_EMAIL=${POCKETBASE_ADMIN_EMAIL:-admin@nomadflow.io}
|
- POCKETBASE_ADMIN_EMAIL=${POCKETBASE_ADMIN_EMAIL:-admin@nomadflow.io}
|
||||||
@ -33,7 +33,7 @@ services:
|
|||||||
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://nomadweb.nomadro.com/api/v1}
|
NEXT_PUBLIC_API_URL: ${NEXT_PUBLIC_API_URL:-https://nomadweb.nomadro.com/api/v1}
|
||||||
container_name: nomadflow-web
|
container_name: nomadflow-web
|
||||||
ports:
|
ports:
|
||||||
- "127.0.0.1:3020:3000"
|
- "127.0.0.1:3055:3000"
|
||||||
depends_on:
|
depends_on:
|
||||||
- backend
|
- backend
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|||||||
@ -47,14 +47,20 @@ docker compose -f docker-compose.prod.yml down 2>/dev/null || true
|
|||||||
docker compose -f docker-compose.prod.yml build --no-cache
|
docker compose -f docker-compose.prod.yml build --no-cache
|
||||||
docker compose -f docker-compose.prod.yml up -d
|
docker compose -f docker-compose.prod.yml up -d
|
||||||
|
|
||||||
echo "==> Configuring Nginx..."
|
echo "==> Configuring Caddy..."
|
||||||
cp deploy/nginx/nomadweb.conf "/etc/nginx/sites-available/${DOMAIN}"
|
mkdir -p /etc/caddy/sites
|
||||||
ln -sf "/etc/nginx/sites-available/${DOMAIN}" "/etc/nginx/sites-enabled/${DOMAIN}"
|
cp deploy/caddy/nomadweb.caddy /etc/caddy/sites/nomadweb.caddy
|
||||||
rm -f /etc/nginx/sites-enabled/default 2>/dev/null || true
|
caddy validate --config /etc/caddy/Caddyfile
|
||||||
nginx -t
|
systemctl reload caddy
|
||||||
systemctl reload nginx
|
|
||||||
|
|
||||||
if command -v certbot &>/dev/null; then
|
# Fallback Nginx (optional, only if not using Caddy)
|
||||||
|
if command -v nginx &>/dev/null && ! command -v caddy &>/dev/null; then
|
||||||
|
cp deploy/nginx/nomadweb.conf "/etc/nginx/sites-available/${DOMAIN}"
|
||||||
|
ln -sf "/etc/nginx/sites-available/${DOMAIN}" "/etc/nginx/sites-enabled/${DOMAIN}"
|
||||||
|
nginx -t && systemctl reload nginx
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v certbot &>/dev/null && ! command -v caddy &>/dev/null; then
|
||||||
echo "==> Renewing SSL certificate..."
|
echo "==> Renewing SSL certificate..."
|
||||||
certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos --register-unsafely-without-email --redirect 2>/dev/null || \
|
certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos --register-unsafely-without-email --redirect 2>/dev/null || \
|
||||||
certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos -m "admin@${DOMAIN}" --redirect || true
|
certbot --nginx -d "$DOMAIN" --non-interactive --agree-tos -m "admin@${DOMAIN}" --redirect || true
|
||||||
@ -62,8 +68,8 @@ fi
|
|||||||
|
|
||||||
echo "==> Health check..."
|
echo "==> Health check..."
|
||||||
sleep 5
|
sleep 5
|
||||||
curl -sf "http://127.0.0.1:8020/api/v1/health" && echo " API OK"
|
curl -sf "http://127.0.0.1:8055/api/v1/health" && echo " API OK"
|
||||||
curl -sf -o /dev/null "http://127.0.0.1:3020" && echo " Frontend OK"
|
curl -sf -o /dev/null "http://127.0.0.1:3055" && echo " Frontend OK"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "Deploy complete!"
|
echo "Deploy complete!"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user