绝大多数情况是环境变量未进入Python进程:Web服务器(如Gunicorn)不加载shell配置,systemd需显式声明Environment,Docker需透传且注意大小写与特殊字符。

Python项目线上环境变量读取不到的常见原因
绝大多数情况不是代码写错了,而是环境变量根本没进到 Python 进程里——os.environ 只能看到进程启动时继承的那批变量,不是你本地 .bashrc 里写的、也不是你 export 一下就自动生效的。
Web服务器(如Gunicorn/Uvicorn)启动时没加载环境变量
用 systemd 或 supervisor 管理服务时,子进程默认不读取用户 shell 的配置文件(~/.bashrc、/etc/profile),所以你在终端里 export DEBUG=1 对 Gunicorn 完全无效。
- 用
systemd:在 service 文件里显式声明,比如Environment="DEBUG=1"或EnvironmentFile=/etc/default/myapp - 用
supervisor:在[program:myapp]段下加environment=DEBUG="1",DATABASE_URL="sqlite:///app.db" - 直接命令行启动?别用
source .env && gunicorn app:app,要写成env $(cat .env | xargs) gunicorn app:app(注意.env格式需为KEY=VALUE且无空格/引号)
python-dotenv 在线上不该用但很多人误用
python-dotenv 是开发辅助工具,它只在 Python 进程内加载 .env 文件,不改变系统级环境变量。线上部署时如果依赖它来“补救”缺失的变量,等于把敏感配置明文塞进代码目录,还可能因路径错误(比如工作目录不是项目根目录)导致加载失败。
- 线上应禁用
load_dotenv(),或至少加守卫:if os.getenv("ENV") != "prod": load_dotenv() - 若必须用,确保
.env路径绝对且可读:load_dotenv(Path(__file__).parent / ".env") - 它无法覆盖已存在的同名环境变量(默认行为),要用
override=True才能强制替换
容器(Docker)里环境变量没透传或拼写错误
Docker 默认不会把宿主机的环境变量带进容器,docker run -e KEY 或 docker-compose.yml 的 environment 字段漏写、大小写不一致、用了 env_file 但文件路径不对,都会导致 Python 读不到。
立即学习“Python免费学习笔记(深入)”;
- 检查是否用了
env_file却忘了environment显式声明变量名:env_file: .env不等于自动导入所有键,还得写environment: [DB_URL, DEBUG] - Docker Compose v2.20+ 支持
env_file: [.env]自动加载,但变量仍需在environment中列出才透传给容器内进程 - 用
docker exec -it myapp sh -c 'env | grep -i debug'直接验证变量是否真进了容器
最常被忽略的是:环境变量名本身有特殊字符(比如连字符 -)、值里有空格或未转义的 $,导致 shell 解析失败;还有就是 Python 代码里写成了 os.getenv("debug")(小写),而实际设置的是 DEBUG=1(大写)——Linux 环境变量严格区分大小写。


















