Configuring the NGINX Server - HTTP Virtual Hosts / Rewrites / Custom Error Pages / Directives

1 hour
  • 14 Learning Objectives

About this Hands-on Lab

Before we can start building our world-changing website or application on LEMP, we have to lay the foundation – the stack. In this hands-on lab, we will walk through configuring NGINX on Ubuntu Linux. We will explore configuring HTTP (non-secure) virtual hosts, rewrites, custom error pages, and directives.

Completing this lab will provide a good understanding of how to implement these NGINX concepts on Ubuntu Linux.

Learning Objectives

Successfully complete this lab by achieving the following learning objectives:

Create an HTTP Virtual Host Configuration

We’re going to become the ‘root‘ user.

sudo su -

First, change to the /etc/nginx/sites-available directory so we can add the new virtual host configuration block:

cd /etc/nginx/sites-available

We’re going to copy the configuration file related to the virtual host for

Edit the New HTTP Virtual Host Configuration

Edit the configuration file for site4:


Change the port that the virtual host is listening on to 8081:

listen 8081;

Also, change the site3 entries for the root directory and the server_name to point to site4. Save and exit the new configuration file for

Activate and Test the New Virtual Host Configuration

Create a soft link in /etc/nginx/sites-enabled to "activate" the configuration:

ln -s /etc/nginx/sites-available/ /etc/nginx/sites-enabled/ 

Validate and restart NGINX:

nginx -t
systemctl reload nginx

Test the virtual host:


We should see the following:

Welcome to!

Explore the Legacy Download Server

There’s a download directory for legacy website downloads, and a virtual host (port 8084). We wish to present this directory as

ls -la /var/www/download_files

We can get to the file via

Create a Rewrite for the Legacy Download Server

Edit the configuration file:


Add the following section:

        location /downloads {
                rewrite ^(/downloads)/(.*)$$2 permanent;
                return 403;

This will pass the file name in the /downloads part of the URL to the new URL as the second argument ($2).

Test the Rewrite

Validate and restart NGINX:

nginx -t
systemctl reload nginx

Test the rewrite:


Retry the request with the new location:

curl -L

To see what’s going on behind the scenes, use the ‘-I‘ switch with curl:

curl -I

The Location information points to

View the Custom Error Page

We’ve provided a custom 404 error page on the lab server that is branded for This file is /var/www/html/BSC_404.html.

cat /var/www/html/BSC_404.html

Try accessing a file that doesn’t exist with curl:


We will get a generic error page.

Configure the Custom Error Page

We will need to configure our custom error page in the virtual host server configuration file:


We’re going to add a section of code to configure a custom error page for 404 errors:

        error_page 404 /BSC_404.html;
        location = /BSC_404.html {
                root /var/www/html;

Save and exit the configuration file.

Test the Custom Error Page

Test the NGINX configuration and reload the NGINX service:

nginx -t
systemctl reload nginx

Now, try accessing the file that doesn’t exist:


We now see the custom error page.

Exploring the Application Servers

Big State College is building an application backend, which they want to proxy under The backend application servers are already up and running. We can validate this using curl:

Configuring the Upstream Directive for the Application Servers

Define a group of (application) servers using the upstream directive:


Add the following at the beginning of the configuration file:

upstream bscapp  {
   server backup;
   server backup;

Add a location block for the app directory:

        location /app {
                proxy_pass http://bscapp/;

Save and exit the file.

Restart NGINX and Test the Upstream

Validate and reload NGINX:

nginx -t
systemctl reload nginx

Test the upstream:


We will see that the server is serving requests. The other two servers are backups right now.

Mark the app1 Server as Down

Mark the app1 server as down in the upstream configuration, and see if the backup servers take over:

upstream bscapp  {
   server down;
   server backup;
   server backup;

Validate and reload NGINX. Test the upstream:


We will see that NGINX pulls from both the app2 and app3 servers.

Enable the app1 Server and Test

Edit the configuration file and remove the down from app1 in the bscapp group:

upstream bscapp  {
   server backup;
   server backup;

Save, exit, validate and restart the NGINX service. Test the upstream:


We should get Welcome to!. The app2 and app3 servers are only acting as backups.

Additional Resources

Big State College (BSC) is a Large Ten Conference school in a Midwestern state. BSC is looking to deploy a centralized web hosting service using the LEMP stack.

As the engineers tasked with executing this project, we will be configuring HTTP virtual hosts, rewrites, custom error pages, and directives on an Ubuntu Linux server. Let's begin!

Connecting to the Lab Server

Use the credentials provided on the hands-on lab overview page, and log in using an SSH connection to the Public IP or DNS of the server as cloud_user.

Making a SSH connection using the ssh command. Replace <<public_IP_or_DNS>> with the Public IP or DNS provided on the overview page.

ssh cloud_user@<<public_IP_or_DNS>>

If you can't use ssh or prefer a GUI client, use the credentials provided on the hands-on lab overview page to configure your SSH connection to the lab server.

Lab Git Repository

Feel free to explore the configurations and code from the lab at: GitHub - linuxacademy/content-lemp-deep-dive

What are Hands-on Labs

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Sign In
Welcome Back!

Psst…this one if you’ve been moved to ACG!

Get Started
Who’s going to be learning?