Put Secrets in Environment Variables#

Secrets like Django’s SECRET_KEY don’t belong in a container image or a public repository. They need to be handled in a way that protects them from being revealed. With containers, the most common way to do that is to put secrets in environment variables. This lab will show you how to use an environment variable in Python.

Edit Django’s Configuration#

Django’s configuration is Python where using environment variables isn’t quite as easy as with the shell. Edit your mysite/settings.py file and add the following line to the top near the other import statements:

import os

Now find the line that looks like this:

SECRET_KEY = 'django-insecure-@o71s+_^+tm0*33j7gv3xrjjtue5)z55sjg40urg(7pu*8kl)5'

And change it to this:

SECRET_KEY = os.environ['SECRET_KEY']

If you try to start Django now you should see an error:

$ python3 ./manage.py runserver
python3 ./manage.py runserver
Traceback (most recent call last):
  File "/home/maximus/lifealgorithmic-web/work/cis-92/django/mysite/./manage.py", line 22, in <module>
    main()
  File "/home/maximus/lifealgorithmic-web/work/cis-92/django/mysite/./manage.py", line 18, in main
    execute_from_command_line(sys.argv)
  File "/home/maximus/.local/lib/python3.10/site-packages/django/core/management/__init__.py", line 446, in execute_from_command_line
    utility.execute()
  File "/home/maximus/.local/lib/python3.10/site-packages/django/core/management/__init__.py", line 386, in execute
    settings.INSTALLED_APPS
  File "/home/maximus/.local/lib/python3.10/site-packages/django/conf/__init__.py", line 92, in __getattr__
    self._setup(name)
  File "/home/maximus/.local/lib/python3.10/site-packages/django/conf/__init__.py", line 79, in _setup
    self._wrapped = Settings(settings_module)
  File "/home/maximus/.local/lib/python3.10/site-packages/django/conf/__init__.py", line 190, in __init__
    mod = importlib.import_module(self.SETTINGS_MODULE)
  File "/usr/lib/python3.10/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1050, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1027, in _find_and_load
  File "<frozen importlib._bootstrap>", line 1006, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 688, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 883, in exec_module
  File "<frozen importlib._bootstrap>", line 241, in _call_with_frames_removed
  File "/home/maximus/lifealgorithmic-web/work/cis-92/django/mysite/mysite/settings.py", line 24, in <module>
    SECRET_KEY = os.environ['SECRET_KEY']
  File "/usr/lib/python3.10/os.py", line 679, in __getitem__
    raise KeyError(key) from None
KeyError: 'SECRET_KEY'

Set an Environment Variable in Docker#

You should already know how to set an environment variable in the shell. But local variables don’t affect docker containers. Rebuild your container on your dev box with the new code:

$ docker build -t mysite .

Now run the new container and set an environment variable:

$ docker run -it --rm -e SECRET_KEY=django-super-secret-key -p 8080:8000 mysite