Join PromCon EU 2026 , the Prometheus users conference, on October 7–8, 2026 in Munich. The Call for Speakers  is open until July 19, 2026.
PromCon EU 2026  — Oct 7–8, Munich. CFP  open until July 19.

Running Prometheus behind a reverse proxy

Prometheus is often placed behind a reverse proxy (nginx, Caddy, Traefik, Apache, etc.) for TLS termination, path prefixes, or access control. This guide covers common settings that keep the UI and HTTP API working correctly.

NOTE: Reverse proxies do not replace network isolation. Treat Prometheus HTTP endpoints as sensitive (see the security model). Do not expose them on the public internet without authentication and careful rate limiting.

External URL

If the proxy serves Prometheus under a public hostname or URL prefix, set --web.external-url to that public base URL (including path prefix if any). This is used for generated links, redirects, and the expression browser.

Example when the UI is at https://monitoring.example.com/prometheus/:

prometheus \
  --config.file=/etc/prometheus/prometheus.yml \
  --web.external-url=https://monitoring.example.com/prometheus/ \
  --web.route-prefix=/

When using a path prefix, also configure the proxy to strip or forward that prefix consistently with --web.route-prefix (see Prometheus command-line docs for the combination that matches your setup).

Headers to forward

Proxies should pass through at least:

HeaderPurpose
HostOriginal host as seen by clients (or the public hostname you intend Prometheus to see)
X-Forwarded-Protohttps when TLS is terminated at the proxy so redirects stay on HTTPS
X-Forwarded-For / X-Real-IPClient IP for logs and any IP-based logic (optional but useful)

Example nginx location (TLS terminated on nginx, Prometheus on localhost):

location /prometheus/ {
  proxy_pass http://127.0.0.1:9090/;
  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;
}

With this layout, a typical external URL is https://monitoring.example.com/prometheus/.

Example Caddy:

monitoring.example.com {
  handle_path /prometheus/* {
    reverse_proxy 127.0.0.1:9090
  }
}

(handle_path strips the /prometheus prefix before proxying; align --web.external-url accordingly.)

Web lifecycle and admin APIs

If you enable --web.enable-lifecycle or --web.enable-admin-api, the proxy path to /-/reload, /-/quit, and /api/*/admin/ becomes especially sensitive. Prefer restricting those paths at the proxy (IP allowlist, mTLS, or separate internal listener) rather than exposing them to every user who can open the UI.

On this page