Deploy Django, Gunicorn, NGINX, Postgresql using Docker
Aug 09, 2016 · 4 Min Read · 15 Likes · 67 CommentsThis post is based on this article on docker documentation.
I will be extending this post by serving django+gunicorn using Nginx, also I will using Postgresql docker container to use it as database.
Steps
Let us checkout to the following steps.
Create django project
Let’s make an empty directory named myproject and add another folder inside name it src. src should contain the django project. For testing purpose lets put a simple django project inside named mydjango.
Add ‘requirement.pip’
Let’s create a subdirectory inside myproject and name it config. Lets put a requirement.pip
file inside config and write these line in it:
Django==1.10
gunicorn==19.6.0
psycopg2==2.6.2
Create ‘Dockerfile’
Now let’s make a Dockerfile
inside the myproject. This should contain the following lines:
FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN mkdir /config
ADD /config/requirements.pip /config/
RUN pip install -r /config/requirements.pip
RUN mkdir /src;
WORKDIR /src
So this Dockerfile starts with a Python 3.5 based image. Then the container is modified by adding the requirement.pip
file in /config directory within the container and installing the packages from it.
Install ‘docker-compose’
Let’s create a file called docker-compose.yml
in myproject directory.
The docker-compose.yml
file describes the services that make your app. Here we need a web service(Django+Gunicorn), A database(Postgres), and Proxy Server(Nginx). It also describes which Docker images these services will use, how they will link together, any volumes they might need mounted inside the containers. Finally, the docker-compose.yml
file describes which ports these services expose. See the docker-compose.yml reference for more information on how this file works. Don’t forget to add docker-compose to your python environment by running pip install docker-compose
.
Add configuration to ‘docker-compose.yml’
Let’s add the following configuration to the docker-compose.yml
file:
version: "2"
services:
nginx:
image: nginx:latest
container_name: ng01
ports:
- "8000:8000"
volumes:
- ./src:/src
- ./config/nginx:/etc/nginx/conf.d
depends_on:
- web
web:
build: .
container_name: dg01
command: bash -c "python manage.py makemigrations && python manage.py migrate && gunicorn mydjango.wsgi -b 0.0.0.0:8000"
depends_on:
- db
volumes:
- ./src:/src
expose:
- "8000"
db:
image: postgres:latest
container_name: ps01
It says that there are three services for this project: nginx, web, db. nginx depends on web, web depends on db. db container uses postgres’s latest image from dockerhub. Default username for db is postgres
and password is postgres
web container is build using project’s Dockerfile
. It mounts src directory into it and exposes port 8000. version
is being used for which format to use to compose the docker file.
nginx uses nginx’s latest image from dockerhub. This proxy server is accessible from port 8000. It mounts src and config directory.
Create NGINX config
Now let’s write a nginx configuration config file named mydjango.conf
inside myproject’s config folder and put it in a subdirectory named nginx.
upstream web {
ip_hash;
server web:8000;
}
# portal
server {
location / {
proxy_pass http://web/;
}
listen 8000;
server_name localhost;
}
So what it does that, nginx acts as a reverse proxy for any connections going to django server and all connections goes through nginx to reach django server.
Project Directory should look like this:
── myproject
├── src
│ ├── mydjango
│ ├── manage.py
├── config
│ ├── requirements.pip
│ ├── nginx
│ ├── mydjango.conf
├── Dockerfile
└── docker-compose.yml
Database configuration
To communicate from django to postgres, we need to put database configuration in django applications settings file. It should look like this:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'postgres',
'USER': 'postgres',
'HOST': 'db',
'PORT': 5432,
}
}
Almost done
All is done. Now lets run docker-compose build
in terminal within the project directory. It will build/rebuild(if necessary) all the containers. For first time running the containers, run docker-compose up -d
. Lets go to browser and type: localhost:8000
. We should see the django application up and running.
Start and stop docker compose
For stopping the docker, run docker-compose stop
. Re-running docker, use docker-compose start
.
Shell access
For shell accessing.
#Nginx
docker exec -ti nginx bash
#Web
docker exec -ti web bash
#Database
docker exec -ti db bash
For logs:
#Nginx
docker-compose logs nginx
#Web
docker-compose logs web
#DB
docker-compose logs db
Thats it.
Example source code
You can see an working example here in my repo: https://github.com/ruddra/docker-django
Also another deployment example for Ruby on rails here: https://github.com/ruddra/deploy-notebook (Thanks to Akimul Islam for the source)
In conclusion
Thats all for now. Thanks for reading. If you have any question, please post it in comment section below.
Cheers!!
Update
Serving django with gunicorn won’t allow you to serve static files with it. You need to serve static files seperately. You can follow this post for how to do serve static files using Nginx from docker.
Last updated: Jul 13, 2024
I won't spam you. Unsubscribe at any time.