Nginx – Docker how to Django + uwsgi/gunicorn + nginx

djangodockergunicornnginxuwsgi

I can't get my head around on what's the "correct" way to deploy a Django project that uses uwsgi/gunicorn (I haven't decide yet what to use, probably uwsgi since it has better performances, suggestions?) and nginx using docker.

I saw that some people put everything in the same container. I'm not an expert of docker, but the container should just do one (1) thing. So, having Django + nginx seems to be 2 rather than 1.

Now, my idea of the deployment is:

  • a container with Django and uwsgi. At the end of the Dockerfile i run the uwsgi script. This container exposes the port 8000
  • a container with nginx that is linked to django one. This exposes port 80 and proxies the requests to django.

Is there any other way to do it? Is there a tutorial that covers this case a bit deeper. I need for a solid production, not just to test some code on my pc.

Best Answer

I'm currently building a django app the way you want.

I use docker-compose to do this. This is my docker-compose.yml

version: '2'
services:
  nginx:
    container_name: nginx-container
    links:
      - uwsgi
    build: ./nginx
    ports:
      - "8888:80"
    volumes_from:
      - uwsgi
  uwsgi:
    container_name: uwsgi-container
    build: ./uwsgi
    expose:
      - "8001"
    volumes:
      - ./code/conf:/opt/conf
      - ./code/app:/opt/app

Dockerfile for uWSGI:

FROM python:3.5
RUN ["pip", "install", "uwsgi"]
CMD ["uwsgi", "--master", "--ini", "/opt/conf/uwsgi.ini"]

Dockerfile for nginx:

FROM nginx
RUN ["rm", "/etc/nginx/conf.d/default.conf"]
RUN ["ln", "-s", "/opt/conf/nginx.conf", "/etc/nginx/conf.d/"]
CMD ["nginx", "-g", "daemon off;"]

And this is my directory tree:

├── README.md
├── code
│   ├── app
│   └── conf
├── collectstatic.sh
├── docker-compose.yml
├── install.sh
├── migrate.sh
├── nginx
│   └── Dockerfile
├── restart.sh
├── upgrade.sh
├── uwsgi
│   └── Dockerfile

So I build my images with docker-compose build then launch new containers in background with docker-compose up -d then I can perform some setup tasks like installing django, generate secret key or whatever you want to have your container ready.

nginx and uwsgi containers uses shared volumes to read config files AND to communicate with a file socket.

Well, not sure that is the best way, but it's a work in progress.