Chapter 8

Capstone: Secure Workshop Co.

Full Nginx + TLS plan for www and staging.

Capstone objectives

  • Design Nginx vhosts for production and staging
  • Plan TLS certificates, renewal, and HSTS
  • Document verification steps before go-live

The brief

Workshop Co. — secure go-live

Production VPS
203.0.113.10www.workshopco.ca + apex redirect
Staging VPS
203.0.113.99staging.workshopco.ca (basic auth)
Stack
Nginx + PHP 8.3-FPM, Let’s Encrypt, Ubuntu 24.04
Requirements
HTTPS only, HSTS on production, ACME-friendly HTTP challenge path
Canonical URL
https://www.workshopco.ca

Your task — full secure site plan

On paper, produce:

  1. List of Nginx config files and what each contains
  2. Certbot command(s) with domain flags
  3. Post-deploy verification checklist (5+ items)
Model solution

Config files

# /etc/nginx/sites-available/workshopco.conf
# Port 80 — ACME + redirect to HTTPS
server {
    listen 80;
    server_name workshopco.ca www.workshopco.ca;
    location /.well-known/acme-challenge/ { root /var/www/certbot; }
    location / { return 301 https://www.workshopco.ca$request_uri; }
}

# Apex HTTPS → www
server {
    listen 443 ssl http2;
    server_name workshopco.ca;
    ssl_certificate     /etc/letsencrypt/live/workshopco.ca/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/workshopco.ca/privkey.pem;
    return 301 https://www.workshopco.ca$request_uri;
}

# Production www
server {
    listen 443 ssl http2;
    server_name www.workshopco.ca;
    root /var/www/workshopco/public;
    index index.php;
    ssl_certificate     /etc/letsencrypt/live/workshopco.ca/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/workshopco.ca/privkey.pem;
    add_header Strict-Transport-Security "max-age=31536000" always;
    location / { try_files $uri $uri/ /index.php?$query_string; }
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.3-fpm-workshopco.sock;
    }
}
# /etc/nginx/sites-available/staging.conf (on 203.0.113.99)
server {
    listen 443 ssl http2;
    server_name staging.workshopco.ca;
    root /var/www/staging/public;
    auth_basic "Staging";
    auth_basic_user_file /etc/nginx/.htpasswd-staging;
    ssl_certificate     /etc/letsencrypt/live/staging.workshopco.ca/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/staging.workshopco.ca/privkey.pem;
    # ... PHP block ...
}

Certbot

sudo certbot certonly --webroot -w /var/www/certbot \
  -d workshopco.ca -d www.workshopco.ca
sudo certbot certonly --webroot -w /var/www/certbot \
  -d staging.workshopco.ca

Verification checklist

  • curl -I http://workshopco.ca → 301 to https www
  • Padlock valid; SAN includes apex + www
  • Booking form submits over HTTPS; no mixed content in console
  • sudo certbot renew --dry-run succeeds
  • Staging requires auth; not indexed (X-Robots-Tag: noindex optional)
  • nginx -t clean; HSTS header present on production only after confirming HTTPS works

Part 2 — rollback plan

Write 3 steps to roll back if the new cert breaks production during maintenance.

Sample plan
  1. Restore previous Nginx config from backup symlink
  2. Reinstall prior cert paths or temporarily use last-known-good fullchain.pem
  3. Reload Nginx; verify with curl from external network; extend maintenance window comms
What’s next?

Book 3 covers IP addressing and LAN design — useful when Workshop Co. opens a physical shop with Wi‑Fi, cameras, and a office network behind one public IP.

Book 2 complete

You can trace HTTP/TLS flow, obtain and renew certificates, configure Nginx with PHP-FPM, and troubleshoot the errors users actually see. Workshop Co.’s site is ready for production HTTPS.