Skip to content

48|配置管理与多环境

代码中硬编码配置(数据库地址、密钥、超时时间)会带来几个问题:不同环境需要不同值、敏感信息不能进版本控制、修改配置需要重新部署。把配置从代码中分离出来,通过环境变量或配置文件管理,是工程化的基本要求。

一、环境变量

python
import os

DB_URL = os.getenv("DATABASE_URL", "sqlite:///ops.db")
SECRET_KEY = os.environ["SECRET_KEY"]   # 必填,没有就报错
DEBUG = os.getenv("DEBUG", "false").lower() == "true"
方法行为用途
os.getenv(key)不存在返回 None可选配置
os.getenv(key, default)不存在返回默认值有默认值的配置
os.environ[key]不存在抛 KeyError必填配置

.env 文件

开发时把环境变量写在 .env 文件中,不用每次都 export:

bash
# .env
DATABASE_URL=sqlite:///ops.db
SECRET_KEY=dev-secret-key
DEBUG=true
bash
# 加载 .env
uv add python-dotenv
python
from dotenv import load_dotenv

load_dotenv()   # 从 .env 文件加载环境变量

.env 文件不能提交到版本控制,在 .gitignore 中排除:

gitignore
.env
.env.local
.env.production

二、pydantic-settings

用 Pydantic 模型管理配置,自动从环境变量读取、类型转换、校验:

bash
uv add pydantic-settings
python
from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    database_url: str = "sqlite:///ops.db"
    secret_key: str
    debug: bool = False
    access_token_expire_minutes: int = 30

    class Config:
        env_file = ".env"

settings = Settings()
特性行为
自动映射database_url 对应环境变量 DATABASE_URL
类型转换环境变量都是字符串,自动转成模型声明的类型
必填校验secret_key 没有默认值且环境变量中没有时,启动报错
.env 支持Config.env_file 指定文件

使用:

python
from config import settings

print(settings.database_url)
print(settings.debug)

三、多环境配置

环境变量区分

bash
# 启动时指定环境
ENV=production uv run uvicorn main:app
python
class Settings(BaseSettings):
    env: str = "development"
    database_url: str
    debug: bool = False

    class Config:
        env_file = ".env"

settings = Settings()

# 根据环境调整默认值
if settings.env == "development":
    settings.debug = True

多文件配置

python
class Config:
    env_file = f".env.{os.getenv('ENV', 'development')}"
bash
.env.development
.env.staging
.env.production

四、敏感信息管理

密钥生成

python
import secrets

# 生成安全的随机密钥
secret = secrets.token_urlsafe(32)
print(secret)

生产环境密钥来源

方式适用场景
环境变量Docker、systemd、云服务
密钥管理服务AWS Secrets Manager、阿里云 KMS
配置文件(加密)Ansible Vault、sops

不要把密钥写在代码里或提交到 Git

五、常见错误

配置和代码混在一起

python
# 错误
DB_URL = "sqlite:///ops.db"   # 硬编码

# 正确
DB_URL = os.getenv("DATABASE_URL", "sqlite:///ops.db")

.env 提交到版本控制

bash
# 错误:.env 进了 Git,密钥泄露
git add .env
git commit -m "add config"

# 正确
# .gitignore 中加入 .env

没有给必填配置报错

python
# 错误:运行时才发现配置缺失
database_url = os.getenv("DATABASE_URL")   # None
connect(database_url)   # 报错

# 正确:启动时就检查
class Settings(BaseSettings):
    database_url: str   # 没有默认值,启动时缺失会报错