108 lines
4.0 KiB
Nginx Configuration File
108 lines
4.0 KiB
Nginx Configuration File
# desfoto.de - static site behind the existing VPS Traefik (Docker provider).
|
|
#
|
|
# Truthfulness contract (see /datenschutz/): this server writes no access log,
|
|
# sets no cookies, runs no analytics and loads no third-party assets. YouTube is
|
|
# only embedded after an explicit click (youtube-nocookie.com).
|
|
map $uri $desfoto_cache {
|
|
default "public, max-age=0, must-revalidate";
|
|
~^/assets/img/ "public, max-age=604800, stale-while-revalidate=86400";
|
|
~^/assets/fonts/ "public, max-age=604800, stale-while-revalidate=86400";
|
|
~^/assets/site\.(css|js)$ "public, max-age=0, must-revalidate";
|
|
~^/(favicon\.svg|site\.webmanifest)$ "public, max-age=86400";
|
|
}
|
|
|
|
server {
|
|
listen 80;
|
|
listen [::]:80;
|
|
server_name _;
|
|
|
|
root /usr/share/nginx/html;
|
|
index index.html;
|
|
charset utf-8;
|
|
server_tokens off;
|
|
# Redirects stay relative so they keep the https scheme terminated by Traefik.
|
|
absolute_redirect off;
|
|
|
|
# No stored visitor data: the privacy page promises log-free operation.
|
|
# Access logging is off and error messages are discarded completely, so this
|
|
# server never writes a log file that could contain a visitor IP address.
|
|
access_log off;
|
|
error_log /dev/null crit;
|
|
|
|
etag on;
|
|
gzip on;
|
|
gzip_vary on;
|
|
gzip_comp_level 6;
|
|
gzip_min_length 512;
|
|
gzip_types text/css text/javascript application/javascript application/json application/ld+json application/xml application/manifest+json image/svg+xml;
|
|
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
|
add_header X-Frame-Options "DENY" always;
|
|
add_header Permissions-Policy "camera=(), microphone=(), geolocation=(), interest-cohort=()" always;
|
|
add_header Strict-Transport-Security "max-age=31536000" always;
|
|
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-src https://www.youtube-nocookie.com; object-src 'none'; base-uri 'self'; form-action 'self' mailto:; frame-ancestors 'none'; upgrade-insecure-requests" always;
|
|
add_header Cache-Control $desfoto_cache always;
|
|
|
|
error_page 404 /404.html;
|
|
|
|
location = /404.html {
|
|
internal;
|
|
}
|
|
|
|
location = / {
|
|
try_files /index.html =404;
|
|
}
|
|
|
|
# Keep canonical URLs: no /index.html duplicates in the index. The check uses
|
|
# $request_uri so the internal redirect from the index module (which still
|
|
# carries the original URI) is not caught in a loop.
|
|
if ($request_uri ~ ^/(.*/)?index\.html(\?.*)?$) {
|
|
return 301 /$1;
|
|
}
|
|
|
|
location = /impressum.html { return 301 /impressum/; }
|
|
location = /datenschutz.html { return 301 /datenschutz/; }
|
|
location = /kontakt.html { return 301 /kontakt/; }
|
|
location = /gtin { return 301 /gtin/; }
|
|
location = /gtin/manifest.webmanifest {
|
|
default_type application/manifest+json;
|
|
try_files $uri =404;
|
|
}
|
|
# /fotografie.html used to redirect to /shootings/; it resolves to its own
|
|
# canonical page now instead of turning into a 404.
|
|
location = /fotografie.html { return 301 /fotografie/; }
|
|
|
|
# Fotografie is the umbrella term for the photographic work; the old
|
|
# /shootings/ URL stays reachable and points to the new page.
|
|
# (/fotografie/index.html is already canonicalised to /fotografie/ above.)
|
|
location = /shootings { return 301 /fotografie/; }
|
|
location = /shootings/ { return 301 /fotografie/; }
|
|
location = /shootings.html { return 301 /fotografie/; }
|
|
|
|
# Familie keeps the photographic range that stays with desfoto; the old
|
|
# combined Familien-und-Paare URL points here.
|
|
location = /familien-und-paare { return 301 /familie/; }
|
|
location = /familien-und-paare/ { return 301 /familie/; }
|
|
location = /familien-und-paare.html { return 301 /familie/; }
|
|
|
|
location ^~ /.well-known/ {
|
|
allow all;
|
|
autoindex off;
|
|
types { }
|
|
default_type text/plain;
|
|
}
|
|
|
|
location /assets/ {
|
|
try_files $uri =404;
|
|
}
|
|
|
|
location / {
|
|
try_files $uri $uri/ =404;
|
|
}
|
|
|
|
location ~ /\.(?!well-known/) {
|
|
deny all;
|
|
}
|
|
}
|