Aug 15, 2021
5 min read

How to Set Environment Variables for a Python Django Application using Apache and mod_wsgi in Docker

How to Set Environment Variables for a Python Django Application using Apache and mod_wsgi in Docker

Using environment variables to configure Django and other Python applications is awesome, but using them with Apache and mod_wsgi in Docker is a tricky process to get right.

That's why I created a step-by-step tutorial and a sample application to review all the info you need in one place.

While this tutorial uses Docker and Django, the same steps apply whether you're using a virtual machine or a different Python framework.

Review the code directly from the repository >

Environment Variables, Apache, and mod_wsgi

When hosting a Python WSGI compatible framework like Django in Apache with mod_wsgi, the only environment variables populated in the os.environ dictionary are those that exist in the environment of the script that starts Apache. But instead of having to mess with Apache's service manager settings (e.g. systemd or systemctl), there's a better way.

Most Apache distributions provide a shell script specifically for the purpose of setting environment variables that are made available to modules such as mod_wsgi.

It's then a matter of knowing the location of this shell script since it can be different depending on the Linux distribution. For example:

  • Debian/Ubuntu: /etc/apache2/envvars
  • CentOS: /etc/sysconfig/httpd

We'll be using Debian-based python:3.9-slim-buster Docker image.

Appending App Config and Secrets to the Environment Variables File

Our goal is for secrets to be fetched as key/value pairs and written to the envvars file in the typical shell environment variables format:

But from where and how do we fetch the app config and secrets to populate that file?

Since we're fans of Doppler :) let's start with a Doppler CLI example. But it's important to note that the mechanics of "fetch secrets, then append to file" can easily be adapted.

Set up your project

First, you need to set up your project in Doppler. To make the process easier, Import to Doppler to follow along.

Then use the Doppler CLI inside the Docker container to fetch the secrets:

Note: This requires a DOPPLER_TOKEN environment variable with a Service Token value

Did you notice that I used single quotes, not double quotes around the values?

That's because it gives you the flexibility of storing secrets with double quotes such as JSON in Doppler. As an example, you could use this to dynamically set Django's ALLOWED_HOSTS for any environment.

While you could also use a .env file, I wouldn't recommend it. Instead, consider using a secrets manager— why not Doppler?

Knowing the downsides to using .env files, If you must use them in your environment, the process is still straightforward:

Now that we know how to pass environment variables from Apache to mod_wsgi, let's move onto getting this working in Docker.

Docker Configuration for Apache and mod_wsgi

Let's review the task of configuring a Python Django Application using Apache and mod_wsgi in Docker into three parts:

  1. Custom Start Script
  2. Apache Site Config
  3. Dockerfile

If you only want to review the working code examples, review the examples on GitHub >

Since this isn't a Docker or Apache tutorial, we won't go into depth about the Dockerfile or Apache site config file. Do you have questions, need help, or want to share your thoughts? Check out our community forum >

1. Custom Start Script

Running your application in Docker is usually a case of setting the CMD, for example:

But it's trickier here because we need to append the environment variables to /etc/apache2/envvars before running Apache.

Since this requires multiple commands, let's create a custom script:

2. Apache Site Config

Here's an example Apache site config file for a Django application:

3. Docker file

The Docker file is reasonably straightforward, installing the Doppler CLI and Apache dependencies before copying the Django source code, custom script, and Apache site config:

With all the pieces in place, we can now build the Docker image (clone the sample repository to follow along):

Now we're ready to run the container!

Running the Django Application with Apache and mod_wsgi in Docker

Let's start with a Doppler example, then with an .env file.

With Doppler, you'll first need to set a DOPPLER_TOKEN environment variable to the value of a Service Token. This is what provides read-only access to a specific Doppler config in production environments.

Usually, this would be securely set by your deployment environment (e.g. GitHub Actions Secret) but for this exercise, we'll set it manually:

Now run the container:

.env File

To run the .env file version, we'll use the sample.env file from the sample repository:

Then to run the container:

Summary

Now you know how to configure Python applications hosted with Apache and mod_wsgi running in Docker using environment variables for app configuration and secrets.

After using the Doppler CLI versus managing .env files through our exercise, the difference is clear.

Manage environment variables, rotate secrets, and ship securely with Doppler >

Enjoying this content? Stay up to date and get our latest blogs, guides, and tutorials.

Related Content

Explore More