server {
    listen 80;

    # Re-resolve the app container on every request (its IP changes when it restarts).
    resolver 127.0.0.11 valid=10s ipv6=off;
    set $php_upstream app:9000;

    server_name _;
    root /var/www/html/public;
    index index.php;
    client_max_body_size 32M;

    # Security headers come from the app (App\Http\Middleware\SecurityHeaders); only static files get nosniff here.

    # Mirrors public/.htaccess on cPanel (mod_deflate + mod_expires), so local Lighthouse runs are realistic.
    gzip on;
    gzip_comp_level 6;
    gzip_min_length 1024;
    gzip_types text/css application/javascript application/json image/svg+xml text/xml application/xml application/rss+xml text/plain;

    # Vite output is content-hashed: cache it for a year.
    location /build/ {
        add_header Cache-Control "public, max-age=31536000, immutable";
        add_header X-Content-Type-Options "nosniff";
        try_files $uri =404;
    }

    # Media library files (storage symlink or public/media on hosts without symlinks).
    location ~ ^/(storage|media)/ {
        add_header Cache-Control "public, max-age=2592000";
        add_header X-Content-Type-Options "nosniff";
        try_files $uri =404;
    }

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location = /favicon.ico { access_log off; log_not_found off; }

    location ~ \.php$ {
        fastcgi_pass $php_upstream;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_hide_header X-Powered-By;
        fastcgi_buffer_size 32k;
        fastcgi_buffers 16 16k;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}
