Basic micro service based on Django-Posgres-Gunicorn-Nginx

By yuseferi, 22 July, 2018
Django Micro serivce

I’m working in a company which our main product is based on Php, with several servers and several services, but when a project gets larger and larger it’s very hard to extend it and in modern design architectures, micro-service architecture could be a good solution. 

Microservices is also known as the microservice architecture – is an architectural style that structures an application as a collection of loosely coupled services, which implement business capabilities. The microservice architecture allows the continuous delivery/deployment of large and complex applications. It also enables an organization to evolve its technology stack.

Microservices design helps to ease the problems associated with the monolithic model. Implementing microservices is perhaps one of the greatest ways to improve the productivity of a software engineering team. This is especially true if the following takes place:


I’ll be back and share much more things about microservice and my experiences with you. But for now, I’m decided to share a basic microservice with you.

As I mentioned our product is based on Php and it’s very costly to implement a temporary custom request from BI team within the main project and I’ve decided to implement it as a microservice and easily drop it later because the requested feature is temporary. Because I had some experiences in working with Django and also the requirement needs some system programming ( some multiprocessing task) and some REST endpoints, I’d preferred to use Python and Django for this micro-service.

In this article, I’m going to create a portable microservice with Docker, Django, Postgres, Gunicorn and great Nginx. let’s dive into it.

If you don’t have much more knowledge I strongly recommend you Getting start with Docker Documentation.

For creating this stack follow the following steps


1. Make an empty directory named dpgn and add another folder inside name it src. src should contain the Django project. For testing, purpose lets put a simple Django project inside name it to dpgn.

2. Create a subdirectory inside dpgn and name its config. Create  a file with the name requirements.txt inside config and write the following lines in it:

Django==1.10
gunicorn==19.9
psycopg2==2.7.5

3. Make a Dockerfile inside the dpgn. And add the following lines to it:

FROM python:3.6
ENV PYTHONUNBUFFERED 1
RUN mkdir /config
ADD /config/requirements.txt /config/
RUN pip install -r /config/requirements.txt
RUN mkdir /src
WORKDIR /src


4. Create a file called docker-compose.yml in dpgn directory. It’s docker compose file and play a big role in our job. Fill it with the following configurations.
 

version: '1'
services:
 nginx:
   image: nginx:latest
   container_name: nginx01
   ports:
     - "8000:8000"
   volumes:
     - ./src:/src
     - ./config/nginx:/etc/nginx/conf.d
   depends_on:
     - web
   links:
     - web:web
 
 web:
   build: .
   container_name: django01
   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
   links:
     - db:db
   expose:
     - "8000"
 
 db:
   image: postgres:latest
   container_name: postgres01


 
6. Now we need to configure Nginx config file, create a file, named it to my-dpgn.conf inside dpgn 's config directory and put the following lines to it.
 

# webservice
server {
 listen 8000;
 server_name localhost;
 location / {
       proxy_pass http://web/;
        proxy_set_header Host $host;
   }
}


 
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 reachDjangoo server.
7. To communicate from Django to Postgres, we need to put database configuration in Django applications settings file (settings.py). It should look like this:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'postgres',
        'USER': 'postgres',
        'HOST': 'db',
        'PORT': 5432,
    }
} 


 
 
8. To make you microservice secure, disable debugging in settings.py by set Debug=False and  Enter  valid hosts ( and IPs)  which are allowed to interact with your microservice in ALLOWED_HOSTS = ['yuseferi.com','localhost'] And because we forwarding port 8080 to 8000 we should set USE_X_FORWARDED_PORT = True  in settings.py as well.
 
9. We are Almost Done, Now everything is ready and you just need to build it with : docker-compose up --build  within  your project main path. And  open the localhost:8080  return you the Django welcome page .

Note: If you want to run it as Daemon try docker-compose up -d 


Note:  you can access the containers separately with the following commands:

#Nginx
docker exec -it nginx bash
#Web
docker exec -it web bash
#Database
docker exec -it db bash

This images is pushed to Docker hub you can pull it easily by  docker pull yuseferi/dpgn
 
And also the source of this article is pushed to github and available in the https://github.com/yuseferi/dpgn , feel free to clone and customize it based on requirements in your projects.
 
Reference: https://docs.docker.com/compose/django/#more-compose-documentation