This is a multi-page article....

What is Nginx? Nginx is a web server which can also be used as, importantly for us, a reverse proxy. In layman's terms, Nginx will be our externally-facing web server that routes traffic from a certain server name or port to another server; consider the following use case: I have a single domain name (, a single VPS and two APIs (api_a and api_b). Say I want to access api_a from and access api_b from, I can use Nginx to direct traffic from to api_a and the same for api_b – simple!

The Nginx directory contains a Dockerfile, a general Nginx configuration file (nginx.conf) and configuration specific to this application (my_web_app.conf). Let's start with the Dockerfile:

FROM nginx:1.15.5

RUN rm /etc/nginx/nginx.conf

COPY nginx.conf /etc/nginx/

RUN rm /etc/nginx/conf.d/.conf

COPY my_web_app.conf /etc/nginx/conf.d/

We start with an Nginx base image that handles the installation of Nginx and all prerequisites and then we replace the main Nginx and application specific configuration files with our own. I won't talk in too much detail about nginx.conf but it's imperative that you include the following two lines, they are responsible for ensuring our application is served securely:

ssl_protocols TLSv1 TLSv1.1 TLSv1.2; 
ssl_prefer_server_ciphers on;

The application specific Nginx configuration file is as follows:

server {
    listen 80;
    listen 443 ssl;

    ssl_certificate /etc/letsencrypt/live/;
    ssl_certificate_key /etc/letsencrypt/live/;


    client_body_buffer_size 64k;

    location / {
        proxy_pass http://rest_api:8000;
        proxy_redirect off;
        proxy_set_header Host \)host;
        proxy_set_header X-Real-IP \(remote_addr;
        proxy_set_header X-Forwarded-For \)proxy_add_x_forwarded_for;

Here we define a server object and tell it to listen on the ports that we exposed in the docker-compose.yml file. We specify a server_name that tells the Nginx server object exactly which requests to respond to (i.e. from the previous example) and then where to forward the request to. Most importantly we specify the directory of our SSL private key and certificate, keep a note of this.

So that is the application. I know it seems like a lot, and it is, but much of the code is transferable between projects and it's a great basis for a stable and reliable multi-container application.