Using Portainer with reverse proxies
When running Portainer behind a reverse proxy, several security behaviours can interact with your proxy configuration in ways that may not be immediately obvious. Review the sections below before deploying.
Auth cookies and scheme detection
Portainer sets the Secure flag on authentication cookies when it believes the connection is using HTTPS. This is triggered when any of the following are true:
Portainer itself is serving over TLS (
:9443)The proxy sends an
X-Forwarded-Proto: httpsorForwarded: proto=httpsheaderThe Force secure cookies setting is enabled in Portainer
A Secure cookie is silently dropped by the browser if the browser-to-proxy connection is plain HTTP. This causes users to be immediately logged out or unable to log in, with a 401 response.
The proxy must make Portainer's view of the connection scheme match what the browser is actually using. If the browser connects to the proxy over HTTP, do not forward X-Forwarded-Proto: https to Portainer, and do not connect to Portainer over TLS unless you also upgrade the browser-facing connection to HTTPS.
CSRF protection and host forwarding
CSRF protection is always enabled. Portainer uses Go's cross-origin protection, which primarily checks the Sec-Fetch-Site header (supported by all major browsers since 2023). For older browsers, it falls back to comparing the hostname in the Origin header against the Host header. Requests without either header are assumed to be same-origin or non-browser requests and are allowed. If the headers are present but don't match, the request is rejected with a 403.
When configuring your proxy, forward the full host as the browser sent it, including any non-standard port. In nginx, use $http_host rather than $host:
proxy_set_header Host $http_host;If your public-facing origin cannot be inferred from the forwarded headers, for example, if the proxy rewrites the host, you can explicitly trust an origin using the --trusted-origins flag or the TRUSTED_ORIGINS environment variable:
--trusted-origins https://portainer.yourdomain.com,https://example.comTrusted origins can also include custom ports and IP addresses:
Recommended forwarded headers
Set the following headers in your proxy configuration to ensure Portainer correctly detects the connection scheme:
Content Security Policy
Portainer sends a Content-Security-Policy header by default (controlled by the --csp flag, which is on by default). This header includes frame-ancestors 'none', which means:
Portainer cannot be embedded in an iframe, for example, within a web portal or dashboard.
Proxies that inject or rewrite page content (scripts, headers) will break the Portainer UI.
If you need to embed Portainer in a frame, you will need to disable or customise the CSP header by setting --no-csp.
Authentication logs
To ensure that the correct IP address is displayed in the Origin field of the Authentication logs, we recommend using the --trusted-proxies CLI option and specifying the IP addresses / CIDRs of your proxy. This tells Portainer to read the X-Forwarded-For / Forwarded header in the request and trust it's value as the real source IP address. Without this set, the Origin field will contain your proxy's IP address rather than the true source.
Reverse proxy guides
We have guides to walk you through deploying Portainer behind a proxy for Traefik and nginx:
Deploying Portainer behind Traefik ProxyDeploying Portainer behind nginx reverse proxyLast updated
Was this helpful?