Skip to main content
HTTPS is essential for production FastAPI applications. Understanding how HTTPS works will help you configure it correctly.

Why HTTPS Matters

HTTPS (HTTP over TLS) provides:
  • Encryption - Protects data in transit from eavesdropping
  • Authentication - Verifies the server’s identity
  • Integrity - Prevents tampering with data
  • Trust - Required by browsers for modern web features
  • SEO - Search engines favor HTTPS sites
Running production APIs without HTTPS exposes sensitive data and user credentials to attackers.

How HTTPS Works

HTTPS is not just “HTTP with encryption enabled”. It’s more complex than that.

Key Concepts

1

Certificates Required

The server needs TLS certificates from a trusted third party (Certificate Authority).
2

Certificates Expire

Certificates have a lifetime (typically 90 days with Let’s Encrypt) and must be renewed.
3

TCP-Level Encryption

Encryption happens at the TCP level, below HTTP. The certificate is used before HTTP communication begins.
4

Domain-Specific

Each certificate is tied to a specific domain name, not an IP address.
5

SNI Extension

Server Name Indication (SNI) allows multiple HTTPS certificates on a single IP address.
For an interactive explanation of HTTPS basics, visit https://howhttps.works/.

TLS Termination Proxy

The standard approach is using a TLS Termination Proxy:
The proxy:
  1. Receives encrypted HTTPS requests
  2. Decrypts them using TLS certificates
  3. Forwards plain HTTP to your FastAPI app
  4. Encrypts responses before sending to client

Why Use a Proxy?

  • Certificate management - Centralized certificate storage and renewal
  • Multiple applications - One proxy can handle HTTPS for many apps
  • Zero downtime - Renew certificates without restarting your app
  • Simplicity - FastAPI app doesn’t need to handle TLS
Your FastAPI application runs plain HTTP internally. The TLS proxy handles all HTTPS complexity.

Let’s Encrypt

Let’s Encrypt provides free, automated TLS certificates.

Benefits

  • Free - No cost for certificates
  • Automated - Automatic issuance and renewal
  • Trusted - Accepted by all major browsers
  • Short-lived - 90-day lifetime improves security
  • Standard - Uses industry-standard cryptography

How It Works

1

Domain Verification

Prove you control the domain (DNS challenge or HTTP challenge).
2

Certificate Issuance

Let’s Encrypt issues a certificate valid for 90 days.
3

Automatic Renewal

Renewal happens automatically before expiration.
Let’s Encrypt certificates are identical in functionality to paid certificates, just with automated issuance.

TLS Termination Proxy Options

Traefik is a modern reverse proxy with automatic HTTPS. docker-compose.yml:
Traefik automatically:
  • Obtains Let’s Encrypt certificates
  • Renews certificates before expiration
  • Routes requests to your application
  • Redirects HTTP to HTTPS
Traefik is the easiest option for Docker-based deployments with automatic certificate management.

Caddy

Caddy automatically enables HTTPS with zero configuration. Caddyfile:
That’s it! Caddy automatically:
  • Obtains certificates from Let’s Encrypt
  • Renews certificates
  • Redirects HTTP to HTTPS
  • Configures secure TLS settings
Docker Compose:
Caddy is the simplest option - HTTPS is automatic with just the domain name in the config.

Nginx with Certbot

Nginx is a popular web server that can act as a reverse proxy. nginx.conf:
docker-compose.yml:
Obtain initial certificate:
Nginx requires more manual configuration than Traefik or Caddy but offers maximum flexibility.

HAProxy

HAProxy is a high-performance load balancer. haproxy.cfg:
Certificate setup:

Proxy Headers Configuration

When behind a proxy, FastAPI needs to know about the original request.

The Problem

Your FastAPI app receives:
  • HTTP requests (not HTTPS)
  • From proxy IP (not client IP)
  • On internal domain (not public domain)

The Solution

Proxies send forwarded headers:
  • X-Forwarded-For - Original client IP
  • X-Forwarded-Proto - Original protocol (https)
  • X-Forwarded-Host - Original host header

FastAPI Configuration

Enable proxy header trust:
Docker Dockerfile:
Only enable --proxy-headers when running behind a trusted proxy. Never enable it for directly exposed applications.

Advanced Proxy Configuration

For specific proxy IPs:
Programmatic configuration:

Cloud Platform HTTPS

Most cloud platforms handle HTTPS automatically.

AWS (Application Load Balancer)

Your FastAPI app:

Google Cloud Run

Cloud Run provides automatic HTTPS:

Azure App Service

App Service includes automatic HTTPS:
Cloud platforms typically handle HTTPS, certificates, and renewal automatically. Your app just needs --proxy-headers.

Kubernetes Ingress

Kubernetes uses Ingress controllers for HTTPS.

With cert-manager

ingress.yaml:
cluster-issuer.yaml:
Apply:
cert-manager automates Let’s Encrypt certificates in Kubernetes, handling both issuance and renewal.

Local Development with HTTPS

For local development, use mkcert for trusted certificates.

Install mkcert

Create Certificates

Use with Uvicorn

Access at: https://localhost:8000
Only use self-signed certificates for development. Production must use certificates from trusted CAs like Let’s Encrypt.

Security Best Practices

Modern TLS Configuration

Nginx example with strong security:

HTTP Strict Transport Security (HSTS)

Force HTTPS for all future requests:
Or configure in proxy:
Enable HSTS after confirming HTTPS works correctly. HSTS is difficult to reverse once enabled.

Troubleshooting

Certificate Not Trusted

Problem: Browser shows “Certificate not trusted” error. Solutions:
  • Verify domain DNS points to your server
  • Check certificate includes correct domain
  • Ensure certificate chain is complete
  • Wait for DNS propagation (up to 48 hours)

Mixed Content Warnings

Problem: HTTPS page loading HTTP resources. Solution: Ensure all resources use HTTPS:

Certificate Renewal Failing

Problem: Let’s Encrypt renewal fails. Solutions:
  • Check port 80 is accessible (HTTP challenge)
  • Verify DNS records are correct
  • Check certbot/Traefik logs
  • Ensure webroot path is correct

Proxy Headers Not Working

Problem: FastAPI sees proxy IP instead of client IP. Solution: Verify both proxy and FastAPI configuration:

Recap

HTTPS for FastAPI involves:
  • TLS Termination Proxy - Handles HTTPS externally (Traefik, Caddy, Nginx)
  • Let’s Encrypt - Free automated certificates
  • Proxy Headers - Enable with --proxy-headers flag
  • Automatic Renewal - Use tools that renew certificates automatically
  • Security Headers - Add HSTS and other security headers
Best approach:
  1. Development: Use mkcert for local HTTPS
  2. Production (Docker): Use Traefik or Caddy for automatic HTTPS
  3. Production (Cloud): Use platform’s built-in HTTPS
  4. Production (Kubernetes): Use Ingress with cert-manager
Start with Traefik or Caddy for the simplest automatic HTTPS setup. Both handle certificates with zero configuration.