4

I am deploying a Django app on my VPS using Nginx as the web server and Gunicorn installed in virtualenv. (I am using virtualenv with virtualenvwrapper.)

When I run Gunicorn like this, environment variables (such as database password, name) can be found:

workon virtual_env_name
# from my_project's root path
gunicorn my_project.wsgi --bind localhost:9000 --daemon
# this works

I exported the environment variables this way:

# /home/user_name/Envs/virtual_env_name/bin/postactivate
export DATABASE_PASSWORD="secret_password"

However the way below does not (whether or not virtual_env_name is activated):

sudo service gunicorn start
# env variables can't be found - KeyError thrown

This is how my gunicorn.conf script looks like:

start on (local-filesystems and net-device-up IFACE=eth0)
stop on runlevel [!12345]

# If the process quits unexpectadly trigger a respawn
respawn

setuid user_name
setgid www-data
chdir /home/user_name/my_project

exec /home/user_name/Envs/virtual_env_name/bin/gunicorn \
    --name=my_project \
    --pythonpath=/home/user_name/my_project \
    --bind=127.0.0.1:9000 \
    my_project.wsgi:application

I can confirm this gunicorn.conf works if I hard code all the password, keys into my Django's settings.py instead of using os.environ[..].

What do I need to do to make my environment variables found when I start Gunicorn with sudo service start? What's the difference between the first and second way? Thanks.

Jonas
  • 534
  • 8
  • 16
  • Please kindly correct me (or edit my question) if I use any terms wrong or ambiguously. – Jonas Nov 11 '15 at 14:35
  • Please show output of `pip freeze` on Your system and on virtualenv. – Tomasz Jakub Rup Nov 11 '15 at 14:40
  • Here is my [pip freeze for system](https://gist.github.com/jnshey/3b37eb8bfc2f1392d355) and [pip freeze for virtualenv](https://gist.github.com/jnshey/24acc400606bb91d3de7). – Jonas Nov 11 '15 at 14:47

2 Answers2

5

You need to define those variables inside gunicorn.conf.

env DATABASE_PASSWORD="secret_password"
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Thanks. Yes, it works. But why can't the env variables in postactivate be seen when I use `sudo service gunicorn start`? – Jonas Nov 11 '15 at 14:56
  • One more question, why doesn't `env DEBUG=False` in `gunicorn.conf` disable debug mode for Django? In `settings.py`, I use `DEBUG = os.environ['DEBUG']`. – Jonas Nov 11 '15 at 15:09
  • 2
    First, because upstart starts your job in a completely new environment. And secondly, because the variables are all strings, and "False" is boolean true. – Daniel Roseman Nov 11 '15 at 15:23
  • Thanks. I now use `eval(os.environ['DEBUG'])`. Are there better methods such as making use of Truthy and Falsey values? – Jonas Nov 11 '15 at 15:45
  • It's a bad solution. When You remove Django from global packages (look at Your pip freeze results) then Your application does not start properly. – Tomasz Jakub Rup Nov 11 '15 at 16:07
  • @Thomasz Jakub Rup I think when I use virtual env's gunicorn by `/home/user_name/Envs/virtual_env_name/bin/gunicorn`, I am also using virtual env's django? – Jonas Nov 11 '15 at 16:28
1

You don't run the code in virtualenv.

Instead of exec use

pre-start script
    workon virtual_env_name
end script

script
    gunicorn \
        --name=my_project \
        --pythonpath=/home/user_name/my_project \
        --bind=127.0.0.1:9000 \
        my_project.wsgi:application
end script

workon update Your $PATH env variable.

Tomasz Jakub Rup
  • 10,502
  • 7
  • 48
  • 49