Ravindra BagaleCourses & study guides

13. Multiple Websites on One Server and HTTPS with Certbot

13.2 Multiple Sites with Nginx (Amazon Linux 2023 and Ubuntu)

for s in site1 site2; do
  sudo mkdir -p /var/www/$s
  echo "<h1>Welcome to $s</h1>" | sudo tee /var/www/$s/index.html
done

Nginx (AL2023/CentOS: files in conf.d/; Ubuntu: files in sites-available/ plus a symlink for each):

# site1.conf
server {
    listen 80;
    server_name site1.example.com;
    root /var/www/site1;
    access_log /var/log/nginx/site1_access.log;
}

# site2.conf
server {
    listen 80;
    server_name site2.example.com;
    root /var/www/site2;
    access_log /var/log/nginx/site2_access.log;
}

# 00-default.conf: requests by IP or unknown names
server {
    listen 80 default_server;
    server_name _;
    return 444;          # close connection (or: return 301 http://site1.example.com;)
}
# Ubuntu only: enable and disable
sudo ln -s /etc/nginx/sites-available/site1.conf /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/site2.conf /etc/nginx/sites-enabled/
sudo rm -f /etc/nginx/sites-enabled/default

Amazon Linux 2023 – complete commands (note \$uri, escaped because the here-doc is unquoted so that $s expands):

for s in site1 site2; do
sudo tee /etc/nginx/conf.d/$s.conf > /dev/null <<CONF
server {
    listen 80;
    server_name $s.yourdomain.com;
    root /var/www/$s;
    index index.html;
    location / { try_files \$uri \$uri/ =404; }
    access_log /var/log/nginx/${s}_access.log;
}
CONF
done
sudo nginx -t && sudo service nginx reload

Ubuntu – same files in sites-available, then enable:

for s in site1 site2; do
sudo tee /etc/nginx/sites-available/$s > /dev/null <<CONF
server {
    listen 80;
    server_name $s.yourdomain.com;
    root /var/www/$s;
    index index.html;
    location / { try_files \$uri \$uri/ =404; }
}
CONF
sudo ln -sf /etc/nginx/sites-available/$s /etc/nginx/sites-enabled/$s
done
sudo rm -f /etc/nginx/sites-enabled/default
sudo nginx -t && sudo service nginx reload

Ravindra Bagale's Tip

If you write <<'CONF' (with quotes) in a here-doc, $s is not expanded. Here we used it without quotes because the loop needs the variable – but then Nginx variables like $uri must be escaped as \$uri. Many students get caught here; after creating the config, always check it with cat.

Lab

Create site1 and site2 with Nginx on Amazon Linux or Ubuntu, add the catch-all default, and test with curl -H "Host: ..." http://localhost.