From 11b338432acf83eded74827ae66514214e2e851b Mon Sep 17 00:00:00 2001 From: david_bai Date: Tue, 1 Jul 2025 23:10:07 +0800 Subject: [PATCH] update DEPLOYMENT procedure --- backend/docker/Dockerfile | 2 +- backend/docker/Nginx/default | 2 +- backend/docker/env_install.log | 2 +- docs/DEPLOYMENT.zh-CN.md | 238 +++++++++++++++++---------------- 4 files changed, 129 insertions(+), 115 deletions(-) diff --git a/backend/docker/Dockerfile b/backend/docker/Dockerfile index 1978805..e21b868 100644 --- a/backend/docker/Dockerfile +++ b/backend/docker/Dockerfile @@ -13,7 +13,7 @@ RUN apt-get update && apt-get install -y tzdata RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime # Install certbot nginx -RUN apt install -y certbot python3-certbot-nginx +RUN apt install -y certbot python3-certbot-nginx ssl-cert # TURN server RUN apt-get install -y vim coturn diff --git a/backend/docker/Nginx/default b/backend/docker/Nginx/default index fe08045..f11971a 100644 --- a/backend/docker/Nginx/default +++ b/backend/docker/Nginx/default @@ -44,7 +44,7 @@ server { # Define the root path of the frontend build artifacts inside the container # !!! Important: Please modify this path to the actual path of your frontend project build inside the Nginx container !!! - set $frontend_build_root path/to/your/frontend_build_root; + set $frontend_build_root path/to/PrivyDrop/frontend; # 1. Prioritize handling of Next.js core static resources (_next/static) location /_next/static/ { diff --git a/backend/docker/env_install.log b/backend/docker/env_install.log index 3afaa4d..5712eab 100644 --- a/backend/docker/env_install.log +++ b/backend/docker/env_install.log @@ -1,4 +1,4 @@ -sudo apt install -y certbot python3-certbot-nginx +sudo apt install -y certbot python3-certbot-nginx ssl-cert sudo apt-get install -y vim coturn sudo apt-get install -y redis-server diff --git a/docs/DEPLOYMENT.zh-CN.md b/docs/DEPLOYMENT.zh-CN.md index e85b0ef..82c7068 100644 --- a/docs/DEPLOYMENT.zh-CN.md +++ b/docs/DEPLOYMENT.zh-CN.md @@ -12,10 +12,10 @@ - **操作系统:** Linux 发行版(例如,推荐 Ubuntu 20.04 LTS 或更高版本)。 - **Node.js:** v18.x 或更高版本。 -- **npm (或 yarn/pnpm):** Node.js 的包管理器。 +- **npm/pnpm:** Node.js 的包管理器。 - **Root 或 Sudo 权限:** 安装软件包和配置服务所需。 - **域名:** 生产环境部署需要一个域名。 -- **可选:基础环境与 Docker 镜像参考:** 如果您需要从一个非常纯净的系统环境开始搭建,或者希望了解用于 Docker 构建的基础依赖,可以参考 `backend/docker/Dockerfile` 文件(用于 Docker 镜像构建)和 `backend/docker/env_install.log` 文件(依赖安装记录)。 +- **可选:基础环境与 Docker 镜像参考:** 如果您需要从一个非常纯净的系统环境开始搭建,或者希望了解用于 Docker 构建的基础依赖,可以参考 `backend/docker/Dockerfile` 文件(用于 Docker 基础镜像构建)和 `backend/docker/env_install.log` 文件(依赖安装记录)。 ## 3. 依赖服务安装与配置 @@ -32,7 +32,7 @@ sudo apt install redis-server **配置:** -- 默认情况下,Redis 监听 `127.0.0.1:6379` 且无需密码。请确保后端的 `.env` 文件中包含 `REDIS_HOST` 和 `REDIS_PORT`。 +- 默认情况下,Redis 监听 `127.0.0.1:6379` 且无需密码。请确保后端的 `.env.production[development]` 文件中包含 `REDIS_HOST` 和 `REDIS_PORT`。 - 确保 Redis 正在运行:`sudo systemctl status redis-server` - 如果未运行,请启动:`sudo systemctl start redis-server` @@ -49,91 +49,23 @@ sudo apt update sudo apt install coturn ``` -**配置:** +**基础配置:** -1. **启用 Coturn 服务:** 编辑 `/etc/default/coturn` 并取消注释 `TURNSERVER_ENABLED=1`。 -2. **防火墙配置:** 在服务器的防火墙上打开必要的端口 (例如,使用 `ufw`): - - TCP & UDP `3478`: 用于 STUN 和 TURN。 - - TCP & UDP `5349`: 用于 TURNS (TURN over TLS/DTLS) - **生产环境**。 - - UDP `49152-65535`: Coturn 的默认中继端口范围。 +1. **启用 Coturn 服务:** + 编辑 `/etc/default/coturn` 并取消注释 `TURNSERVER_ENABLED=1`。 + +2. **防火墙配置:** + 在服务器的防火墙上打开必要的端口 (例如,使用 `ufw`): + - TCP & UDP `3478`: 用于 STUN 和 TURN。 + - TCP & UDP `5349`: 用于 TURNS (TURN over TLS/DTLS)。 + - UDP `49152-65535`: Coturn 的默认中继端口范围。 ```bash sudo ufw allow 3478 sudo ufw allow 5349 sudo ufw allow 49152:65535/udp - sudo ufw enable + sudo ufw reload # 或 ufw enable ``` -3. **生产环境的 SSL 证书 (用于 TURNS):** - 为你的 TURN 域名 (例如 `turn.yourdomain.com`) 获取 SSL 证书。 - ```bash - # 确保 DNS 'A' 记录将 turn.yourdomain.com 指向服务器 IP - sudo apt install certbot - sudo certbot certonly --standalone -d turn.yourdomain.com - ``` -4. **SSL 证书权限验证:** - Coturn 进程(通常以用户 `turnserver` 运行)需要读取 SSL 证书和密钥的权限。 - - - 检查当前权限: - ```bash - sudo ls -lh /etc/letsencrypt/live/turn.yourdomain.com/fullchain.pem - sudo ls -ld /etc/letsencrypt/archive/ - ``` - - 如果 Coturn 日志显示权限错误: - 创建一个组(例如 `ssl-cert`),将 `turnserver` 添加到该组,并调整权限: - ```bash - sudo groupadd -f ssl-cert - # 查找 coturn 运行的用户,通常是 'turnserver' 或 'coturn' - # ps aux | grep turnserver - sudo usermod -a -G ssl-cert turnserver # 如果不同,请替换 'turnserver' - sudo chown -R root:ssl-cert /etc/letsencrypt/ - sudo chmod -R 750 /etc/letsencrypt/ - ``` - 验证 `/etc/letsencrypt/archive/` 和 `/etc/letsencrypt/live/` 上的新权限。 - -5. **配置并启动 Coturn:** - - - 在后端的 `.env` 文件中配置 `TURN_*` 相关环境变量(如用户名、密码、证书路径等)。 - - 在测试环境下需要填入的变量为: - ``` - TURN_EXTERNAL_IP=YourServerPublicIP # 例如: 123.123.456.567 - TURN_REALM=YourServerPublicIP - TURN_USERNAME=YourTurnUsername - TURN_PASSWORD=YourTurnPassword - ``` - - 在生产部署环境下需要填入的变量为: - ``` - TURN_EXTERNAL_IP=YourServerPublicIP # 例如: 123.123.456.567 - TURN_REALM=turn.yourdomain - TURN_USERNAME=YourTurnUsername - TURN_PASSWORD=YourTurnPassword - TURN_CERT_PATH=/etc/letsencrypt/live/turn.yourdomain/fullchain.pem - TURN_KEY_PATH=/etc/letsencrypt/live/turn.yourdomain/privkey.pem - ``` - - 使用项目提供的脚本生成配置文件并启动服务: - - ```bash - # 位于 backend/ 目录 - sudo bash ./docker/TURN/configure.sh path/to/your/.env.production - # 开发环境使用 .env.development - sudo systemctl status coturn - ``` - - - 检查日志 `/var/log/turnserver.log` 确认无误。 - -6. **在线测试(可选):** - 使用在线工具,如 Metered TURN Server Tester (https://www.metered.ca/turn-server-testing): - - - **用于开发/测试 (非 TLS):** - - TURN URL: `你的服务器公网IP` - - TURN Port: `3478` - - 用户名: `你的Turn用户名` - - 密码: `你的Turn密码` - - **用于生产 (TURNS):** - - TURNS URL: `turn.yourdomain` - - TURNS Port: `5349` - - 用户名: `你的Turn用户名` - - 密码: `你的Turn密码` - - 正常的话,能看到 "Reachable" 消息。 +**工程师提示**:关于 Coturn 在生产环境中的详细配置(如 SSL 证书、用户名、密码等),将在 `第 4 节:应用部署` 中与 Nginx 和主应用一同进行,以确保流程的统一和简化。 ## 4. 应用部署 (生产环境) @@ -142,8 +74,8 @@ sudo apt install coturn ### 4.1. 获取代码并安装依赖 ```bash -git clone privydrop -cd privydrop +git clone https://github.com/david-bai00/PrivyDrop.git +cd PrivyDrop # 安装后端依赖 cd backend && npm install && cd .. @@ -156,7 +88,7 @@ cd frontend && pnpm install && cd .. ```bash cd frontend && pnpm build && cd .. -cd backend && npm build && cd .. +cd backend && npm run build && cd .. ``` 这将分别在 `frontend/.next` 和 `backend/dist` 目录生成优化后的生产版本。 @@ -169,40 +101,116 @@ cd backend && npm build && cd .. 2. **防火墙:** 确保 `TCP:80 (HTTP)` 和 `TCP/UDP:443 (HTTPS/HTTP3)` 端口已打开。 -3. **主域名 SSL 证书:** 为你的主域名 (如 `yourdomain.com`) 获取证书。 +3. **生成 Nginx 基础配置:** + 后端项目 `backend/docker/Nginx/` 目录中提供了配置脚本和模板。此模板使用一个临时的“占位符”证书,以确保 Nginx 配置在申请真实证书前是有效的。 + + - 在后端的 `.env.production` 文件中添加 `NGINX_*` 相关变量,**无需 SSL 证书路径**。示例为: + ``` + NGINX_SERVER_NAME=privydrop.app # 你的主域名 + NGINX_FRONTEND_ROOT=/path/to/your/PrivyDrop/frontend # 前端项目根目录 + ``` + - 执行脚本生成 Nginx 配置文件: + ```bash + # 此脚本会使用 .env 文件中的变量来生成 Nginx 配置文件 + sudo bash backend/docker/Nginx/configure.sh backend/.env.production + ``` +### 4.4. 使用 Certbot 安装统一 SSL 证书 + +现在 Nginx 有了基础配置,我们可以使用 Certbot 来获取并安装真实的 SSL 证书。我们将为所有服务(主域名、www 和 TURN)申请一张统一的证书,并让 Certbot 自动更新 Nginx 配置。 + +1. **安装 Certbot 的 Nginx 插件:** ```bash sudo apt install python3-certbot-nginx - sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com ``` -4. **Nginx 配置文件:** - 后端项目 `backend/docker/Nginx/` 目录中提供了配置脚本和模板。 +2. **运行 Certbot 申请证书:** + - 此命令会自动检测您的 Nginx 配置并为其安装证书。 + - `-d` 参数指定所有需要包含在此证书中的域名。请确保您的域名 DNS 已正确解析到服务器 IP。 + - `--deploy-hook` 是一个关键参数:它会在证书成功续期后,自动重启 Coturn 服务,以加载新证书。这实现了完全自动化的证书维护。 - - 在后端的 `.env.production` 文件中添加 `NGINX_*` 相关变量,包括域名、证书路径和**前端构建产物的根目录**,示例为: - - ``` - NGINX_SERVER_NAME=yourdomain # 不带 www 前缀,yourdomain包含了后缀 - NGINX_SSL_CERT=/etc/letsencrypt/live/yourdomain/fullchain.pem - NGINX_SSL_KEY=/etc/letsencrypt/live/yourdomain/privkey.pem - NGINX_FRONTEND_ROOT=/path/to/your/frontend/build # 前端静态文件构建产物的路径 - ``` - -5. **应用配置:** 创建软链接并重启 Nginx。 ```bash - # 此脚本会使用 .env.production 中的 NGINX_* 变量来生成 Nginx 配置文件 - sudo bash docker/Nginx/configure.sh .env.production + # 将 privydrop.app 替换为你的主域名 + sudo certbot --nginx \ + -d privydrop.app \ + -d www.privydrop.app \ + -d turn.privydrop.app \ + --deploy-hook "sudo systemctl restart coturn" + ``` + 按照 Certbot 的提示操作(例如输入邮箱、同意服务条款等)。 + +3. **验证与排错 (重要):** + 首先,验证 Nginx 配置文件中的证书路径是否已自动更新。 + ```bash + sudo grep ssl_certificate /etc/nginx/sites-available/default + ``` + 正常情况下,您应该能看到指向 `/etc/letsencrypt/live/privydrop.app/` 的路径。 + + 如果 `certbot --nginx` 执行后,上述路径依然是旧的占位符路径,请运行以下命令强制更新证书: + ```bash + sudo certbot install --cert-name privydrop.app -d privydrop.app -d www.privydrop.app -d turn.privydrop.app + # 然后重载 Nginx 使之生效 + sudo systemctl reload nginx ``` -### 4.4. 配置环境变量 +### 4.5. 配置并启动 TURN 服务 (生产环境) -- **后端:** - - 在 `backend/` 目录下创建 `.env.production` 或 `.env.development` 文件 - - 在 `.env.development` 文件中填入环境变量 (BACKEND_PORT, REDIS_HOST, REDIS_PORT, CORS_ORIGIN)。 - - 在 `.env.production` 文件中除了上述变量外,还要加入 (NGINX_SERVER_NAME, NGINX_SSL_CERT, NGINX_SSL_KEY, NGINX_FRONTEND_ROOT)。 -- **前端:** 在 `frontend/` 目录下创建 `.env.production` 或 `.env.development` 文件,并填入环境变量 (NEXT_PUBLIC_API_URL)。 +获取到统一的 SSL 证书后,我们现在来完成 Coturn 服务的生产环境配置。 -### 4.5. 使用 PM2 运行应用 +1. **配置环境变量**: + 在后端的 `.env.production` 文件中,配置所有 `TURN_*` 相关变量。 + ```ini + # .env.production + + # ... 其他变量 ... + + # TURN/STUN Server (Coturn) Configuration + TURN_REALM=turn.privydrop.app # 你的 TURN 域名 + TURN_USERNAME=YourTurnUsername # 设置一个安全的用户名 + TURN_PASSWORD=YourTurnPassword # 设置一个强密码 + + # 关键:将证书路径指向由 Certbot 为主域名生成的统一证书 + TURN_CERT_PATH=/etc/letsencrypt/live/privydrop.app/fullchain.pem + TURN_KEY_PATH=/etc/letsencrypt/live/privydrop.app/privkey.pem + ``` + +2. **验证 SSL 证书权限**: + Coturn 进程通常以一个低权限用户(如 `turnserver` 或 `coturn`)运行,而 Certbot 生成的证书文件默认属于 `root` 用户。因此,我们需要调整权限,确保 Coturn 有权限读取证书。 + + ```bash + # (可选) 查找 coturn 服务的运行用户 + # ps aux | grep turnserver + + # 创建一个共享组,并将 turnserver 用户添加进去 + sudo groupadd -f ssl-cert + sudo usermod -a -G ssl-cert turnserver # 如果运行用户不是 turnserver,请替换 + + # 更改证书目录的所有权和权限 + sudo chown -R root:ssl-cert /etc/letsencrypt/ + sudo chmod -R 750 /etc/letsencrypt/ + ``` +3. **生成配置文件并启动服务**: + 运行项目提供的脚本,它会根据 `.env.production` 文件生成 `/etc/turnserver.conf` 并重启 Coturn。 + ```bash + # 使用你的 .env 文件路径 + sudo bash backend/docker/TURN/configure.sh backend/.env.production + ``` +4. **检查服务状态与在线测试**: + - 检查服务状态: + ```bash + sudo systemctl status coturn + # 同时检查日志确保没有权限错误 + # sudo journalctl -u coturn -f + ``` + - **在线测试 (推荐)**: + 服务启动后,使用在线工具,如 [Metered TURN Server Tester](https://www.metered.ca/turn-server-testing),验证 TURNS 服务是否正常工作: + - **TURNS URL**: `turns:turn.privydrop.app:5349` (将域名替换为你的) + - **Username**: `你在 .env 中设置的用户名` + - **Password**: `你在 .env 中设置的密码` + + 如果所有检查点都显示绿色 "Success" 或 "Reachable",则表示您的 TURN 服务器已成功配置。 + +### 4.6. 使用 PM2 运行应用 PM2 是一个强大的 Node.js 进程管理器,我们将用它来分别运行后端服务和前端服务。 @@ -217,15 +225,20 @@ PM2 是一个强大的 Node.js 进程管理器,我们将用它来分别运行 ```bash cd backend + # 如果之前运行过,则先执行 + sudo pm2 stop signaling-server && sudo pm2 delete signaling-server # 确保 .env.production 已配置完毕 - pm2 start ecosystem.config.js + sudo pm2 start ecosystem.config.js ``` 3. **启动前端服务:** ```bash cd frontend - pm2 start npm --name "privydrop-frontend" -- run start + # 如果之前运行过,则先执行 + sudo pm2 stop privydrop-frontend && sudo pm2 delete privydrop-frontend + + sudo pm2 start npm --name "privydrop-frontend" -- run start ``` `npm start` 会启动 Next.js 的生产服务器,默认监听 3000 端口。 @@ -240,9 +253,10 @@ PM2 是一个强大的 Node.js 进程管理器,我们将用它来分别运行 - **连接问题:** 检查防火墙、Nginx 代理设置、CORS_ORIGIN 配置,确保所有 PM2 进程都在运行。 - **Nginx 错误:** `sudo nginx -t` 检查语法,查看 `/var/log/nginx/error.log`。 - **PM2 问题:** `pm2 logs ` 查看应用日志。 -- **证书权限 (生产环境):** 如果 Coturn 或 Nginx 无法读取 SSL 证书,请仔细检查文件权限和用户/组设置。 +- **证书权限 (生产环境):** 如果 Coturn 或 Nginx 无法读取 SSL 证书,请仔细检查 `第 4.5 节` 中的文件权限和用户/组设置。 + ## 7. 安全与维护 -- **SSL 证书续订 (生产环境相关):** 可以参考 `backend/docker/Nginx/renew_ssl.sh` 脚本进行自动续订。 +- **SSL 证书续订:** 当你使用 `certbot --nginx` 并配合 `--deploy-hook` 成功配置证书后,Certbot 会自动处理 Nginx 证书的续订和 Coturn 服务的重启。你无需手动干预或使用额外的脚本。 - **防火墙:** 保持防火墙规则严格,仅允许必要的端口。