Dotfile location moved above caching regex locations (first match wins). application/pdf out of gzip_types (already flate-compressed). Compose healthcheck block removed — image HEALTHCHECK is the single source, inherited. Oracles: nginx -t, dotfiles 404, PDF no Content-Encoding, HTML still gzipped, headers 5/5, inherited health = healthy.
76 lines
2.4 KiB
Nginx Configuration File
76 lines
2.4 KiB
Nginx Configuration File
# nginx server block for bchanot.fr static site.
|
|
# Container (nginx-unprivileged) listens on 8080; host port is configured via
|
|
# docker-compose (PORT env var). A host-level reverse proxy (nginx, Traefik,
|
|
# Caddy) should terminate TLS and proxy_pass to http://127.0.0.1:${PORT}.
|
|
|
|
server {
|
|
listen 8080;
|
|
listen [::]:8080;
|
|
server_name _;
|
|
|
|
root /usr/share/nginx/html;
|
|
index index.html;
|
|
|
|
# Don't advertise the nginx version.
|
|
server_tokens off;
|
|
|
|
# Security headers — shared snippet. Re-included in every location that
|
|
# sets its own add_header (inheritance is all-or-nothing in nginx).
|
|
include /etc/nginx/snippets/security-headers.conf;
|
|
|
|
# Forwarded headers — trust only the local reverse proxy (the container
|
|
# port is bound to 127.0.0.1 in docker-compose).
|
|
real_ip_header X-Forwarded-For;
|
|
set_real_ip_from 127.0.0.1;
|
|
|
|
# Compression.
|
|
gzip on;
|
|
gzip_vary on;
|
|
gzip_min_length 1024;
|
|
gzip_proxied any;
|
|
gzip_comp_level 6;
|
|
gzip_types
|
|
text/plain
|
|
text/css
|
|
text/javascript
|
|
application/javascript
|
|
application/json
|
|
application/xml
|
|
image/svg+xml;
|
|
|
|
# Block access to dotfiles (defense-in-depth — none are shipped anyway).
|
|
# First regex location wins: keep this above the caching regex blocks so
|
|
# a hypothetical /.foo.html can't be served by them.
|
|
location ~ /\. {
|
|
return 404;
|
|
}
|
|
|
|
# Long cache for the PDF (regenerated rarely, content-hash not used).
|
|
location ~* \.pdf$ {
|
|
add_header Cache-Control "public, max-age=604800";
|
|
include /etc/nginx/snippets/security-headers.conf;
|
|
}
|
|
|
|
# Short cache for HTML so content updates land fast.
|
|
location ~* \.html$ {
|
|
add_header Cache-Control "public, max-age=3600, must-revalidate";
|
|
include /etc/nginx/snippets/security-headers.conf;
|
|
}
|
|
|
|
# Long cache for favicon + image assets (rarely change).
|
|
location ~* \.(?:ico|svg|png|jpg|jpeg|gif|webp)$ {
|
|
add_header Cache-Control "public, max-age=2592000, immutable";
|
|
include /etc/nginx/snippets/security-headers.conf;
|
|
access_log off;
|
|
}
|
|
|
|
# Logs to stdout/stderr (default in nginx images).
|
|
access_log /var/log/nginx/access.log;
|
|
error_log /var/log/nginx/error.log warn;
|
|
|
|
# Default: serve files, fall back to 404.
|
|
location / {
|
|
try_files $uri $uri/ =404;
|
|
}
|
|
}
|