Files
mnemosyne/nginx/mnemosyne.conf
Robert Helewka 72bd4b381d
All checks were successful
CVE Scan & Docker Build / security-scan (push) Successful in 50s
CVE Scan & Docker Build / build-and-push (push) Successful in 56s
Port number adjustments
2026-05-03 19:56:01 -04:00

128 lines
4.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
# Suppress probe paths from the access log (health checks, Prometheus scrapes).
# These fire every 1530 s and would drown out real traffic in Loki.
map $request_uri $loggable {
default 1;
~^/live(/|\?|$) 0;
~^/ready(/|\?|$) 0;
~^/metrics(/|\?|$) 0;
~^/healthz(/|\?|$) 0;
~^/health 0;
~^/mcp/health(/|\?|$) 0;
~^/ping(/|\?|$) 0;
}
# Map of upstreams to give us readable proxy_pass targets and easy retries.
upstream mnemosyne_app {
server app:8000 max_fails=3 fail_timeout=30s;
}
upstream mnemosyne_mcp {
server mcp:8001 max_fails=3 fail_timeout=30s;
}
server {
listen 80 default_server;
server_name _;
access_log /var/log/nginx/access.log combined if=$loggable;
# 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;
# Liveness probe — always 200 if the Django process is up.
# Use the trailing-slash form: /live/ returns 200 directly.
# /live (no slash) triggers Django's APPEND_SLASH 301 redirect, which
# will cause health check clients that don't follow redirects to fail.
location = /live/ {
proxy_pass http://mnemosyne_app;
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;
access_log off;
}
# Readiness probe — 200 only when PostgreSQL + Memcached are reachable.
# Same trailing-slash rule applies.
location = /ready/ {
proxy_pass http://mnemosyne_app;
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;
access_log off;
}
# HAProxy liveness probe — proxies through to the MCP health endpoint.
location = /healthz {
proxy_pass http://mnemosyne_mcp/mcp/health;
access_log off;
}
# 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_app;
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_app;
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 app service.
location /static/ {
alias /var/www/static/;
access_log off;
expires 30d;
}
# Prometheus scrape endpoint — internal networks only.
# Allows: loopback + all RFC1918 private ranges.
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_app;
access_log off;
}
}