Hello from inside the Ubuntu-Verrazano Test Container!

Expanding Nginx Proxy & Avoiding SSL Initialization Loops

This guide explains how to add a new subdomain (example-next.mydomain.com) targeting a new internal container backend, while preventing Nginx from crashing due to missing SSL files before Certbot can run.

The "Catch-22" Problem Explained: If you add ssl_certificate directives to Nginx pointing to paths that do not exist yet, Nginx will fail its syntax test (nginx -t) and refuse to start. Because Nginx is dead, Port 80 goes offline, causing Certbot's webroot challenge to instantly fail with a Connection Refused error.

Step 1Apply a Safe Initial Configuration

Open your Nginx configuration file (/etc/nginx/sites-available/reverse-proxy.conf) and append this configuration. Notice that the SSL certificate lines are intentionally commented out so Nginx can start safely on Port 80 and Port 443.

# =========================================================
# NEW CONTAINER: example-next.mydomain.com
# =========================================================

# 1. HTTP Port 80 Listener (Handles Certbot challenge local routing)
server {
    listen 80;
    server_name example-next.mydomain.com;

    # Pass let's encrypt validation requests directly to local storage
    location /.well-known/acme-challenge/ {
        root /var/www/html;
        allow all;
    }

    # Fallback redirect all normal requests to HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}

# 2. HTTPS Port 443 Listener (Staged safely without crashing Nginx)
server {
    listen 443 ssl;
    server_name example-next.mydomain.com;

    # TEMPORARILY COMMENTED OUT - AVOIDS THE "NO SUCH FILE" BOOT ERROR
    # ssl_certificate /etc/letsencrypt/live/://mydomain.com;
    # ssl_certificate_key /etc/letsencrypt/live/://mydomain.com;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
        # Replace with your actual backend container destination network target
        proxy_pass http://INTERNAL_CONTAINER_IP:PORT;
        
        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;
    }
}

Step 2Validate and Start Port 80 Routing

Since the missing parameters are hidden behind comments, Nginx passes checks cleanly. Restart Nginx to open your Port 80 validation endpoint:

nginx -t
systemctl restart nginx

Step 3Request the SSL Certificate via Webroot

Run Certbot. Because Nginx is fully live, the Let's Encrypt validation server will reach your proxy machine, discover the directory token via Port 80, and sign the certificate request successfully.

certbot certonly --webroot -w /var/www/html -d example-next.mydomain.com

Step 4Uncomment and Unshackle SSL Encryption

Now that the automated system has dropped the actual .pem keys onto your filesystem, return to your configuration file:

nano /etc/nginx/sites-available/reverse-proxy.conf

Scroll down to the example-next.mydomain.com block and remove the comment symbols (#) from your certificate lines:

    # NOW UNCOMMENTED SAFELY:
    ssl_certificate /etc/letsencrypt/live/://mydomain.com;
    ssl_certificate_key /etc/letsencrypt/live/://mydomain.com;

Step 5Reload Nginx to Finalize

Execute your final reload script to safely mount the newly activated security layer:

nginx -t
systemctl restart nginx
Success Check: Your new container is now fully proxied behind an encrypted connection at https://mydomain.com.