Django/Python无法获取环境变量:DigitalOcean Droplet配置异常
嘿,我来帮你搞定这个问题——你在Droplet的/etc/environment里加了DJANGO_DEVELOPMENT="1",重启后Django的settings.py还是读不到这个变量对吧?咱们一步步来排查:
1. 先确认系统层面变量是否真的生效
首先SSH到你的Droplet,先验证这个变量在系统里能不能读到:
- 先登出当前SSH会话,重新登录(因为
/etc/environment是用户登录时由PAM加载的,重启Droplet也行,但重新登录更快) - 执行
echo $DJANGO_DEVELOPMENT,看看输出是不是1 - 如果这里输出为空,那说明
/etc/environment的配置可能有问题:- 试试去掉引号,改成
DJANGO_DEVELOPMENT=1——有些系统对/etc/environment里的引号解析有问题,这个文件的标准格式是KEY=VALUE,值不含空格的话不需要引号 - 检查文件里有没有语法错误,确保每行只定义一个变量,不要有多余的空格或者换行
- 试试去掉引号,改成
2. 核心问题:后台服务进程读不到用户登录环境变量
如果刚才手动登录后能看到变量,但Django还是读不到,那十有八九是因为你的Django是通过后台服务(比如Gunicorn、uWSGI或者systemd管理的进程)运行的——这些进程不会加载用户登录时的PAM环境变量,也就是/etc/environment里的内容对它们来说是不可见的。
分场景解决:
场景A:用systemd管理Gunicorn/Django服务
直接在你的systemd服务文件(比如/etc/systemd/system/gunicorn.service)里添加环境变量:
[Service] # 保留你原来的其他配置,比如ExecStart、User这些 Environment="DJANGO_DEVELOPMENT=1"
然后执行命令让配置生效:
sudo systemctl daemon-reload sudo systemctl restart gunicorn
这样Gunicorn启动时就会带上这个变量,Django自然能读到。
场景B:用uWSGI运行Django
可以在uWSGI的配置文件里加一行:
env = DJANGO_DEVELOPMENT=1
或者启动uWSGI时直接指定:
uwsgi --env DJANGO_DEVELOPMENT=1 --http :8000 --module your_project.wsgi
场景C:临时测试(不推荐生产环境用)
如果只是临时验证,可以在启动Django前手动导出变量:
export DJANGO_DEVELOPMENT=1 python manage.py runserver 0.0.0.0:8000
但这只是临时的,重启进程就失效,生产环境还是用服务配置的方式更靠谱。
3. 额外排查技巧:打印所有环境变量
要是还是有问题,可以在settings.py开头加一段代码,把所有环境变量打出来,确认变量是否真的被加载了:
import os import logging logger = logging.getLogger(__name__) # 生产环境记得测试完注释掉这段! for key, value in os.environ.items(): logger.info(f"环境变量 {key}: {value}") # 你的原有判断逻辑 if os.environ.get('DJANGO_DEVELOPMENT') == '1': logger.info('DJANGO_DEVELOPMENT=="1"')
这样能清楚看到哪些变量被进程加载了,方便定位问题。
总结一下
/etc/environment里的变量只对用户登录的会话生效,后台运行的服务进程不会自动加载这些变量。所以生产环境中,直接在服务的配置文件里指定需要的环境变量是最稳定可靠的方式。
内容的提问来源于stack exchange,提问作者Milano

