# nginx för imagesbyolofsson.se (Docker-image: dist/ i /usr/share/nginx/html). # Bygget använder build.format "file": /about -> about.html, 404 -> 404.html. # Samma regler som Caddy-varianten i deploy/caddy-site.snippet. # Cache-Control per sökväg (inte per Content-Type, så att /_astro/*.jpg också blir immutable). map $uri $ibo_cache_control { default "public, max-age=0, must-revalidate"; ~^/_astro/ "public, max-age=31536000, immutable"; ~*\.(?:jpe?g|png|webp|avif|gif|svg|ico|woff2?|ttf|otf)$ "public, max-age=2592000"; ~*\.(?:xml|txt)$ "public, max-age=3600"; } # www -> apex (om www-trafik når den här containern). server { listen 80; server_name www.imagesbyolofsson.se; return 301 https://imagesbyolofsson.se$request_uri; } server { listen 80 default_server; server_name _; root /usr/share/nginx/html; index index.html; # Relativa Location-headers: bakom Cloudflare/proxy blir det aldrig http://host:80/... absolute_redirect off; server_tokens off; # Säkerhetsheaders. OBS: inga add_header i location-blocken nedan, annars ärvs inte dessa. # CSP: tillåter Meta Pixel (connect.facebook.net/facebook.com, laddas först efter samtycke), # den anonyma statistiken (sendBeacon till customer.imagesbyolofsson.se) och Cloudflares # egna skript (/cdn-cgi, ev. Web Analytics). 'unsafe-inline' behövs för samtyckesskriptet # och Astros inlinade skript/stilar; byt mot hashar (Astro experimental.csp) i ett senare steg. add_header Strict-Transport-Security "max-age=31536000" always; add_header X-Content-Type-Options "nosniff" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header Referrer-Policy "strict-origin-when-cross-origin" always; add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=()" always; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://connect.facebook.net https://static.cloudflareinsights.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https://www.facebook.com https://*.facebook.com; font-src 'self' data:; connect-src 'self' https://customer.imagesbyolofsson.se https://www.facebook.com https://*.facebook.com https://connect.facebook.net https://cloudflareinsights.com; frame-src https://www.facebook.com; frame-ancestors 'self'; base-uri 'self'; form-action 'self'; object-src 'none'; upgrade-insecure-requests" always; add_header Cache-Control $ibo_cache_control always; # Gamla indexerade adresser -> närmaste nya sida. location ~ ^/(?:my-people|animales-and-nature|celebrations-with-family|northen-lights)/?$ { return 301 /portfolio; } # /index.html och /about.html -> rena URL:er (bara externa anrop; try_files nedan # serverar filerna internt utan att gå hit). location = /index.html { return 301 /; } location ~ ^(?/.+)\.html$ { return 301 $ibo_noext$is_args$args; } # Inga dubbletter med avslutande snedstreck: /about/ -> /about. location ~ ^(?/.+)/$ { return 301 $ibo_noslash$is_args$args; } # Startsidan serveras direkt (ingen intern omdirigering till /index.html). location = / { try_files /index.html =404; } # Hashade Astro-filer: cachas ett år (immutable sätts via map ovan). location ^~ /_astro/ { access_log off; try_files $uri =404; } # Originalnedladdning (/download/original) proxas till Immich någon annanstans # (Cloudflare/Caddy). Finns den regeln i den här nginx: lägg den här ovanför. location / { try_files $uri $uri.html =404; } # Riktig 404: 404.html med status 404 (inte startsidan med 200). error_page 404 /404.html; location = /404.html { internal; } gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml application/xml application/json application/javascript application/xml+rss image/svg+xml; }