feat: 添加安全检查和部署优化
- 添加 JWT_SECRET 和 ADMIN_RESET_PASSWORD_KEY 安全检查,防止使用默认值 - 创建 docker-compose.prod.yml 和 docker-compose.prod.env.example,支持独立部署 - 添加 Nginx 反向代理配置示例,支持 HTTPS 和域名绑定 - 更新部署文档,将 Docker Hub 部署方式放在首位 - 添加多架构构建支持(amd64、arm64) - 优化部署文档结构,提供更清晰的部署指南
This commit is contained in:
@@ -43,6 +43,9 @@ jobs:
|
|||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
if: github.event.action == 'published'
|
if: github.event.action == 'published'
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
with:
|
||||||
|
# 启用多架构构建支持
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
|
||||||
- name: Log in to Docker Hub
|
- name: Log in to Docker Hub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
@@ -57,6 +60,8 @@ jobs:
|
|||||||
context: .
|
context: .
|
||||||
file: ./Dockerfile
|
file: ./Dockerfile
|
||||||
push: true
|
push: true
|
||||||
|
# 多架构构建:支持 amd64 和 arm64
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
tags: |
|
tags: |
|
||||||
wrbug/polyhermes:${{ steps.extract_version.outputs.TAG }}
|
wrbug/polyhermes:${{ steps.extract_version.outputs.TAG }}
|
||||||
wrbug/polyhermes:latest
|
wrbug/polyhermes:latest
|
||||||
|
|||||||
@@ -115,10 +115,75 @@
|
|||||||
|
|
||||||
**部署步骤**:
|
**部署步骤**:
|
||||||
|
|
||||||
1. **使用部署脚本(推荐)**
|
1. **使用 Docker Hub 镜像(推荐,生产环境首选)**
|
||||||
|
|
||||||
|
**方式 1:独立部署(无需 clone 代码,推荐)**
|
||||||
|
|
||||||
|
适用于生产环境,无需下载项目代码,只需两个文件即可部署:
|
||||||
|
|
||||||
```bash
|
```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
|
./deploy.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -128,7 +193,7 @@
|
|||||||
- 构建 Docker 镜像(包含前后端)
|
- 构建 Docker 镜像(包含前后端)
|
||||||
- 启动服务(应用 + MySQL)
|
- 启动服务(应用 + MySQL)
|
||||||
|
|
||||||
2. **手动部署**
|
3. **手动部署**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 创建 .env 文件
|
# 创建 .env 文件
|
||||||
@@ -154,16 +219,6 @@ docker-compose logs -f
|
|||||||
docker-compose down
|
docker-compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **使用 Docker Hub 镜像(生产环境推荐)**
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# 使用部署脚本
|
|
||||||
./deploy.sh --use-docker-hub
|
|
||||||
|
|
||||||
# 或修改 docker-compose.yml,取消注释:
|
|
||||||
# image: wrbug/polyhermes:latest
|
|
||||||
```
|
|
||||||
|
|
||||||
**访问应用**:
|
**访问应用**:
|
||||||
- 前端和后端统一访问:`http://localhost:80`
|
- 前端和后端统一访问:`http://localhost:80`
|
||||||
- Nginx 自动处理:
|
- Nginx 自动处理:
|
||||||
@@ -171,6 +226,12 @@ docker-compose down
|
|||||||
- `/ws` → 后端 WebSocket(`localhost:8000`)
|
- `/ws` → 后端 WebSocket(`localhost:8000`)
|
||||||
- 其他路径 → 前端静态文件
|
- 其他路径 → 前端静态文件
|
||||||
|
|
||||||
|
**使用外部 Nginx 反向代理(生产环境推荐)**:
|
||||||
|
|
||||||
|
在生产环境中,建议在 Docker 容器外部部署 Nginx 作为反向代理,用于 SSL/TLS 终止、域名绑定等。
|
||||||
|
|
||||||
|
详细配置请参考:[部署文档 - Nginx 反向代理](docs/DEPLOYMENT.md#使用外部-nginx-反向代理生产环境推荐)
|
||||||
|
|
||||||
### 📦 分别部署
|
### 📦 分别部署
|
||||||
|
|
||||||
#### 后端部署
|
#### 后端部署
|
||||||
|
|||||||
@@ -89,8 +89,64 @@ EOF
|
|||||||
fi
|
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() {
|
deploy() {
|
||||||
|
# 检查安全配置
|
||||||
|
check_security_config
|
||||||
|
|
||||||
# 检查是否使用 Docker Hub 镜像
|
# 检查是否使用 Docker Hub 镜像
|
||||||
USE_DOCKER_HUB="${USE_DOCKER_HUB:-false}"
|
USE_DOCKER_HUB="${USE_DOCKER_HUB:-false}"
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|
||||||
@@ -23,6 +23,9 @@ services:
|
|||||||
- DB_PASSWORD=${DB_PASSWORD:-}
|
- DB_PASSWORD=${DB_PASSWORD:-}
|
||||||
- SERVER_PORT=8000
|
- SERVER_PORT=8000
|
||||||
- POLYGON_RPC_URL=${POLYGON_RPC_URL:-https://polygon-rpc.com}
|
- 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}
|
- JWT_SECRET=${JWT_SECRET:-change-me-in-production}
|
||||||
- ADMIN_RESET_PASSWORD_KEY=${ADMIN_RESET_PASSWORD_KEY:-change-me-in-production}
|
- ADMIN_RESET_PASSWORD_KEY=${ADMIN_RESET_PASSWORD_KEY:-change-me-in-production}
|
||||||
depends_on:
|
depends_on:
|
||||||
|
|||||||
@@ -4,6 +4,41 @@
|
|||||||
|
|
||||||
set -e
|
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() {
|
cleanup() {
|
||||||
echo "收到退出信号,清理进程..."
|
echo "收到退出信号,清理进程..."
|
||||||
|
|||||||
+178
-4
@@ -5,6 +5,8 @@
|
|||||||
## 目录
|
## 目录
|
||||||
|
|
||||||
- [一体化部署(推荐)](#一体化部署推荐)
|
- [一体化部署(推荐)](#一体化部署推荐)
|
||||||
|
- [使用 Docker Hub 镜像](#使用-docker-hub-镜像推荐生产环境首选)
|
||||||
|
- [使用外部 Nginx 反向代理](#使用外部-nginx-反向代理生产环境推荐)
|
||||||
- [后端部署](#后端部署)
|
- [后端部署](#后端部署)
|
||||||
- [Java 直接部署](#java-直接部署)
|
- [Java 直接部署](#java-直接部署)
|
||||||
- [Docker 部署](#docker-部署)
|
- [Docker 部署](#docker-部署)
|
||||||
@@ -23,10 +25,89 @@
|
|||||||
|
|
||||||
### 部署步骤
|
### 部署步骤
|
||||||
|
|
||||||
1. **使用部署脚本(推荐)**
|
1. **使用 Docker Hub 镜像(推荐,生产环境首选)**
|
||||||
|
|
||||||
|
使用官方构建的 Docker 镜像,无需本地构建,快速部署。
|
||||||
|
|
||||||
|
**方式 1:独立部署(无需 clone 代码,推荐生产环境)**
|
||||||
|
|
||||||
|
适用于生产环境,无需下载项目代码,只需配置文件即可部署。
|
||||||
|
|
||||||
```bash
|
```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
|
./deploy.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -36,7 +117,9 @@
|
|||||||
- 构建 Docker 镜像(包含前后端)
|
- 构建 Docker 镜像(包含前后端)
|
||||||
- 启动服务(应用 + MySQL)
|
- 启动服务(应用 + MySQL)
|
||||||
|
|
||||||
2. **手动部署**
|
**注意**:本地构建的版本号会显示为 `dev`。
|
||||||
|
|
||||||
|
3. **手动部署**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 创建 .env 文件
|
# 创建 .env 文件
|
||||||
@@ -62,7 +145,7 @@ docker-compose logs -f
|
|||||||
docker-compose down
|
docker-compose down
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **访问应用**
|
4. **访问应用**
|
||||||
|
|
||||||
- 前端和后端统一访问:`http://localhost:80`
|
- 前端和后端统一访问:`http://localhost:80`
|
||||||
- Nginx 自动处理:
|
- 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 直接部署
|
### Java 直接部署
|
||||||
|
|||||||
@@ -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;
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
|
||||||
Reference in New Issue
Block a user