Files
tech-log-backend/infra/fileserver/nginx/nginx.conf
T
DongHyeonkaandClaude Opus 5 5f10b791d3 chore: record pre-existing uncommitted repository state
Snapshot of the in-flight state that already existed, identically, in both
this worktree and the main checkout before this session began: the initial
HTTP Client platform implementation (previously untracked), the redis-lab
removal, and the JPA / object-storage / notification integration work.

Kept separate from this session's HTTP Client review response, which lands
in the following commit, so the two bodies of work stay reviewable apart.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 16:48:43 +09:00

68 lines
2.6 KiB
Nginx Configuration File

# 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;
}
}
}