check / check (push) Waiting to run
With TRUSTED_PROXIES unset, bin/entrypoint.sh gives nginx one set_real_ip_from line for each of 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16, as sneak ruled on 2026-09-22 for every app. A list replaces them, and set and empty trusts no proxy; each entry is checked as before. The backend inside the container still trusts only 127.0.0.1/32. README.md, configs/nginx.conf and the comment in script/frontend-viewport-test say the new default. Model: opus-5-5
79 lines
2.8 KiB
Nginx Configuration File
79 lines
2.8 KiB
Nginx Configuration File
# A template: the nginx image renders it into conf.d at container start,
|
|
# filling in PORT and nothing else. bin/entrypoint.sh sets PORT and that
|
|
# limit.
|
|
server {
|
|
listen ${PORT};
|
|
server_name _;
|
|
|
|
# Keep the nginx version out of the Server header and error pages.
|
|
server_tokens off;
|
|
|
|
# The security headers, on every response. An add_header in a
|
|
# location drops every add_header from here, so a location with one
|
|
# of its own includes this file again.
|
|
include /etc/nginx/security-headers.conf;
|
|
|
|
root /usr/share/nginx/html;
|
|
index index.html;
|
|
|
|
# The client address comes from X-Forwarded-For only on a request
|
|
# from the reverse proxies in TRUSTED_PROXIES: bin/entrypoint.sh
|
|
# writes one set_real_ip_from line for each into this file. Unset,
|
|
# TRUSTED_PROXIES is the three private ranges of RFC 1918; set and
|
|
# empty, the file is empty and the client address is the one each
|
|
# request comes from.
|
|
include /etc/nginx/trusted-proxies.conf;
|
|
real_ip_header X-Forwarded-For;
|
|
real_ip_recursive on;
|
|
|
|
# Access log to stdout (Docker best practice)
|
|
access_log /dev/stdout combined;
|
|
error_log /dev/stderr warn;
|
|
|
|
location / {
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
|
|
# Cache static assets aggressively
|
|
location /assets/ {
|
|
expires 1y;
|
|
add_header Cache-Control "public, immutable";
|
|
include /etc/nginx/security-headers.conf;
|
|
}
|
|
|
|
# netwatch-server, the Go backend, runs in the same container and
|
|
# listens on loopback only: bin/entrypoint.sh starts it on
|
|
# 127.0.0.1:8081. These headers go with every request passed to it.
|
|
# X-Forwarded-For carries only the client address, as resolved by
|
|
# the real IP settings above, and not the chain the request came
|
|
# with: the backend takes the first entry, which a client can write.
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $remote_addr;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
|
|
# netwatch-server sets the same security headers on its own
|
|
# responses. Its copies are dropped so that each header goes out
|
|
# once, as configs/security-headers.conf sets it.
|
|
proxy_hide_header Strict-Transport-Security;
|
|
proxy_hide_header Content-Security-Policy;
|
|
proxy_hide_header X-Frame-Options;
|
|
proxy_hide_header X-Content-Type-Options;
|
|
proxy_hide_header Referrer-Policy;
|
|
proxy_hide_header Permissions-Policy;
|
|
|
|
location /api/ {
|
|
proxy_pass http://127.0.0.1:8081;
|
|
}
|
|
|
|
location = /.well-known/healthcheck {
|
|
proxy_pass http://127.0.0.1:8081;
|
|
}
|
|
|
|
# The backend's Prometheus metrics, behind its own basic auth. Unless
|
|
# METRICS_USERNAME and METRICS_PASSWORD are set, it answers 404.
|
|
location = /metrics {
|
|
proxy_pass http://127.0.0.1:8081;
|
|
}
|
|
}
|