Week 6: Deploy NGINX inside a docker container
In this week's piece, we shall look at how to deploy a simple website using NGINX......inside a Docker container!
Serve a simple site
-
Let's create a simple website that we shall serve inside our container. I'll create a directory called
simple-website
and add the followinghtml
fileindex.html<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>A simple website</title> <style> body { display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background-color: #f0f0f0; } </style> </head> <body> <div class="container"> <p>Welcome to this week's blog post</p> </div> </body> <script src="index.js"></script> </html>
-
Download the
nginx
docker image from docker hubYou can run
docker images
to view the containers you have on your machine. The image you just downloaded will show among them. -
Create a
docker-compose.yml
file and add the following content to it.docker-compose.ymlservices: web: image: nginx container_name: preview ports: - 80:80 volumes: - /path/to/simple/website:/simple-website - /path/to/nginx/default:/usr/share/nginx/html - /etc/nginx/sites-available/<config-file-name>.conf:/etc/nginx/conf.d/<config-file-name>.conf
Let's walk through what each of these sections of this file does:
services
:docker-compose
allows one to run multi-container applications. This field allows one to specify the list of the services that will be running in the app. In this case, we have only a single service calledweb
image
: The name of the image that will form this containercontainer-name
: You can give this container a name, in our case previewports
: We get to map some ports from the host machine to docker. In this case, we want all requests to the host on port 80 to be forwared to port 80 of our container.-
volumes
: These allow us to make some files/folders on our host machine available to the docker. The changes made to these files are also visible inside the docker container.We are mounting the following directories:
- We are mounting our website directory to a folder also called
simple-website
inside our container. The target directory name can be anything but we are choosing this for convenience. - We also mount our server blocks file so that it can picked up by nginx
- We are mounting our website directory to a folder also called
-
Create a server block configuration file. I am working on a Linux system, so the files are normally located at
/etc/nginx/sites-available/
. I am very certain something similar exists for Windows users! -
With that out of the way, it's time to start the container.
Tip!On some systems, connections to certain ports will be blocked by the firewall and so we have to make sure that port 80 on our host machine is open. Run `sudo ufw allow 80` to open this port!
In the same directory that has you docker-compose file, run
docker-compose up -d
. This will run it in detached mode.Run the following command to see if the container is up and running:
docker ps -a
.I will assume you have configured a domain name for your host machine, so go ahead and paste it in your browser. You should see the following page
Add https
capability to the site.
With the basic stuff out of the way, its time to make sure that our site can be accessed over a more secure protocol.
There are a couple ways to add https
to your site, but for the sake of this tutorial we shall use a service called acme.sh. It allows you to generate certificates that you can then add to your site.
-
We shall issue a certificate for our domain with the following command
The
-w
flag means we are going to specify a webroot(the folder that hosts our website's public files)This will generate some certificates and key files and store them in a specified directory(let's call it the
key directory
) -
Add the following block to your configuration file
Add https server blockserver{ listen 443 ssl; server_name your-domain www.your-domain; # SSL configuration goes here ssl_certificate /etc/nginx/ssl/fullchain.cer; ssl_certificate_key /etc/nginx/ssl/your-domain.key; root /simple-website; index index.html; location / { try_files $uri /index.html; } }
The following two lines should interest you:
server key configurationWe are telling nginx that our key files will be in the /etc/nginx/ssl directory but we have not put them there. So, we will do just that!ssl_certificate /etc/nginx/ssl/fullchain.cer; ssl_certificate_key /etc/nginx/ssl/your-domain.key;
One last thing that we have to do is mount this folder to our docker container. Add the following lines to your docker-compose file
docker-compose.yml# under the ports section, since https serves on port 443 - 443:443 # under the volumes section /etc/nginx/ssl:/etc/nginx/ssl
In case port 443 is blocked on the firewall run
sudo ufw allow 443
to open itThat should be it. Stop and restart your docker container to view the changes. If you visit your domain with
https://your-domain
, your site should now be served!