DNS & TLS
Production deployments need a real hostname and a real TLS certificate. This page covers DNS records, certificate issuance, and renewal.
DNS records
Minimum: one A record. Example for a host serving from 192.0.2.10:
files.example.com. A 192.0.2.10
# Optional: www / docs / api subdomains pointing to the same IP
www.files.example.com. CNAME files.example.com.
TLS certificate (Let's Encrypt)
HTTP-01 with certbot + nginx (simplest)
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d files.example.com
# certbot edits your nginx config to add SSL + sets up auto-renewal
DNS-01 with Route 53 (cleaner — no port :80 required)
sudo apt install python3-certbot-dns-route53
# AWS creds with route53:ChangeResourceRecordSets at /root/.aws/credentials
sudo certbot certonly --dns-route53 -d files.example.com \
--non-interactive --agree-tos --register-unsafely-without-email
DNS-01 with Cloudflare
sudo apt install python3-certbot-dns-cloudflare
# API token with Zone.DNS:Edit at /etc/letsencrypt/cloudflare.ini (mode 600)
sudo certbot certonly --dns-cloudflare \
--dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
-d files.example.com
All three methods set up a renewal timer automatically.
Behind a CDN / proxy
You can put Cloudflare or another CDN in front of SpeedyFiles, but be aware:
- Cloudflare has a 100 MB upload limit on free plans. Disable proxying (gray cloud) on the SpeedyFiles hostname, or use Cloudflare Enterprise for higher limits.
- Set
X-Forwarded-Forvia your CDN so audit logs show real client IPs. - Trust forwarded headers on the uvicorn side — we already pass
--forwarded-allow-ips 127.0.0.1; add your CDN's IPs if it's not localhost.
Self-signed for local-only deployments
If you only need it for internal use:
openssl req -x509 -newkey rsa:2048 -days 365 -nodes \
-keyout /etc/ssl/private/speedyfiles.key \
-out /etc/ssl/certs/speedyfiles.crt \
-subj "/CN=files.lan"
# Add CA to client trust stores manually
HSTS & security headers
The bundled nginx config sets:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "DENY" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; ..." always;
Only enable HSTS once you're confident TLS is permanent — it's hard to undo for a year.