Deployment with Docker

(Outdated docs - Only for version 1.11 and before)


  • Docker 17.05+.

  • Docker Compose 1.17+

Understanding the Docker Compose Setup

Before you begin, check out the production.yml file in the root of this project. Keep note of how it provides configuration for the following services:

  • django : your application running behind Gunicorn ;

  • postgres : PostgreSQL database with the application's relational data;

  • redis : Redis instance for caching;

  • traefik : Traefik reverse proxy with HTTPS on by default.

  • worker running a Huey worker process;

Configuring the Stack

The majority of services above are configured through the use of environment variables. Just check out envs.

To obtain logs and information about crashes in a production setup, make sure that you have access to an external Sentry instance (e.g. by creating an account with ), and set the SENTRY_DSN variable. Logs of level logging.ERROR are sent as Sentry events. Therefore, in order to send a Sentry event use:

bash import logging logging.error("This event is sent to Sentry", extra={"<example_key>": "<example_value>"})

The extra parameter allows you to send additional information about the context of this error.

You will probably also need to setup the Mail backend, for example by adding a Mailgun API key and a Mailgun sender domain, otherwise, the account creation view will crash and result in a 500 error when the backend attempts to send an email to the account owner.

HTTPS is On by Default

SSL (Secure Sockets Layer) is a standard security technology for establishing an encrypted link between a server and a client, typically in this case, a web server (website) and a browser. Not having HTTPS means that malicious network users can sniff authentication credentials between your website and end users' browser.

It is always better to deploy a site behind HTTPS and will become crucial as the web services extend to the IoT (Internet of Things). For this reason, we have set up several security defaults to help make your website secure:

  • If you are not using a subdomain of the domain name set in the project, then remember to put your staging/production IP address in the DJANGO_ALLOWED_HOSTS environment variable (see settings) before you deploy your website. Failure to do this will mean you will not have access to your website through the HTTP protocol.

  • Access to the Django admin is set up by default to require HTTPS in production or once live .

The Traefik reverse proxy used in the default configuration will get you a valid certificate from Lets Encrypt and update it automatically. All you need to do to enable this is to make sure that your DNS records are pointing to the server Traefik runs on.

You can read more about this feature and how to configure it, at Automatic HTTPS in the Traefik docs.

(Optional) Postgres Data Volume Modifications

Postgres saves its database files to the specified volume by default. Change that if you want something else and make backups since this is not done automatically.

Building & Running Production Stack

You will need to build the stack first. To do that, run:

bash docker-compose -f production.yml build

Once this is ready, you can run it with:

bash docker-compose -f production.yml up

To run the stack and detach the containers, run:

bash docker-compose -f production.yml up -d

To run a migration, open up a second terminal and run:

bash docker-compose -f production.yml run --rm django python migrate

To create a superuser, run:

bash docker-compose -f production.yml run --rm django python verified_superuser

This will create a superuser with access to the django admin who is also able to enable authentication methods etc in the user facing app.

If you need a shell, run:

bash docker-compose -f production.yml run --rm django python shell

To check the logs out, run:

docker-compose -f production.yml logs

If you want to scale your application, run:

bash docker-compose -f production.yml up --scale django=4 docker-compose -f production.yml up --scale celeryworker=2


don't try to scale postgres , worker , or traefik .

To see how your containers are doing run:

docker-compose -f production.yml ps

Process Manager

Once you are ready with your initial setup, you want to make sure that your application is run by a process manager to survive reboots and auto restarts in case of an error.

You can use the process manager you are most familiar with. All it needs to do is to run docker-compose -f production.yml up in your project's root directory.

If you are using supervisor , you can use this file as a starting point:

command=docker-compose -f production.yml up

Move it to /etc/supervisor/conf.d/project_slug.conf and run:

bash supervisorctl reread supervisorctl update supervisorctl start project_slug

For status check, run:

bash supervisorctl status