Redirect HTTP to HTTPS in Nginx — Quick & Clean
Got an old site that still sits on plain‑text, and you want every visitor forced onto the secure channel?
Below is a no‑frills walkthrough of how to make Nginx hand off all HTTP traffic straight to HTTPS.
You’ll see the exact directives, why each one matters, and what to do if something goes wrong.
Why It Matters
Browsers are increasingly flagging unencrypted sites as “not secure.”
Even Google’s search ranking gives a bump to HTTPS‑only domains, so you’re basically giving away half your traffic if you leave HTTP hanging around.
In my last server upgrade I forgot the redirect; visitors got that dreaded “Your connection is not private” pop‑up and bounced straight to my competitor’s site.
Prepare Your SSL Certificate
Nginx needs a certificate before it can speak HTTPS.
If you’re on Ubuntu, certbot makes this painless:
sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d example.com -d www.example.com
It pulls a free Let’s Encrypt cert and patches your config for you.
Why bother? Without a certificate the redirect will never work; HTTPS won’t be available.
Edit the Server Block
Open the file that Nginx uses for your site—usually /etc/nginx/sites-enabled/example.com.
Add a tiny block dedicated to port 80:
server {
listen 80 default_server;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
- listen 80 tells Nginx that this block only handles HTTP.
- default_server makes it the catch‑all for any unmatched request, so you don’t get a “404 not found” when someone hits http://example.com.
- The return 301 directive issues a permanent redirect.
Using $host$request_uri preserves the exact path and query string the visitor requested.
If you already have an HTTPS block in the same file, just add this new block—no need to touch anything else.
Test the Configuration
A typo in Nginx’s syntax can bring down the whole web server.
Run:
sudo nginx -t
It will either say “syntax is ok” or point out the exact line where it failed.
If you see an error, fix it before reloading.
Reload Nginx
Apply the changes without dropping connections:
sudo systemctl reload nginx
A full restart (restart) would temporarily take your site offline, which isn’t worth it for a simple redirect tweak.
Verify It Works
From another machine or using curl, check that HTTP gets a 301:
curl -I http://example.com HTTP/1.1 301 Moved Permanently Location: https://example.com/ ...
If you see the Location header pointing to HTTPS, you’re all set.
Optional: Add HSTS (Optional)
If you want browsers to remember “no HTTP” for your domain, add this inside your HTTPS server block:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
It tells compliant browsers to refuse plain‑text connections for a year.
Some developers over‑enable it and then forget to test on older clients, so only enable if you’re sure your users are on up‑to‑date browsers.
Final Thoughts
That’s the whole shebang: one tiny server block, a cert, a quick reload.
I’ve seen plenty of folks stumble over the listen 80 line or forget to preserve $request_uri.
Fix those and you’ll have every visitor coming in on HTTPS, no more security warnings, and a cleaner user experience.