Setting Up Nginx Web Server in Docker

As I already have a running Nginx reverse proxy that handles domain routing to local web servers or services and terminates SSL, I will document here how to set up a single-page Nginx HTTP-only web server using Docker.

Step 1: Create a Folder for the Webpage and Webserver Files

Firstly, create a folder where you’ll store your webpage and webserver files. This can be done by running:

mkdir -p yourDomain/{nginx-config,webroot,access-logs}

This command creates three subfolders within yourDomain: nginx-config, webroot, and access-logs.

Step 2: Copy the Nginx Configuration File

Next, copy the default Nginx configuration file from a temporary container to your local machine. This can be achieved by running:

# Create a temporary container
docker run --name temp-nginx -d nginx:latest
# Copy the default nginx.conf to your local machine
docker cp temp-nginx:/etc/nginx/nginx.conf /yourpath/yourDomain/nginx-config/nginx.conf
# Remove the temporary container
docker rm -f temp-nginx

This command creates a temporary Nginx container, copies its configuration file (nginx.conf) to your specified location /yourpath/yourDomain/nginx-config/nginx.conf, and then removes the temporary container.

Step 3: Modify the Nginx Configuration File

Now that you have copied the default configuration file, modify it by adding a server block within the HTTP block. This can be done by editing:

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log notice;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    server {
        listen 80;
        server_name my-service;  # This can be a placeholder if you don't use domain names

        root /usr/share/nginx/html;
        index index.html;

        location / {
            try_files $uri $uri/ /404.html; # Refering to Hugos generated own 404 page
        }
    }

    # include /etc/nginx/conf.d/*.conf;
}

Step 4: Run Docker with Custom Parameters

Now that you have modified your Nginx configuration file, run Docker using custom parameters:

docker run -d \
  --name hugo-blog-page \
  -p 8010:80 \
  -v /yourpath/yourDomain/webroot:/usr/share/nginx/html:ro \
  -v /yourpath/yourDomain/nginx-config/nginx.conf:/etc/nginx/nginx.conf:ro \
  -v /yourpath/yourDomain/access-logs:/var/log/nginx \
  --restart unless-stopped \
  nginx:latest

Step 5: Test Your Web Server

Finally, test your web server by visiting http://yourIpAdress:8010 in a web browser. You should see an HTTP 403 response and be able to view the corresponding Nginx error page. Congratulations! At this point, you have successfully set up a single-page Nginx HTTP-only web server using Docker.

Building a Production-Ready Webpage with Hugo

When developing your website with Hugo, it’s essential to create a production-ready webpage that can be successfully deployed. This involves building the site using the correct base URL, which is configured in hugo.toml.

Why You Need a Production Build

During development, you’ve likely used the hugo server command to preview your website on localhost:1313. However, if you were to deploy this content directly to production without proper configuration, it would lead to broken links and other issues. This is because internal links within your HTML files point to localhost, which won’t resolve correctly in a live environment.

Using a Script for Efficient Builds

To streamline this process, create a script (e.g., buildForProd.sh ) containing the following command:

#! /bin/bash
hugo --cleanDestinationDir

This script uses Hugo’s built-in feature to clean up any orphaned files or directories in your destination directory. This is particularly useful when renaming posts or drafts, as it ensures that old versions are removed before building a new production-ready version of your site.

Making the Script Executable

Save this script and make it executable using:

chmod +x buildForProd.sh

Now you can run this script to efficiently generate a production-ready webpage for deployment.

Deploying Hugos Public Directory using Nginx

For a website created by Hugo to be accessible through an Nginx web server, you need to copy the contents of the public folder into the Nginx webroot directory. This can be achieved efficiently with a script that utilizes rsync, a powerful tool for synchronizing files and directories.

Creating the Deployment Script

Create a new file called deployToProd.sh in your Hugo project’s root directory, using a text editor or IDE of your choice. Add the following content to this file:

#! /bin/bash

rsync -avz --delete /yourpath/yourDomain/public/ username@domainOrIp:/destinationpath/webroot

Replace /yourpath/yourDomain/public/ with your actual Hugo project’s public directory, and username@domainOrIp:/destinationpath/webroot/ with the correct Nginx web server webroot directory.

Understanding rsync Options

The script uses several useful options:

  • -avz: This option enables verbose mode (-v) for detailed output, preserves permissions (a), compression (z), and ensures that only changed files are transferred.
  • --delete: This flag removes any items from the destination directory that do not exist in the source folder.

Making the Script Executable

Save the script file as deployToProd.sh, then make it executable using:

chmod +x deployToProd.sh

This step is crucial to allow your system to execute the script directly without specifying its path.

Running the Deployment Script

Finally, run the deployment script by executing:

./deployToProd.sh

Make sure you’re in the Hugo project’s root directory when running this command. The rsync tool will efficiently copy the updated contents of your public folder to the Nginx webroot directory. By following these steps and using a simple deployment script, you can automate the process of updating your website with new content created by Hugo, ensuring that it remains synchronized with your production environment via an efficient rsync transfer.

Streamlining Workflow with a Single Deployment Script

Now that you have two essential scripts in place: buildForProd.sh and deployToProd.sh, it’s time to take your workflow to the next level. By combining these two scripts into a single deployment script called prodBuildAndDeployment.sh, you’ll be able to automate both building and deploying your Hugo site for production with ease.

You can easiely combine the two into a buildAndDeployToProd.sh script:

#!/bin/bash

# Build the Hugo site for production
./buildForProd.sh

# Deploy the built site to production using rsync
./deployToProd.sh

This script leverages the benefits of both buildForProd.sh (which ensures a clean and optimized build) and deployToProd.sh (which efficiently deploys the built content to your Nginx webroot).

Making the Script Executable

Save this new script file, then make it executable using:

chmod +x prodBuildAndDeployment.sh

Running the Combined Deployment Script

To deploy your Hugo site to production with a single command, simply run:

./prodBuildAndDeployment.sh

By doing so, you’ll be able to automate both building and deploying your website in one efficient step. This streamlined workflow will save you time and reduce errors, making it easier to maintain and update your live site. You’re Done! Congratulations on completing the setup of a robust deployment pipeline for your Hugo-powered website! With these scripts in place, you’ll be able to efficiently build and deploy new content with confidence.

♥♥♥

Monero