> For the complete documentation index, see [llms.txt](https://docs.portainer.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.portainer.io/sts/advanced/reverse-proxy.md).

# 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: https` or `Forwarded: proto=https` header
* The [Force secure cookies setting](/sts/admin/settings/general.md#force-secure-cookies) 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.

{% hint style="info" %}
A common misconfiguration is a setup where the browser connects to the proxy over HTTP on port 80, but the proxy forwards to Portainer over HTTPS on port 9443. In this case, Portainer sets `Secure` cookies, the browser discards them, and login fails.
{% endhint %}

### 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`:

<pre class="language-nginx" data-title="nginx"><code class="lang-nginx"><strong>proxy_set_header Host $http_host;
</strong></code></pre>

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.com
```

Trusted origins can also include custom ports and IP addresses:

```
--trusted-origins https://portainer.yourdomain.com:9443
```

### Recommended forwarded headers

Set the following headers in your proxy configuration to ensure Portainer correctly detects the connection scheme:

```
X-Forwarded-Proto: http   # or https, matching the browser-facing scheme
Host: $http_host
```

### 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`.

{% hint style="warning" %}
Disabling CSP reduces your security posture. Only do this if your deployment specifically requires iframe embedding, and ensure other controls are in place.&#x20;
{% endhint %}

## Reverse proxy guides

We have guides to walk you through deploying Portainer behind a proxy for Traefik and nginx:

{% content-ref url="/pages/-MjfiPhBr46KPbuBBkPd" %}
[Deploying Portainer behind Traefik Proxy](/sts/advanced/reverse-proxy/traefik.md)
{% endcontent-ref %}

{% content-ref url="/pages/-MjfiSyBAn9stimm0BA3" %}
[Deploying Portainer behind nginx reverse proxy](/sts/advanced/reverse-proxy/nginx.md)
{% endcontent-ref %}
