# Mnemosyne nginx — single virtual host that fronts the Django web app # and the FastMCP server. HAProxy on Titania terminates TLS and routes by # hostname; this nginx is plain HTTP on the internal network. # Map of upstreams to give us readable proxy_pass targets and easy retries. upstream mnemosyne_web { server web:8000 max_fails=3 fail_timeout=30s; } upstream mnemosyne_mcp { server mcp:22091 max_fails=3 fail_timeout=30s; } server { listen 80 default_server; server_name _; # Reasonable limits — file uploads to the ingest endpoint can be big, # but the bulk path is S3-direct from Daedalus. 64 MB covers admin # uploads and direct REST POST /library/api/items/upload. client_max_body_size 64m; client_body_timeout 120s; # Mnemosyne's REST API — Django REST Framework views + admin. # Under /library/api/* per mnemosyne/urls.py and /admin/* per Django. location /library/ { proxy_pass http://mnemosyne_web; 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; proxy_read_timeout 300s; } location /admin/ { proxy_pass http://mnemosyne_web; 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; proxy_read_timeout 300s; } # FastMCP Streamable HTTP at /mcp/ and SSE at /mcp/sse/. # Long-running streams need disabled buffering and a generous timeout. location /mcp/ { proxy_pass http://mnemosyne_mcp; 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; proxy_set_header Connection ""; proxy_buffering off; proxy_cache off; proxy_read_timeout 600s; } # Static files baked into the image at /app/staticfiles, mounted into # this nginx via a named volume populated by the web service. location /static/ { alias /var/www/static/; access_log off; expires 30d; } # Prometheus scrape endpoint — internal networks only. # Allows: localhost + RFC1918 private ranges (10/8, 172.16/12, 192.168/16). location /metrics { allow 127.0.0.0/8; allow 10.0.0.0/8; allow 172.16.0.0/12; allow 192.168.0.0/16; deny all; proxy_pass http://mnemosyne_web; access_log off; } # Liveness probe — proxies through to the MCP health endpoint. location = /healthz { proxy_pass http://mnemosyne_mcp/mcp/health; access_log off; } }