# ---------------------------------------------------------------------------
# nginx in front of PHP-FPM (production).
#
# Served by the `web` stage of apps/backend/Dockerfile, which bakes in the
# application's public/ directory from the same build as the PHP image.
# ---------------------------------------------------------------------------

server {
    listen 80;
    server_name _;

    root /var/www/html/public;
    index index.php index.html;

    # Must be >= post_max_size (14M) in docker/php/php.ini, but not wildly
    # above it - anything larger is rejected by PHP anyway, after nginx has
    # already buffered the whole body to disk.
    # Was 25M, which silently disagreed with PHP's 8M default.
    client_max_body_size 15M;

    # --- Compression --------------------------------------------------------
    gzip              on;
    gzip_vary         on;
    gzip_proxied      any;
    gzip_comp_level   5;
    gzip_min_length   1024;
    gzip_types        text/plain text/css application/json application/javascript
                      application/xml text/xml image/svg+xml application/rss+xml;

    # --- Uploaded files -----------------------------------------------------
    # Fixes two problems at once.
    #
    # 1. Correctness: uploads live in the `backend_storage` volume, which is now
    #    mounted read-only into this container. Previously nginx only saw the
    #    `backend_app` volume, so /storage/* requests fell through to Laravel,
    #    which matched them against its PRIVATE-disk route (config/filesystems
    #    sets 'serve' => true on the local disk) and returned 404 for want of a
    #    signature. Serving the path directly sidesteps that entirely.
    #
    # 2. Performance: each static file no longer occupies a PHP-FPM worker for
    #    the duration of the transfer.
    #
    # The `^~` modifier is SECURITY-LOAD-BEARING, not stylistic. Without it the
    # regex `location ~ \.php$` below takes precedence over this prefix match,
    # and an uploaded .php file would be executed. Note that TemplateRequest
    # validates uploads with ['file', 'max:10240'] and no MIME restriction.
    location ^~ /storage/ {
        alias /var/www/html/storage/app/public/;
        access_log off;
        expires 7d;
        add_header Cache-Control "public";
        try_files $uri =404;
    }

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

    location ~ \.php$ {
        # Refuse to hand nginx-unresolvable paths to PHP; blocks path-info
        # injection such as /uploads/evil.jpg/x.php
        try_files $uri =404;

        fastcgi_pass  backend:9000;
        fastcgi_index index.php;
        include       fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT   $realpath_root;

        # 90s is deliberately LONGER than request_terminate_timeout (75s) in
        # docker/php/www.conf, so PHP-FPM kills a runaway request first and logs
        # a backtrace, rather than nginx returning 504 while FPM keeps burning
        # the worker for another 15s. Sized for the worst-case outbound path
        # (30s call + 1s sleep + 30s retry).
        fastcgi_read_timeout    90s;
        fastcgi_connect_timeout 5s;
        fastcgi_send_timeout    60s;

        # 512 KB of response buffer. Larger buffers let FPM finish writing and
        # free the worker earlier instead of blocking on a slow client.
        fastcgi_buffer_size       32k;
        fastcgi_buffers        16 32k;
        fastcgi_busy_buffers_size 64k;

        fastcgi_keep_conn on;
    }

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