From 38c68ca831cae620d39a596454d8809f65a5f1df Mon Sep 17 00:00:00 2001 From: shaw Date: Thu, 24 Jul 2025 14:53:34 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DDocker=E9=83=A8?= =?UTF-8?q?=E7=BD=B2=E6=97=B6=E5=8A=A0=E5=AF=86=E5=AF=86=E9=92=A5=E6=8C=81?= =?UTF-8?q?=E4=B9=85=E5=8C=96=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在docker-compose.yml中添加.env文件映射,避免重建容器时生成新密钥 - 修改docker-entrypoint.sh,只在密钥不存在时生成新的,否则使用现有的 - 移除Dockerfile中自动复制.env的逻辑,改为运行时检查 - 更新README文档,添加重要提示说明.env文件映射的必要性 - 解决了每次重建容器导致之前加密数据无法解密的严重问题 --- Dockerfile | 3 --- README.md | 6 +++++- docker-compose.yml | 1 + docker-entrypoint.sh | 28 +++++++++++++++++++++++----- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/Dockerfile b/Dockerfile index 78d022fd..339da465 100644 --- a/Dockerfile +++ b/Dockerfile @@ -36,9 +36,6 @@ RUN mkdir -p logs data temp # 🔧 预先创建配置文件 RUN if [ ! -f "/app/config/config.js" ] && [ -f "/app/config/config.example.js" ]; then \ 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 # 🌐 暴露端口 diff --git a/README.md b/README.md index 926268da..f01a9450 100644 --- a/README.md +++ b/README.md @@ -238,6 +238,7 @@ docker run -d \ -p 3000:3000 \ -v $(pwd)/data:/app/data \ -v $(pwd)/logs:/app/logs \ + -v $(pwd)/.env:/app/.env \ -e ADMIN_USERNAME=my_admin \ -e ADMIN_PASSWORD=my_secure_password \ weishaw/claude-relay-service:latest @@ -260,6 +261,7 @@ services: volumes: - ./logs:/app/logs - ./data:/app/data + - ./.env:/app/.env # 重要:持久化加密密钥 depends_on: - redis @@ -306,11 +308,13 @@ cat ./data/init.json docker-compose.yml 已包含: - ✅ 自动初始化管理员账号 -- ✅ 数据持久化(logs和data目录自动挂载) +- ✅ 数据持久化(logs、data目录和.env文件自动挂载) - ✅ Redis数据库 - ✅ 健康检查 - ✅ 自动重启 +> ⚠️ **重要提示**:从 v1.1.15 版本开始,`.env` 文件必须映射到本地以持久化加密密钥。如果不映射,每次重建容器都会生成新的加密密钥,导致之前加密的数据无法解密! + ### 管理员凭据获取方式 1. **查看容器日志**(推荐) diff --git a/docker-compose.yml b/docker-compose.yml index 8bd4bbf6..a10bf1c3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,7 @@ services: volumes: - ./logs:/app/logs - ./data:/app/data + - ./.env:/app/.env depends_on: - redis networks: diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 1f29f3f3..7bf3e696 100644 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -3,6 +3,18 @@ set -e 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() { length=$1 @@ -31,7 +43,11 @@ if [ -f "/app/.env" ]; then JWT_SECRET=$(grep "^JWT_SECRET=" /app/.env | cut -d'=' -f2) if [ -z "$JWT_SECRET" ] || [ "$JWT_SECRET" = "your-jwt-secret-here" ]; then 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 @@ -40,13 +56,15 @@ if [ -f "/app/.env" ]; then ENCRYPTION_KEY=$(grep "^ENCRYPTION_KEY=" /app/.env | cut -d'=' -f2) if [ -z "$ENCRYPTION_KEY" ] || [ "$ENCRYPTION_KEY" = "your-encryption-key-here" ]; then 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 - # 直接使用sed修改.env文件 - root用户无权限问题 - sed -i "s/JWT_SECRET=.*/JWT_SECRET=${JWT_SECRET}/" /app/.env - sed -i "s/ENCRYPTION_KEY=.*/ENCRYPTION_KEY=${ENCRYPTION_KEY}/" /app/.env + # 更新 Redis 主机配置 sed -i "s/REDIS_HOST=.*/REDIS_HOST=redis/" /app/.env echo "✅ .env 已配置"