Flask通过FLASK_CONFIG环境变量选择配置类实现多环境切换,FLASK_ENV仅控制运行模式(如调试器启用),不参与配置加载;必须在create_app()内读取FLASK_CONFIG并调用app.config.from_object()加载对应子类,敏感配置须从环境变量读取。

Flask 应用如何通过 FLASK_ENV 和 FLASK_CONFIG 区分环境
Flask 本身不强制多环境配置,但依赖两个关键环境变量控制行为:FLASK_ENV(已弃用但仍有影响)和更推荐的 FLASK_CONFIG。注意:从 Flask 2.3 起,FLASK_ENV=development 会自动启用调试器和重载,但不再影响配置类加载逻辑;真正决定加载哪个配置的是你代码中如何实现配置选择。
常见错误是以为设了 FLASK_ENV=production 就自动切到生产配置——其实它只改运行模式,不改 app.config 内容。必须自己写逻辑读取 FLASK_CONFIG 或其他变量来加载对应配置类。
- 推荐统一用
FLASK_CONFIG=development/production/testing,并在代码里解析该值 - 避免混用
FLASK_ENV控制配置,容易和旧文档混淆 - 启动时未设置
FLASK_CONFIG会导致默认配置为空或 fallback 失败
用配置类 + 工厂函数实现动态加载
最稳妥的方式是定义多个配置类,再用工厂函数根据环境变量实例化应用。这是官方推荐模式,也便于测试和部署隔离。
示例结构:
config.py
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'dev-key'
class DevelopmentConfig(Config):
DEBUG = True
DATABASE_URL = 'sqlite:///dev.db'
class ProductionConfig(Config):
DEBUG = False
DATABASE_URL = os.environ.get('DATABASE_URL')
class TestingConfig(Config):
TESTING = True
DATABASE_URL = 'sqlite:///:memory:'
工厂函数中按需加载:
app.py
def create_app(config_name=None):
app = Flask(__name__)
config_name = config_name or os.environ.get('FLASK_CONFIG', 'development')
config_class = {
'development': DevelopmentConfig,
'production': ProductionConfig,
'testing': TestingConfig
}.get(config_name)
if not config_class:
raise RuntimeError(f'Unknown config: {config_name}')
app.config.from_object(config_class)
return app
- 不要在
create_app()外直接调用app.config.from_object(...),否则无法动态切换 -
os.environ.get('FLASK_CONFIG')必须在create_app()内部读取,否则模块导入时就固化了 - 生产环境务必从环境变量读敏感配置(如数据库密码),不要硬编码在类里
app.config.from_envvar() 的局限与替代方案
app.config.from_envvar() 只能加载一个 Python 文件路径(比如 MY_APP_SETTINGS=/path/to/prod.py),但它绕过了类继承和默认值管理,容易丢失基础配置(如 SECRET_KEY 默认值)。实际项目中很少单独用它。
更实用的做法是组合使用:
- 先
from_object(Config)加载基类 - 再
from_prefixed_env()(需 Flask 2.1+)或手动os.environ覆盖关键项 - 例如:
app.config['DATABASE_URL'] = os.environ.get('DATABASE_URL', app.config['DATABASE_URL'])
注意:多次调用 from_object 不会合并,而是完全替换,所以基类必须包含所有可能被覆盖的键。
部署时 Docker / systemd 怎么传配置
Docker 中通过 -e 注入环境变量最直接:
docker run -e FLASK_CONFIG=production -e DATABASE_URL=postgresql://... my-flask-app
systemd 服务文件里写:
[Service] Environment="FLASK_CONFIG=production" EnvironmentFile=/etc/myapp/env
关键点:
-
EnvironmentFile中的变量不会自动大写,而 Flask 默认读取的FLASK_*变量是大小写敏感的 - 确保
FLASK_CONFIG值和配置类名/字典 key 完全一致(比如不能写prod期望匹配ProductionConfig) - Gunicorn 启动时如果用
--env,要确认是否传递给了子进程(某些版本需加--preload)
复杂项目里,配置最终往往变成“环境变量 → 配置类 → 实例化时覆盖”,中间任何一层漏掉检查,都会导致本地开发正常、上线后 500。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











