Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

The reliable production pattern is to terminate TLS at Nginx on your VPS, proxy HTTPS requests to Gunicorn or Uvicorn, and configure Django to trust the HTTPS signal only when Nginx sets it correctly. Point your domain at the VPS, open TCP ports 80 and 443, obtain a certificate through ACME with Certbot, redirect HTTP to HTTPS, then enable Django’s secure-cookie and redirect settings.

This guide walks through that setup, explains why redirect loops and CSRF failures occur, and shows how to verify and renew the certificate without taking the application offline unnecessarily.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What the finished setup looks like

A browser connects to https://your-domain.example on port 443. Nginx presents the certificate, handles the encrypted connection, and forwards the request over the VPS’s local network to Gunicorn or Uvicorn. Django never needs to hold the private key and should not be exposed directly to the internet.

Layer Responsibility Important setting
DNS Resolves the public hostname to the VPS A and, if used, AAAA records point to the VPS addresses
Firewall Allows certificate validation and web traffic Inbound TCP 80 and 443 are permitted in both provider and VPS firewalls
Nginx Terminates TLS, redirects HTTP, and proxies requests Passes the original host and a truthful X-Forwarded-Proto value
Gunicorn or Uvicorn Runs the Django application server Listens on a Unix socket or localhost port, not a public interface
Django Applies host, cookie, CSRF, and HTTPS policies Uses SECURE_PROXY_SSL_HEADER only with a trusted proxy
Certbot and ACME Obtains and renews the certificate Renewal must be followed by an Nginx reload

Django’s security documentation says that deploying behind HTTPS is always better for security. A login-capable site should enforce it site-wide: otherwise passwords, session cookies, and password-reset tokens can travel in clear text.

#1 Best Overall
Sale
Compressed Air Duster,130000RPM Super Power Cordless Air Duster,Rechargeable Brushless Blower,3 Gear Adjustable Blower with LED Light,Dust Remover for Computer/House/Outdoor/Car
  • Powerful Turbo Fan:CAGIWIRU Electric Air Duster have reached speed up to 130000RPM,Can efficient remove dust and debris.With LED light and Three Adjustable Speed to meet with different cleaning tasks.
  • With Attached USB C Fasting Charging cable.Charing 3 hours,Enjoy up to 240 minutes of use on the lowest setting, For third speed can use for 25mins.with four charging options to meet with your needs.
  • Wide Application: attached 5 different nozzles,making it suitable for a variety of scenes, such as car,pet, pc, keyboards, and other electronic devices. It also serves for office and home clean duster.
  • Handy Design & Portable:Cordless air duster electric nozzle is Light weight and small size, design and comfortable to hold and space saving, convenient to carry around. You can put it in your room or inside the car without taking up space.
  • Economical &Reusable: Built durable materials with a long-lasting battery,our CAGIWIRU air duster it's a sustainable alternative to disposable air cans.

Prerequisites and a safe starting point

Have these details before changing the live configuration:

  • An Ubuntu or Debian-like VPS with administrative access. Package names and service paths differ on other distributions.
  • The exact public hostnames users will visit, such as example.com and www.example.com.
  • The VPS public IPv4 address and, if applicable, its IPv6 address.
  • A working Gunicorn or Uvicorn service and its Unix socket or localhost port.
  • Access to the DNS provider and to both the VPS provider firewall and the operating-system firewall.
  • A rollback copy of the current Nginx site file and main configuration.

Do not use Django’s development server as the public endpoint. It is intended for development, not for handling production traffic or TLS.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Record the current state

Before editing, save the relevant files and service status. Typical commands on a systemd-based Debian or Ubuntu VPS are:

sudo cp -a /etc/nginx /etc/nginx.backup-$(date +%F-%H%M%S)
sudo systemctl status nginx
gunicorn --version
sudo systemctl status gunicorn

Your Gunicorn unit may have a project-specific name, and Uvicorn may run through a different service. Record the actual unit name and the socket or port it uses; the Nginx upstream must match it exactly.

Point DNS at the VPS and open the network path

DNS records

Create an A record for the hostname’s IPv4 address. Add an AAAA record only when IPv6 is configured and reachable on the VPS; an incorrect AAAA record can make some visitors fail even while IPv4 works. If you serve both the apex and www hostname, create records for both or use a CNAME for the alias as appropriate.

Check resolution from a workstation before requesting a certificate:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
dig +short example.com A
dig +short example.com AAAA

