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.