Ubuntu 26.04 Tutorial / Configure Nginx Sites and Verify Host Routing
Manage Ubuntu Nginx sites by inspecting the actual include layout, then enabling a configuration from sites-available through sites-enabled. This lab binds two sites to 127.0.0.1:8080 so you can test Host routing without public exposure.
The new 8080 lab site is loopback-only; that does not make the entire server local-only. Ubuntu’s Nginx installation can start its default site. Before installing, confirm the UFW lesson’s management access and filtering, or use a dedicated VM isolated from external networks.
Install and inspect existing configuration
sudo apt update
sudo apt install nginx curl
sudo nginx -t
sudo nginx -T
sudo ss -lntp
Use a dedicated VM and do not kill another web server occupying a port. Inspect active includes, listen directives, server names, and default servers in nginx -T. The full configuration can contain sensitive addresses or authentication details; do not publish it.
Ubuntu’s Nginx configuration guide explains server blocks, document roots, and the default site.
Check exposure of the default port 80 site
sudo ss -lntp
sudo ufw status verbose
ls -l /etc/nginx/sites-enabled
sudo nginx -T
Listeners such as 0.0.0.0:80 or [::]:80 differ from 127.0.0.1:8080. With inactive UFW or a broad port 80 allowance, another device may reach the default site. Check local responses separately from new connections by permitted and excluded clients.
On a fresh dedicated VM, the following block can preserve and disable only the package-default site’s symlink. Do not apply it to a production site. It stops on an unexpected link/target or failed backup/validation.
(
set -eu
link=/etc/nginx/sites-enabled/default
if [ ! -L "$link" ] || [ "$(readlink -f "$link")" != /etc/nginx/sites-available/default ]; then
printf 'Not the expected package-default symlink; inspect manually.\n' >&2
exit 1
fi
backup_dir=$(sudo mktemp -d /root/nginx-default-link.XXXXXX)
sudo cp -a "$link" "$backup_dir/default"
printf 'Preserved link: %s/default\n' "$backup_dir"
sudo rm -- "$link"
sudo nginx -t
sudo systemctl reload nginx
sudo ss -lntp
)
The original sites-available/default remains. If port 80 still listens, investigate other sites/processes. Restore the recorded backup symlink only after checking for intervening changes at its original path, then validate and reload. Preserve other administrators’ changes.
Ubuntu’s Nginx installation guide describes package installation and service startup.
Prepare distinct document roots
If these paths or configuration names already exist, preserve them and choose new lab names. In dedicated empty paths, create distinct responses as follows. Nginx needs read access, not world-writable content.
sudo install -d -m 0755 /srv/ubuntu-course-alpha /srv/ubuntu-course-beta
printf '%s\n' 'alpha-site' | sudo tee /srv/ubuntu-course-alpha/index.html
printf '%s\n' 'beta-site' | sudo tee /srv/ubuntu-course-beta/index.html
Define complete local server blocks
Save the complete configuration below as the new file /etc/nginx/sites-available/ubuntu-course-lab. The .test names are for documentation and local testing, not public DNS or certificate issuance. Preserve any existing port 80 default site separately.
server {
listen 127.0.0.1:8080 default_server;
server_name _;
return 404;
}
server {
listen 127.0.0.1:8080;
server_name alpha.example.test;
root /srv/ubuntu-course-alpha;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
server {
listen 127.0.0.1:8080;
server_name beta.example.test;
root /srv/ubuntu-course-beta;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
The first block returns 404 for unmatched Host requests on this address and port. The underscore is not a special denial mechanism; default_server makes that block the fallback. Avoid duplicate defaults on the same address and port.
Enable, validate, and reload
(
set -eu
sudo ln -s /etc/nginx/sites-available/ubuntu-course-lab /etc/nginx/sites-enabled/ubuntu-course-lab
sudo nginx -t
sudo systemctl reload nginx
)
If the symlink exists, inspect it instead of overwriting it. Do not reload after a failed syntax check; fix the reported file, line, or listener conflict first. Syntax success does not establish correct file access or Host routing.
Test names, paths, and fallback responses
curl --fail --show-error --resolve alpha.example.test:8080:127.0.0.1 http://alpha.example.test:8080/
curl --fail --show-error --resolve beta.example.test:8080:127.0.0.1 http://beta.example.test:8080/
curl -i -H "Host: unknown.example.test" http://127.0.0.1:8080/
Expect alpha-site and beta-site for the first two requests and 404 for the last. --resolve changes name/address mapping only for this request, not system DNS. For unexpected results, compare includes, duplicate names, port, document root, and logs.
Disable the lab by removing only its sites-enabled symlink, then validate and reload. Preserve other sites and source files. Public deployment requires separate domain, address, firewall, HTTPS, and logging preparation.




