From 7d752073fbad0c3e32f99a8233d55fba538f4edf Mon Sep 17 00:00:00 2001 From: WrBug Date: Sun, 7 Dec 2025 17:08:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=AE=89=E5=85=A8?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E5=92=8C=E9=83=A8=E7=BD=B2=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加 JWT_SECRET 和 ADMIN_RESET_PASSWORD_KEY 安全检查,防止使用默认值 - 创建 docker-compose.prod.yml 和 docker-compose.prod.env.example,支持独立部署 - 添加 Nginx 反向代理配置示例,支持 HTTPS 和域名绑定 - 更新部署文档,将 Docker Hub 部署方式放在首位 - 添加多架构构建支持(amd64、arm64) - 优化部署文档结构,提供更清晰的部署指南 --- .github/workflows/docker-build.yml | 5 + README.md | 87 +++++++++++--- deploy.sh | 56 +++++++++ docker-compose.prod.env.example | 49 ++++++++ docker-compose.prod.yml | 67 +++++++++++ docker-compose.yml | 3 + docker/start.sh | 35 ++++++ docs/DEPLOYMENT.md | 182 ++++++++++++++++++++++++++++- docs/nginx-reverse-proxy.conf | 170 +++++++++++++++++++++++++++ 9 files changed, 637 insertions(+), 17 deletions(-) create mode 100644 docker-compose.prod.env.example create mode 100644 docker-compose.prod.yml create mode 100644 docs/nginx-reverse-proxy.conf diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index ae5381f..54ba879 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -43,6 +43,9 @@ jobs: - name: Set up Docker Buildx if: github.event.action == 'published' uses: docker/setup-buildx-action@v3 + with: + # 启用多架构构建支持 + platforms: linux/amd64,linux/arm64 - name: Log in to Docker Hub uses: docker/login-action@v3 @@ -57,6 +60,8 @@ jobs: context: . file: ./Dockerfile push: true + # 多架构构建:支持 amd64 和 arm64 + platforms: linux/amd64,linux/arm64 tags: | wrbug/polyhermes:${{ steps.extract_version.outputs.TAG }} wrbug/polyhermes:latest diff --git a/README.md b/README.md index ab19216..2dd86af 100644 --- a/README.md +++ b/README.md @@ -115,10 +115,75 @@ **部署步骤**: -1. **使用部署脚本(推荐)** +1. **使用 Docker Hub 镜像(推荐,生产环境首选)** + +**方式 1:独立部署(无需 clone 代码,推荐)** + +适用于生产环境,无需下载项目代码,只需两个文件即可部署: ```bash -# 在项目根目录 +# 1. 创建部署目录 +mkdir polyhermes && cd polyhermes + +# 2. 下载生产环境配置文件 +# 从 GitHub 下载 docker-compose.prod.yml 和 docker-compose.prod.env.example +curl -O https://raw.githubusercontent.com/WrBug/PolyHermes/main/docker-compose.prod.yml +curl -O https://raw.githubusercontent.com/WrBug/PolyHermes/main/docker-compose.prod.env.example + +# 3. 创建配置文件 +cp docker-compose.prod.env.example .env + +# 4. 编辑 .env 文件,修改以下必需配置: +# - DB_PASSWORD: 数据库密码 +# - JWT_SECRET: 使用 openssl rand -hex 64 生成 +# - ADMIN_RESET_PASSWORD_KEY: 使用 openssl rand -hex 32 生成 + +# 5. 启动服务 +docker-compose -f docker-compose.prod.yml up -d + +# 6. 查看日志 +docker-compose -f docker-compose.prod.yml logs -f + +# 7. 停止服务 +docker-compose -f docker-compose.prod.yml down +``` + +**方式 2:使用部署脚本(需要 clone 代码)** + +```bash +# 如果已经 clone 了代码 +./deploy.sh --use-docker-hub +``` + +**方式 3:修改现有 docker-compose.yml** + +```bash +# 1. 修改 docker-compose.yml,取消注释: +# image: wrbug/polyhermes:latest +# 并注释掉 build 部分 +# 2. 创建 .env 文件(见下方) +# 3. 启动服务 +docker-compose up -d +``` + +**优势**: +- ✅ 无需本地构建,快速部署 +- ✅ 无需 clone 代码,只需配置文件即可部署 +- ✅ 使用官方构建的镜像,包含正确的版本号 +- ✅ 支持多架构(amd64、arm64),自动选择匹配的架构 +- ✅ 生产环境推荐方式 + +**拉取特定版本**: + +```bash +# 修改 docker-compose.prod.yml 中的镜像标签 +# image: wrbug/polyhermes:v1.0.0 +``` + +2. **本地构建部署(开发环境)** + +```bash +# 使用部署脚本 ./deploy.sh ``` @@ -128,7 +193,7 @@ - 构建 Docker 镜像(包含前后端) - 启动服务(应用 + MySQL) -2. **手动部署** +3. **手动部署** ```bash # 创建 .env 文件 @@ -154,16 +219,6 @@ docker-compose logs -f docker-compose down ``` -3. **使用 Docker Hub 镜像(生产环境推荐)** - -```bash -# 使用部署脚本 -./deploy.sh --use-docker-hub - -# 或修改 docker-compose.yml,取消注释: -# image: wrbug/polyhermes:latest -``` - **访问应用**: - 前端和后端统一访问:`http://localhost:80` - Nginx 自动处理: @@ -171,6 +226,12 @@ docker-compose down - `/ws` → 后端 WebSocket(`localhost:8000`) - 其他路径 → 前端静态文件 +**使用外部 Nginx 反向代理(生产环境推荐)**: + +在生产环境中,建议在 Docker 容器外部部署 Nginx 作为反向代理,用于 SSL/TLS 终止、域名绑定等。 + +详细配置请参考:[部署文档 - Nginx 反向代理](docs/DEPLOYMENT.md#使用外部-nginx-反向代理生产环境推荐) + ### 📦 分别部署 #### 后端部署 diff --git a/deploy.sh b/deploy.sh index ce044ff..41a1ebe 100755 --- a/deploy.sh +++ b/deploy.sh @@ -89,8 +89,64 @@ EOF fi } +# 检查安全配置 +check_security_config() { + # 默认值常量 + DEFAULT_JWT_SECRET="change-me-in-production" + DEFAULT_ADMIN_RESET_KEY="change-me-in-production" + + # 从 .env 文件读取配置(如果存在) + local jwt_secret="" + local admin_reset_key="" + + if [ -f ".env" ]; then + # 从 .env 文件读取(使用 grep 和 sed 避免 source 可能的问题) + jwt_secret=$(grep "^JWT_SECRET=" .env 2>/dev/null | cut -d'=' -f2- | sed 's/^"//;s/"$//' || echo "") + admin_reset_key=$(grep "^ADMIN_RESET_PASSWORD_KEY=" .env 2>/dev/null | cut -d'=' -f2- | sed 's/^"//;s/"$//' || echo "") + fi + + # 如果环境变量已设置,优先使用环境变量 + if [ -n "$JWT_SECRET" ]; then + jwt_secret="$JWT_SECRET" + fi + if [ -n "$ADMIN_RESET_PASSWORD_KEY" ]; then + admin_reset_key="$ADMIN_RESET_PASSWORD_KEY" + fi + + local errors=0 + + # 检查 JWT_SECRET + if [ -z "$jwt_secret" ] || [ "$jwt_secret" = "$DEFAULT_JWT_SECRET" ]; then + error "JWT_SECRET 不能使用默认值 '${DEFAULT_JWT_SECRET}'" + error "请在 .env 文件中设置 JWT_SECRET 为安全的随机字符串" + errors=$((errors + 1)) + fi + + # 检查 ADMIN_RESET_PASSWORD_KEY + if [ -z "$admin_reset_key" ] || [ "$admin_reset_key" = "$DEFAULT_ADMIN_RESET_KEY" ]; then + error "ADMIN_RESET_PASSWORD_KEY 不能使用默认值 '${DEFAULT_ADMIN_RESET_KEY}'" + error "请在 .env 文件中设置 ADMIN_RESET_PASSWORD_KEY 为安全的随机字符串" + errors=$((errors + 1)) + fi + + if [ $errors -gt 0 ]; then + echo "" + error "安全配置检查失败,部署已取消" + echo "" + info "提示:可以使用以下命令生成随机密钥:" + info " openssl rand -hex 32 # 生成 32 字节的随机字符串(用于 ADMIN_RESET_PASSWORD_KEY)" + info " openssl rand -hex 64 # 生成 64 字节的随机字符串(用于 JWT_SECRET)" + exit 1 + fi + + info "安全配置检查通过" +} + # 构建并启动 deploy() { + # 检查安全配置 + check_security_config + # 检查是否使用 Docker Hub 镜像 USE_DOCKER_HUB="${USE_DOCKER_HUB:-false}" diff --git a/docker-compose.prod.env.example b/docker-compose.prod.env.example new file mode 100644 index 0000000..bbef8f3 --- /dev/null +++ b/docker-compose.prod.env.example @@ -0,0 +1,49 @@ +# PolyHermes 生产环境配置文件示例 +# +# 使用方法: +# 1. 复制此文件为 .env: cp docker-compose.prod.env.example .env +# 2. 修改以下配置项(特别是安全相关的密钥) +# 3. 运行: docker-compose -f docker-compose.prod.yml up -d + +# ============================================ +# 数据库配置 +# ============================================ +DB_URL=jdbc:mysql://mysql:3306/polyhermes?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&allowPublicKeyRetrieval=true +DB_USERNAME=root +DB_PASSWORD=your_database_password_here + +# ============================================ +# Spring Profile +# ============================================ +SPRING_PROFILES_ACTIVE=prod + +# ============================================ +# 服务器端口(对外暴露的端口) +# ============================================ +SERVER_PORT=80 + +# ============================================ +# MySQL 端口(可选,用于外部连接,默认 3307 避免与本地 MySQL 冲突) +# ============================================ +MYSQL_PORT=3307 + +# ============================================ +# Polygon RPC +# ============================================ +POLYGON_RPC_URL=https://polygon-rpc.com + +# ============================================ +# 安全配置(⚠️ 必须修改,不能使用默认值) +# ============================================ +# 生成随机密钥命令: +# openssl rand -hex 32 # 用于 ADMIN_RESET_PASSWORD_KEY +# openssl rand -hex 64 # 用于 JWT_SECRET + +JWT_SECRET=your-jwt-secret-key-here-change-in-production +ADMIN_RESET_PASSWORD_KEY=your-admin-reset-key-here-change-in-production + +# ============================================ +# 加密密钥(可选,用于加密存储私钥和 API Key) +# ============================================ +# CRYPTO_SECRET_KEY=your-crypto-secret-key-here + diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..e7b27bf --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,67 @@ +version: '3.8' + +# PolyHermes 生产环境部署配置 +# 使用 Docker Hub 官方镜像,无需本地构建 +# +# 使用方法: +# 1. 创建 .env 文件(参考下方配置) +# 2. 运行: docker-compose -f docker-compose.prod.yml up -d +# +# 注意: +# - JWT_SECRET 和 ADMIN_RESET_PASSWORD_KEY 不能使用默认值 +# - 请使用 openssl rand -hex 生成安全的随机密钥 + +services: + app: + # 使用 Docker Hub 官方镜像 + image: wrbug/polyhermes:latest + container_name: polyhermes + ports: + - "${SERVER_PORT:-80}:80" + environment: + - SPRING_PROFILES_ACTIVE=${SPRING_PROFILES_ACTIVE:-prod} + - DB_URL=${DB_URL:-jdbc:mysql://mysql:3306/polyhermes?useSSL=false&serverTimezone=UTC&characterEncoding=utf8&allowPublicKeyRetrieval=true} + - DB_USERNAME=${DB_USERNAME:-root} + - DB_PASSWORD=${DB_PASSWORD:-} + - SERVER_PORT=8000 + - POLYGON_RPC_URL=${POLYGON_RPC_URL:-https://polygon-rpc.com} + # ⚠️ 安全警告:以下两个环境变量不能使用默认值,否则容器启动会失败 + # 请在 .env 文件中设置,或通过环境变量传入 + # 生成随机密钥:openssl rand -hex 32 (ADMIN_RESET_PASSWORD_KEY) 或 openssl rand -hex 64 (JWT_SECRET) + - JWT_SECRET=${JWT_SECRET:-change-me-in-production} + - ADMIN_RESET_PASSWORD_KEY=${ADMIN_RESET_PASSWORD_KEY:-change-me-in-production} + depends_on: + mysql: + condition: service_healthy + restart: unless-stopped + networks: + - polyhermes-network + + mysql: + image: mysql:8.2 + container_name: polyhermes-mysql + ports: + - "${MYSQL_PORT:-3307}:3306" + environment: + - MYSQL_ROOT_PASSWORD=${DB_PASSWORD:-rootpassword} + - MYSQL_DATABASE=polyhermes + - MYSQL_CHARACTER_SET_SERVER=utf8mb4 + - MYSQL_COLLATION_SERVER=utf8mb4_unicode_ci + volumes: + - mysql-data:/var/lib/mysql + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p${DB_PASSWORD:-rootpassword}"] + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped + networks: + - polyhermes-network + +volumes: + mysql-data: + +networks: + polyhermes-network: + driver: bridge + diff --git a/docker-compose.yml b/docker-compose.yml index 386c68f..6841b5d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,6 +23,9 @@ services: - DB_PASSWORD=${DB_PASSWORD:-} - SERVER_PORT=8000 - POLYGON_RPC_URL=${POLYGON_RPC_URL:-https://polygon-rpc.com} + # ⚠️ 安全警告:以下两个环境变量不能使用默认值,否则容器启动会失败 + # 请在 .env 文件中设置,或通过环境变量传入 + # 生成随机密钥:openssl rand -hex 32 (ADMIN_RESET_PASSWORD_KEY) 或 openssl rand -hex 64 (JWT_SECRET) - JWT_SECRET=${JWT_SECRET:-change-me-in-production} - ADMIN_RESET_PASSWORD_KEY=${ADMIN_RESET_PASSWORD_KEY:-change-me-in-production} depends_on: diff --git a/docker/start.sh b/docker/start.sh index 8dece49..8bffa6b 100755 --- a/docker/start.sh +++ b/docker/start.sh @@ -4,6 +4,41 @@ set -e +# 默认值常量 +DEFAULT_JWT_SECRET="change-me-in-production" +DEFAULT_ADMIN_RESET_KEY="change-me-in-production" + +# 检查安全配置 +check_security_config() { + local errors=0 + + # 检查 JWT_SECRET + if [ -z "$JWT_SECRET" ] || [ "$JWT_SECRET" = "$DEFAULT_JWT_SECRET" ]; then + echo "❌ 错误: JWT_SECRET 不能使用默认值 '${DEFAULT_JWT_SECRET}'" + echo " 请设置环境变量 JWT_SECRET 为安全的随机字符串" + errors=$((errors + 1)) + fi + + # 检查 ADMIN_RESET_PASSWORD_KEY + if [ -z "$ADMIN_RESET_PASSWORD_KEY" ] || [ "$ADMIN_RESET_PASSWORD_KEY" = "$DEFAULT_ADMIN_RESET_KEY" ]; then + echo "❌ 错误: ADMIN_RESET_PASSWORD_KEY 不能使用默认值 '${DEFAULT_ADMIN_RESET_KEY}'" + echo " 请设置环境变量 ADMIN_RESET_PASSWORD_KEY 为安全的随机字符串" + errors=$((errors + 1)) + fi + + if [ $errors -gt 0 ]; then + echo "" + echo "⚠️ 安全配置检查失败,容器将不会启动" + echo " 请在 docker-compose.yml 或 .env 文件中设置正确的值" + exit 1 + fi + + echo "✅ 安全配置检查通过" +} + +# 执行安全配置检查 +check_security_config + # 函数:清理进程 cleanup() { echo "收到退出信号,清理进程..." diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index d7ee395..6d5cdd9 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -5,6 +5,8 @@ ## 目录 - [一体化部署(推荐)](#一体化部署推荐) + - [使用 Docker Hub 镜像](#使用-docker-hub-镜像推荐生产环境首选) + - [使用外部 Nginx 反向代理](#使用外部-nginx-反向代理生产环境推荐) - [后端部署](#后端部署) - [Java 直接部署](#java-直接部署) - [Docker 部署](#docker-部署) @@ -23,10 +25,89 @@ ### 部署步骤 -1. **使用部署脚本(推荐)** +1. **使用 Docker Hub 镜像(推荐,生产环境首选)** + +使用官方构建的 Docker 镜像,无需本地构建,快速部署。 + +**方式 1:独立部署(无需 clone 代码,推荐生产环境)** + +适用于生产环境,无需下载项目代码,只需配置文件即可部署。 ```bash -# 在项目根目录 +# 1. 创建部署目录 +mkdir polyhermes && cd polyhermes + +# 2. 下载生产环境配置文件 +# 从 GitHub 下载 docker-compose.prod.yml 和 docker-compose.prod.env.example +curl -O https://raw.githubusercontent.com/WrBug/PolyHermes/main/docker-compose.prod.yml +curl -O https://raw.githubusercontent.com/WrBug/PolyHermes/main/docker-compose.prod.env.example + +# 3. 创建配置文件 +cp docker-compose.prod.env.example .env + +# 4. 编辑 .env 文件,修改以下必需配置: +# - DB_PASSWORD: 数据库密码(建议使用强密码) +# - JWT_SECRET: JWT 密钥(使用 openssl rand -hex 64 生成) +# - ADMIN_RESET_PASSWORD_KEY: 管理员密码重置密钥(使用 openssl rand -hex 32 生成) +# +# 生成随机密钥示例: +# openssl rand -hex 64 # 用于 JWT_SECRET +# openssl rand -hex 32 # 用于 ADMIN_RESET_PASSWORD_KEY + +# 5. 启动服务 +docker-compose -f docker-compose.prod.yml up -d + +# 6. 查看日志 +docker-compose -f docker-compose.prod.yml logs -f + +# 7. 停止服务 +docker-compose -f docker-compose.prod.yml down +``` + +**方式 2:使用部署脚本(需要 clone 代码)** + +```bash +# 如果已经 clone 了代码 +./deploy.sh --use-docker-hub +``` + +**方式 3:修改现有 docker-compose.yml** + +```bash +# 1. 修改 docker-compose.yml +# 取消注释:image: wrbug/polyhermes:latest +# 注释掉 build 部分 + +# 2. 创建 .env 文件(见下方环境配置) + +# 3. 启动服务 +docker-compose up -d +``` + +**优势**: +- ✅ 无需本地构建,快速部署 +- ✅ 无需 clone 代码,只需配置文件即可部署 +- ✅ 使用官方构建的镜像,包含正确的版本号 +- ✅ 支持多架构(amd64、arm64),自动选择匹配的架构 +- ✅ 生产环境推荐方式 + +**拉取特定版本**: + +```bash +# 修改 docker-compose.prod.yml 中的镜像标签 +# image: wrbug/polyhermes:v1.0.0 + +# 或使用环境变量 +export IMAGE_TAG=v1.0.0 +# 在 docker-compose.prod.yml 中使用: image: wrbug/polyhermes:${IMAGE_TAG:-latest} +``` + +2. **本地构建部署(开发环境)** + +适用于开发环境或需要自定义构建的场景。 + +```bash +# 使用部署脚本 ./deploy.sh ``` @@ -36,7 +117,9 @@ - 构建 Docker 镜像(包含前后端) - 启动服务(应用 + MySQL) -2. **手动部署** +**注意**:本地构建的版本号会显示为 `dev`。 + +3. **手动部署** ```bash # 创建 .env 文件 @@ -62,7 +145,7 @@ docker-compose logs -f docker-compose down ``` -3. **访问应用** +4. **访问应用** - 前端和后端统一访问:`http://localhost:80` - Nginx 自动处理: @@ -88,6 +171,97 @@ Nginx (端口 80) - ✅ 自动处理前后端路由 - ✅ 生产环境就绪 +### 使用外部 Nginx 反向代理(生产环境推荐) + +在生产环境中,建议在 Docker 容器外部部署 Nginx 作为反向代理,用于: + +- **SSL/TLS 终止**:处理 HTTPS 请求 +- **域名绑定**:绑定自定义域名 +- **负载均衡**:支持多个后端实例 +- **更灵活的配置**:更细粒度的控制 + +**部署架构**: + +``` +用户请求 (HTTPS) + ↓ +外部 Nginx (443) - SSL 终止 + ↓ +Docker 容器 (80) - 内部 Nginx + 后端 + ├─ /api/* → 后端服务 (localhost:8000) + ├─ /ws → 后端 WebSocket (localhost:8000) + └─ /* → 前端静态文件 +``` + +**部署步骤**: + +1. **部署 Docker 容器** + +```bash +# 使用 docker-compose.prod.yml 部署 +docker-compose -f docker-compose.prod.yml up -d +``` + +2. **配置外部 Nginx** + +```bash +# 1. 下载 Nginx 配置示例 +curl -O https://raw.githubusercontent.com/WrBug/PolyHermes/main/docs/nginx-reverse-proxy.conf + +# 2. 复制到 Nginx 配置目录 +sudo cp nginx-reverse-proxy.conf /etc/nginx/sites-available/polyhermes + +# 3. 编辑配置文件,修改域名和 SSL 证书路径 +sudo nano /etc/nginx/sites-available/polyhermes +# 修改以下内容: +# - server_name: 改为你的域名 +# - ssl_certificate: SSL 证书路径 +# - ssl_certificate_key: SSL 私钥路径 +# - upstream server: 如果 Docker 容器端口不是 80,需要修改 + +# 4. 创建软链接 +sudo ln -s /etc/nginx/sites-available/polyhermes /etc/nginx/sites-enabled/ + +# 5. 测试配置 +sudo nginx -t + +# 6. 重载配置 +sudo systemctl reload nginx +``` + +3. **配置 SSL 证书(使用 Let's Encrypt)** + +```bash +# 安装 Certbot +sudo apt-get update +sudo apt-get install certbot python3-certbot-nginx + +# 获取 SSL 证书 +sudo certbot --nginx -d your-domain.com -d www.your-domain.com + +# 证书会自动配置到 Nginx,并设置自动续期 +``` + +4. **修改 Docker 端口映射(可选)** + +如果使用外部 Nginx,可以将 Docker 容器的端口改为内部端口,不对外暴露: + +```yaml +# 在 docker-compose.prod.yml 中 +ports: + - "127.0.0.1:80:80" # 只绑定到本地,不对外暴露 +``` + +**Nginx 配置说明**: + +- 配置文件位置:`docs/nginx-reverse-proxy.conf` +- 支持 HTTPS(SSL/TLS) +- 支持 WebSocket 代理 +- 包含安全头设置 +- 支持负载均衡(可配置多个后端) + +详细配置示例请参考:[Nginx 反向代理配置](nginx-reverse-proxy.conf) + ## 后端部署 ### Java 直接部署 diff --git a/docs/nginx-reverse-proxy.conf b/docs/nginx-reverse-proxy.conf new file mode 100644 index 0000000..92c39b0 --- /dev/null +++ b/docs/nginx-reverse-proxy.conf @@ -0,0 +1,170 @@ +# PolyHermes Nginx 反向代理配置示例 +# +# 适用于生产环境,在 Docker 容器外部部署 Nginx 作为反向代理 +# +# 使用场景: +# - SSL/TLS 终止(HTTPS) +# - 域名绑定 +# - 负载均衡 +# - 更灵活的配置 +# +# 部署步骤: +# 1. 将本文件复制到 /etc/nginx/sites-available/polyhermes +# 2. 创建软链接: ln -s /etc/nginx/sites-available/polyhermes /etc/nginx/sites-enabled/ +# 3. 修改配置中的域名和 SSL 证书路径 +# 4. 测试配置: nginx -t +# 5. 重载配置: systemctl reload nginx + +# HTTP 服务器(可选:用于重定向到 HTTPS) +server { + listen 80; + server_name your-domain.com www.your-domain.com; + + # 重定向到 HTTPS + return 301 https://$server_name$request_uri; +} + +# HTTPS 服务器 +server { + listen 443 ssl http2; + server_name your-domain.com www.your-domain.com; + + # SSL 证书配置(使用 Let's Encrypt 或其他证书) + ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem; + + # SSL 安全配置 + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384'; + ssl_prefer_server_ciphers on; + ssl_session_cache shared:SSL:10m; + ssl_session_timeout 10m; + + # 安全头 + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + + # 日志 + access_log /var/log/nginx/polyhermes-access.log; + error_log /var/log/nginx/polyhermes-error.log; + + # 客户端最大上传大小 + client_max_body_size 10M; + + # 上游服务(Docker 容器) + # 如果使用 docker-compose,容器名是 polyhermes,端口是 80 + upstream polyhermes_backend { + server 127.0.0.1:80; + # 如果需要负载均衡,可以添加多个后端: + # server 127.0.0.1:8001; + # server 127.0.0.1:8002; + } + + # API 代理 + location /api { + proxy_pass http://polyhermes_backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + + # 超时设置 + proxy_connect_timeout 60s; + proxy_send_timeout 60s; + proxy_read_timeout 60s; + + # 缓冲设置 + proxy_buffering on; + proxy_buffer_size 4k; + proxy_buffers 8 4k; + proxy_busy_buffers_size 8k; + } + + # WebSocket 代理 + location /ws { + proxy_pass http://polyhermes_backend; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + + # WebSocket 超时设置(长连接) + proxy_connect_timeout 7d; + proxy_send_timeout 7d; + proxy_read_timeout 7d; + } + + # 前端静态文件代理 + location / { + proxy_pass http://polyhermes_backend; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header X-Forwarded-Host $host; + proxy_set_header X-Forwarded-Port $server_port; + + # 静态资源缓存(由后端 Nginx 处理) + proxy_cache_valid 200 1y; + } + + # 健康检查(可选) + location /health { + proxy_pass http://polyhermes_backend; + access_log off; + } +} + +# 如果不需要 HTTPS,可以使用以下简化配置 +# server { +# listen 80; +# server_name your-domain.com www.your-domain.com; +# +# access_log /var/log/nginx/polyhermes-access.log; +# error_log /var/log/nginx/polyhermes-error.log; +# +# client_max_body_size 10M; +# +# upstream polyhermes_backend { +# server 127.0.0.1:80; +# } +# +# location /api { +# proxy_pass http://polyhermes_backend; +# proxy_set_header Host $host; +# proxy_set_header X-Real-IP $remote_addr; +# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +# proxy_set_header X-Forwarded-Proto $scheme; +# } +# +# location /ws { +# proxy_pass http://polyhermes_backend; +# proxy_http_version 1.1; +# proxy_set_header Upgrade $http_upgrade; +# proxy_set_header Connection "upgrade"; +# proxy_set_header Host $host; +# proxy_set_header X-Real-IP $remote_addr; +# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +# proxy_set_header X-Forwarded-Proto $scheme; +# proxy_read_timeout 86400; +# proxy_send_timeout 86400; +# } +# +# location / { +# proxy_pass http://polyhermes_backend; +# proxy_set_header Host $host; +# proxy_set_header X-Real-IP $remote_addr; +# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +# proxy_set_header X-Forwarded-Proto $scheme; +# } +# } +