Every returned address must belong to the VPS that will answer the request. DNS changes can take time to reach all resolvers, so do not start validation while records still point to an old host.

Firewall rules

Allow inbound TCP 80 and 443 in the VPS provider’s firewall and in the operating-system firewall. HTTP-01 ACME validation normally needs port 80 even if you intend to redirect all ordinary HTTP traffic. SSH should remain available on your administration port.

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status verbose

If your distribution does not use UFW, apply equivalent rules with its firewall tooling. Also verify that a cloud security group, network ACL, or IPv6 policy is not blocking the same ports.

Install Nginx and Certbot

On Debian or Ubuntu, install Nginx and the Certbot Nginx plugin from the distribution repositories:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo apt update
sudo apt install nginx certbot python3-certbot-nginx

Enable and start Nginx if it is not already running:

sudo systemctl enable --now nginx

Package names and Certbot integration can change between distributions. Use the package supplied for your operating system and confirm that the installed client provides the Nginx plugin before relying on the commands below.

Rank #2
EVEO® Screen Cleaner Spray Kit (Streak-Free) TV Screen Cleaner for Smart TV, Lcd, LEd, Oled | Computer Screen Cleaner Spray and Wipe Microfiber Cloth - TV, Monitor, Laptop, iPad, Car - 6.7oz 1 Pack
  • Screen Cleaner is Your Screen’s New Bestfriend! - EVEO is proud to present a screen cleaner that’s perfectly suited for your TV. Meet your new screen cleaner, computer screen cleaner, laptop cleaner, iPad cleaner, Macbook,tv cleaner or any other electronic device. Our screen cleaner spray and wipe along with the included plush microfiber cloth, easily removes dust, fingerprints & other smudges on the screen’s surface. Clean effectively for a streak-free screen
  • Gentle on your Screens - Our screen cleaner spray and wipes is compatible to be used even for the most sensitive LCD, LED, CRT, and OLED screens in proper use. Be at ease knowing that this product is compatible with all the major brands: LG, SONY, Samsung, Sharp, iPad, iPhone, Android screens, Kindle, PC monitors - we’ve got you covered! Can be used as LCD screen cleaner, tv cleaner, smart tv screen cleaner, and more
  • Premium Super Soft Plush Microfiber Cloth - Included in this efficient screen cleaning kit. This screen cleaner spray and wipe has our signature plush microfiber cloth specially designed to comply with screens and monitors and leave them streak-free. Has been shown to effectively absorbs stubborn stains, zero streaks, and no fiber shedding. Always use this together with our screen cleaner for the best results
  • Easy-to-Use Screen Cleaner Kit + microfiber cleaning cloth - The EVEO Screen Cleaning Kit will easily be your new favorite tool when it comes to taking care of the things you love most, quick and easy solution for a streak-free screen. Simply screw on the sprayer gun on the screen cleaner bottle. Spray the cleaning liquid onto the microfiber cloth, then wipe the screen until desired cleanliness & shine is achieved.
  • Quality Screen Care Kit Worth Purchasing - Enjoy a convenient Screen Cleaner anytime, anywhere you need it. Your satisfaction is our top priority. We stand behind the quality of our products and that’s why, you shouldn’t be worrying at all. We manufacture the Best Screen Cleaner. and can be used for laptop cleaning kit, laptop screen cleaner, tv screen cleaner for smart tv. MacBook screen cleaner, monitor cleaner or screen cleaner spray for electronic devices with microfiber cleaning cloth

Request the certificate with an ACME challenge

Using the Nginx plugin

When DNS resolves correctly and Nginx can answer on port 80, the Nginx plugin is the simplest path. Replace the names with every hostname that should appear on the certificate:

sudo certbot --nginx -d example.com -d www.example.com

Certbot may ask for an email address, acceptance of the certificate authority’s terms, and whether HTTP should redirect to HTTPS. Review the proposed Nginx changes rather than accepting a configuration that points at the wrong site or upstream.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Certificate files are normally exposed through paths under /etc/letsencrypt/live/. Protect the private key, restrict permissions, and never copy it into the Django repository, an image build context, or a public backup. Nginx should read the key directly from the certificate directory.

When HTTP-01 cannot reach the VPS

A standalone challenge temporarily binds port 80 and therefore also requires that port to be reachable:

sudo certbot certonly --standalone -d example.com -d www.example.com

Stop any service occupying port 80 only for the challenge, then start it again. If port 80 cannot be made reachable because DNS or network policy prevents it, use a DNS-01 challenge with a client and DNS provider integration suitable for your environment. The validation method must match the actual network path; changing Django settings cannot fix an unreachable challenge endpoint.

