feat: 使用 Gitea Secrets 管理全部密钥
- deploy.yml 从 secrets 动态生成 .env,部署后自动删除 - docker-compose.prod.yml 支持全部业务配置注入(短信/微信/支付宝等) - .env.example 只保留 GITEA_RUNNER_TOKEN,其他密钥全部迁移到 Secrets - 更新 deploy/README.md 文档,完整列出 Secrets 配置清单 服务器上不再存储任何密码文件,安全性大幅提升 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -66,17 +66,43 @@ 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 down --remove-orphans
|
||||
docker-compose -f docker-compose.prod.yml build --parallel
|
||||
docker-compose -f docker-compose.prod.yml up -d
|
||||
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
|
||||
docker image prune -f
|
||||
echo "等待服务启动..."
|
||||
sleep 10
|
||||
docker-compose -f docker-compose.prod.yml ps
|
||||
docker-compose -f docker-compose.prod.yml --env-file .env.prod ps
|
||||
rm -f .env.prod
|
||||
|
||||
deploy-test:
|
||||
runs-on: [self-hosted, rent-deploy]
|
||||
@@ -85,14 +111,24 @@ 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 down --remove-orphans
|
||||
docker-compose -f docker-compose.test.yml build --parallel
|
||||
docker-compose -f docker-compose.test.yml up -d
|
||||
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
|
||||
docker image prune -f
|
||||
echo "等待服务启动..."
|
||||
sleep 10
|
||||
docker-compose -f docker-compose.test.yml ps
|
||||
docker-compose -f docker-compose.test.yml --env-file .env.test ps
|
||||
rm -f .env.test
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
DB_HOST=localhost
|
||||
DB_PORT=3306
|
||||
DB_USERNAME=root
|
||||
DB_PASSWORD=quan131735
|
||||
DB_PASSWORD=xxx
|
||||
DB_DATABASE=rent_platform
|
||||
|
||||
# Redis配置
|
||||
|
||||
+46
-6
@@ -64,16 +64,16 @@ scripts/
|
||||
|
||||
```bash
|
||||
# 将代码克隆到服务器
|
||||
git clone <你的GitLab仓库地址> ~/rent-platform
|
||||
git clone <你的Gitea仓库地址> ~/rent-platform
|
||||
cd ~/rent-platform
|
||||
|
||||
# 运行初始化(安装 Docker、创建网络、启动网关)
|
||||
# 运行初始化(安装 Docker、创建网络、启动 Gitea + 网关)
|
||||
bash scripts/setup-server.sh
|
||||
```
|
||||
|
||||
脚本会自动完成:
|
||||
- 安装 Docker、Docker Compose、Git、pnpm
|
||||
- 创建 `.env` 文件并提示你填写密码
|
||||
- 启动 Gitea + Act Runner
|
||||
- 创建 Docker 网络(rent-prod、rent-test)
|
||||
- 启动 Gateway Nginx
|
||||
|
||||
@@ -148,7 +148,47 @@ docker logs rent-act-runner
|
||||
|
||||
在 Gitea → **Settings → Actions → Runners** 页面应能看到 `rent-deploy-runner` 已注册并在线。
|
||||
|
||||
### 第 3 步:推送代码到 Gitea
|
||||
### 第 3 步:配置 Secrets(密钥安全)
|
||||
|
||||
> 所有密钥通过 Gitea Secrets 管理,服务器上不存储任何密码文件。
|
||||
|
||||
Gitea → **仓库 → Settings → Actions → Secrets**,添加以下密钥:
|
||||
|
||||
**生产环境:**
|
||||
|
||||
| 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` |
|
||||
|
||||
**测试环境:**
|
||||
|
||||
| Secret 名 | 说明 |
|
||||
|-----------|------|
|
||||
| `TEST_DB_PASSWORD` | 测试数据库密码 |
|
||||
| `TEST_JWT_SECRET` | 测试 JWT 密钥 |
|
||||
| `TEST_API_BASE_URL` | `https://api-test.pinzhuhui.com` |
|
||||
|
||||
> 暂时没有的配置(如微信支付、支付宝)可以先不填,流水线会使用空值默认。
|
||||
|
||||
### 第 4 步:推送代码到 Gitea
|
||||
|
||||
```bash
|
||||
# 添加 Gitea 远程仓库
|
||||
@@ -160,7 +200,7 @@ git push gitea test
|
||||
git push gitea prod
|
||||
```
|
||||
|
||||
### 第 4 步:自动部署触发
|
||||
### 第 5 步:自动部署触发
|
||||
|
||||
```bash
|
||||
# 推送 test 分支 → 自动部署测试环境
|
||||
@@ -170,7 +210,7 @@ git push gitea test
|
||||
git push gitea prod
|
||||
```
|
||||
|
||||
流水线:install → build → deploy
|
||||
流水线:install → build → generate .env from secrets → deploy
|
||||
|
||||
在 Gitea → **仓库 → Actions** 页面查看实时日志。
|
||||
|
||||
|
||||
@@ -1,10 +1,4 @@
|
||||
# ===== 生产环境 =====
|
||||
PROD_DB_PASSWORD=change_me_in_production
|
||||
PROD_JWT_SECRET=change_me_in_production
|
||||
|
||||
# ===== 测试环境 =====
|
||||
TEST_DB_PASSWORD=change_me_in_test
|
||||
TEST_JWT_SECRET=change_me_in_test
|
||||
|
||||
# ===== Gitea Act Runner =====
|
||||
# 注册 Runner 时从 Gitea Web 界面获取 token 填入这里
|
||||
# 其他所有密钥通过 Gitea → Settings → Actions → Secrets 管理
|
||||
GITEA_RUNNER_TOKEN=change_me
|
||||
|
||||
@@ -52,14 +52,33 @@ services:
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
PORT: 3000
|
||||
# Docker 内部网络
|
||||
DB_HOST: mysql
|
||||
DB_PORT: 3306
|
||||
DB_USERNAME: root
|
||||
DB_PASSWORD: ${PROD_DB_PASSWORD:-rent123456}
|
||||
DB_DATABASE: rent_platform
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
JWT_SECRET: ${PROD_JWT_SECRET:-change_this_in_production}
|
||||
# 从 .env.prod 注入的密钥
|
||||
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}
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
|
||||
@@ -55,11 +55,12 @@ services:
|
||||
DB_HOST: mysql
|
||||
DB_PORT: 3306
|
||||
DB_USERNAME: root
|
||||
DB_PASSWORD: ${TEST_DB_PASSWORD:-rent123456}
|
||||
DB_DATABASE: rent_platform
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: 6379
|
||||
JWT_SECRET: ${TEST_JWT_SECRET:-change_this_in_test}
|
||||
DB_PASSWORD: ${TEST_DB_PASSWORD}
|
||||
JWT_SECRET: ${TEST_JWT_SECRET}
|
||||
API_BASE_URL: ${TEST_API_BASE_URL:-http://localhost:3001}
|
||||
depends_on:
|
||||
mysql:
|
||||
condition: service_healthy
|
||||
|
||||
Reference in New Issue
Block a user