FastAPI多环境配置实战:从.env文件到Docker部署的完整指南
1. 为什么需要多环境配置第一次用FastAPI写项目时我直接把数据库连接字符串硬编码在代码里。结果测试时把生产数据库给清空了差点被开除...这才明白环境隔离的重要性。现代软件开发至少要区分四种环境开发环境本机调试用需要热重载、详细日志测试环境自动化测试专用需要隔离的测试数据库预发布环境仿真生产环境用于最终验证生产环境真实用户访问需要最高级别安全配置举个实际例子你的Redis配置在不同环境可能是这样的# 开发环境用本地Redis REDIS_HOST localhost # 生产环境用云服务商集群 REDIS_HOST rds.aliyun.com直接用if-else判断环境太原始了我在多个百万级用户项目中验证过的方案是环境变量配置文件。FastAPI官方推荐的python-dotenv就是专门干这个的配合Docker能实现配置与代码完全分离。2. 环境配置实战四步走2.1 安装与基础配置先装必备工具pip install python-dotenv uvicorn项目目录建议这样组织这是我踩坑后总结的最佳实践my_project/ ├── app/ # 业务代码 ├── deploy/ # 环境配置 │ ├── dev.env # 开发环境 │ ├── test.env # 测试环境 │ ├── stage.env # 预发布环境 │ └── prod.env # 生产环境 └── main.py # 入口文件.env文件示例注意千万别把prod.env提交到Git# deploy/dev.env DEBUGTrue DATABASE_URLpostgresql://dev:123456localhost:5432/dev_db REDIS_HOSTredis://localhost API_RATE_LIMIT10002.2 启动时动态加载在main.py里可以这样灵活切换环境import os from fastapi import FastAPI app FastAPI() # 从环境变量获取当前环境类型 ENV os.getenv(ENV, dev) # 默认开发环境 app.get(/config) async def show_config(): return { database: os.getenv(DATABASE_URL), rate_limit: os.getenv(API_RATE_LIMIT) } if __name__ __main__: import uvicorn env_file fdeploy/{ENV}.env # 动态匹配环境文件 uvicorn.run(app, env_fileenv_file)启动命令示例# 开发环境默认 python main.py # 指定测试环境 ENVtest python main.py2.3 类型安全处理环境变量读取出来全是字符串需要手动转换类型。我推荐用pydantic做校验from pydantic import BaseSettings class Settings(BaseSettings): redis_host: str redis_port: int 6379 # 默认值 debug: bool False class Config: env_file fdeploy/{os.getenv(ENV, dev)}.env settings Settings() # 自动读取并转换类型2.4 多环境Docker化Docker部署才是终极方案Dockerfile关键配置FROM python:3.9 # 安装依赖 COPY requirements.txt . RUN pip install -r requirements.txt # 拷贝代码 COPY . . # 通过--env-file指定环境配置 CMD [uvicorn, main:app, --host, 0.0.0.0, --env-file, deploy/prod.env]启动容器时动态注入配置# 开发环境构建 docker build -t myapp . docker run -e ENVdev myapp # 生产环境使用独立配置 docker run -e ENVprod -v ./deploy/prod.env:/app/deploy/prod.env myapp3. 高级技巧与避坑指南3.1 CI/CD集成在GitLab CI中这样安全传递环境变量deploy_prod: stage: deploy only: - master script: - docker build -t myapp . - docker run -e ENVprod --env-file deploy/prod.env myapp重要安全提示永远不要把.env文件放入Docker镜像生产环境配置应该通过docker run --env-file动态挂载在K8s中推荐使用Secret管理敏感配置3.2 配置继承与覆盖我常用这种分层配置方案base.env # 通用配置 dev.env # 继承base覆盖开发特定配置 prod.env # 继承base覆盖生产特定配置通过python-dotenv的override参数实现from dotenv import load_dotenv load_dotenv(deploy/base.env) load_dotenv(fdeploy/{ENV}.env, overrideTrue) # 覆盖基础配置3.3 敏感信息处理千万别这样写# 错误示范明文密码 DB_PASSWORD123456应该生产环境使用Vault等密钥管理系统开发环境可以用example.env模板在代码中设置缺省值db_password os.getenv(DB_PASSWORD, default_for_dev)4. 真实项目经验分享去年我们有个项目在AWS上遭遇配置泄露事故。现在我的团队强制要求所有环境配置必须通过env_file管理生产环境配置由运维单独保管CI/CD管道中自动检查是否包含敏感信息一个实用的调试技巧在启动时打印加载的配置生产环境记得关闭if ENV dev: print( Loaded Config ) for k, v in os.environ.items(): print(f{k}: {v})最后提醒几个常见坑Windows下.env文件编码问题必须UTF-8Docker compose中使用env_file的路径问题建议绝对路径环境变量名大小写敏感全大写最保险