Build the Nginx HTTPS configuration

Keep one server block for HTTP that performs only the redirect, and one for HTTPS that serves the certificate and proxies to the application. The following example assumes a Unix socket at /run/gunicorn/myproject.sock; substitute your real socket or localhost port.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

HTTP redirect block

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    return 301 https://$host$request_uri;
}

Nginx performs this redirect before the request reaches Django, which avoids spending application resources on traffic that can never be served securely. A permanent redirect also lets browsers and search engines update their stored URL.

HTTPS proxy block

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass http://unix:/run/gunicorn/myproject.sock;
        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 https;
        proxy_redirect off;
    }

    location /static/ {
        alias /srv/myproject/staticfiles/;
    }

    location /media/ {
        alias /srv/myproject/media/;
    }
}

The exact ssl directives may be generated or adjusted by Certbot and by your distribution’s Nginx packaging. Keep the certificate paths under /etc/letsencrypt/live/ and check that the Nginx worker can read them.

Host preserves the hostname Django uses for host and URL decisions. X-Forwarded-For retains the client address chain. Most importantly, this HTTPS server block sends X-Forwarded-Proto https only for requests that arrived over TLS. Do not send that value from the port-80 block or from an untrusted public client header.

Static and media files

Use paths that match your deployment. Run Django’s collection step after deploying static assets, for example:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
python manage.py collectstatic --noinput

Check that the aliases point to directories readable by Nginx and that uploaded media is not accidentally exposed as executable code. If another component serves static or media files, keep those locations out of the proxy block and verify their URLs are HTTPS.

Configure Django to understand HTTPS

Set the production hostnames explicitly. Do not use a wildcard merely to silence an error:

Rank #3
Sale
BladeHawks RGB Gaming Mouse Pad Extra Large Extended 31.5x12 Inch-Black | LED mouse pad with 14 lighting modes, covers keyboard & mouse, anti-slip rubber base, waterproof surface, USB powered
  • 【Large size】:Measuring 800 x 300 mm/ 31. 5×12 inches, which is wider and taller than others. Large mouse pad can perfectly fit your keyboard and mouse of any size, and there is also ample space for peripherals such as phones, tablets, etc.
  • 【LED backlight mouse pad】:Blade Hawks RGB mouse pad provides 7 static modes and 7 dynamic modes will give you the options you are looking for. Power-off memory function remembers the last lighting mode you selected. The super glow fiber Chroma will give you a colorful gaming setup that you want.
  • 【Anti-slip rubber base】:Made from Natural rubber, this gaming mousepad will firmly grip your desktop, allowing you to enjoy the ultimate precision in the games you are most passionate about. It also comes with a texture that enhances this ability even further.
  • 【Smooth and waterproof surface】: Micro-textured cloth surface, for extremely precise mouse control and a smooth movement. When liquid splashes on the gaming mouse pad, it forms water droplets and slides down. Will not delay your work or gameplay.
  • 【Plug and play】: This mouse and keyboard pad is powered by USB, plug and play, no driver required. One button control light modes. Press one time to change the lighting mode, press twice to change the brightness, press and hold about 3 seconds turn ON/OFF.
ALLOWED_HOSTS = ["example.com", "www.example.com"]

SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True

SECURE_PROXY_SSL_HEADER tells Django that a request is secure when the named header has the expected value. It is safe only when Nginx (or another proxy you control) overwrites that header and sends https exclusively for TLS requests. If clients can inject the header or an intermediate proxy changes it, Django can make incorrect security decisions.

Use SECURE_SSL_REDIRECT when Django must enforce HTTPS in addition to the front-end redirect, or when a front-end redirect is unavailable. In the usual Nginx design, the port-80 block redirects before Django sees the request. If Django does see an HTTP request and does not recognize the proxy’s HTTPS signal, enabling both controls can produce an endless redirect loop. Fix the header path instead of turning off security checks as a first response.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For forms and APIs posted from known HTTPS origins, list those origins explicitly:

CSRF_TRUSTED_ORIGINS = [
    "https://example.com",
    "https://www.example.com",
]

The scheme is part of each trusted origin. Keep the list limited to hostnames you operate, and keep the hostnames consistent across links, cookies, redirects, and users’ bookmarked URLs. A mismatch between example.com and www.example.com can look like a random login or CSRF failure.

HSTS: add it after HTTPS is stable

