This walks through the complete process of getting HTTPS working on Nginx from a plain HTTP-only starting point — certificate acquisition, server block configuration, the redirect, and a basic hardening pass, in the order that avoids common pitfalls.
1. Obtain a certificate
For a straightforward setup, Certbot's Nginx plugin handles both issuance and configuration in one step (see our Certbot automation guide for full detail):
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
If you're installing a certificate obtained separately (a paid certificate from another CA, for example), you'll configure the server block manually instead, as shown below.
2. The HTTPS server block
server {
listen 443 ssl;
server_name yourdomain.com www.yourdomain.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
root /var/www/yourdomain;
index index.html;
}
ssl_certificate should point to the full chain (your certificate plus intermediates concatenated), not just your certificate alone — a common first-time mistake that produces a certificate that works in some browsers (ones that cache the intermediate separately) but fails trust checks in others.
3. The HTTP-to-HTTPS redirect block
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
return 301 https://$host$request_uri;
}
This is a separate server block, not a rule inside the HTTPS block — Nginx needs distinct blocks per listening port, with the port-80 block's only job being this redirect.
4. Reload, don't restart
sudo nginx -t && sudo systemctl reload nginx
Always run nginx -t first to validate configuration syntax — catching a typo before reloading avoids taking the server down with a broken configuration, which reload (unlike some other services' restart behavior) will refuse to do if the test fails first.
5. A basic hardening pass
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
add_header Strict-Transport-Security "max-age=31536000" always;
Session caching improves performance for repeat visitors; the HSTS header (start with a shorter max-age while confirming everything is stable — see our HSTS deep dive) adds the redirect-loop protection covered elsewhere in this site.
6. Confirm it's actually working
Run an SSL scan tool against your domain, and separately check that the plain http:// version correctly redirects with a 301 — both checks catch different classes of misconfiguration that a quick visual browser check alone might miss.
Common first-time mistakes to check for
- Forgetting
ssl_certificateneeds the full chain, not just your leaf certificate alone - Leaving the default Nginx server block active, which can silently intercept requests intended for your new HTTPS server block on some configurations
- Not opening port 443 in the server's firewall, which produces a connection timeout rather than a certificate-related error — easy to misdiagnose as a certificate problem when it's actually a network-level block
What server block priority and default_server means for a multi-site Nginx setup
On a server hosting multiple sites, Nginx selects which server block handles a request based on server_name matching, with a designated default_server block catching anything that doesn't match explicitly — misconfiguring this can cause one site's certificate to be served for an unrelated domain's requests.
How to verify your certificate chain is complete before considering the install finished
Running `openssl s_client -connect yourdomain.com:443 -showcerts` after installation confirms your server presents the complete chain, your certificate followed by intermediates, rather than assuming installation succeeded just because the server started without errors.
Why keeping a tested, working configuration template speeds up future installations
Saving a working, tested Nginx configuration as a reference template for future sites means each subsequent installation starts from a known-good baseline rather than being written from scratch, reducing both setup time and the risk of reintroducing a previously-fixed mistake.
What separates a working configuration from a genuinely production-ready one
A working configuration successfully serves HTTPS; a production-ready one additionally includes OCSP stapling, a current, hardened cipher suite list, HSTS, and session caching — the difference between technically functional and genuinely well-configured, which an SSL scan tool will clearly distinguish with its overall grade.
How to handle the transition period while DNS propagates for a brand new domain
For a brand new domain not yet resolving everywhere, testing your server configuration directly against its IP address (using curl's --resolve flag to simulate the eventual DNS) lets you verify everything works correctly before DNS has fully propagated, rather than waiting on propagation before starting any verification.
Why documenting your specific configuration choices helps whoever maintains this server next
Brief comments directly in your server configuration file explaining any non-default choices, why a specific cipher suite list was chosen, why a particular directive was added, save considerable time for whoever next needs to modify or troubleshoot the configuration, including a future version of yourself who's forgotten the original reasoning.
What a complete, annotated example configuration file looks like put together
Assembling every piece covered in this guide, the redirect block, the HTTPS server block with certificate paths, modern cipher configuration, OCSP stapling, and HSTS, into one complete, commented reference file gives you a single, tested starting point for any future server rather than reassembling the pieces from memory each time.
How to add rate limiting alongside your new HTTPS configuration for additional hardening
Basic request rate limiting, configured alongside your HTTPS setup, adds a meaningful layer of protection against brute-force login attempts or basic abuse — most web servers support this natively through built-in modules, worth adding as a complementary hardening step while you're already reviewing your server's security configuration.
Why testing configuration changes with nginx -t before every reload becomes second nature
Making a habit of running nginx -t before every single reload, not just when troubleshooting a suspected issue, catches a typo or syntax error before it can take down an otherwise working configuration — a small, consistent habit that prevents an entirely avoidable category of self-inflicted downtime.
What a quick closing checklist for a from-scratch Nginx install looks like
Before considering the installation complete, confirm: the certificate and full chain are installed correctly, HTTP redirects to HTTPS with a 301, an SSL scan tool reports a strong grade, and OCSP stapling is confirmed active via a direct OpenSSL check.
Why building this from scratch once makes every future managed-platform shortcut easier to appreciate
Having manually configured every piece of a working HTTPS setup at least once gives you a genuine mental model for what a managed platform like Vercel or Cloudflare is actually doing automatically behind the scenes — a foundation that makes troubleshooting an issue on a managed platform considerably less mysterious when something does need attention.
What HTTP/2 configuration to add alongside your new HTTPS setup
Adding http2 to your listen directive (Nginx) or enabling mod_http2 (Apache) alongside your HTTPS configuration is a straightforward addition that provides a genuine performance benefit for multi-resource pages, essentially a free upgrade once HTTPS is already correctly configured, since HTTP/2 requires HTTPS in every major browser.
How to handle a server also needing to support older TLS 1.0 clients temporarily
If you have specific, confirmed evidence some portion of your audience still requires TLS 1.0 or 1.1, Mozilla's SSL Configuration Generator offers an old compatibility preset explicitly for this scenario — worth treating as a deliberate, temporary compromise with a plan to remove it once the legacy client population is confirmed gone, not a permanent default.
Why a staged rollout, testing on a subdomain first, reduces risk for a critical server
Testing your complete configuration on a lower-stakes subdomain first, before applying identical settings to your primary domain, catches a configuration mistake in a context where it causes minimal disruption rather than affecting your most important, highest-traffic property directly.