Dynamic Nginx Reloads with Docker and Bash : A Step by Step Tutorial

Dynamic Nginx Reloads with Docker and Bash : A Step by Step Tutorial

Introduction

Nginx is one of the most widely used web servers in this industry. The emergence of Kubernetes has made dynamic scaling and micro-services have made automating everything an absolute necessity to avoid manual errors and zero downtime whatsoever.

If you like my Blogs follow me and get my latest blog updates Click here.

Objective

So in this blog, we are going to see a simple Docker setup and mount the config file as a volume in the Docker container then we are going to make changes to the config file from these changes automatically without manual intervention, If we can achieve this it will be a great feature in a dynamic environment.

Step 1: Script to detect changes in the config file

All the scripts used in this Blog are in my Github Repo you can clone and try it yourself https://github.com/2402199/NGINX_AUTO-RELOAD

To monitor the changes in the config file we are using a tool called inotify-tools This tool can detect any type of changes made to a specified file/folder

#!/bin/bash
reload_nginx() {
    nginx -s reload
    echo "Nginx reloaded"
}
while true; do
    inotifywait -r -e modify,move,create,delete /etc/nginx/
    reload_nginx
done

So, in this Bash script, we are monitoring the modify, create, move and delete actions of the nginx config folder and while the condition is true it will call a function which in turn will reload the nginx service.

If you like my Blogs follow me and get my latest blog updates Click here.

Step 2: Dockerfile

FROM nginx
RUN apt update -y
RUN apt install -y nano inotify-tools
COPY /index1.html /usr/share/nginx/html
VOLUME [ "/etc/nginx/conf.d" ]
COPY ./reload.sh /
RUN chmod +x /reload.sh
CMD ["sh", "-c", "nginx -g 'daemon off;' & sh /reload.sh & wait"]

This is the Dockerfile I am using for this demo you can find this in my repo https://github.com/2402199/NGINX_AUTO-RELOAD The base image I used is nginx and I am updating the nginx to install inotify-tools which is required to run the bash script I am copying a file index1.html to show that the nginx is reloaded and this index1.html is placed in the web serving directory of nginx and the bash script we wrote in the previous step is named as reload.sh and we are giving Executing permissions to the bash script then we are starting nginx along with the bash script and remember to run the bash script in the background or else the Dockerfile will not start.

Step 3: Mounting Volume in Docker container

Now, since we have a Dockerfile ready we should build a Docker image

docker build -t <Image_name> .

As you can see in my Github Repo we have a default.conf file which handles all the configurations of nginx this is our default.conf

server {
    listen       80;
    listen  [::]:80;
    server_name  localhost;



    location / {
        root   /usr/share/nginx/html;
        index  index.html index.html;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

we are going to run the docker image as a container as well as mount this default.conf file as volume from the local machine to the container by this command

docker run -itd -p 80:80 -v "$(pwd)/default.conf:/etc/nginx/conf.d" <Image_name>

Now any changes we make in our local machine's default.conf it will be reflected in the running container.

This Log confirms that the script is running.

  • If we hit localhost in our browser you can see the default output from nginx

  • Now we are going to change the default.conf file in our local machine i.e. Laptop/P.C like this

    • ```javascript server { listen 80; listen [::]:80; server_name localhost;

location / { root /usr/share/nginx/html; index index1.html index1.html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } ```

I have changed the default index.html to index1.html to point the serving to index1.html which we have customized

  • Now, Usually, if we didn't have a script to reload nginx we would still be getting the default nginx page to make the changes active we have to manually execute nginx -s reload to point the serving to index1.html

  • But Since we have the script we will get this response

This ensures that the nginx has reloaded.

That's it, folks we have reloaded nginx dynamically based on the changes in the config file Stay tuned cause in the upcoming blogs I will be focusing on where and how this helps in real-time Projects through Kubernetes.

If you like my Blogs follow me and get my latest blog updates Click here.

Happy Coding :)