HTTP Strict Transport Security tells browsers to use HTTPS automatically. Add Django’s HSTS settings only after every required hostname works reliably over HTTPS and you have a recovery plan:

SECURE_HSTS_SECONDS = 31536000
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
# SECURE_HSTS_PRELOAD = True  # only when you understand the preload requirements

An incorrect HSTS policy can make an outage harder to recover from because browsers will refuse an HTTP fallback. Start with a cautious policy, test all subdomains before including them, and do not enable preload casually.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Test and reload without taking avoidable risks

Validate syntax before changing the running service:

sudo nginx -t
sudo systemctl reload nginx

A reload allows existing workers to finish while new workers read the certificate and configuration. Restart Gunicorn or Uvicorn only when its environment, socket, or application code changed; a certificate-only change normally requires an Nginx reload, not an application restart. If nginx -t fails, do not reload. Restore the backup or correct the reported path, brace, permission, or upstream error first.

Check service and error logs immediately after a reload:

sudo systemctl status nginx
sudo journalctl -u nginx -n 100 --no-pager
sudo journalctl -u gunicorn -n 100 --no-pager

Look for an unreadable private key, a missing socket, a syntax error, a certificate path for the wrong hostname, or a permission denial on static and media directories. Keep the previous working site configuration available until the new path has passed external tests.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Verify HTTPS end to end

Test from outside the VPS so that local DNS or firewall exceptions do not hide a problem:

curl -I http://example.com
curl -I https://example.com
curl -I https://www.example.com

The HTTP response should be a redirect to the intended HTTPS URL. The HTTPS response should come from the expected application, not an Nginx default site or another virtual host. Test every hostname on the certificate.

Rank #4
Sale
Vaydeer Wrist Rest for Keyboard and Mouse, Computer Ergonomic Wrist Support Pad, Soft Memory Foam Arm Cushion for Desk, Palm Hand Office Laptop Typing
  • 【Softer and More Comfortable】Vaydeer wrist rest has unique diamond pattern, which is the combination of softness and aesthetics. The materials of wrist rest are improved into higher quality memory foam and covered with silky smooth lycra. The computer wrist rest makes you as comfortable and cushiony as like rest your wrists on clouds.
  • 【Ergonomic Wrist Saver】The wrist rests for keyboard and mouse comes with a 17.32×3.15×0.83 inch keyboard wrist pad and a 5.94×3.15×0.83 inch mouse wrist support. Based on ergonomic design, the unique concave shape is the perfect fit for your wrist joints. The wrist rest pad fits most computer keyboards and laptops, improve hand and wrist posture, release your wrist and arm stress.
  • 【Non-Slip Rubber Bottom】Featuring an anti-skid silicone base on the bottom, this wrist keyboard support stays firmly in place on your desk, preventing the padding from sliding around, ensuring stable and consistent wrist support during extended computer sessions.
  • 【Better Experience & Pain Relief】Our keyboard arm rest is beneficial to alleviate the soreness caused by direct contact and friction between your arm and a hard desk surface, reducing the risk of wrist fatigue or carpal tunnel. The soft texture of memory foam can evenly distribute the pressure around your wrists and provide good support with just enough give.
  • 【Helpful in Multiple Scenarios】Whether you're working, studying, writing, typing, gaming, this keyboard and mouse rest combo is an essential accessory to add comfort and support to your hands and wrists. It’s also a great gift for men, women, family, friend, coworker, gamer, teacher, etc.

Inspect the certificate and name presented on port 443:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
openssl s_client -connect example.com:443 -servername example.com 

Confirm that the certificate chain is complete, the subject or SAN covers the hostname, and the expiration date is not unexpectedly close. A browser warning often means the name, chain, or served certificate differs from the one you intended to install.

Log in through HTTPS and inspect the response cookies in browser developer tools. Session and CSRF cookies should carry the Secure attribute. Submit a CSRF-protected form, test password reset, and exercise any API client that sends an Origin header. Check pages with static CSS, JavaScript, images, and uploaded media: an HTTPS page cannot make an http:// subresource secure, so update absolute URLs in templates, settings, JavaScript, and stored content.

Run Django’s deployment checks with the same production settings used by the service:

python manage.py check --deploy --settings=myproject.settings.production

Resolve warnings about hosts, cookies, redirects, or security middleware rather than hiding them. Also verify that the application sees requests as secure in its logs and that URL generation does not downgrade links to HTTP.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Automatic renewal and post-renewal reloads

