How to set environment variables for your web apps (for SECRET_KEY etc)

Many deployment guides suggest you store configuration information that's likely to vary between platforms in Environment variables. See The 12-factor app for example. While this advice isn't perfectly adapted to a Platform-as-a-Service environment like PythonAnywhere, it can be made to work. Here's how.

We'll use the example of setting the Django SECRET_KEY setting, since it's a common one.

In brief, you need to set the environment variable in two different places:

  • In a postactivate script for it to work in Bash consoles
  • In your WSGI file for it to work in the web app itself.

To avoid duplication, we recommend using a .env file and a tool called python-dotenv to load it.

Start by saving your environment variables into a .env file in your project folder

You can run something like this in a Bash console, or edit the .env file directly using our "Files" tab:

cd ~/my-project-dir
echo "export SECRET_KEY=sekritvalue" >> .env
echo "export OTHER_SECRET=somethingelse" >> .env
# etc

Install python-dotenv into your virtualenv

workon my-virtualenv-name
pip install python-dotenv
# or, if you're not using a virtualenv:
pip3.6 install --user python-dotenv

# and, optionally, add it to your requirements.txt, if you're using one:
echo python-dotenv >> requirements.txt

Make sure that you have at least version 0.8 of the python-dotenv package, as older versions can't handle the export at the start of lines in the .env file.

For your web app itself: loading your .env file in your WSGI file

This will ensure the environment variables is available to the worker processes that are actually serving your web application, live on the Internet.

Click over to the Web tab for your web app, and click on the link to your WSGI file. In here, you can set your environment variable using Python code; this needs to go before the code that actually loads your website (that is, before the call to get_wsgi_application).

import os
from dotenv import load_dotenv
project_folder = os.path.expanduser('~/my-project-dir')  # adjust as appropriate
load_dotenv(os.path.join(project_folder, '.env'))

Save this change, and your code will now have access to the variable from os.getenv, so with the Django SECRET_KEY setting, you can just add this to your

import os
SECRET_KEY = os.getenv("SECRET_KEY")

Hit save, reload your web app, and it should now have access to the variable.

For Bash consoles: load your .env file in your virtualenv postactivate script

For when you're running database migrations, or doing any other command-line interactions with your web app

Here's how to load up the environnment variables from your .env file in a Bash console:

set -a; source ~/my-project-dir/.env; set +a

Assuming you're using a Virtualenv for your web app, and also assuming you're using virtualenvwrapper/workon, a convenient place to set an environment variable to be available in your Bash console sessions is in a special script called "postactivate" that gets run automatically whenever you activate your virtualenv.

  • A typical location might be /home/yourusername/.virtualenvs/my-project-virtualenv/bin/postactivate

Here's how you might add the source command above to your postactivate script:

echo 'set -a; source ~/my-project-dir/.env; set +a' >> ~/.virtualenvs/my-project-virtualenv/bin/postactivate

Test this out by activating your virtualenv, with, eg, workon my-project-virtualenv and then trying to run eg echo $SECRET_KEY

All done!

Your environment variables should now load automatically, both in your webapp, and in your virtualenv.