Production Checklist
To go from “works on an IP” to production HTTPS:
- Buy / own a domain
- Assign an Elastic IP to EC2
- Map DNS A records to that IP
- Confirm HTTP via Nginx
- Install a free Let's Encrypt certificate with Certbot
- Redirect HTTP → HTTPS
Elastic IP
A public IP that does not change when you stop/start the instance.
AWS Console → EC2 → Elastic IPs
→ Allocate Elastic IP
→ Associate with your instance
Example: 13.250.100.50
Benefits: stable DNS target, fewer broken mappings after restarts.
DNS Mapping
Point the domain at the Elastic IP (registrar UI varies — Google Domains, Route 53, Cloudflare, etc.).
Example A records:
| Type | Name | Value |
|---|---|---|
| A | @ | 13.250.100.50 |
| A | www | 13.250.100.50 |
| A | api | 13.250.100.50 |
Verify:
ping api.example.com
# Should resolve to your Elastic IPThen open http://api.example.com — traffic should flow:
Domain → HTTP :80 → Nginx → Application
Install Certbot
sudo apt update
sudo apt install certbot python3-certbot-nginx -y
certbot --versionNginx before / after SSL
Ensure server_name matches the hostname you will certify. Example shape after Certbot (names are illustrative):
server {
listen 80;
server_name api.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl; # managed by Certbot
server_name api.example.com;
location / {
proxy_pass http://localhost:3000;
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;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Validate and reload:
sudo nginx -t
sudo systemctl reload nginxObtain the Certificate
sudo certbot --nginx -d api.example.comCertbot typically:
- Obtains a Let's Encrypt certificate
- Updates Nginx for TLS
- Can set up HTTP → HTTPS redirect
Verify HTTPS
https://api.example.com
Browser flow:
HTTP request → 301 redirect → HTTPS → Nginx → App
Check certificate details in the browser (issuer, expiry).
Auto Renewal
Let's Encrypt certs expire (~90 days). Certbot installs a timer/cron on Ubuntu:
sudo systemctl status certbot.timer
# or
sudo certbot renew --dry-runFinal Architecture
Developer
↓ push
GitHub Actions
↓ self-hosted runner
EC2 (Node + PM2)
↑
Nginx :80/:443 ← Domain + SSL
↑
Users (HTTPS)
Elastic IP + DNS A record + Certbot on Nginx turns your EC2 app into a stable, HTTPS production endpoint.