Files
picpeak/nginx/nginx.conf.example
T
Paul Nothaft d1c582396a fix: enforce gallery access and consolidate gallery workflows
Apply shared session, permission, ownership and lifecycle checks across
gallery access, media grants and session restoration. Validate mutation
origins, pin webhook DNS resolution and redact token-bearing request URLs.

Consolidate gallery creation and queries, extract frontend state hooks,
fix hook ordering and resource cleanup, and repair the fresh event schema.
Update affected dependencies and restore excluded CI suites with regression
and cross-database coverage.
2026-09-08 11:10:03 +02:00

106 lines
3.6 KiB
Plaintext

events {
worker_connections 1024;
}
http {
# Native request error logs contain unredactable bearer URLs.
# Keep safe access statuses here and startup diagnostics at the main level.
error_log /dev/null;
# URLs and Referer can contain gallery, image and customer bearer tokens.
map $uri $request_surface {
~*^/api/(?<picpeak_surface>[a-z-]+)(?:/|$) /api/$picpeak_surface;
default /;
}
log_format picpeak_safe '$remote_addr [$time_local] "$request_method $request_surface" '
'$status $body_bytes_sent $request_time';
access_log /var/log/nginx/access.log picpeak_safe;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
# Gzip compression
gzip on;
gzip_types text/plain text/css text/xml text/javascript application/javascript application/json;
# Rate limiting
limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=auth:10m rate=5r/m;
server {
listen 80;
server_name your-domain.com www.your-domain.com;
# Let's Encrypt challenge
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# Redirect to HTTPS
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl http2;
server_name your-domain.com www.your-domain.com;
# SSL configuration
ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
# Modern SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# API proxy
location /api {
proxy_pass http://backend:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
# Rate limiting for API
limit_req zone=general burst=20 nodelay;
}
# Auth endpoints with stricter rate limiting
location /api/auth {
proxy_pass http://backend:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Strict rate limiting for auth
limit_req zone=auth burst=5 nodelay;
}
# Static files
location / {
proxy_pass http://frontend:80;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
# Security headers for static content
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
proxy_pass http://frontend:80;
expires 1y;
add_header Cache-Control "public, immutable";
}
}
}