# Fileserver front-proxy configuration. # # The application authorizes every download and then hands the transfer to Nginx with # X-Accel-Redirect. Two properties make that safe, and both are enforced here rather than assumed: # # 1. /__files/ is `internal`, so it is reachable ONLY through an internal redirect the application # issued. A direct request from a client returns 404 and never touches the content root. # 2. The application never emits an absolute path. It emits a relative URI below /__files/, and # the alias below is the only place that prefix becomes a filesystem location. # # Keep `alias` in sync with the storage root's content directory. A mismatch is a startup # misconfiguration, not a runtime fallback: the application's startup validator checks that the # internal mapping was proven before it accepts traffic. worker_processes auto; events { worker_connections 4096; } http { include mime.types; default_type application/octet-stream; sendfile on; sendfile_max_chunk 2m; tcp_nopush on; keepalive_timeout 65; # Uploads stream through to the application; buffering a large body to disk here would double # the write and defeat the streaming upload path. proxy_request_buffering off; client_max_body_size 0; server { listen 8080; # Public API. Everything, including download authorization, is decided by the application. location / { proxy_pass http://app:8081; 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; # The application must never see a client-supplied delegation header: it would let a # caller name an arbitrary internal object. proxy_set_header X-Accel-Redirect ""; } # Internal transfer location. Not reachable from outside; see property (1) above. location /__files/ { internal; alias /srv/files/content/; sendfile on; sendfile_max_chunk 2m; # Uploaded content is never trusted to describe itself. add_header X-Content-Type-Options nosniff always; add_header Content-Disposition $upstream_http_content_disposition always; add_header Cache-Control $upstream_http_cache_control always; add_header ETag $upstream_http_etag always; } } }