69 lines
2.6 KiB
Caddyfile
69 lines
2.6 KiB
Caddyfile
# ═══════════════════════════════════════════════════════
|
|
# Jool International — Caddyfile PRODUCTION
|
|
# Domaine : jool-international.com
|
|
# Caddy gère automatiquement HTTPS via Let's Encrypt
|
|
# ═══════════════════════════════════════════════════════
|
|
|
|
# Redirection www → non-www
|
|
www.jool-international.com {
|
|
redir https://jool-international.com{uri} permanent
|
|
}
|
|
|
|
jool-international.com {
|
|
|
|
# ── Fichiers statiques Django (WhiteNoise les sert aussi,
|
|
# mais Caddy est plus rapide pour les assets lourds) ──
|
|
handle_path /static/* {
|
|
root * /app/staticfiles
|
|
file_server
|
|
header Cache-Control "public, max-age=31536000, immutable"
|
|
}
|
|
|
|
# ── CVs uploadés : jamais accessibles publiquement ───
|
|
handle /media/careers/cvs/* {
|
|
respond 404
|
|
}
|
|
|
|
# ── Autres fichiers media ─────────────────────────────
|
|
handle_path /media/* {
|
|
root * /app/media
|
|
file_server
|
|
header Cache-Control "public, max-age=604800"
|
|
}
|
|
|
|
# ── Application Django (Gunicorn) ─────────────────────
|
|
handle {
|
|
reverse_proxy web:8000 {
|
|
header_up X-Forwarded-Proto {scheme}
|
|
header_up X-Real-IP {remote_host}
|
|
transport http {
|
|
read_timeout 60s
|
|
write_timeout 60s
|
|
}
|
|
}
|
|
}
|
|
|
|
# ── En-têtes de sécurité ──────────────────────────────
|
|
header {
|
|
# HSTS — commencer à 1h, passer à 1 an après validation
|
|
Strict-Transport-Security "max-age=3600; includeSubDomains"
|
|
X-Content-Type-Options "nosniff"
|
|
X-Frame-Options "DENY"
|
|
Referrer-Policy "strict-origin-when-cross-origin"
|
|
Permissions-Policy "camera=(), microphone=(), geolocation=()"
|
|
# Masquer la signature du serveur
|
|
-Server
|
|
-X-Powered-By
|
|
}
|
|
|
|
# ── Logs ──────────────────────────────────────────────
|
|
log {
|
|
output stdout
|
|
format json
|
|
level WARN
|
|
}
|
|
|
|
# ── Encodage gzip/zstd automatique ───────────────────
|
|
encode zstd gzip
|
|
}
|