Skip to content

Linux Exercise 10 - Nginx Webserver

Lab: Setting up Nginx on Ubuntu (Static, PHP, ASP.NET, TLS)

Section titled “Lab: Setting up Nginx on Ubuntu (Static, PHP, ASP.NET, TLS)”

Learning goals

By the end of this lab you will be able to:

  • Install and start Nginx on a fresh Ubuntu Server VM
  • Serve a static website (HTML/CSS/JS)**
  • Serve a PHP-based website using php-fpm
  • Serve an ASP.NET website via reverse proxy to a .NET application
  • Secure a virtual host with TLS using a self-signed certificate
  • Explain in theory how Let’s Encrypt would be used in a real public setup

  • You have a fresh Ubuntu Server VM (no GUI needed).
  • You can log in via console or SSH as a user with sudo privileges.
  • The VM has internet access for installing packages.

Protocol requirement:
For every step in this lab, write in your protocol:

  • The commands you executed
  • A short explanation of what you did and why
  • Any error messages and how you fixed them
  • Screenshots or copy-pasted outputs where useful

Update & tools:

Terminal window
sudo apt update
sudo apt upgrade -y
sudo apt install -y curl nano unzip

Install:

Terminal window
sudo apt install -y nginx

Check service:

Terminal window
systemctl status nginx

Test:

Terminal window
curl http://localhost/

<VIRTUAL_MACHINE_IP> static.local

4.2 Create directory and sample static site

Section titled “4.2 Create directory and sample static site”
Terminal window
sudo mkdir -p /var/www/static.local/public
sudo chown -R $USER:$USER /var/www/static.local

index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Static Site Test</title>
<link rel="stylesheet" href="style.css">
<script src="script.js" defer></script>
</head>
<body>
<h1>Hello from Nginx static site!</h1>
<p>This page is served as a static file.</p>
<p>Time loaded: <span id="time"></span></p>
</body>
</html>

style.css

body { font-family: Arial, sans-serif; }
h1 { text-align: center; }

script.js

document.addEventListener("DOMContentLoaded", () => {
const span = document.getElementById("time");
span.textContent = new Date().toLocaleString();
});

Create:

Terminal window
sudo nano /etc/nginx/sites-available/static.local

Content:

server {
listen 80;
server_name static.local;
root /var/www/static.local/public;
location / {
try_files $uri $uri/ =404;
}
}

Enable:

Terminal window
sudo ln -s /etc/nginx/sites-available/static.local /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Terminal window
sudo apt install -y php-fpm php-cli
Terminal window
sudo mkdir -p /var/www/php.local/public
sudo chown -R $USER:$USER /var/www/php.local

index.php

<!DOCTYPE html>
<html>
<body>
<h1>PHP is working!</h1>
<p>Current time: <?php echo date('Y-m-d H:i:s'); ?></p>
<p>PHP version: <?php echo phpversion(); ?></p>
</body>
</html>

Add hosts entry:

<VIRTUAL_MACHINE_IP> php.local

Config:

server {
listen 80;
server_name php.local;
root /var/www/php.local/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}
}

6. Virtual Host for ASP.NET (Reverse Proxy)

Section titled “6. Virtual Host for ASP.NET (Reverse Proxy)”
Terminal window
sudo apt update
sudo apt install -y dotnet-sdk-8.0
Terminal window
mkdir -p ~/aspnet-site
cd ~/aspnet-site
dotnet new web -o WebApp1
cd WebApp1
dotnet run --urls http://localhost:5000

Test:

Terminal window
curl http://localhost:5000

Hosts entry:

<VIRTUAL_MACHINE_IP> aspnet.local

Config:

server {
listen 80;
server_name aspnet.local;
location / {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

Terminal window
sudo mkdir -p /etc/ssl/private
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/ssl/private/static.local.key -out /etc/ssl/certs/static.local.crt

Use CN = static.local.

server {
listen 80;
server_name static.local;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name static.local;
ssl_certificate /etc/ssl/certs/static.local.crt;
ssl_certificate_key /etc/ssl/private/static.local.key;
root /var/www/static.local/public;
location / {
try_files $uri $uri/ =404;
}
}

  • Uses the ACME protocol
  • Proves domain control via HTTP-01, DNS-01, or TLS-ALPN-01
  • Works with Certbot to automate issuing & renewal
  • Requires a public DNS name and publicly reachable server

Example (NOT executed in lab):

Terminal window
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com

  • Static site setup (with sample HTML, CSS, JS)
  • PHP site setup
  • ASP.NET reverse proxy
  • Self-signed TLS
  • Let’s Encrypt explanation
  • Screenshots or curl outputs where useful