How to set up ssl for your EC2 app with nginx and certbot

First Stage (Setting up The Certificate) Please Follow each step one at a time
- If you encounter any problem during any of the steps please seek help from chatgpt or any other tool you prefer
- Ssh into your instance
- sudo yum update -y
- sudo yum install nginx -y
- sudo systemctl start nginx
- sudo systemctl enable nginx
- sudo nano /etc/nginx/conf.d/django.conf
- Add this code into the conf file (we will edit later):
- server {
listen 80;
server_name your-ec2-public-ip;
location / {
proxy_pass http://127.0.0.1:8000; # This assumes your Django app is running on port 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;
}
}
- Replace
your-ec2-public-ipwith the public IP of your EC2 instance. - sudo nginx -t
- sudo systemctl reload nginx
- Verify If Everything Is fine:
- Open your browser and go to http://your-ec2-public-ip.
- You should see your Django app responding (or its API, depending on your setup).
- sudo dnf install certbot python3-certbot-nginx -y
- certbot –version
- sudo certbot –nginx
- Follow The Resulting Prompts
- You will be prompted on the last step to input a domain name … we have to set this up,
- Open another EC2 terminal so that we come back here later.
- Create a DuckDNS Account
- Go to DuckDNS.
- Click on Sign Up (you can use your Google account to sign up quickly).
- Once signed in, you’ll be taken to the DuckDNS dashboard.
- Step 2: Create a Subdomain
- On your DuckDNS dashboard, look for the section that says Domains.
- In the Create new subdomain section:
- Type a name for your subdomain (e.g., myapp).
- Click Add Domain.
- This will create a subdomain, something like:
- myapp.duckdns.org
- Step 3: Update DuckDNS with Your EC2 Public IP
- Get your EC2 public IP:
- You can find the public IP of your EC2 instance in the AWS EC2 dashboard. It should look something like 13.48.203.30.
- On your DuckDNS dashboard, find your token. It should be displayed under your domain (subdomain) name, like this:
- Now run this command on your EC2:
- curl https://www.duckdns.org/update?domains=myapp&token=your-token-goes-here&ip=
- Step 4: Check if the Subdomain is Working/
- Open a web browser.
http://myapp.duckdns.org
- You should see the default page or your app if it’s running.
- Now we go back to step 17/18:
- Input this: myapp.duckdns.org(replace with your domain)
- Next we have to edit the nginx conf file as mentioned in step: 7
- sudo nano /etc/nginx/nginx.conf
- edit the file in this manner:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
http {
types_hash_max_size 2048; # Increased from default
types_hash_bucket_size 128; # Increased from default
include /etc/nginx/mime.types;
default_type application/octet-stream;
# HTTP server block to redirect traffic to HTTPS
server {
listen 80;
server_name myapp.duckdns.org;
# Redirect all HTTP traffic to HTTPS
return 301 https://$host$request_uri;
}
# HTTPS server block
server {
listen 443 ssl;
server_name myapp.duckdns.org;
ssl_certificate /etc/letsencrypt/live/myapp.duckdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/myapp.duckdns.org/privkey.pem;
# SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers off;
location / {
proxy_pass http://127.0.0.1:8000; # Django app is running on port 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;
}
}
}
- sudo nginx -t
- sudo systemctl restart nginx
Finnally visit your domain at: https://myapp.duckdns.org
Verify if it works!
BUT WAIT WE ARE NOT DONE YET WE NEED TO SET UP AUTO RENEWALS OF OUR SSL CERTIFICATE
- ssh into your instace again if you exited
- certbot --version
- sudo certbot renew --dry-run (if you get an error here just retry or try again later)
- sudo systemctl list-timers | grep certbot
- sudo yum install cronie -y
- sudo systemctl enable crond
- sudo systemctl start crond
- sudo crontab -e
- This opens the editor
- Once the editor opens press i(to enter insert mode)
- Paste this in:
- 30 2,14 * * * certbot renew --quiet && systemctl reload nginx
- Then press esc(to enter command mode)
- Then type these keys one at a time to save, : then w then q
- Then press enter
- sudo crontab -l
- sudo certbot renew --dry-run && sudo systemctl reload nginx (if you get an error here just retry or try again later this is usual.)
- Great! Now your certificate will always be renewing twice a day we are done.
- Now just type exit to move out of your ec2.
Please don't hesitate to leave me a feedback if everything works out fine or if you had issues or if you just want more content like this you can reach out HERE.