fix: 修复Docker部署时加密密钥持久化问题

- 在docker-compose.yml中添加.env文件映射,避免重建容器时生成新密钥
- 修改docker-entrypoint.sh,只在密钥不存在时生成新的,否则使用现有的
- 移除Dockerfile中自动复制.env的逻辑,改为运行时检查
- 更新README文档,添加重要提示说明.env文件映射的必要性
- 解决了每次重建容器导致之前加密数据无法解密的严重问题
This commit is contained in:
shaw
2025-07-24 14:53:34 +08:00
parent 36201cee6b
commit 38c68ca831
4 changed files with 29 additions and 9 deletions

View File

@@ -36,9 +36,6 @@ RUN mkdir -p logs data temp
# 🔧 预先创建配置文件 # 🔧 预先创建配置文件
RUN if [ ! -f "/app/config/config.js" ] && [ -f "/app/config/config.example.js" ]; then \ RUN if [ ! -f "/app/config/config.js" ] && [ -f "/app/config/config.example.js" ]; then \
cp /app/config/config.example.js /app/config/config.js; \ cp /app/config/config.example.js /app/config/config.js; \
fi && \
if [ ! -f "/app/.env" ] && [ -f "/app/.env.example" ]; then \
cp /app/.env.example /app/.env; \
fi fi
# 🌐 暴露端口 # 🌐 暴露端口

View File

@@ -238,6 +238,7 @@ docker run -d \
-p 3000:3000 \ -p 3000:3000 \
-v $(pwd)/data:/app/data \ -v $(pwd)/data:/app/data \
-v $(pwd)/logs:/app/logs \ -v $(pwd)/logs:/app/logs \
-v $(pwd)/.env:/app/.env \
-e ADMIN_USERNAME=my_admin \ -e ADMIN_USERNAME=my_admin \
-e ADMIN_PASSWORD=my_secure_password \ -e ADMIN_PASSWORD=my_secure_password \
weishaw/claude-relay-service:latest weishaw/claude-relay-service:latest
@@ -260,6 +261,7 @@ services:
volumes: volumes:
- ./logs:/app/logs - ./logs:/app/logs
- ./data:/app/data - ./data:/app/data
- ./.env:/app/.env # 重要:持久化加密密钥
depends_on: depends_on:
- redis - redis
@@ -306,11 +308,13 @@ cat ./data/init.json
docker-compose.yml 已包含: docker-compose.yml 已包含:
- ✅ 自动初始化管理员账号 - ✅ 自动初始化管理员账号
- ✅ 数据持久化logsdata目录自动挂载 - ✅ 数据持久化logsdata目录和.env文件自动挂载)
- ✅ Redis数据库 - ✅ Redis数据库
- ✅ 健康检查 - ✅ 健康检查
- ✅ 自动重启 - ✅ 自动重启
> ⚠️ **重要提示**:从 v1.1.15 版本开始,`.env` 文件必须映射到本地以持久化加密密钥。如果不映射,每次重建容器都会生成新的加密密钥,导致之前加密的数据无法解密!
### 管理员凭据获取方式 ### 管理员凭据获取方式
1. **查看容器日志**(推荐) 1. **查看容器日志**(推荐)

View File

@@ -18,6 +18,7 @@ services:
volumes: volumes:
- ./logs:/app/logs - ./logs:/app/logs
- ./data:/app/data - ./data:/app/data
- ./.env:/app/.env
depends_on: depends_on:
- redis - redis
networks: networks:

View File

@@ -3,6 +3,18 @@ set -e
echo "🚀 Claude Relay Service 启动中..." echo "🚀 Claude Relay Service 启动中..."
# 检查并创建 .env 文件
if [ ! -f "/app/.env" ]; then
echo "📋 检测到 .env 不存在,从模板创建..."
if [ -f "/app/.env.example" ]; then
cp /app/.env.example /app/.env
echo "✅ .env 已从模板创建"
else
echo "❌ 错误: .env.example 不存在"
exit 1
fi
fi
# 生成随机字符串的函数 # 生成随机字符串的函数
generate_random_string() { generate_random_string() {
length=$1 length=$1
@@ -31,7 +43,11 @@ if [ -f "/app/.env" ]; then
JWT_SECRET=$(grep "^JWT_SECRET=" /app/.env | cut -d'=' -f2) JWT_SECRET=$(grep "^JWT_SECRET=" /app/.env | cut -d'=' -f2)
if [ -z "$JWT_SECRET" ] || [ "$JWT_SECRET" = "your-jwt-secret-here" ]; then if [ -z "$JWT_SECRET" ] || [ "$JWT_SECRET" = "your-jwt-secret-here" ]; then
JWT_SECRET=$(generate_random_string 64) JWT_SECRET=$(generate_random_string 64)
echo "🔑 生成 JWT_SECRET" echo "🔑 生成新的 JWT_SECRET"
# 更新 .env 文件
sed -i "s/JWT_SECRET=.*/JWT_SECRET=${JWT_SECRET}/" /app/.env
else
echo "✅ 使用现有的 JWT_SECRET"
fi fi
fi fi
@@ -40,13 +56,15 @@ if [ -f "/app/.env" ]; then
ENCRYPTION_KEY=$(grep "^ENCRYPTION_KEY=" /app/.env | cut -d'=' -f2) ENCRYPTION_KEY=$(grep "^ENCRYPTION_KEY=" /app/.env | cut -d'=' -f2)
if [ -z "$ENCRYPTION_KEY" ] || [ "$ENCRYPTION_KEY" = "your-encryption-key-here" ]; then if [ -z "$ENCRYPTION_KEY" ] || [ "$ENCRYPTION_KEY" = "your-encryption-key-here" ]; then
ENCRYPTION_KEY=$(generate_random_string 32) ENCRYPTION_KEY=$(generate_random_string 32)
echo "🔑 生成 ENCRYPTION_KEY" echo "🔑 生成新的 ENCRYPTION_KEY"
# 更新 .env 文件
sed -i "s/ENCRYPTION_KEY=.*/ENCRYPTION_KEY=${ENCRYPTION_KEY}/" /app/.env
else
echo "✅ 使用现有的 ENCRYPTION_KEY"
fi fi
fi fi
# 直接使用sed修改.env文件 - root用户无权限问题 # 更新 Redis 主机配置
sed -i "s/JWT_SECRET=.*/JWT_SECRET=${JWT_SECRET}/" /app/.env
sed -i "s/ENCRYPTION_KEY=.*/ENCRYPTION_KEY=${ENCRYPTION_KEY}/" /app/.env
sed -i "s/REDIS_HOST=.*/REDIS_HOST=redis/" /app/.env sed -i "s/REDIS_HOST=.*/REDIS_HOST=redis/" /app/.env
echo "✅ .env 已配置" echo "✅ .env 已配置"