This episode explains the concepts of SSL/TLS and HTTPS, manual HTTPS server blocks, free certificate automation with Certbot and Let's Encrypt, auto-renewal, and HTTP to HTTPS redirects.

A website without HTTPS is an invitation to eavesdroppers. The data being sent can be read and modified in transit. This Episode 9 covers SSL/TLS and HTTPS on NGINX, from basic concepts to free certificate automation with Let's Encrypt.
You'll write a manual HTTPS server block, create free certificates with Certbot, set up automatic renewal, and redirect all HTTP traffic to HTTPS. By the end of this episode, your domain will be secure with a security rating worth showing off.
HTTPS is HTTP on top of a TLS layer. Before any data is sent, the client and server perform a TLS handshake: they exchange keys, verify the server's identity through a certificate, and establish an encrypted channel. After that, all traffic data can't be read or modified by third parties.
Certificates are issued by a Certificate Authority (CA) trusted by browsers. Browsers verify that the certificate is valid for the domain being visited, so clients are confident they're communicating with the right server.
First, prepare the certificate and private key. For production, use a certificate from a trusted CA. For local experiments, you can create a self-signed certificate:
sudo openssl req -x509 -nodes -newkey rsa:2048 \
-keyout /etc/ssl/private/example.key \
-out /etc/ssl/certs/example.crt \
-days 365 -subj "/CN=example.com"The HTTPS server block uses the ssl_certificate and ssl_certificate_key directives:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.crt;
ssl_certificate_key /etc/ssl/private/example.key;
root /var/www/example;
index index.html;
}listen 443 ssl; enables TLS on port 443. After editing, run nginx -t and reload.
Let's Encrypt provides free certificates valid for 90 days. Certbot automates the issuance and installation:
sudo apt install certbot python3-certbot-nginx -yMake sure the domain's DNS already points to the server's IP and that port 80 is reachable from the internet, because the verification process needs HTTP access.
Run certbot with the NGINX plugin:
sudo certbot --nginx -d example.com -d www.example.comCertbot will verify domain ownership, issue the certificate, modify the NGINX configuration automatically, and add an HTTP to HTTPS redirect. The certbot --nginx command also stores the settings for automatic renewal.
Let's Encrypt certificates last 90 days, so renewal must be automatic. Certbot provides a systemd timer:
sudo systemctl enable --now certbot.timer
sudo systemctl list-timers certbot.timercertbot.timer runs renewal twice a day and only renews certificates with fewer than 30 days left. After a successful renewal, Certbot automatically reloads NGINX.
To test the renewal flow without actually renewing:
sudo certbot renew --dry-runcertbot renew --dry-run makes sure the whole renewal pipeline works before it's truly needed.
Every domain using HTTPS must also handle HTTP requests. The most common approach:
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}The return 301 https://$host$request_uri; directive moves all HTTP requests to HTTPS with a permanent status. The $host and $request_uri variables keep the domain and path intact. This is also what Certbot does automatically when you use --nginx.
Once the configuration is active, verify from the client side:
curl -I https://example.com
curl -I http://example.comThe HTTPS response should show HTTP/2 200, and the HTTP request should be redirected with 301. All traffic is now encrypted.
Episode 9 closed the biggest security gap: you understand TLS concepts, write manual HTTPS server blocks, issue free certificates with Certbot and Let's Encrypt, set up auto-renewal, and redirect all traffic to HTTPS.
Key takeaways:
listen 443 ssl; together with ssl_certificate and ssl_certificate_key creates manual HTTPS.certbot --nginx.certbot.timer timer.certbot renew --dry-run tests the renewal pipeline.return 301 https://$host$request_uri;.In the next episode we'll discuss SSL/TLS security hardening and protocols — enabling HTTP/2 and HTTP/3, restricting ssl_protocols and ssl_ciphers, turning on HSTS, OCSP stapling, and custom DH parameters.