How to Configure Django + Gunicorn inside Docker

Introduction

Gunicorn ‘Green Unicorn’ is a Python WSGI HTTP Server for UNIX. It’s a pre-fork worker model ported from Ruby’s Unicornproject[1]. Within this article we will look at the steps on how to configure Gunicorn to serve your Django application inside a Docker container.

Entrypoint

First of all we create a script[2] and name it entrypoint.sh. This script will be used by the ENTRYPOINT instruction within the Dockerfile, in turn allowing you to pass additional Gunicorn variables to the container at runtime.

NOTE The config below is based on a sync worker_class. When configuring the number of workers you should base this on the following calculation – (CPUS * 2) +1. Further information on the different Gunicorn settings can be found here.

#!/bin/bash

# Prepare log files and start outputting logs to stdout
touch ./logs/gunicorn.log
touch ./logs/gunicorn-access.log
tail -n 0 -f ./logs/gunicorn*.log &

export DJANGO_SETTINGS_MODULE=projectx.settings

exec gunicorn projectx.wsgi:application \
    --name projectx_django \
    --bind 0.0.0.0:8000 \
    --workers 5 \
    --log-level=info \
    --log-file=./logs/gunicorn.log \
    --access-logfile=./logs/gunicorn-access.log \
"$@"

Dockerfile

Next lets look at the docker file.

Within the Dockerfile, we add the necessary instructions, to the end of the file, to copy over the previously created script and assign it against the ENTRYPOINT instruction.

WORKDIR $CONTAINER_PROJECT
COPY ./entrypoint-main.sh /
ENTRYPOINT ["/entrypoint.sh"]

Here is the Dockerfile, in its entirety.

# Set the base image to Ubuntu
FROM ubuntu:14.04

# File Author / Maintainer
MAINTAINER Maintaner Ricky Donato

# Update the default application repository sources list
RUN apt-get update && apt-get install -y \
    python-dev \
    python \
    python-pip \
    python-setuptools \
    build-essential \
    python-dev \
    git

# Set variables for project name, and where to place files in container.
ENV PROJECT=projectx
ENV CONTAINER_HOME=/opt
ENV CONTAINER_PROJECT=$CONTAINER_HOME/$PROJECT

# Create application subdirectories
WORKDIR $CONTAINER_HOME
RUN mkdir logs

# Copy application source code to $CONTAINER_PROJECT
COPY . $CONTAINER_PROJECT

# Install Python dependencies
RUN pip install -r $CONTAINER_PROJECT/requirements.txt
RUN pip install gunicorn

# Copy and set entrypoint
WORKDIR $CONTAINER_PROJECT
COPY ./entrypoint.sh /
ENTRYPOINT ["/entrypoint.sh"]

Build/Run

Finally we can then build the image and then run the container,

# build 
docker build -t django_gunicorn:v1 .

# run
docker run –restart=always -p 8000:8000 -i -t django_gunicorn:v1

Sources

[1] https://pypi.python.org/pypi/gunicorn
[2] http://michal.karzynski.pl/blog/2015/04/19/packaging-django-applications-as-docker-container-images

Rick Donato

Want to become a Docker and Kubernetes expert?

Here is our hand-picked selection of the best courses you can find online:
Docker Mastery course
Kubernetes Mastery course
and our recommended certification practice exams:
AlphaPrep Practice Tests - Free Trial