Reverse Proxy & TLS
Automatic HTTPS Caddy Traefik
In production and homelab environments, placing an edge reverse proxy in front of CloudRader containers provides automatic SSL/TLS certificate generation, subdomain routing, and unified ingress security.
Why Use a Reverse Proxy?
-
Automatic HTTPS
Automatically obtain and renew free Let\'s Encrypt or ZeroSSL TLS certificates with zero manual intervention.
-
Subdomain Routing
Map friendly domain names (
reservium.example.com,auth.example.com) to internal container ports on ports 80 and 443. -
Port Isolation
Keep internal database and application ports (5432, 8000, 8080) hidden from the public internet.
-
Compression & Performance
Enable modern HTTP/2, HTTP/3, and Gzip/Zstandard compression on all outbound web requests.
Recommended Option: Caddy
Caddy is the recommended reverse proxy for CloudRader self-hosters due to its clean syntax and zero-configuration HTTPS automation.
1. Example Caddyfile
Create a Caddyfile alongside your compose.yaml:
# ==============================================================================
# CloudRader Reference Caddyfile
# ==============================================================================
# Identity Provider (Keycloak Reference)
auth.example.com {
reverse_proxy keycloak:8080 {
header_up X-Forwarded-Proto https
header_up X-Forwarded-Host {host}
header_up X-Forwarded-Port 443
}
}
# Reservium Web User Interface
reservium.example.com {
reverse_proxy reservium-ui:80
}
# Reservium REST API
api.reservium.example.com {
reverse_proxy reservium-api:8000
}
# Inventarium REST API
api.inventarium.example.com {
reverse_proxy inventarium-api:8080
}
# Central Documentation Portal
docs.example.com {
reverse_proxy docs:8000
}
2. Adding Caddy to Docker Compose
Add the Caddy service to your compose.yaml:
services:
caddy:
image: caddy:2-alpine
container_name: cloudrader-caddy
restart: unless-stopped
ports:
- "80:80"
- "443:443"
- "443:443/udp" # HTTP/3 Support
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
networks:
- cloudrader-net
volumes:
caddy_data:
caddy_config:
Alternative: Traefik
If your infrastructure uses Traefik, attach routing labels directly to your service definitions in compose.yaml:
services:
reservium-ui:
labels:
- "traefik.enable=true"
- "traefik.http.routers.reservium.rule=Host(`reservium.example.com`)"
- "traefik.http.routers.reservium.entrypoints=websecure"
- "traefik.http.routers.reservium.tls.certresolver=letsencrypt"
reservium-api:
labels:
- "traefik.enable=true"
- "traefik.http.routers.reservium-api.rule=Host(`api.reservium.example.com`)"
- "traefik.http.routers.reservium-api.entrypoints=websecure"
- "traefik.http.routers.reservium-api.tls.certresolver=letsencrypt"
inventarium-api:
labels:
- "traefik.enable=true"
- "traefik.http.routers.inventarium-api.rule=Host(`api.inventarium.example.com`)"
- "traefik.http.routers.inventarium-api.entrypoints=websecure"
- "traefik.http.routers.inventarium-api.tls.certresolver=letsencrypt"
Important Proxy Headers
Identity providers (such as Keycloak) and FastAPI require accurate proxy headers to prevent redirect loops and CORS failures:
| Header | Required Value | Purpose |
|---|---|---|
X-Forwarded-Proto |
https |
Informs backend services that the client connection is encrypted. |
X-Forwarded-Host |
{host} (e.g., auth.example.com) |
Preserves the client-requested hostname for OAuth2 redirect generation. |
X-Forwarded-For |
{remote_host} |
Passes client IP address for security logging and rate-limiting. |
X-Forwarded-Port |
443 |
Confirms default HTTPS port for callback validation. |
Pre-Flight DNS & Firewall Checklist
Before starting your reverse proxy:
- DNS Records: Create
A(orAAAA) records for all desired subdomains (auth.example.com,reservium.example.com) pointing to your server\'s public IP. - Port Forwarding: Ensure ports 80 (HTTP verification) and 443 (HTTPS traffic) are open on your router, firewall, or cloud security group.
- Verify Certificate: Once Caddy starts, test certificate issuance in your browser or with:
curl -I https://reservium.example.com