If you have deployed a website recently, you might have noticed browsers throwing "Not Secure" warnings if your site doesn't use HTTPS. In today's web landscape, having SSL/TLS certificates isn't just nice-to-have; it's a must-have for ensuring user trust and data security.
But here's the thing – getting SSL certificates used to cost money. Thankfully, Let's Encrypt came along like a digital superhero and made SSL certificates free for everyone. Today, we'll walk you through setting up NGINX with free SSL certificates on Ubuntu using Certbot.
TL;DR
If you want to skip the detailed explanations and get straight to the commands, here's a quick summary:
- Install and enable NGINX:
sudo apt update
sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx
systemctl status nginx
- Create and link NGINX conf:
sudo nano /etc/nginx/sites-available/yourdomain.com
sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
- Install Certbot:
sudo apt update
sudo apt install certbot python3-certbot-nginx -y
- Obtain SSL certificate:
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
To those who prefer a more detailed guide, read on!
What We're Building Today
By the end of this guide, you'll have:
- NGINX running on your server
- Your domain pointing to your server
- Free SSL certificates that auto-renew
- A website that browsers actually trust
Prerequisites (The Boring But Important Stuff)
Before we dive in, make sure you have:
- An Ubuntu server (18.04+ recommended)
- A domain name pointing to your server's IP address
- Basic terminal skills (if
cd
andls
make sense to you, you're golden)
Step 1: Update Your System (The "Have You Tried Turning It Off and On Again?" of Linux)
First things first – let's make sure your system is up to date. Because running outdated packages is like trying to edit 4K vide on a 2010 MacBook.
sudo apt update && sudo apt upgrade -y
This might take a minute or two. Perfect time to grab some coffee or contemplate your life choices that led you to managing servers.
Step 2: Install NGINX (The Star of Our Show)
NGINX is like that reliable friend who never lets you down. It's fast, lightweight, and handles traffic better than most.
sudo apt install nginx -y
Let's start NGINX and make sure it boots up with your server:
sudo systemctl start nginx
sudo systemctl enable nginx
Check if NGINX is running properly:
sudo systemctl status nginx
You should see something like "active (running)" in green.
Step 3: Configure Your Firewall (Because Security Matters)
Ubuntu comes with UFW (Uncomplicated Firewall), and true to its name, it's pretty uncomplicated. Let's allow HTTP and HTTPS traffic:
sudo ufw allow 'Nginx Full'
sudo ufw allow ssh
sudo ufw enable
The 'Nginx Full' profile allows both HTTP (port 80) and HTTPS (port 443). The SSH rule ensures you don't lock yourself out – trust me, we've been there.
Step 4: Test Your Basic Setup
Open your browser and navigate to your domain (or server IP). You should see the default NGINX welcome page. If you see it, pat yourself on the back – you're halfway there!
If you don't see it, double-check:
- Your domain's DNS settings
- Your server's firewall
Step 5: Create Your Website Directory Structure
Let's create a proper home for your website. NGINX likes to keep things organized:
sudo mkdir -p /var/www/yourdomain.com/html
sudo chown -R $USER:$USER /var/www/yourdomain.com/html
sudo chmod -R 755 /var/www/yourdomain.com
Replace yourdomain.com
with your actual domain.
Create a simple test page:
cat > /var/www/yourdomain.com/html/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head>
<title>Welcome to Your Awesome Website!</title>
<style>
body { font-family: Arial, sans-serif; text-align: center; margin: 50px; }
.container { max-width: 600px; margin: 0 auto; }
.ssl-badge { color: green; font-weight: bold; }
</style>
</head>
<body>
<div class="container">
<h1>🎉 Your Website is Live!</h1>
<p>If you're seeing this page, NGINX is working correctly.</p>
<p class="ssl-badge">Soon to be secured with SSL! 🔒</p>
</div>
</body>
</html>
EOF
Step 6: Configure NGINX Server Block
Now let's tell NGINX about your website. Create a server block configuration:
sudo nano /etc/nginx/sites-available/yourdomain.com
Add this configuration (and yes, replace yourdomain.com
with your actual domain):
server {
listen 80;
listen [::]:80;
server_name yourdomain.com www.yourdomain.com;
root /var/www/yourdomain.com/html;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
# Optional: Add some basic security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
# Optional: Gzip compression (because nobody likes slow websites)
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
}
or if you have a server running on a specific port, use this configuration:
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}
Enable your site by creating a symbolic link:
sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/
Test your NGINX configuration (because syntax errors are embarrassing):
sudo nginx -t
If you see "syntax is ok" and "test is successful", you're golden. If not, check your configuration for typos.
Reload NGINX to apply changes:
sudo systemctl reload nginx
Step 7: Install Certbot (The SSL Magic Wand)
Certbot is the tool that communicates with Let's Encrypt to get your free SSL certificates. It's like having a personal assistant for SSL management.
For Ubuntu 18.04+:
sudo apt install certbot python3-certbot-nginx -y
For older Ubuntu versions, you might need to add the Certbot PPA first:
sudo add-apt-repository ppa:certbot/certbot
sudo apt update
sudo apt install certbot python3-certbot-nginx -y
Step 8: Obtain Your SSL Certificate (The Moment of Truth)
This is where the magic happens. Certbot will automatically configure NGINX for SSL. Run this command and follow the prompts:
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Certbot will prompt you for a few details:
- Email address: For important renewal and security notices (use a real email)
- Terms of Service: Read them if you want, but let's be honest, you'll just agree
- Share email with EFF: Up to you, but they do good work
- Redirect HTTP to HTTPS: Choose "2" to redirect (because why would you want insecure traffic?)
If everything goes well, you'll see a congratulations message. If not, common issues include:
- Domain not pointing to your server
- Firewall blocking port 80/443
- NGINX not running
- DNS propagation still in progress
Step 9: Test Your SSL Setup
Open your browser and navigate to https://yourdomain.com
. You should see:
- Your website loading over HTTPS
- A secure lock icon in the address bar
- No more scary security warnings
You can also test your SSL configuration at SSL Labs. If you followed this guide correctly, you should get an A or A+ rating.
Step 10: Set Up Auto-Renewal (Because Certificates Expire)
Let's Encrypt certificates are valid for 90 days but Certbot can renew them automatically. Certbot automatically sets up a cron job to renew them, but let's verify it's working:
sudo certbot renew --dry-run
This simulates the renewal process. If you see "Congratulations, all renewals succeeded", you're all set.
You can also check the automatic renewal timer:
sudo systemctl status certbot.timer
Integrating Subdomains (If You Have More Than One)
The above steps can be repeated for any subdomains you have. Just add an A record in your DNS settings pointing to your server's IP address, and run the Certbot command with the subdomain:
sudo certbot --nginx -d subdomain.yourdomain.com
Make sure to replace subdomain.yourdomain.com
with your actual subdomain.
Troubleshooting Common Issues (When Things Go Wrong)
"Connection Refused" or "This Site Can't Be Reached"
- Check if NGINX is running:
sudo systemctl status nginx
- Verify firewall settings:
sudo ufw status
- Ensure your domain's DNS is pointing to the correct IP
Certificate Validation Failed
- Make sure your domain is accessible via HTTP before requesting SSL
- Check if port 80 is blocked by your hosting provider
- Verify DNS propagation:
nslookup yourdomain.com
NGINX Configuration Errors
- Always test config before reloading:
sudo nginx -t
- View NGINX error logs:
sudo tail -f /var/log/nginx/error.log
- Ensure proper file permissions
Monitoring Your Setup
Keep an eye on your certificates with this handy command:
sudo certbot certificates
Monitor NGINX access and error logs:
# Access logs (who's visiting your site)
sudo tail -f /var/log/nginx/access.log
# Error logs (what's going wrong)
sudo tail -f /var/log/nginx/error.log
Performance Tips (Because Speed Matters)
Add these snippets inside your NGINX configuration for better performance:
# Inside your server block
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# Enable browser caching
location ~* \.(html|htm)$ {
expires 1h;
add_header Cache-Control "public";
}
Conclusion
Congratulations! You've successfully set up NGINX with free SSL certificates. Your website now has:
- ✅ Professional SSL encryption
- ✅ Automatic certificate renewal
- ✅ Better SEO rankings (Google loves HTTPS)
- ✅ User trust (goodbye scary warnings)
- ✅ Improved security headers
What's Next?
Now that you have a secure foundation, consider:
- Setting up a proper backup strategy
- Implementing monitoring (Uptime Robot, Pingdom, etc.)
- Adding a CDN for global performance
- Setting up log rotation for cleaner logs
- Implementing fail2ban for additional security
Final Thoughts
Setting up NGINX with SSL used to be a painful process involving expensive certificates and complex configurations. Thanks to Let's Encrypt and Certbot, it's now easier than explaining why you need 16GB of RAM for coding.
Remember: security isn't a destination, it's a journey. Keep your system updated, monitor your logs, and don't forget to check on your certificates occasionally (though they should renew automatically).
Have questions or run into issues? The NGINX and Let's Encrypt communities are incredibly helpful. And remember, everyone's been where you are now – we've all had that moment of panic when something doesn't work the first time.
Happy coding, and may your uptime be high and your SSL certificates always valid! 🚀