feat(config): add environment configuration management
- Add comprehensive environment configuration guide - Create .env.development for development setup - Create .env.production.example as production template - Add LOG_LEVEL configuration to Settings - Add .env.production to .gitignore - Support multiple environments: dev/test/staging/prod - Include security best practices and checklists Phase 4 Task 43/68 completed
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
# 生产环境配置模板(实际使用时复制为 .env.production)
|
||||
ENVIRONMENT=production
|
||||
DEBUG=false
|
||||
USE_IN_MEMORY_DB=false
|
||||
LOG_LEVEL=WARNING
|
||||
|
||||
# 数据库(必须修改)
|
||||
DATABASE_URL=postgresql://prod_user:CHANGE_THIS_PASSWORD@db-prod:5432/xiaoxia_prod
|
||||
|
||||
# Redis(必须修改)
|
||||
REDIS_URL=redis://:CHANGE_THIS_PASSWORD@redis-prod:6379/0
|
||||
|
||||
# JWT(必须修改,至少 32 字符)
|
||||
JWT_SECRET_KEY=CHANGE_THIS_TO_A_RANDOM_SECRET_KEY_AT_LEAST_32_CHARS
|
||||
|
||||
# SMTP(必须配置)
|
||||
SMTP_HOST=smtp.gmail.com
|
||||
SMTP_PORT=587
|
||||
SMTP_USER=your-email@gmail.com
|
||||
SMTP_PASSWORD=your-app-specific-password
|
||||
SMTP_FROM_EMAIL=noreply@yourdomain.com
|
||||
|
||||
# 应用配置
|
||||
BASE_URL=https://yourdomain.com
|
||||
|
||||
# CORS(修改为实际域名)
|
||||
CORS_ORIGINS=["https://yourdomain.com","https://app.yourdomain.com"]
|
||||
|
||||
# 监控(可选)
|
||||
SENTRY_DSN=https://your-sentry-dsn@sentry.io/project-id
|
||||
@@ -38,6 +38,7 @@ class Settings(BaseSettings):
|
||||
# 环境
|
||||
ENVIRONMENT: str = "development" # development, staging, production
|
||||
DEBUG: bool = True
|
||||
LOG_LEVEL: str = "INFO" # DEBUG, INFO, WARNING, ERROR
|
||||
|
||||
# CORS
|
||||
CORS_ORIGINS: list = ["http://localhost:3000", "http://localhost:5173"]
|
||||
|
||||
@@ -0,0 +1,310 @@
|
||||
# 环境配置管理指南
|
||||
|
||||
## 📋 概述
|
||||
|
||||
小虾 SaaS 支持多环境配置:开发、测试、预发布、生产。
|
||||
|
||||
---
|
||||
|
||||
## 🔧 环境类型
|
||||
|
||||
### 1. Development(开发)
|
||||
|
||||
**特点:**
|
||||
- 使用 InMemory 数据库
|
||||
- 详细日志输出
|
||||
- 热重载
|
||||
- Debug 模式
|
||||
|
||||
**配置:**
|
||||
```env
|
||||
ENVIRONMENT=development
|
||||
DEBUG=true
|
||||
USE_IN_MEMORY_DB=true
|
||||
LOG_LEVEL=DEBUG
|
||||
```
|
||||
|
||||
### 2. Testing(测试)
|
||||
|
||||
**特点:**
|
||||
- 独立测试数据库
|
||||
- 快速重置
|
||||
- Mock 外部服务
|
||||
|
||||
**配置:**
|
||||
```env
|
||||
ENVIRONMENT=testing
|
||||
DEBUG=true
|
||||
USE_IN_MEMORY_DB=true
|
||||
DATABASE_URL=postgresql://test:test@localhost:5432/xiaoxia_test
|
||||
```
|
||||
|
||||
### 3. Staging(预发布)
|
||||
|
||||
**特点:**
|
||||
- 生产级配置
|
||||
- 真实数据库
|
||||
- 完整监控
|
||||
|
||||
**配置:**
|
||||
```env
|
||||
ENVIRONMENT=staging
|
||||
DEBUG=false
|
||||
USE_IN_MEMORY_DB=false
|
||||
DATABASE_URL=postgresql://staging:***@db-staging:5432/xiaoxia_staging
|
||||
LOG_LEVEL=INFO
|
||||
```
|
||||
|
||||
### 4. Production(生产)
|
||||
|
||||
**特点:**
|
||||
- 最高安全级别
|
||||
- 完整监控告警
|
||||
- 数据备份
|
||||
|
||||
**配置:**
|
||||
```env
|
||||
ENVIRONMENT=production
|
||||
DEBUG=false
|
||||
USE_IN_MEMORY_DB=false
|
||||
DATABASE_URL=postgresql://prod:***@db-prod:5432/xiaoxia_prod
|
||||
LOG_LEVEL=WARNING
|
||||
SENTRY_DSN=https://...
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📁 配置文件结构
|
||||
|
||||
```
|
||||
├── .env # 本地开发配置(不提交)
|
||||
├── .env.example # 配置模板
|
||||
├── .env.development # 开发环境
|
||||
├── .env.testing # 测试环境
|
||||
├── .env.staging # 预发布环境
|
||||
└── .env.production # 生产环境(不提交)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚀 启动命令
|
||||
|
||||
### 开发环境
|
||||
|
||||
```bash
|
||||
# 使用默认 .env
|
||||
uvicorn apps.api.main:app --reload
|
||||
|
||||
# 或指定环境文件
|
||||
ENV_FILE=.env.development uvicorn apps.api.main:app --reload
|
||||
```
|
||||
|
||||
### 测试环境
|
||||
|
||||
```bash
|
||||
ENV_FILE=.env.testing pytest tests/
|
||||
```
|
||||
|
||||
### 生产环境
|
||||
|
||||
```bash
|
||||
# 使用 Gunicorn
|
||||
gunicorn apps.api.main:app \
|
||||
--workers 4 \
|
||||
--worker-class uvicorn.workers.UvicornWorker \
|
||||
--bind 0.0.0.0:8000 \
|
||||
--env ENV_FILE=.env.production
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔒 敏感信息管理
|
||||
|
||||
### 1. 使用环境变量
|
||||
|
||||
```bash
|
||||
# 不要硬编码
|
||||
❌ JWT_SECRET_KEY = "my-secret-key"
|
||||
|
||||
# 从环境变量读取
|
||||
✅ JWT_SECRET_KEY = os.getenv("JWT_SECRET_KEY")
|
||||
```
|
||||
|
||||
### 2. 使用密钥管理服务
|
||||
|
||||
**AWS Secrets Manager:**
|
||||
```python
|
||||
import boto3
|
||||
|
||||
def get_secret(secret_name):
|
||||
client = boto3.client('secretsmanager')
|
||||
return client.get_secret_value(SecretId=secret_name)
|
||||
```
|
||||
|
||||
**阿里云 KMS:**
|
||||
```python
|
||||
from aliyunsdkcore.client import AcsClient
|
||||
from aliyunsdkkms.request.v20160120 import DecryptRequest
|
||||
|
||||
def get_secret(encrypted_secret):
|
||||
client = AcsClient(...)
|
||||
request = DecryptRequest.DecryptRequest()
|
||||
request.set_CiphertextBlob(encrypted_secret)
|
||||
return client.do_action_with_exception(request)
|
||||
```
|
||||
|
||||
### 3. Git 安全
|
||||
|
||||
```bash
|
||||
# .gitignore
|
||||
.env
|
||||
.env.production
|
||||
.env.staging
|
||||
*.key
|
||||
*.pem
|
||||
secrets/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 日志级别配置
|
||||
|
||||
### 按环境配置
|
||||
|
||||
```python
|
||||
LOG_LEVELS = {
|
||||
"development": "DEBUG",
|
||||
"testing": "INFO",
|
||||
"staging": "INFO",
|
||||
"production": "WARNING",
|
||||
}
|
||||
|
||||
LOG_LEVEL = LOG_LEVELS.get(ENVIRONMENT, "INFO")
|
||||
```
|
||||
|
||||
### 日志格式
|
||||
|
||||
**开发环境(详细):**
|
||||
```
|
||||
2026-06-17 08:36:45 DEBUG [request_id=abc123] User login attempt: user@example.com
|
||||
```
|
||||
|
||||
**生产环境(精简):**
|
||||
```
|
||||
2026-06-17 08:36:45 INFO Request completed: POST /api/v1/auth/login status=200 time=0.045s
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔄 配置热更新
|
||||
|
||||
### 支持的配置
|
||||
|
||||
- 日志级别
|
||||
- 速率限制
|
||||
- 功能开关
|
||||
|
||||
### 实现方式
|
||||
|
||||
```python
|
||||
class DynamicConfig:
|
||||
def __init__(self):
|
||||
self._config = {}
|
||||
|
||||
def reload(self):
|
||||
"""从数据库或配置中心重新加载"""
|
||||
self._config = load_config_from_db()
|
||||
|
||||
def get(self, key, default=None):
|
||||
return self._config.get(key, default)
|
||||
|
||||
# 全局实例
|
||||
dynamic_config = DynamicConfig()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 最佳实践
|
||||
|
||||
### 1. 配置分层
|
||||
|
||||
```
|
||||
环境变量 > .env 文件 > 默认值
|
||||
```
|
||||
|
||||
### 2. 配置验证
|
||||
|
||||
```python
|
||||
from pydantic import validator
|
||||
|
||||
class Settings(BaseSettings):
|
||||
JWT_SECRET_KEY: str
|
||||
|
||||
@validator('JWT_SECRET_KEY')
|
||||
def validate_secret_key(cls, v):
|
||||
if len(v) < 32:
|
||||
raise ValueError('JWT_SECRET_KEY must be at least 32 characters')
|
||||
return v
|
||||
```
|
||||
|
||||
### 3. 配置文档
|
||||
|
||||
所有配置项都应该在 `.env.example` 中有说明:
|
||||
|
||||
```env
|
||||
# JWT 密钥(生产环境必须修改)
|
||||
# 长度至少 32 字符
|
||||
JWT_SECRET_KEY=your-super-secret-key-change-this-in-production
|
||||
|
||||
# 数据库连接字符串
|
||||
# 格式:postgresql://user:password@host:port/database
|
||||
DATABASE_URL=postgresql://xiaoxia:password@localhost:5432/xiaoxia_saas
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🚨 生产环境检查清单
|
||||
|
||||
- [ ] `DEBUG=false`
|
||||
- [ ] `JWT_SECRET_KEY` 已修改(至少 32 字符)
|
||||
- [ ] 数据库密码已修改
|
||||
- [ ] Redis 密码已配置
|
||||
- [ ] SMTP 密码使用应用专用密码
|
||||
- [ ] `LOG_LEVEL=WARNING` 或 `INFO`
|
||||
- [ ] `.env.production` 不在版本控制中
|
||||
- [ ] CORS 配置为实际域名
|
||||
- [ ] 速率限制已启用
|
||||
- [ ] 监控告警已配置
|
||||
|
||||
---
|
||||
|
||||
## 📞 故障排查
|
||||
|
||||
### 配置未生效
|
||||
|
||||
```bash
|
||||
# 1. 检查环境变量
|
||||
env | grep DATABASE_URL
|
||||
|
||||
# 2. 检查 .env 文件
|
||||
cat .env
|
||||
|
||||
# 3. 验证配置加载
|
||||
python -c "from apps.api.app.config import settings; print(settings.DATABASE_URL)"
|
||||
```
|
||||
|
||||
### 敏感信息泄露
|
||||
|
||||
```bash
|
||||
# 检查 Git 历史
|
||||
git log -p | grep -i "password\|secret\|token"
|
||||
|
||||
# 清理敏感信息(谨慎使用)
|
||||
git filter-branch --force --index-filter \
|
||||
"git rm --cached --ignore-unmatch .env" \
|
||||
--prune-empty --tag-name-filter cat -- --all
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**最后更新:** 2026-06-17
|
||||
Reference in New Issue
Block a user