# casjaysdevdocker/apprise - nginx.conf # Based on upstream caronc/apprise-api/webapp/etc/nginx.conf, adapted to our paths. # Runs in foreground (daemon off) under the start-apprise wrapper. daemon off; worker_processes auto; pid /run/apprise/nginx.pid; error_log /data/logs/apprise/nginx-error.log error; events { worker_connections 4096; } http { # Upstream gunicorn (started by start-apprise) upstream apprise_upstream { server unix:/run/apprise/gunicorn.sock max_fails=0; keepalive 16; } # Basic Settings sendfile on; tcp_nopush on; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; server_tokens off; # Upload Restriction client_max_body_size 500M; # Logging access_log /data/logs/apprise/nginx-access.log; # Centralize tmp paths so a tmpfs mount on /tmp works cleanly client_body_temp_path /tmp/apprise/nginx_client_temp 1 2; proxy_temp_path /tmp/apprise/nginx_proxy_temp 1 2; fastcgi_temp_path /tmp/apprise/nginx_fastcgi_temp 1 2; uwsgi_temp_path /tmp/apprise/nginx_uwsgi_temp 1 2; scgi_temp_path /tmp/apprise/nginx_scgi_temp 1 2; # Gzip gzip on; gzip_proxied any; gzip_vary on; gzip_min_length 1024; gzip_types application/json text/plain text/css application/javascript text/xml application/xml; # Host config client_body_buffer_size 256k; client_body_in_file_only off; # Retry cushions proxy_next_upstream error timeout http_502 http_503 http_504; proxy_next_upstream_tries 2; # Rate limits for /status and /metrics limit_req_zone $binary_remote_addr zone=status:10m rate=5r/s; server { listen 8000; listen [::]:8000; # Error handling proxy_intercept_errors on; error_page 404 = /_/404/; error_page 500 = /_/50x/; error_page 502 503 504 /50x.html; # # 1. Welcome page # location = / { proxy_pass http://apprise_upstream; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Accept-Encoding ""; proxy_set_header Transfer-Encoding ""; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_read_timeout 120s; } # # 2. Stateless notify # location = /notify { proxy_pass http://apprise_upstream; proxy_http_version 1.1; proxy_request_buffering off; proxy_set_header Connection ""; proxy_set_header Accept-Encoding ""; proxy_set_header Transfer-Encoding ""; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Expect $http_expect; client_max_body_size 500M; proxy_read_timeout 300s; proxy_send_timeout 300s; } # # 3. Stateful notify with key # location ~ "^/notify/[\w_-]{1,128}/?$" { proxy_pass http://apprise_upstream; proxy_http_version 1.1; proxy_request_buffering off; proxy_set_header Connection ""; proxy_set_header Accept-Encoding ""; proxy_set_header Transfer-Encoding ""; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Expect $http_expect; client_max_body_size 500M; proxy_read_timeout 300s; proxy_send_timeout 300s; } # # 4. Health check / metrics # location ~ "^/(status|metrics)/?$" { rewrite ^/status/?$ /status/ break; rewrite ^/metrics/$ /metrics break; proxy_pass http://apprise_upstream; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Accept-Encoding ""; proxy_set_header Transfer-Encoding ""; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 1s; proxy_send_timeout 2s; proxy_read_timeout 2s; proxy_buffering off; access_log off; limit_req zone=status burst=10 nodelay; add_header Cache-Control "no-store" always; } # # 5. Service discovery and metadata # location ~ "^/(details|json/urls/[\w_-]{1,128})/?$" { proxy_pass http://apprise_upstream; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Accept-Encoding ""; proxy_set_header Transfer-Encoding ""; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_read_timeout 120s; } # # 6. Config list view: GET /cfg # location = /cfg { proxy_pass http://apprise_upstream; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Accept-Encoding ""; proxy_set_header Transfer-Encoding ""; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_read_timeout 120s; } # # 7. Django Error pages # location /_/ { proxy_intercept_errors off; proxy_pass http://apprise_upstream; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Accept-Encoding ""; proxy_set_header Transfer-Encoding ""; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_read_timeout 120s; access_log off; } # # 8. Config management (HTML UI + API) # location ~ "^/(cfg|add|del|get)/[\w_-]{1,128}/?$" { proxy_pass http://apprise_upstream; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Accept-Encoding ""; proxy_set_header Transfer-Encoding ""; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_read_timeout 300s; } # # 9. Static content (apprise-api ships static files under webapp/static/) # Serve /s/ from the bundled static dir. # location /s/ { alias /usr/local/share/apprise-api/webapp/static/; index index.html; } # # 10. favicon # location = /favicon.ico { alias /usr/local/share/apprise-api/webapp/static/favicon.ico; access_log off; log_not_found off; } # # 11. robots.txt # location = /robots.txt { access_log off; log_not_found off; default_type text/plain; return 200 "User-agent: *\nDisallow: /\n"; } # # 12. Catch-all # location / { proxy_pass http://apprise_upstream; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header Accept-Encoding ""; proxy_set_header Transfer-Encoding ""; proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # Optional user-supplied location overrides include /config/apprise/conf.d/*.conf; } }