【问题标题】:Gunicorn Environment Variable SettingGunicorn 环境变量设置
【发布时间】:2014-09-24 10:11:52
【问题描述】:

我目前在将环境变量传递到 Gunicorn 以用于我的 Django 项目时遇到困难。我使用的是最新的 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'

打印出环境值确认没有传入环境变量。我尝试在 virtualenv 激活脚本和专用的 gunicorn shell 脚本中设置环境变量,还可以使用 - -env 标志,但似乎没有任何效果。

有什么想法吗?

【问题讨论】:

    标签: django wsgi gunicorn django-wsgi


    【解决方案1】:

    我在部署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
    

    【讨论】:

    • 我没有立即意识到 env 文件中的变量需要设置为 MY_VAR=someValue 而不是 export MY_VAR=someValue。以防其他人遇到类似问题
    • WorkingDirectory 和 EnvironmentFile 的目录必须相同吗?
    • @AnuroopSingh EnvironmentFile 被 systemd 读取,它可能在任何地方。
    • 你觉得PATH变量应该设置在这里吗?或者 gunicorn 是否继承了它正在使用的用户主目录中的 .bash 文件中设置的环境变量?
    【解决方案2】:

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

    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') 不起作用?
    • 不,确实如此。设置 wsgi 时使用了 def application(environ, start_response) django 调用
    【解决方案3】:

    如果你想使用 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
    

    【讨论】:

      【解决方案4】:

      我不太明白你想在这里做什么。如果您在 bash 命令行中传递环境变量,它们在os.environ已经:无需从其他任何地方获取它们。 environ 字典由请求传递的元素组成,而不是 shell。

      【讨论】:

      • 服务器重启后环境变量会发生什么变化?
      猜你喜欢
      • 2014-12-17
      • 2018-07-13
      • 1970-01-01
      • 2016-02-03
      • 2012-04-04
      • 2014-09-05
      • 2013-03-03
      • 2019-01-15
      • 1970-01-01
      相关资源
      最近更新 更多