Gunicorn Environment Variable Setting
Asked Answered
D

4

26

I'm currently having difficulty passing environment variables into Gunicorn for my Django project. I'm on the latest 19.1 version. I have a wsgi.py file like so:

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)

When I run gunicorn from the command line as:

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

and I then pass a request to gunicorn I keep getting:

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'

Printing out the environ values confirms that the environment variables are not being passed in. I've tried setting the environment variables in the virtualenv activation script and also in a dedicated gunicorn shell script and also by setting the environment variables using the --env flag but nothing seems to work.

Any ideas?

Devise answered 1/8, 2014 at 8:49 Comment(0)
B
42

I got a similar problem when deploying gunicorn.service. And I passed environment variables to it by a file:

<on gunicorn.service>
[Service]
...
EnvironmentFile=/pathto/somefilewith_secrets
...

For example (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  

and the .env file can be:

my_var=someValue
some_secret=secretvalue
another_secret=blah
Brookweed answered 2/4, 2018 at 14:40 Comment(4)
I did not immediately realize the variables in the env file need to be set like MY_VAR=someValue not export MY_VAR=someValue. In case anyone else runs into a similar issueVolant
Does WorkingDirectory and EnvironmentFile's directory have to be same?Malapropos
@AnuroopSingh EnvironmentFile is read by systemd, it may be anywhere.Dearborn
Do you think the PATH variable should be set here? Or does gunicorn inherit the environ variables that are set in .bash files in the home dir of the User that it is using?Highbred
F
12

You just have to export your environment variable.

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

And in your code you can get them like that

os.getenv('SERVER_ENV')
Flasher answered 1/8, 2014 at 12:22 Comment(3)
Why os.environ.get('SERVER_ENV') doesn't work?Purlieu
No, it does. Was using the def application(environ, start_response) django calls when setting up wsgiPurlieu
Isn't this the same thing as the OP demonstrates? Setting env vars at the start of a command I think would have the same affect, so if that isn't working for the OP, I wouldn't think that this would either.Parochialism
S
5

If you want to run Django using gunicorn config file:

Write a config.py file

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"

Run it like this: From inside the project directory

gunicorn -c config.py
Saccharoid answered 14/9, 2021 at 14:41 Comment(0)
S
-3

I don't quite understand what you are trying to do here. If you pass environment variables in the bash command line, they are already in os.environ: there is no need to get them from anywhere else. The environ dictionary is made up of elements passed from the request, not the shell.

Straightout answered 1/8, 2014 at 9:7 Comment(1)
What happens to the environment variables when the server reboots?Ustulation

© 2022 - 2024 — McMap. All rights reserved.