Certificate issuance is only the first step. Confirm that the Certbot timer or another ACME scheduler is installed and active:

systemctl list-timers | grep -i certbot
sudo systemctl status certbot.timer

Use the client’s safe renewal test to exercise the account, challenge, and deployment path:

sudo certbot renew --dry-run

A successful renewal must be followed by an Nginx reload so workers stop serving the old certificate. If your installation does not already provide a deploy hook, configure one appropriate to your service, for example:

sudo certbot renew --deploy-hook "systemctl reload nginx"

Confirm the hook is actually used by the scheduled job, and test it during a maintenance window. After a real renewal, inspect the certificate served externally rather than assuming the files on disk are active. Keep the previous Nginx configuration so a failed hook or malformed change can be rolled back.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting the common failures

Infinite redirect loop

This usually means Django cannot see the proxy’s HTTPS signal, or Nginx sends X-Forwarded-Proto https on requests that arrived over plain HTTP. Check that the HTTPS server block sets the header, the HTTP block does not, and SECURE_PROXY_SSL_HEADER matches the exact header name and value. Check every proxy hop if a provider edge sits in front of Nginx. Do not disable redirects before correcting the trust boundary.

Login or CSRF failures after enabling HTTPS

Verify SESSION_COOKIE_SECURE and CSRF_COOKIE_SECURE, then check CSRF_TRUSTED_ORIGINS for the exact HTTPS origins used by forms and clients. Confirm that Nginx preserves the host and that users are not switching between apex and www during a session. Proxy-header mistakes can affect Django’s CSRF protection as well as redirect detection.

ACME challenge failure

Recheck A and AAAA records, port 80 reachability from the public internet, both firewall layers, and Nginx server-block ordering. Another virtual host may intercept /.well-known/acme-challenge/. A standalone client cannot bind port 80 while another process owns it. If HTTP-01 cannot reach the VPS by design, select DNS-01 with a DNS provider integration that you can secure and operate.

Best Value
Sale
Under Desk Cable Management Tray No Drill, Metal Mesh Cable Management Under Desk with Clamp Mount, 2 Hole Cable Tray with Wire Management and Cord Organizer for Home Office Standing Desk
  • 【No Drill Mounted】Cable management tray can be assembled in as little as 3 minutes or less-simply. Side clips easily clampe the edge of desk, pass through the holes on the sides, and secure excess cables with baskets. Desk cable management supports inward or outward installation to meet your needs in different scenarios, and provides you with great convenience when collecting and organizing wires.
  • 【Rubber Pad Protects Desk】Wire organizer under desk built-in soft rubber pads on the clamp protect your desk from scratches, so you will not damage your furniture or office.
  • 【Sturdy and Beautiful】Cord management under desk is made of high-quality carbon steel and holds about 15 lbs. The wire basket has 2 holes on each side of the tray to enable your cables to pass freely. Cable baskets are suitable for desk thickness use from 0.4" to 2.4".
  • 【Space Saving & Keep Organized】Desk cable management tray holds all your power cords, outlet strips, USB hubs and computer transformers hidden from your feet, and the data cables will not enter the vacuum cleaner to keep your desk clean and tidy. Desk wire organizer is also suitable for use in the kitchen and outdoors.
  • 【Reduce Safety Risks】Cable tray under desk keeps all plugs away from your kids, no more worry about tripping. Using 2 holes wire tray saves extra space, helps you easily cabling and wire protection. The mesh design is not easy to accumulate dust, but avoids safety accidents caused by messy wires.

Mixed-content warnings

Search templates, JavaScript, CSS, environment variables, and stored HTML for absolute http:// URLs. Update canonical URLs, callback URLs, asset hosts, and API endpoints to HTTPS. Redirecting the top-level page does not rewrite embedded resources.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The renewed certificate is not being served

Check the files linked under /etc/letsencrypt/live/, then inspect the certificate actually returned on port 443 with the hostname supplied via SNI. Verify the renewal deploy hook or timer ran and that Nginx reloaded successfully. A second Nginx instance, a load balancer, or an overlooked IPv6 listener can still be serving the old certificate.

One address works and another fails

If IPv4 works but some users fail, test the AAAA address and the provider’s IPv6 firewall policy. Remove or correct an AAAA record that points somewhere unable to serve the same certificate and application. Likewise, ensure every hostname listed in DNS is represented in Nginx’s server_name and the certificate request.

Nginx, Caddy, or a managed edge: what to compare

