Using NGINX with Docker-Compose and Django — The Official Breakdown
I was recently given the assignment by one of my freelancing clients to modify a repo to use NGINX to serve a Django application. The application is containerized using docker-compose and includes a Postgres database. I have been struggling with this topic, but have found multiple repos where this is achieved. In this article, I am going to analyze the repo found here to understand the way the pieces work together to bring Django up on NGINX.
Let’s start with the docker-compose.yaml file. I’ve minimized the djangoapp and nginx services for now because I will explain them later.
The docker-compose.yaml file
There are two database containers using the postgres:10 image. The data is persisted in ‘database1_volume’ and ‘database2_volume’ which are defined at the bottom of the file. The data will be found in /var/lib/postgresql/data in the respective containers. The environment files are set and the networks used are defined at the bottom of the file. The networks allow the services that are using them to reach each other.
The djangoapp Service Definition
In the djangoapp service definition, the ‘build’ key is establishing that the context of the build is the current directory and the Dockerfile should be found there too. We will look at the Dockerfile next. The volumes have been defined at the bottom and will be mounted to the directories defined on the right-hand side of the colons within the container. The service will use the database networks, the nginx network, and also will depends on database1 and database2.
The djangoapp Dockerfile
This dockerfile uses the python3.6 image, installs dependencies, copies the django application into /opt/services/djangoapp/src
, and runs a command to change the directory and run the manage.py command using a --no-input
argument because we do not want an input prompt to pop up when building an image. After that, port 8000 is exposed. Gunicorn is bound to port 8000 in the final command using the wsgi application found in hello/wsgi
.
The nginx Service Definition
This service uses the nginx:1.13 image and port forwards port 8000 to port 80. The directory ./config/nginx/conf.d
is moved to the container’s directory /etc/nginx/conf.d
. Static and media are also persisted as volumes in the nginx container. Obviously, this will depend on the djangoapp service.
The nginx .conf File
First we define an upstream called hello_server
which is a connection to djangoapp:8000. Just a reminder, djangoapp
is defined and port 8000 is exposed in the docker-compose file.This means that NGINX is accessing the django application’s wsgi connection.
This server’s name is localhost and will listen on port 80. This means that when you go to localhost
it should send requests upstream— to the django app. The locations /static/
and /media/
are defined as aliases so the server will know to look in /opt/services/djangoapp/
for both static and media files.
The location /
is defined to pass requests to the upstream hello_server
. It uses http because the server is listening at port 80. If it were https for example, the server would be listening on port 443. Last, headers are set o any request URL starting with /
will have the necessary headers when being sent to Django.