From aba3f7e2ec0518057b2074ea75783efaca5fdf46 Mon Sep 17 00:00:00 2001 From: eric Date: Fri, 28 Aug 2026 20:11:05 -0500 Subject: [PATCH] Production deploy: Caddy reverse proxy, ports 3055/8055, nomadweb.nomadro.com live Co-authored-by: Cursor --- .gitignore | 10 ++++++++ README.md | 50 +++++++++++++++++++++++++++++++----- deploy/caddy/nomadweb.caddy | 19 ++++++++++++++ deploy/nginx/nomadweb.conf | 8 +++--- docker-compose.prod.yml | 4 +-- scripts/deploy-production.sh | 24 ++++++++++------- 6 files changed, 93 insertions(+), 22 deletions(-) create mode 100644 deploy/caddy/nomadweb.caddy diff --git a/.gitignore b/.gitignore index ed93383..89bf445 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,13 @@ Thumbs.db # IDE .idea/ .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 diff --git a/README.md b/README.md index c813334..9061fa9 100644 --- a/README.md +++ b/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 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. 自动构建部署 ### 后端 → Railway @@ -185,12 +227,6 @@ NEXT_PUBLIC_API_URL=http://localhost:8000/api/v1 2. 配置 `POCKETBASE_URL`、`CORS_ORIGINS` 3. 读取 `railway.toml` 自动部署 -### 全栈 → Docker Compose - -```bash -docker compose up -d -``` - ## 快捷键 | 按键 | 功能 | diff --git a/deploy/caddy/nomadweb.caddy b/deploy/caddy/nomadweb.caddy new file mode 100644 index 0000000..6efa793 --- /dev/null +++ b/deploy/caddy/nomadweb.caddy @@ -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 + } +} diff --git a/deploy/nginx/nomadweb.conf b/deploy/nginx/nomadweb.conf index f56733e..c3747c7 100644 --- a/deploy/nginx/nomadweb.conf +++ b/deploy/nginx/nomadweb.conf @@ -5,7 +5,7 @@ server { client_max_body_size 20M; 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_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; @@ -14,18 +14,18 @@ server { } 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 X-Real-IP $remote_addr; } 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; } location / { - proxy_pass http://127.0.0.1:3020; + proxy_pass http://127.0.0.1:3055; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 3284a73..13b0997 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -15,7 +15,7 @@ services: build: ./backend container_name: nomadflow-api ports: - - "127.0.0.1:8020:8000" + - "127.0.0.1:8055:8000" environment: - POCKETBASE_URL=http://pocketbase:8090 - 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} container_name: nomadflow-web ports: - - "127.0.0.1:3020:3000" + - "127.0.0.1:3055:3000" depends_on: - backend restart: unless-stopped diff --git a/scripts/deploy-production.sh b/scripts/deploy-production.sh index 4034dda..6e35e7e 100644 --- a/scripts/deploy-production.sh +++ b/scripts/deploy-production.sh @@ -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 up -d -echo "==> Configuring Nginx..." -cp deploy/nginx/nomadweb.conf "/etc/nginx/sites-available/${DOMAIN}" -ln -sf "/etc/nginx/sites-available/${DOMAIN}" "/etc/nginx/sites-enabled/${DOMAIN}" -rm -f /etc/nginx/sites-enabled/default 2>/dev/null || true -nginx -t -systemctl reload nginx +echo "==> Configuring Caddy..." +mkdir -p /etc/caddy/sites +cp deploy/caddy/nomadweb.caddy /etc/caddy/sites/nomadweb.caddy +caddy validate --config /etc/caddy/Caddyfile +systemctl reload caddy -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..." 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 @@ -62,8 +68,8 @@ fi echo "==> Health check..." sleep 5 -curl -sf "http://127.0.0.1:8020/api/v1/health" && echo " API OK" -curl -sf -o /dev/null "http://127.0.0.1:3020" && echo " Frontend 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:3055" && echo " Frontend OK" echo "" echo "Deploy complete!"