From fefd64957dd0d4bf5550b4a3f1c42b141bbfbf07 Mon Sep 17 00:00:00 2001 From: xiaoquan <838115837@qq.com> Date: Tue, 2 Jun 2026 12:06:43 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=B2=BE=E7=AE=80=20CI/CD=20=E5=AF=86?= =?UTF-8?q?=E9=92=A5=EF=BC=8C=E4=B8=9A=E5=8A=A1=E5=AF=86=E9=92=A5=E8=BF=81?= =?UTF-8?q?=E7=A7=BB=E5=88=B0=E6=95=B0=E6=8D=AE=E5=BA=93=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Gitea Secrets 只保留 5 个基础密钥(DB密码、JWT、加密密钥) - 删除 deploy.yml 中所有业务密钥的 secrets 注入 - docker-compose 移除业务环境变量,只保留 DB/JWT/ENCRYPTION_KEY - 业务密钥(微信/支付宝/短信等)通过后台「系统密钥」页面管理 - 改用 export 方式注入环境变量,不再写 .env 文件 - 更新部署文档 Co-Authored-By: Claude Opus 4.8 --- .gitea/workflows/deploy.yml | 58 +++++++-------------------- deploy/README.md | 46 ++++++--------------- deploy/docker/docker-compose.prod.yml | 21 ++-------- deploy/docker/docker-compose.test.yml | 2 +- 4 files changed, 30 insertions(+), 97 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 67de75e..202a771 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -66,43 +66,20 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Generate .env from secrets - run: | - cat > deploy/docker/.env.prod << 'EOF' - PROD_DB_PASSWORD=${{ secrets.PROD_DB_PASSWORD }} - PROD_JWT_SECRET=${{ secrets.PROD_JWT_SECRET }} - PROD_JWT_EXPIRES_IN=${{ secrets.PROD_JWT_EXPIRES_IN }} - PROD_JWT_REFRESH_EXPIRES_IN=${{ secrets.PROD_JWT_REFRESH_EXPIRES_IN }} - PROD_SMS_ACCESS_KEY_ID=${{ secrets.PROD_SMS_ACCESS_KEY_ID }} - PROD_SMS_ACCESS_KEY_SECRET=${{ secrets.PROD_SMS_ACCESS_KEY_SECRET }} - PROD_SMS_SIGN_NAME=${{ secrets.PROD_SMS_SIGN_NAME }} - PROD_SMS_TEMPLATE_CODE=${{ secrets.PROD_SMS_TEMPLATE_CODE }} - PROD_WECHAT_APPID=${{ secrets.PROD_WECHAT_APPID }} - PROD_WECHAT_SECRET=${{ secrets.PROD_WECHAT_SECRET }} - PROD_WECHAT_MCHID=${{ secrets.PROD_WECHAT_MCHID }} - PROD_WECHAT_SERIAL_NO=${{ secrets.PROD_WECHAT_SERIAL_NO }} - PROD_WECHAT_APIV3_KEY=${{ secrets.PROD_WECHAT_APIV3_KEY }} - PROD_WECHAT_PRIVATE_KEY=${{ secrets.PROD_WECHAT_PRIVATE_KEY }} - PROD_WECHAT_PAY_NOTIFY_URL=${{ secrets.PROD_WECHAT_PAY_NOTIFY_URL }} - PROD_WECHAT_REFUND_NOTIFY_URL=${{ secrets.PROD_WECHAT_REFUND_NOTIFY_URL }} - PROD_ALIPAY_APPID=${{ secrets.PROD_ALIPAY_APPID }} - PROD_ALIPAY_PRIVATE_KEY=${{ secrets.PROD_ALIPAY_PRIVATE_KEY }} - PROD_API_BASE_URL=${{ secrets.PROD_API_BASE_URL }} - EOF - chmod 600 deploy/docker/.env.prod - - name: Deploy to production run: | echo "部署到生产环境..." cd deploy/docker - docker-compose -f docker-compose.prod.yml --env-file .env.prod down --remove-orphans - docker-compose -f docker-compose.prod.yml --env-file .env.prod build --parallel - docker-compose -f docker-compose.prod.yml --env-file .env.prod up -d + export PROD_DB_PASSWORD="${{ secrets.PROD_DB_PASSWORD }}" + export PROD_JWT_SECRET="${{ secrets.PROD_JWT_SECRET }}" + export ENCRYPTION_KEY="${{ secrets.ENCRYPTION_KEY }}" + docker-compose -f docker-compose.prod.yml down --remove-orphans + docker-compose -f docker-compose.prod.yml build --parallel + docker-compose -f docker-compose.prod.yml up -d docker image prune -f echo "等待服务启动..." sleep 10 - docker-compose -f docker-compose.prod.yml --env-file .env.prod ps - rm -f .env.prod + docker-compose -f docker-compose.prod.yml ps deploy-test: runs-on: [self-hosted, rent-deploy] @@ -111,24 +88,17 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Generate .env from secrets - run: | - cat > deploy/docker/.env.test << 'EOF' - TEST_DB_PASSWORD=${{ secrets.TEST_DB_PASSWORD }} - TEST_JWT_SECRET=${{ secrets.TEST_JWT_SECRET }} - TEST_API_BASE_URL=${{ secrets.TEST_API_BASE_URL }} - EOF - chmod 600 deploy/docker/.env.test - - name: Deploy to test run: | echo "部署到测试环境..." cd deploy/docker - docker-compose -f docker-compose.test.yml --env-file .env.test down --remove-orphans - docker-compose -f docker-compose.test.yml --env-file .env.test build --parallel - docker-compose -f docker-compose.test.yml --env-file .env.test up -d + export TEST_DB_PASSWORD="${{ secrets.TEST_DB_PASSWORD }}" + export TEST_JWT_SECRET="${{ secrets.TEST_JWT_SECRET }}" + export ENCRYPTION_KEY="${{ secrets.ENCRYPTION_KEY }}" + docker-compose -f docker-compose.test.yml down --remove-orphans + docker-compose -f docker-compose.test.yml build --parallel + docker-compose -f docker-compose.test.yml up -d docker image prune -f echo "等待服务启动..." sleep 10 - docker-compose -f docker-compose.test.yml --env-file .env.test ps - rm -f .env.test + docker-compose -f docker-compose.test.yml ps diff --git a/deploy/README.md b/deploy/README.md index 242d935..4b7b90e 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -148,45 +148,23 @@ docker logs rent-act-runner 在 Gitea → **Settings → Actions → Runners** 页面应能看到 `rent-deploy-runner` 已注册并在线。 -### 第 3 步:配置 Secrets(密钥安全) +### 第 3 步:配置 Secrets -> 所有密钥通过 Gitea Secrets 管理,服务器上不存储任何密码文件。 +> CI/CD 流水线只需要 4 个基础密钥,其他业务密钥(微信、支付宝、短信等)通过平台后台「系统密钥」页面管理。 -Gitea → **仓库 → Settings → Actions → Secrets**,添加以下密钥: +Gitea → **仓库 → Settings → Actions → Secrets**,添加: -**生产环境:** +| Secret 名 | 说明 | 生成方式 | +|-----------|------|----------| +| `PROD_DB_PASSWORD` | 生产数据库密码 | 自定义强密码 | +| `PROD_JWT_SECRET` | 生产 JWT 密钥 | `openssl rand -hex 32` | +| `TEST_DB_PASSWORD` | 测试数据库密码 | 自定义强密码 | +| `TEST_JWT_SECRET` | 测试 JWT 密钥 | `openssl rand -hex 32` | +| `ENCRYPTION_KEY` | 业务密钥加密密钥 | `openssl rand -hex 32` | -| Secret 名 | 说明 | 示例 | -|-----------|------|------| -| `PROD_DB_PASSWORD` | 数据库密码 | 强密码 | -| `PROD_JWT_SECRET` | JWT 密钥 | 随机字符串 | -| `PROD_JWT_EXPIRES_IN` | Token 过期时间 | `2h` | -| `PROD_JWT_REFRESH_EXPIRES_IN` | 刷新 Token 过期 | `7d` | -| `PROD_SMS_ACCESS_KEY_ID` | 阿里云 AK | 短信服务 | -| `PROD_SMS_ACCESS_KEY_SECRET` | 阿里云 SK | 短信服务 | -| `PROD_SMS_SIGN_NAME` | 短信签名 | 品居会 | -| `PROD_SMS_TEMPLATE_CODE` | 短信模板编码 | SMS_xxx | -| `PROD_WECHAT_APPID` | 微信 AppID | wx1234... | -| `PROD_WECHAT_SECRET` | 微信 Secret | 微信密钥 | -| `PROD_WECHAT_MCHID` | 微信商户号 | 1234567890 | -| `PROD_WECHAT_SERIAL_NO` | 证书序列号 | 微信支付 | -| `PROD_WECHAT_APIV3_KEY` | APIv3 密钥 | 32 位字符串 | -| `PROD_WECHAT_PRIVATE_KEY` | 商户私钥 | PEM 内容 | -| `PROD_WECHAT_PAY_NOTIFY_URL` | 支付回调 | `https://api.pinzhuhui.com/...` | -| `PROD_WECHAT_REFUND_NOTIFY_URL` | 退款回调 | `https://api.pinzhuhui.com/...` | -| `PROD_ALIPAY_APPID` | 支付宝 AppID | 2021xxx | -| `PROD_ALIPAY_PRIVATE_KEY` | 支付宝私钥 | 密钥内容 | -| `PROD_API_BASE_URL` | API 地址 | `https://api.pinzhuhui.com` | +> `ENCRYPTION_KEY` 用于加解密数据库中存储的业务密钥(微信、支付宝等),务必妥善保管。 -**测试环境:** - -| Secret 名 | 说明 | -|-----------|------| -| `TEST_DB_PASSWORD` | 测试数据库密码 | -| `TEST_JWT_SECRET` | 测试 JWT 密钥 | -| `TEST_API_BASE_URL` | `https://api-test.pinzhuhui.com` | - -> 暂时没有的配置(如微信支付、支付宝)可以先不填,流水线会使用空值默认。 +业务密钥(微信、支付宝、短信等)的配置方式:平台后台 → **系统密钥** 页面。 ### 第 4 步:推送代码到 Gitea diff --git a/deploy/docker/docker-compose.prod.yml b/deploy/docker/docker-compose.prod.yml index d77bf34..e22a897 100644 --- a/deploy/docker/docker-compose.prod.yml +++ b/deploy/docker/docker-compose.prod.yml @@ -59,26 +59,11 @@ services: DB_DATABASE: rent_platform REDIS_HOST: redis REDIS_PORT: 6379 - # 从 .env.prod 注入的密钥 + # CI 注入的基础密钥 DB_PASSWORD: ${PROD_DB_PASSWORD} JWT_SECRET: ${PROD_JWT_SECRET} - JWT_EXPIRES_IN: ${PROD_JWT_EXPIRES_IN:-2h} - JWT_REFRESH_EXPIRES_IN: ${PROD_JWT_REFRESH_EXPIRES_IN:-7d} - SMS_ACCESS_KEY_ID: ${PROD_SMS_ACCESS_KEY_ID:-} - SMS_ACCESS_KEY_SECRET: ${PROD_SMS_ACCESS_KEY_SECRET:-} - SMS_SIGN_NAME: ${PROD_SMS_SIGN_NAME:-} - SMS_TEMPLATE_CODE: ${PROD_SMS_TEMPLATE_CODE:-} - WECHAT_APPID: ${PROD_WECHAT_APPID:-} - WECHAT_SECRET: ${PROD_WECHAT_SECRET:-} - WECHAT_MCHID: ${PROD_WECHAT_MCHID:-} - WECHAT_SERIAL_NO: ${PROD_WECHAT_SERIAL_NO:-} - WECHAT_APIV3_KEY: ${PROD_WECHAT_APIV3_KEY:-} - WECHAT_PRIVATE_KEY: ${PROD_WECHAT_PRIVATE_KEY:-} - WECHAT_PAY_NOTIFY_URL: ${PROD_WECHAT_PAY_NOTIFY_URL:-} - WECHAT_REFUND_NOTIFY_URL: ${PROD_WECHAT_REFUND_NOTIFY_URL:-} - ALIPAY_APPID: ${PROD_ALIPAY_APPID:-} - ALIPAY_PRIVATE_KEY: ${PROD_ALIPAY_PRIVATE_KEY:-} - API_BASE_URL: ${PROD_API_BASE_URL:-http://localhost:3000} + # 加密密钥(用于解密数据库中的业务密钥) + ENCRYPTION_KEY: ${ENCRYPTION_KEY} depends_on: mysql: condition: service_healthy diff --git a/deploy/docker/docker-compose.test.yml b/deploy/docker/docker-compose.test.yml index e7a58fe..f8413fb 100644 --- a/deploy/docker/docker-compose.test.yml +++ b/deploy/docker/docker-compose.test.yml @@ -60,7 +60,7 @@ services: REDIS_PORT: 6379 DB_PASSWORD: ${TEST_DB_PASSWORD} JWT_SECRET: ${TEST_JWT_SECRET} - API_BASE_URL: ${TEST_API_BASE_URL:-http://localhost:3001} + ENCRYPTION_KEY: ${ENCRYPTION_KEY} depends_on: mysql: condition: service_healthy