Gunicorn环境变量设置

26

目前我在尝试将环境变量传递给我的Django项目中的Gunicorn,但是遇到了困难。我正在使用最新的19.1版本。我有一个类似于以下代码的wsgi.py文件:

import os
import sys
from django.core.wsgi import get_wsgi_application

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
PROJECT_DIR = os.path.abspath(os.path.join(BASE_DIR, '..'))

sys.path.append(PROJECT_DIR)
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "app.settings")

def application(environ, start_response):
    _application = get_wsgi_application()
    os.environ['SERVER_ENV'] = environ['SERVER_ENV']
    os.environ['SERVER_ID'] = environ['SERVER_ID']
    return _application(environ, start_response)

当我在命令行上运行gunicorn时:

SERVER_ENV=TEST SERVER_ID=TEST gunicorn -b 127.0.0.1:8080 --error-logfile - --access-logfile - app.wsgi:application

当我向gunicorn发送请求时,我经常会遇到以下问题:

2014-08-01 08:39:17 [21462] [ERROR] Error handling request
Traceback (most recent call last):
  File "/opt/virtualenv/python-2.7.5/django-1.5.5/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 93, in handle
    self.handle_request(listener, req, client, addr)
  File "/opt/virtualenv/python-2.7.5/django-1.5.5/lib/python2.7/site-packages/gunicorn/workers/sync.py", line 134, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
  File "/opt/sites/itracker/wsgi.py", line 18, in application
    os.environ['SERVER_ENV'] = environ['SERVER_ENV']
KeyError: 'SERVER_ENV'

打印出环境变量值可以确认环境变量未被传递。我尝试在虚拟环境激活脚本中设置环境变量,也尝试在专用的 gunicorn shell 脚本中设置环境变量,并尝试使用 --env 标志设置环境变量,但似乎都无效。

有任何想法吗?

4个回答

37

当我部署 gunicorn.service 时,遇到了类似的问题。 我通过一个文件向其传递环境变量:

<on gunicorn.service>
[Service]
...
EnvironmentFile=/pathto/somefilewith_secrets
...
例如(cat /etc/systemd/system/gunicorn.service)。
[Unit]  
Description=gunicorn daemon  
After=network.target  
  
[Service]  
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/10008/digichainOpen
EnvironmentFile=/home/ubuntu/10008/digichainOpen/.env
ExecStart=/home/ubuntu/.local/share/virtualenvs/digichainOpen-Zk2Jnvjv/bin/gunicorn \
          --worker-class=gevent --workers 4 \
          --bind unix:/home/ubuntu/10008/digichainOpen/gunicorn.sock digichainOpen.wsgi:application
            
[Install]  
WantedBy=multi-user.target  

并且.env文件可以是:

my_var=someValue
some_secret=secretvalue
another_secret=blah

4
我当时没有立即意识到 env 文件中的变量需要设置为 MY_VAR=someValue 而不是 export MY_VAR=someValue。如果其他人遇到类似问题,希望可以提供帮助。 - johnchase
工作目录和环境文件的目录必须相同吗? - Bagghi Daku
1
@AnuroopSingh EnvironmentFile是由systemd读取的,它可以放在任何地方。 - temoto
你认为应该在这里设置PATH变量吗?还是gunicorn会继承使用者主目录中.bash文件中设置的环境变量? - Francesco Pegoraro

12

你只需要导出你的环境变量即可。

export SERVER_ENV=TEST
export SERVER_ID=TEST
gunicorn -b 127.0.0.1:8080 --error-logfile - --access-logfile - app.wsgi:application

在您的代码中,您可以像这样获取它们

os.getenv('SERVER_ENV')

为什么 os.environ.get('SERVER_ENV') 不起作用? - Patrick Bassut
不,它确实有用。在设置WSGI时,Django调用def application(environ, start_response) - Patrick Bassut
这难道不是与 OP 演示的同样事情吗?我认为在命令开始时设置环境变量会产生相同的影响,所以如果对 OP 来说这种方式不起作用,那么我也不认为这种方式会起作用。 - CryptoFool

5

如果您想使用gunicorn配置文件运行Django:

编写一个config.py文件

command = 'venv/bin/gunicorn'
pythonpath = 'venv'
bind = '127.0.0.1:8000'
workers = 2
raw_env = ["VARIABLE_HERE=VARIABLE_VALUE_HERE"]
wsgi_app = "project.wsgi"

按照以下方式运行: 从项目目录内部

gunicorn -c config.py

-3

我不太明白你在这里尝试做什么。如果你在bash命令行中传递环境变量,它们已经存在于os.environ中:没有必要从其他地方获取它们。 environ字典由请求传递的元素组成,而不是shell。


3
服务器重启时环境变量会发生什么变化? - Brylie Christopher Oxley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接