Files
cmhub/docs/env.md
T

103 lines
6.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 环境变量与配置
> 本文集中约定运行 `cmhub` 所需配置项。真实密钥、数据库密码、支付凭证不得写入代码、文档样例或提交记录;本文件只写变量名、用途和占位示例。
## 一、配置来源
- Django 运行级配置走环境变量或 `.env`(`.env` 不提交)。
- 仓库根目录提供 `.env.example` 作为无密钥样例;新增配置项时同步更新 `.env.example` 与本文。
- 上游 AI 模型的 `api_key` 存入数据库前必须用 `AI_KEY_ENCRYPTION_KEY` 加密,admin 脱敏展示且不回显明文。
- 微信、支付宝商户密钥/证书走环境变量或部署机安全文件路径,不写入数据库明文字段。
- 本地开发、测试、生产使用同一套变量名;差异只在变量值。
## 二、Django 基础配置
| 变量 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- |
| `DJANGO_SECRET_KEY` | 是 | `change-me` | Django SECRET_KEY;生产必须使用高强度随机值 |
| `DJANGO_DEBUG` | 是 | `false` | 生产必须为 `false` |
| `DJANGO_ALLOWED_HOSTS` | 是 | `cmhub.example.com,127.0.0.1` | 逗号分隔 |
| `DJANGO_CSRF_TRUSTED_ORIGINS` | 生产是 | `https://cmhub.example.com` | 用户端表单、admin、充值页需要 |
| `DJANGO_TIME_ZONE` | 否 | `Asia/Shanghai` | 默认按中国业务时区 |
## 三、数据库配置
开发和生产都使用 MySQL 8.4 LTS 独立实例,不使用 SQLite。
| 变量 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- |
| `MYSQL_HOST` | 是 | `127.0.0.1` | cmhub 专用 MySQL 实例地址 |
| `MYSQL_PORT` | 是 | `3306` | MySQL 默认端口;若与已有实例共存,可改为专用独立端口 |
| `MYSQL_DATABASE` | 是 | `cmhub` | 数据库名 |
| `MYSQL_USER` | 是 | `cmhub` | 应用账号 |
| `MYSQL_PASSWORD` | 是 | `change-me` | 数据库密码 |
| `MYSQL_CHARSET` | 是 | `utf8mb4` | 必须为 `utf8mb4` |
| `MYSQL_CONNECT_TIMEOUT` | 否 | `30` | 客户端连接 MySQL 的超时秒数;远程测试库建议显式设置,避免默认值过短造成误判 |
| `MYSQL_READ_TIMEOUT` | 否 | `120` | 客户端等待 MySQL 响应的读取超时秒数 |
| `MYSQL_WRITE_TIMEOUT` | 否 | `120` | 客户端向 MySQL 写入数据的超时秒数 |
## 四、AI 与加密配置
| 变量 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- |
| `AI_KEY_ENCRYPTION_KEY` | 是 | `base64-fernet-key` | Fernet 主密钥,用于加密 `AiModel.api_key_encrypted`;生产不可更换,除非完成密钥轮换 |
`AI_KEY_ENCRYPTION_KEY` 必须是 `cryptography.fernet.Fernet.generate_key()` 生成的 base64 字符串,可用 `py -3.12 -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"` 生成。
`AiModel.url`、`AiModel.model`、`AiModel.api_type`、`AiModel.capabilities` 与加密后的 `api_key` 由后台或数据迁移维护,不通过环境变量硬编码具体模型。
AI 上游连接超时与读取超时不走全局环境变量:连接超时由 `AiModel.connect_timeout_seconds` 控制,读取超时由 `AiModel.timeout_seconds` 控制;当读取超时为 `0` 时,Provider 按分辨率使用内置默认值。
## 五、支付配置
| 变量 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- |
| `PAYMENT_CALLBACK_MODE` | 是 | `mock` / `sdk` | 回调验签模式;本地/测试可用 `mock`,生产必须为 `sdk` |
| `PAYMENT_MOCK_CALLBACK_SECRET` | mock 是 | `change-me` | mock 回调 HMAC 密钥;仅用于本地/测试,不得冒充真实支付验签 |
| `PAYMENT_QR_EXPIRES_MINUTES` | 否 | `10` | 扫码下单返回的二维码本地有效期提示;不作为自动阻断延迟回调的依据 |
### 微信 V3 native
| 变量 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- |
| `WECHAT_PAY_APPID` | 真实支付是 | `wx...` | 微信 appid |
| `WECHAT_PAY_MCHID` | 真实支付是 | `1900000001` | 商户号 |
| `WECHAT_PAY_API_V3_KEY` | 真实支付是 | `change-me` | API v3 key |
| `WECHAT_PAY_CERT_SERIAL_NO` | 真实支付是 | `ABC...` | 商户证书序列号 |
| `WECHAT_PAY_PRIVATE_KEY_PATH` | 真实支付是 | `/secure/wechat/apiclient_key.pem` | 私钥文件路径 |
| `WECHAT_PAY_NOTIFY_URL` | 真实支付是 | `https://cmhub.example.com/api/v1/recharge/callback/wechat` | 公网回调地址 |
### 支付宝当面付
| 变量 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- |
| `ALIPAY_APPID` | 真实支付是 | `202100...` | 支付宝 appid |
| `ALIPAY_APP_PRIVATE_KEY_PATH` | 真实支付是 | `/secure/alipay/app_private_key.pem` | 应用私钥路径 |
| `ALIPAY_PUBLIC_KEY_PATH` | 真实支付是 | `/secure/alipay/alipay_public_key.pem` | 支付宝公钥路径 |
| `ALIPAY_NOTIFY_URL` | 真实支付是 | `https://cmhub.example.com/api/v1/recharge/callback/alipay` | 公网回调地址 |
| `ALIPAY_DEBUG` | 否 | `false` | 生产必须为 `false` |
缺少真实商户配置时,充值任务只能使用 mock 支付客户端;mock 必须在代码和测试中标明,不得伪装成真实支付。
## 六、对象存储配置
图片结果默认返回 URL,避免大 base64 进入同步响应体。对象存储选型未最终落地前,可使用本地开发存储,但生产必须给出可公开访问或可签名访问的 URL。
| 变量 | 必填 | 示例 | 说明 |
| --- | --- | --- | --- |
| `STORAGE_BACKEND` | 否 | `local` | `local` / `s3`;MVP 可先 `local` |
| `MEDIA_ROOT` | local 是 | `D:\chengma\cmhub\media` | 本地媒体文件目录 |
| `MEDIA_URL` | local 是 | `/media/` | 本地媒体 URL 前缀 |
| `S3_ENDPOINT_URL` | s3 是 | `https://s3.example.com` | S3 兼容 endpoint |
| `S3_BUCKET_NAME` | s3 是 | `cmhub-media` | bucket |
| `S3_ACCESS_KEY_ID` | s3 是 | `change-me` | access key |
| `S3_SECRET_ACCESS_KEY` | s3 是 | `change-me` | secret key |
## 七、上线前检查
- `DJANGO_DEBUG=false`。
- `DJANGO_SECRET_KEY`、`AI_KEY_ENCRYPTION_KEY`、数据库密码、支付密钥均已使用生产值。
- `ALLOWED_HOSTS`、`CSRF_TRUSTED_ORIGINS`、支付 `notify_url` 使用同一公网域名。
- MySQL 为 8.4 LTS / InnoDB / `utf8mb4`,不是 SQLite 或已有 MySQL 5.7。
- 图片同步链路的客户端、Nginx、Gunicorn、上游 read timeout 均按最慢图片模型放大到同一量级。