Blog

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 (example.com), a single VPS and two APIs (api_a and api_b). Say I want to access api_a from api_a.example.com and access api_b from api_b.example.com, I can use Nginx to direct traffic from api_a.example.com 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/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    server_name example.com;

    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. api_a.example.com 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.