环境变量和配置文件,到底该用哪个?

写完一个 Python 脚本,本地跑得好好的,一扔到服务器上就报错:数据库连接失败、API 密钥找不到……你翻代码,发现所有参数都硬编码在 config.py 里;再翻服务器,发现压根没改这个文件

它们不是一回事

环境变量(Environment Variable)是操作系统给进程传递的一组键值对,比如 PATHHOME,你在终端敲 echo $USER 看到的就是它。它不依赖任何具体程序,只要进程启动时继承了,就能读到。

配置文件(Config File)则是项目自己约定的文本文件,比如 .envconfig.yamlsettings.json,靠代码主动去读、解析、加载——它只是个普通文件,系统不认识,不加载就等于不存在。

一个真实对比场景

假设你要部署一个 Flask 应用:

环境变量

export FLASK_ENV=production
export DATABASE_URL=postgresql://user:pass@db:5432/myapp
然后运行 flask run,Flask 自动从环境里取值。

配置文件

# config.py
class Config:
SQLALCHEMY_DATABASE_URI = 'sqlite:///app.db'
SECRET_KEY = 'dev-key'

得在代码里显式导入并调用:app.config.from_object(Config),否则这些值永远不会生效。

谁更灵活?谁更安全?

环境变量天生适合切换环境:开发机设 DEBUG=True,测试机设 LOG_LEVEL=warning,生产机设 SENTRY_DSN=https://xxx@o123.ingest.sentry.io/456 ——不用动代码,也不用传文件,只改启动命令或容器环境即可。

配置文件更适合存结构化、多层级、不易变动的设置,比如日志格式字段、邮件模板路径、API 接口路由映射表。但它一旦提交到 Git,敏感信息(密码、密钥)就容易泄露——而环境变量通常不在代码库中,运维同学配好就完事。

当然,别走极端:有人把整个 JSON 配置塞进一个叫 APP_CONFIG 的环境变量里,结果调试时连换行都看不到;也有人把数据库密码明文写进 config.ini 还提交了 GitHub ——这两种都算自找麻烦。

小建议:混着用,分清主次

基础开关、敏感凭证、环境标识(dev/staging/prod)走环境变量;业务规则、界面文案、功能开关列表这类非敏感、常需多人协作调整的内容,放配置文件更直观。Django 默认读 .env 文件来设置环境变量,Vue CLI 启动时自动载入 .env.production ——工具早帮你搭好了桥,关键是别把桥当路,也别把路当桥。