diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md deleted file mode 100644 index 3878c76..0000000 --- a/docs/DEPLOYMENT.md +++ /dev/null @@ -1,400 +0,0 @@ -# PrivyDrop Deployment Guide (Bare-Metal) - -> Audience & Scope: This guide targets developers/operators who prefer a non-container (bare-metal) setup. -> -> Recommended: Prefer the one-click Docker deployment for simplicity and robustness, including auto HTTPS and TURN. See [Docker Deployment Guide](./DEPLOYMENT_docker.md). - -This guide provides comprehensive instructions for deploying the full-stack PrivyDrop application, including setting up Redis, a TURN server, the backend service, the frontend application, and configuring Nginx as a reverse proxy. - -## 1. Introduction - -This document will guide you through preparing your server environment, configuring dependencies, and deploying both the frontend and backend of PrivyDrop. Whether you are setting up a development/testing environment or a full production instance, this guide aims to cover all essential aspects. - -## 2. Prerequisites - -Before you begin, please ensure your server environment meets the following requirements: - -- **Operating System:** A Linux distribution (e.g., Ubuntu 20.04 LTS or newer is recommended). -- **Node.js:** v18.x or higher. -- **npm/pnpm:** The package manager for Node.js. -- **Root or Sudo Privileges:** Required for installing packages and configuring services. -- **Domain Name:** Required for a production deployment. -- **Optional: Base Environment & Docker Image Reference:** If you are starting from a very clean system environment or wish to see the base dependencies for a Docker build, you can refer to the `backend/docker/Dockerfile` (for Docker image creation) and `backend/docker/env_install.log` (dependency installation log) files. - -## 3. Environment Installation - -**Important Note:** The `backend/docker/env_install.sh` script in the project root contains all necessary dependency installation commands, including Node.js, Redis, Coturn, Nginx, and more. You can run this script directly to install all dependencies: - -```bash -# Make the script executable -chmod +x backend/docker/env_install.sh - -# Run the installation script -sudo bash backend/docker/env_install.sh -``` - -This script will automatically install: - -- **Node.js v20** - Runtime environment -- **Redis Server** - Used for room management and caching -- **Coturn** - TURN/STUN server (optional, for NAT traversal) -- **Nginx** - Web server and reverse proxy (from official repository) -- **PM2** - Node.js process manager -- **Certbot** - SSL certificate management - -After installation, you can verify the services: - -```bash -# Verify Node.js version -node -v - -# Verify Redis status -sudo systemctl status redis-server - -# Verify Nginx installation -nginx -V - -# Verify Coturn installation -sudo systemctl status coturn -``` - -**Configuration Notes:** - -- **Redis Configuration:** Default listening on `127.0.0.1:6379`, ensure your backend `.env` file includes correct `REDIS_HOST` and `REDIS_PORT` -- **TURN Service:** Optional configuration, PrivyDrop uses public STUN servers by default, only needed for extremely high NAT traversal requirements -- **Nginx:** Script installs official version and verifies stream module support - -**TURN Server Firewall Configuration (if configuring TURN service):** - -```bash -# Enable the Coturn service -sudo sed -i 's/#TURNSERVER_ENABLED=1/TURNSERVER_ENABLED=1/' /etc/default/coturn - -# Firewall Configuration: Open Turnserver default ports -sudo ufw allow Turnserver -sudo ufw reload -``` - -The ports seen via `sudo ufw app info Turnserver` are as follows: - -- `3478,3479,5349,5350,49152:65535/tcp` -- `3478,3479,5349,5350,49152:65535/udp` - -## 4. Application Deployment (Production) - -This section describes how to deploy PrivyDrop in a production environment using Nginx and PM2. - -### 4.1. Get the Code and Install Dependencies - -```bash -git clone https://github.com/david-bai00/PrivyDrop.git -cd PrivyDrop - -# Install backend dependencies -cd backend && npm install && cd .. - -# Install frontend dependencies -cd frontend && pnpm install && cd .. -``` - -### 4.2. Build the Application - -```bash -cd frontend && pnpm build && cd .. -cd backend && npm run build && cd .. -``` - -This will generate an optimized production build in the `frontend/.next` and `backend/dist` directories. - -### 4.3. Configure Nginx as a Reverse Proxy - -In production, Nginx will act as the entry point for all traffic, handling SSL termination and routing requests to the correct frontend or backend service. - -1. **Prepare Production Environment Variables for Backend and Frontend** - Before deployment, ensure the production environment files for both backend and frontend are ready. You will need to copy them from the example files and modify them with your server's information. - - - **Backend Configuration:** - - ```bash - # From the project root - cp backend/.env_production_example backend/.env.production - ``` - - Then, edit `backend/.env.production`, configuring at least `CORS_ORIGIN` to your main domain (e.g., `https://privydrop.app`) and your `REDIS` details. - - - **Frontend Configuration:** - ```bash - # From the project root - cp frontend/.env_production_example frontend/.env.production - ``` - Then, edit `frontend/.env.production` to set `NEXT_PUBLIC_API_URL` to your backend service domain (e.g., `https://privydrop.app`). - -2. **Firewall:** - Open 'Nginx Full' default ports and 443/udp: - - ```bash - sudo ufw allow 'Nginx Full' - sudo ufw reload # or ufw enable - ``` - - The ports seen via `sudo ufw app info 'Nginx Full'` are as follows: - 80,443/tcp - -3. **Generate Base Nginx Configuration:** - The `backend/docker/Nginx/` directory provides a configuration script and template. This template uses a temporary "placeholder" certificate to ensure the Nginx configuration is valid before obtaining a real certificate. - - - Now, edit the `backend/.env.production` file and add the `NGINX_*` related variables. **Do not include SSL certificate paths yet**. Example: - ``` - NGINX_SERVER_NAME=privydrop.app # Your main domain - NGINX_FRONTEND_ROOT=/path/to/your/PrivyDrop/frontend # Path to the frontend project root - TURN_REALM=turn.privydrop.app # TURN server domain name (if configuring TURN service) - ``` - - Execute the script to generate the Nginx configuration file: - ```bash - # This script uses variables from your .env file to generate the Nginx config - sudo bash backend/docker/Nginx/configure.sh backend/.env.production - ``` - -### 4.4. Use Certbot to Install a Unified SSL Certificate - -With the base Nginx configuration in place, we can now use Certbot to obtain and install a real SSL certificate. We will request a single, unified certificate for all our services (main domain, www, and TURN) and let Certbot automatically update your Nginx configuration. - -1. **Install Certbot's Nginx Plugin:** - - ```bash - sudo apt install python3-certbot-nginx - ``` - -2. **Run Certbot to Request the Certificate:** - - - This command automatically detects your Nginx configuration. - - The `-d` flag specifies all domains to be included in the certificate. Ensure your domains' DNS records correctly point to your server's IP. - - The `--deploy-hook` is a crucial parameter: it will automatically restart the Coturn service after a successful certificate renewal, applying the new certificate. This enables fully automated certificate maintenance. - - ```bash - # Replace privydrop.app with your main domain - sudo certbot --nginx \ - -d privydrop.app \ - -d www.privydrop.app \ - -d turn.privydrop.app \ - --deploy-hook "sudo systemctl restart coturn" - ``` - - Follow the on-screen prompts from Certbot (e.g., enter your email, agree to the ToS). Once complete, Certbot will automatically modify your Nginx configuration to enable HTTPS and reload the Nginx service. - - Run the following command to check if the certificate path has been replaced: - - ```bash - sudo grep ssl_certificate /etc/nginx/sites-enabled/default - ``` - - You should see a path pointing to `/etc/letsencrypt/live/privydrop.app/` - -3. **Remove the redundant configuration generated by Certbot:** - - ```bash - sudo bash backend/docker/Nginx/del_redundant_cfg.sh - ``` - -4. **start nginx:** - ```bash - sudo systemctl start[reload] nginx - ``` - If you see an error "Address already in use" (check via `systemctl status nginx.service`), run `pkill nginx`. - -### 4.5. Configure and Start the TURN Service (Production) - -With the unified SSL certificate obtained, we can now complete the production configuration for the Coturn service. - -1. **Configure Environment Variables**: - Open your `backend/.env.production` file and configure all `TURN_*` related variables. - - ```ini - # .env.production - - # ... other variables ... - - # TURN/STUN Server (Coturn) Configuration - TURN_REALM=turn.privydrop.app # Your TURN domain - TURN_USERNAME=YourTurnUsername # Set a secure username - TURN_PASSWORD=YourTurnPassword # Set a strong password - - # Critical: Point to the unified certificate generated by Certbot for your main domain - TURN_CERT_PATH=/etc/letsencrypt/live/privydrop.app/fullchain.pem - TURN_KEY_PATH=/etc/letsencrypt/live/privydrop.app/privkey.pem - ``` - -2. **Verify SSL Certificate Permissions**: - The Coturn process typically runs as a low-privilege user (e.g., `turnserver` or `coturn`), while certificates generated by Certbot are owned by `root`. We need to adjust permissions to allow Coturn to read the certificate. - - ```bash - # (Optional) Find the user the coturn service runs as - # ps aux | grep turnserver - - # Create a shared group and add the turnserver user to it - sudo groupadd -f ssl-cert - sudo usermod -a -G ssl-cert turnserver # Replace 'turnserver' if the user is different - - # Change ownership and permissions of the certificate directories - sudo chown -R root:ssl-cert /etc/letsencrypt/ - sudo chmod -R 750 /etc/letsencrypt/ - ``` - -3. **Generate Configuration File and Start the Service**: - Run the provided script, which will generate `/etc/turnserver.conf` from your `.env.production` file and restart Coturn. - ```bash - # Located in the backend/ directory - # Use the path to your .env file - sudo bash ./docker/TURN/configure.sh backend/.env.production - ``` -4. **Check Service Status and Test Online**: - - - Check the service status: - ```bash - sudo systemctl status coturn - # Also, check the logs to ensure there are no permission errors - # sudo journalctl -u coturn -f - ``` - - **Online Test (Recommended)**: - Once the service is running, use an online tool like the [Metered TURN Server Tester](https://www.metered.ca/turn-server-testing) to verify that your TURNS service is working correctly: - - - **TURNS URL**: `turn:turn.privydrop.app:3478` (replace with your domain) - - **Username**: `The username you set in your .env file` - - **Password**: `The password you set in your .env file` - - If all checkpoints show a green "Success" or "Reachable", your TURN server is configured successfully. - -### 4.6. Run the Application with PM2 - -PM2 is a powerful process manager for Node.js. We will use it to run both backend and frontend services. - -1. **Start Services Using Unified Configuration:** - - The project root directory provides a unified `ecosystem.config.js` configuration file that can start all services at once: - - ```bash - # If services were previously running, stop and delete them first - sudo pm2 stop all && sudo pm2 delete all - - # Start all services using the unified configuration file - sudo pm2 start ecosystem.config.js - ``` - -2. **Manage Applications:** - - View status: `pm2 list` - - View logs: `pm2 logs ` (e.g., `pm2 logs signaling-server` or `pm2 logs privydrop-frontend`) - - Set up startup script: `pm2 startup` followed by `pm2 save` - - Restart services: `pm2 restart all` or specific service `pm2 restart signaling-server` - - Stop services: `pm2 stop all` or specific service `pm2 stop privydrop-frontend` - -### 4.7. Daily Incremental Update (Local Build + Remote Replace) - -This section describes how to build locally and deploy only the built artifacts to the server. It is optimized for day-to-day releases: fast, low resource usage on the server, and easy to verify. - -- Assumes you have completed the first-time deployment and can access the app in production. -- The frontend runs in Next.js Standalone mode (configured in `ecosystem.config.js`), so the server does not need Next CLI or frontend dependencies installed. - -0. Sync frontend production environment variables (important) - - The local build reads variables from `frontend/.env.production` (e.g., `NEXT_PUBLIC_API_URL`, TURN settings, and build-time flags like `NEXT_IMAGE_UNOPTIMIZED`). To ensure the build matches production behavior, copy the production environment file from the server to your local machine before running `bash build-and-deploy.sh`. - - - Example (sync from server to local): - ```bash - # Assuming the server project root is /root/PrivyDrop - scp root@:/root/PrivyDrop/frontend/.env.production ./frontend/.env.production - ``` - - If the file does not exist on the server yet, create it from the example and keep it consistent with production: - ```bash - cp frontend/.env_production_example frontend/.env.production - # Fill in NEXT_PUBLIC_API_URL, TURN_*, NEXT_IMAGE_UNOPTIMIZED, etc. - ``` - - Note: `build-and-deploy.sh` does not auto-create or overwrite `frontend/.env.production`. Make sure it exists locally and matches production; otherwise, the built behavior may differ from the server (e.g., image optimization toggles). - -1. Prepare deployment configuration - - - From the project root: - ```bash - cp deploy.config.example deploy.config - ``` - - Edit `deploy.config` with at least: - ```bash - DEPLOY_SERVER="" - DEPLOY_USER="root" # Recommended: use ssh root for simplicity - DEPLOY_PATH="/root/PrivyDrop" # Project root on the server - # Optional: SSH_PORT, SSH_KEY_PATH - ``` - - Security notes: Use SSH key authentication, restrict source IPs, and enforce firewall rules in production. - -2. Build locally and deploy - - - From the project root: - ```bash - bash build-and-deploy.sh - ``` - - When an existing package (out.zip) is detected, the script lets you choose: - - 1. Deploy existing package - - 2. Rebuild and deploy - - Script flow (summary): - - Build frontend and backend locally - - Package artifacts into `out.zip` - - Upload to server path `/tmp/out.zip` - - Server-side backup to `/tmp/privydrop_backup/YYYYmmdd_HHMMSS/` - - Unzip and replace: - - Frontend: `frontend/.next` (includes `.next/standalone` and `.next/static`) - - Frontend static assets: `frontend/public` - - Frontend content: `frontend/content` (for blog file reads) - - Backend: `backend/dist` - - Restart using `pm2 start ecosystem.config.js` - -3. Post-deployment verification - - - Check process status on the server: - ```bash - ssh root@ 'sudo pm2 status' - ``` - - Compare frontend BUILD_ID (optional): - ```bash - ssh root@ 'cat /root/PrivyDrop/frontend/.next/BUILD_ID' - ``` - - Force refresh the browser or use an incognito window to confirm the new version. - -4. Backups and manual rollback - - - Each deployment creates a structured backup on the server at `/tmp/privydrop_backup/YYYYmmdd_HHMMSS/`: - - Frontend: `frontend/.next` - - Backend: `backend/dist` - - To rollback manually (example): - - ```bash - # Stop PM2 - sudo pm2 stop all && sudo pm2 delete all - - # Choose a backup directory, e.g. /tmp/privydrop_backup/20241024_235959 - export DEPLOY_PATH=/root/PrivyDrop - export BACKUP=/tmp/privydrop_backup/20241024_235959 - - # Restore frontend and backend build artifacts - rm -rf "$DEPLOY_PATH/frontend/.next" "$DEPLOY_PATH/backend/dist" - cp -a "$BACKUP/frontend/.next" "$DEPLOY_PATH/frontend/.next" - cp -a "$BACKUP/backend/dist" "$DEPLOY_PATH/backend/dist" - - # Restart PM2 - sudo pm2 start ecosystem.config.js - ``` - -5. Common issues - - Page still shows the old version: clear browser cache/force refresh; compare BUILD_ID; check Nginx/CDN caching. - - Blog posts not loading: ensure `frontend/content/blog` exists on the server and the PM2 frontend process `cwd` is `./frontend`. - - `out.zip not found`: choose “Rebuild and deploy” to create a new package. - -## 5. Troubleshooting - -- **Connection Issues:** Check firewall settings, Nginx proxy configurations, `CORS_ORIGIN` settings, and ensure all PM2 processes are running. -- **Nginx Errors:** Use `sudo nginx -t` to check syntax and review `/var/log/nginx/error.log`. -- **PM2 Issues:** Use `pm2 logs ` to view application logs. -- **Certificate Permissions (Production):** If Coturn or Nginx cannot read SSL certificates, carefully review the file permissions and user/group settings in `Section 4.5`. - -## 6. Security & Maintenance - -- **SSL Certificate Renewal:** When you successfully configure your certificate using `certbot --nginx` with the `--deploy-hook`, Certbot automatically creates a renewal task for both Nginx and Coturn. No manual intervention is required; the certificate will be renewed and applied automatically before it expires. -- **Firewall:** Maintain strict firewall rules, only allowing necessary ports. diff --git a/docs/DEPLOYMENT.zh-CN.md b/docs/DEPLOYMENT.zh-CN.md deleted file mode 100644 index 60db8e6..0000000 --- a/docs/DEPLOYMENT.zh-CN.md +++ /dev/null @@ -1,400 +0,0 @@ -# Privydrop 部署指南(裸机部署) - -> 说明与定位:本指南面向具备 Linux 运维能力的开发者,介绍“裸机(非容器)”部署方式。 -> -> 推荐方案:优先使用“一键 Docker 部署”,更简单、更稳健,支持自动签发/续期证书与 TURN。详见 [Docker 部署指南](./DEPLOYMENT_docker.zh-CN.md)。 - -本指南提供部署 Privydrop 全栈应用的全面说明,包括设置 Redis、TURN 服务器、后端服务、前端应用以及配置 Nginx 作为反向代理。 - -## 1. 引言 - -本文档将引导您完成准备服务器环境、配置依赖项和部署 Privydrop 的前后端。无论您是设置开发/测试环境还是完整的生产实例,本指南都旨在涵盖所有基本方面。 - -## 2. 先决条件 - -在开始之前,请确保您的服务器环境满足以下要求: - -- **操作系统:** Linux 发行版(例如,推荐 Ubuntu 20.04 LTS 或更高版本)。 -- **Node.js:** v18.x 或更高版本。 -- **npm/pnpm:** Node.js 的包管理器。 -- **Root 或 Sudo 权限:** 安装软件包和配置服务所需。 -- **域名:** 生产环境部署需要一个域名。 -- **可选:基础环境与 Docker 镜像参考:** 如果您需要从一个非常纯净的系统环境开始搭建,或者希望了解用于 Docker 构建的基础依赖,可以参考 `backend/docker/Dockerfile` 文件(用于 Docker 基础镜像构建)和 `backend/docker/env_install.log` 文件(依赖安装记录)。 - -## 3. 环境安装 - -**重要提示:** 项目根目录的 `backend/docker/env_install.sh` 脚本包含了所有必要的依赖安装命令,包括 Node.js、Redis、Coturn、Nginx 等。您可以直接运行此脚本来安装所有依赖: - -```bash -# 确保脚本有执行权限 -chmod +x backend/docker/env_install.sh - -# 运行安装脚本 -sudo bash backend/docker/env_install.sh -``` - -该脚本将自动安装: - -- **Node.js v20** - 运行环境 -- **Redis Server** - 用于房间管理和缓存 -- **Coturn** - TURN/STUN 服务器(可选,用于 NAT 穿透) -- **Nginx** - Web 服务器和反向代理(使用官方仓库) -- **PM2** - Node.js 进程管理器 -- **Certbot** - SSL 证书管理 - -安装完成后,可以验证各服务状态: - -```bash -# 验证 Node.js 版本 -node -v - -# 验证 Redis 状态 -sudo systemctl status redis-server - -# 验证 Nginx 安装 -nginx -V - -# 验证 Coturn 安装 -sudo systemctl status coturn -``` - -**注意事项:** - -- **Redis 配置:** 默认监听 `127.0.0.1:6379`,请确保后端 `.env` 文件中包含正确的 `REDIS_HOST` 和 `REDIS_PORT` -- **TURN 服务:** 为可选配置,Privydrop 默认使用公共 STUN 服务器,只有对 NAT 穿透有极高要求时才需要配置 -- **Nginx:** 脚本安装官方版本并验证 stream 模块支持 - -**TURN 服务器防火墙配置(如果需要配置 TURN 服务):** - -```bash -# 启用 Coturn 服务 -sudo sed -i 's/#TURNSERVER_ENABLED=1/TURNSERVER_ENABLED=1/' /etc/default/coturn - -# 防火墙配置:打开 Turnserver 默认端口 -sudo ufw allow Turnserver -sudo ufw reload -``` - -通过 `sudo ufw app info Turnserver` 看到的端口如下: - -- `3478,3479,5349,5350,49152:65535/tcp` -- `3478,3479,5349,5350,49152:65535/udp` - -## 4. 应用部署 (生产环境) - -本节介绍如何使用 Nginx 和 PM2 在生产环境部署 PrivyDrop。 - -### 4.1. 获取代码并安装依赖 - -```bash -git clone https://github.com/david-bai00/PrivyDrop.git -cd PrivyDrop - -# 安装后端依赖 -cd backend && npm install && cd .. - -# 安装前端依赖 -cd frontend && pnpm install && cd .. -``` - -### 4.2. 构建应用 - -```bash -cd frontend && pnpm build && cd .. -cd backend && npm run build && cd .. -``` - -这将分别在 `frontend/.next` 和 `backend/dist` 目录生成优化后的生产版本。 - -### 4.3. 配置 Nginx 作为反向代理 - -在生产中,Nginx 将作为所有流量的入口,负责 SSL 终止,并将请求路由到正确的前端或后端服务。 - -1. **为后端和前端准备生产环境变量** - 在部署之前,请确保后端和前端的生产环境变量文件已准备就绪。您需要从示例文件复制并根据您的服务器信息进行修改。 - - - **后端配置:** - - ```bash - # 位于项目根目录 - cp backend/.env_production_example backend/.env.production - ``` - - 然后编辑 `backend/.env.production`,至少配置 `CORS_ORIGIN` 为您的主域名 (例如 `https://privydrop.app`) 以及 `REDIS` 相关信息。 - - - **前端配置:** - ```bash - # 位于项目根目录 - cp frontend/.env_production_example frontend/.env.production - ``` - 然后编辑 `frontend/.env.production`,配置 `NEXT_PUBLIC_API_URL` 为您的后端服务域名 (例如 `https://privydrop.app`)。 - -2. **防火墙:** - 打开'Nginx Full'默认端口以及 443/udp - - ```bash - sudo ufw allow 'Nginx Full' - sudo ufw reload # 或 ufw enable - ``` - - 通过 sudo ufw app info 'Nginx Full'看到的端口如下: - 80,443/tcp - -3. **生成 Nginx 基础配置:** - 后端项目 `backend/docker/Nginx/` 目录中提供了配置脚本和模板。此模板使用一个临时的"占位符"证书,以确保 Nginx 配置在申请真实证书前是有效的。 - - - 现在,编辑 `backend/.env.production` 文件,添加 `NGINX_*` 相关变量。**无需 SSL 证书路径**。示例为: - ``` - NGINX_SERVER_NAME=privydrop.app # 你的主域名 - NGINX_FRONTEND_ROOT=/path/to/your/PrivyDrop/frontend # 前端项目根目录 - TURN_REALM=turn.privydrop.app # TURN 服务器域名(如需配置 TURN 服务) - ``` - - 执行脚本生成 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 - ``` - -2. **运行 Certbot 申请证书:** - - - 此命令会自动检测您的 Nginx 配置并为其安装证书。 - - `-d` 参数指定所有需要包含在此证书中的域名。请确保您的域名 DNS 已正确解析到服务器 IP。 - - `--deploy-hook` 是一个关键参数:它会在证书成功续期后,自动重启 Coturn 服务,以加载新证书。这实现了完全自动化的证书维护。 - - ```bash - # 将 privydrop.app 替换为你的主域名 - sudo certbot --nginx \ - -d privydrop.app \ - -d www.privydrop.app \ - -d turn.privydrop.app \ - --deploy-hook "sudo systemctl restart coturn" - ``` - - 按照 Certbot 的提示操作(例如输入邮箱、同意服务条款等)。 - - 运行如下命令,查看证书路径是否已替换: - - ```bash - sudo grep ssl_certificate /etc/nginx/sites-enabled/default - ``` - - 应该能看到指向 `/etc/letsencrypt/live/privydrop.app/` 的路径 - -3. **删除由 Certbot 产生的多余配置:** - - ```bash - sudo bash backend/docker/Nginx/del_redundant_cfg.sh - ``` - -4. **启动 nginx 服务:** - ```bash - sudo systemctl start[reload] nginx - ``` - 如果报错显示 Address already in use(通过 systemctl status nginx.service 查看),则运行 pkill nginx。 - -### 4.5. 配置并启动 TURN 服务 (生产环境) - -获取到统一的 SSL 证书后,我们现在来完成 Coturn 服务的生产环境配置。 - -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**: `turn:turn.privydrop.app:3478` (将域名替换为你的) - - **Username**: `你在 .env 中设置的用户名` - - **Password**: `你在 .env 中设置的密码` - - 如果所有检查点都显示绿色 "Success" 或 "Reachable",则表示您的 TURN 服务器已成功配置。 - -### 4.6. 使用 PM2 运行应用 - -PM2 是一个强大的 Node.js 进程管理器,我们将用它来运行后端和前端服务。 - -1. **使用统一配置文件启动服务:** - - 项目根目录提供了一个统一的 `ecosystem.config.js` 配置文件,可以一次性启动所有服务: - - ```bash - # 如果之前运行过服务,先停止并删除 - sudo pm2 stop all && sudo pm2 delete all - - # 使用统一配置文件启动所有服务 - sudo pm2 start ecosystem.config.js - ``` - -2. **管理应用:** - - 查看状态: `pm2 list` - - 查看日志: `pm2 logs ` (例如:`pm2 logs signaling-server` 或 `pm2 logs privydrop-frontend`) - - 设置开机自启: `pm2 startup` 然后 `pm2 save` - - 重启服务: `pm2 restart all` 或指定服务 `pm2 restart signaling-server` - - 停止服务: `pm2 stop all` 或指定服务 `pm2 stop privydrop-frontend` - -### 4.7. 日常增量更新(本地构建 + 远程替换) - -本小节介绍如何在本地构建后,将前后端的生产产物一并打包上传到服务器,完成“增量更新”。该流程适合日常发布,速度快、资源占用低。 - -- 默认假设你已按“首次部署”完成环境配置(包括 PM2、Nginx/证书等),并能正常访问应用。 -- 默认使用前端 Next.js Standalone 运行方式(ecosystem.config.js 已配置),服务器无需安装前端依赖和 next CLI。 - -0. 同步前端生产环境变量(重要) - - 本地构建会读取 `frontend/.env.production` 中的变量(例如 `NEXT_PUBLIC_API_URL`、TURN 配置、以及构建期开关 `NEXT_IMAGE_UNOPTIMIZED` 等)。 - 为确保构建产物与线上一致,请在执行 `bash build-and-deploy.sh` 之前,将“线上部署环境的 `frontend/.env.production`”拷贝到本地对应路径。 - - - 示例(从服务器同步到本地): - ```bash - # 假设服务器项目根目录为 /root/PrivyDrop - scp root@:/root/PrivyDrop/frontend/.env.production ./frontend/.env.production - ``` - - 如线上暂未建立该文件,可基于示例创建并与线上保持一致: - ```bash - cp frontend/.env_production_example frontend/.env.production - # 按需填写 NEXT_PUBLIC_API_URL、TURN_*、NEXT_IMAGE_UNOPTIMIZED 等 - ``` - - 说明:`build-and-deploy.sh` 不会自动生成/覆盖你的 `frontend/.env.production`,请确保本地文件存在且与线上一致,否则可能出现与线上不一致的行为(例如图片优化开关不同导致的差异)。 - -1. 准备部署配置 - - - 在项目根目录复制示例配置: - ```bash - cp deploy.config.example deploy.config - ``` - - 编辑 `deploy.config`,至少设置: - ```bash - DEPLOY_SERVER="<你的服务器IP或域名>" - DEPLOY_USER="root" # 推荐使用 ssh root 登录(简单直接) - DEPLOY_PATH="/root/PrivyDrop" # 你的服务器项目根目录 - # 可选:SSH_PORT、SSH_KEY_PATH - ``` - - 安全建议:生产环境请启用密钥登录、限制来源 IP、开启防火墙(仅放行必要端口)。 - -2. 本地构建并部署 - - - 在项目根目录执行: - ```bash - bash build-and-deploy.sh - ``` - - 当脚本检测到现有打包(out.zip)时,可选择: - - 1. 直接部署现有包 - - 2. 重新构建并部署 - - 脚本流程(简述): - - 本地构建前端与后端 - - 将产物打包为 `out.zip` - - 上传至服务器 `/tmp/out.zip` - - 服务器侧备份当前版本到 `/tmp/privydrop_backup/YYYYmmdd_HHMMSS/` - - 解压替换: - - 前端:`frontend/.next`(包含 `.next/standalone` 与 `.next/static`) - - 前端静态资源:`frontend/public` - - 前端内容:`frontend/content`(用于博客文件读取) - - 后端:`backend/dist` - - 使用 `pm2 start ecosystem.config.js` 重启应用 - -3. 发布校验 - - - 服务器上查看进程状态: - ```bash - ssh root@ 'sudo pm2 status' - ``` - - 核对前端 BUILD_ID(可选): - ```bash - ssh root@ 'cat /root/PrivyDrop/frontend/.next/BUILD_ID' - ``` - - 浏览器强制刷新或使用隐身模式,确认页面为新版本。 - -4. 备份和回退(手工) - - - 每次部署会在服务器保存结构化备份:`/tmp/privydrop_backup/YYYYmmdd_HHMMSS/` - - 前端:`frontend/.next` - - 后端:`backend/dist` - - 如需回退,可手工执行(示例): - - ```bash - # 停止 PM2 - sudo pm2 stop all && sudo pm2 delete all - - # 假设选定备份目录为 /tmp/privydrop_backup/20241024_235959 - export DEPLOY_PATH=/root/PrivyDrop - export BACKUP=/tmp/privydrop_backup/20241024_235959 - - # 恢复前端与后端构建产物 - rm -rf "$DEPLOY_PATH/frontend/.next" "$DEPLOY_PATH/backend/dist" - cp -a "$BACKUP/frontend/.next" "$DEPLOY_PATH/frontend/.next" - cp -a "$BACKUP/backend/dist" "$DEPLOY_PATH/backend/dist" - - # 重启 PM2 - sudo pm2 start ecosystem.config.js - ``` - -5. 常见问题 - - 页面仍显示旧版本:清除浏览器缓存/强制刷新;核对 BUILD_ID;检查 Nginx/CDN 缓存。 - - 前端博客文章为空:确认服务器目录存在 `frontend/content/blog`,并确保 PM2 前端进程的 `cwd` 为 `./frontend`。 - - 部署脚本报错 `out.zip not found`:先选择“重新构建并部署”。 - -## 5. 故障排除 - -- **连接问题:** 检查防火墙、Nginx 代理设置、CORS_ORIGIN 配置,确保所有 PM2 进程都在运行。 -- **Nginx 错误:** `sudo nginx -t` 检查语法,查看 `/var/log/nginx/error.log`。 -- **PM2 问题:** `pm2 logs ` 查看应用日志。 -- **证书权限 (生产环境):** 如果 Coturn 或 Nginx 无法读取 SSL 证书,请仔细检查 `第 4.5 节` 中的文件权限和用户/组设置。 - -## 6. 安全与维护 - -- **SSL 证书续订:** 当你使用 `certbot --nginx` 并配合 `--deploy-hook` 成功配置证书后,Certbot 会自动处理 Nginx 证书的续订和 Coturn 服务的重启。你无需手动干预或使用额外的脚本。 -- **防火墙:** 保持防火墙规则严格,仅允许必要的端口。