Nginx with Certbot is a transparent choice when you want direct control of the VPS, certificate files, proxy headers, firewall rules, and rollback files. Other arrangements can also work, but compare them on the operational details that affect Django:

  • TLS termination: identify whether encryption ends at the VPS, at another edge, or at both layers.
  • Validation path: confirm which DNS records and ports the ACME challenge reaches, including IPv6 behavior.
  • Renewal and reload: determine who renews the certificate and how the active proxy reloads it without serving stale files.
  • Forwarded headers: ensure the component in front of Django sets and overwrites the scheme and host headers consistently.
  • Cookie and HSTS controls: verify that Django still receives a trustworthy HTTPS signal and that browser policies match all subdomains.
  • Rollback: retain a known-good proxy configuration and understand how to restore it if an automated change breaks routing.
  • Network compatibility: check the VPS provider firewall, security groups, DNS setup, and IPv6 path rather than assuming the alternative handles them for you.

Do not choose based only on a certificate button in a control panel. The complete request path, renewal behavior, and ability to recover from a bad change matter more than where a certificate is requested.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Production checklist

  • DNS A and any AAAA records resolve to the intended VPS.
  • Provider and host firewalls permit TCP 80 and 443.
  • Gunicorn or Uvicorn listens only on the expected socket or localhost port.
  • The private key remains outside the repository and is readable only by the necessary service.
  • Nginx has separate HTTP redirect and HTTPS proxy blocks.
  • The HTTPS block preserves Host, forwards the client chain, and sends a truthful X-Forwarded-Proto.
  • ALLOWED_HOSTS, secure cookies, CSRF trusted origins, and proxy SSL settings match the public URLs.
  • HSTS is enabled only after HTTPS and all required subdomains have been tested.
  • nginx -t passes before every reload, and logs are monitored afterward.
  • HTTP redirects, HTTPS certificates, cookies, CSRF forms, static files, media, and deployment checks have all been tested externally.
  • The renewal timer, dry run, deploy hook, and Nginx reload have been verified.

Frequently Asked Questions

Do I need a separate SSL certificate for each Django hostname?

Request a certificate that covers every hostname users will visit, such as the apex and www names, and configure those names in the same Nginx server block when appropriate. A hostname missing from either the certificate or Nginx configuration will produce a name or routing error.

Why does Django redirect forever after HTTPS is enabled?

Django is usually not receiving a trustworthy indication that the original request used HTTPS, or Nginx is sending X-Forwarded-Proto incorrectly. Set the header only in the TLS server block, make SECURE_PROXY_SSL_HEADER match it, and check every proxy hop before changing redirect settings.

Should I set SECURE_SSL_REDIRECT if Nginx already redirects HTTP?

Nginx should normally perform the redirect for efficiency. Django’s setting can provide an additional control or cover deployments without a front-end redirect, but it depends on correct proxy-header detection. Misconfigured headers can create a loop.

Why do login and CSRF checks fail only after moving to HTTPS?

Check SESSION_COOKIE_SECURE, CSRF_COOKIE_SECURE, exact HTTPS entries in CSRF_TRUSTED_ORIGINS, and consistent apex versus www hostnames. Also verify that the proxy preserves Host and reports the original scheme correctly.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can I use Certbot standalone mode while Nginx is running?

Standalone mode needs to bind port 80, so stop the process occupying that port for the challenge and start it again afterward. If port 80 cannot be reached at all, use a DNS-01 challenge instead.

How can I tell whether renewal is automatic?

Inspect the Certbot systemd timer or cron job, run certbot renew –dry-run, and verify that a successful renewal triggers an Nginx reload. Finally, inspect the certificate actually served on port 443.

Is it safe to put the certificate private key in my Django project?

No. Keep certificate material under the ACME client’s protected directory, grant Nginx only the access it needs, and exclude keys from repositories, image build contexts, and public backups.

Why are CSS or images still blocked after enabling HTTPS?

The page may contain absolute http:// URLs in templates, JavaScript, settings, or stored content. Update those URLs and confirm that static and media locations are served through HTTPS.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Bottom Line

Point DNS to the VPS, open ports 80 and 443, let Nginx terminate TLS, and proxy only to a private Gunicorn or Uvicorn listener. Configure Django to trust a correctly controlled HTTPS header, secure session and CSRF cookies, and use exact production hostnames. Test redirects, certificates, forms, cookies, assets, logs, and deployment checks, then verify that automated renewal reloads Nginx. This arrangement keeps the private key out of Django while making HTTPS an enforceable part of the production path.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.