生产环境下Django(Gunicorn)无法读取环境变量但django-shell可正常获取
问题根本原因
你遇到的差异是因为Django Shell和Gunicorn的运行环境完全独立,环境变量不共享:
- 你手动启动Django Shell时,使用的是当前登录用户的Shell会话环境,系统会自动加载
/etc/environment、用户目录下的.bashrc/.zshrc等配置,所以能正常读取到配置的变量。 - 绝大多数线上场景下Gunicorn是通过systemd/supervisor等进程管理工具运行的,这类工具启动的服务默认不会加载
/etc/environment的内容,服务运行时的环境变量是隔离配置的,所以读不到你设置的VUE_APP_WEB_URL,只能拿到默认值。
解决方案
方案1:修改Gunicorn的systemd服务配置(最推荐,无需改动项目代码)
- 找到你的Gunicorn systemd配置文件,默认路径一般为
/etc/systemd/system/[你的gunicorn服务名].service - 在
[Service]配置段中添加以下内容:# 方式一:直接声明需要的环境变量 Environment="VUE_APP_WEB_URL=http://my.url.xyz/" # 方式二:直接加载整个/etc/environment文件 EnvironmentFile=/etc/environment - 重载systemd配置并重启Gunicorn生效:
sudo systemctl daemon-reload sudo systemctl restart gunicorn
方案2:在Django项目中显式加载系统环境变量配置
如果不想修改服务端配置,可以在settings.py读取环境变量前,先手动加载/etc/environment的内容:
import os from pathlib import Path # 先加载/etc/environment的变量 env_file = Path("/etc/environment") if env_file.exists(): with open(env_file, "r", encoding="utf-8") as f: for line in f: line = line.strip() # 跳过注释、空行和不符合key=value格式的行 if not line or line.startswith("#") or "=" not in line: continue key, val = line.split("=", 1) # 去除值两端的引号 val = val.strip("'\" ") os.environ.setdefault(key, val) # 再读取BASE_URL配置 BASE_URL = os.getenv('VUE_APP_WEB_URL','http://127.0.0.1:8080/')
修改后重启Gunicorn即可生效。
特殊情况:使用Supervisor管理Gunicorn
如果你的Gunicorn是用Supervisor管理的,需要在对应项目的Supervisor配置(一般在/etc/supervisor/conf.d/目录下)的[program:xxx]段添加:
environment=VUE_APP_WEB_URL="http://my.url.xyz/"
之后执行supervisorctl update重载配置即可。
内容的提问来源于stack exchange,提问作者Milano
相关产品推荐
相关产品推荐

