Back to Guides
NginxSSLCertbotReverse Proxy

Setup Nginx Reverse Proxy with Let's Encrypt SSL

Secure your applications with free HTTPS certificates using Certbot and configure Nginx to act as a reverse proxy for apps running on internal ports (like 8000 or 8501).

1

Install Nginx & Certbot

First, ensure your server has the web server and the certificate management tool installed.

For Amazon Linux / CentOS / RHEL:

Terminal
sudo yum update -y sudo yum install nginx certbot python3-certbot-nginx -y sudo systemctl start nginx sudo systemctl enable nginx

For Ubuntu / Debian:

Terminal
sudo apt update sudo apt install nginx certbot python3-certbot-nginx sudo systemctl start nginx

A list of installed packages will appear upon completion.

2

The "Chicken & Egg" Configuration

You cannot configure Nginx for SSL/HTTPS immediately because the certificates don't exist yet. Nginx will crash if you reference missing files.

The Strategy: Create a simple HTTP (Port 80) config first -> Run Certbot -> Then add the full Proxy/SSL config.

Create a new configuration file for your domain:

Terminal
sudo nano /etc/nginx/conf.d/myapp.conf

Paste this temporary configuration:

/etc/nginx/conf.d/myapp.conf
server { listen 80; server_name yourdomain.com www.yourdomain.com; location / { # Just a placeholder for validation root /usr/share/nginx/html; index index.html; } }

Replace yourdomain.com with your actual domain.

Reload Nginx to apply changes:

Terminal
sudo nginx -t && sudo systemctl reload nginx
3

Obtain the Certificate

Now that Port 80 is open and listening for your domain, Certbot can verify ownership.

Terminal
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com

Follow the prompts. When asked to redirect HTTP traffic to HTTPS, select Yes (2). Certbot will automatically modify your config file to add the SSL paths.

4

Configure the Reverse Proxy

Now we modify the file one last time to forward traffic to your running application (e.g., Streamlit on port 8501 or FastAPI on 8000).

Terminal
sudo nano /etc/nginx/conf.d/myapp.conf

Option A: For Streamlit Apps (Port 8501)
Streamlit requires special headers for WebSockets.

Streamlit Configuration
# INSIDE THE server { listen 443 ssl ... } BLOCK location / { proxy_pass http://localhost:8501; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }

Option B: For Standard Apps (Port 8000/3000)
For FastAPI, Node.js, or Flask.

Standard App Configuration
# INSIDE THE server { listen 443 ssl ... } BLOCK location / { proxy_pass http://localhost:8000; 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; }

Final Test & Reload:

Terminal
sudo nginx -t && sudo systemctl reload nginx
5

Automate Renewal

Let's Encrypt certificates expire every 90 days. Set up a cron job to renew them automatically.

Terminal
sudo crontab -e

Add this line to the bottom of the file:

Crontab
0 0 * * * certbot renew --nginx --quiet

This checks for renewal eligibility every day at midnight.

Troubleshooting

If you see a "502 Bad Gateway" error, it means your application (Streamlit/FastAPI) isn't running.
Check if it's active with: sudo lsof -i :8501 or ensure you used nohup to keep it running in the background.