Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions content/docs/guides/ad-guard.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ description: Put AdGuard Home behind Pomerium for single sign-on, injecting its
# cSpell:ignore adguardhome
---

import CodeBlock from '@theme/CodeBlock';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';

import Config from '/content/examples/guides/ad-guard/config.yaml.md';
import Compose from '/content/examples/guides/ad-guard/docker-compose.yaml.md';
import Config from '!!raw-loader!/content/examples/guides/ad-guard/config.yaml';
import Compose from '!!raw-loader!/content/examples/guides/ad-guard/docker-compose.yaml';
Comment on lines +15 to +16

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Absolute imports break builds

These raw-loader requests use /content/... as the resource path. After the ! separator, webpack treats the leading slash as a filesystem-absolute path, so it looks outside the repository for /content/examples/.... The repository's working raw-loader imports instead use @site/content/... or relative paths. As a result, the migrated guides cannot resolve these modules during MDX compilation. The same pattern appears in all 15 changed guide pages; use @site/content/... for each resource.

Red test proving the current paths do not resolve:

import assert from 'node:assert/strict';
import { existsSync } from 'node:fs';
import test from 'node:test';

const imports = [
  '!!raw-loader!/content/examples/guides/ad-guard/config.yaml',
  '!!raw-loader!/content/examples/guides/ad-guard/docker-compose.yaml',
];

test('raw-loader resource paths resolve', () => {
  for (const request of imports) {
    const resource = request.slice(request.lastIndexOf('!') + 1);
    assert.ok(existsSync(resource), `webpack resource does not exist: ${resource}`);
  }
});

This test is red because /content/examples/guides/ad-guard/config.yaml does not exist at the filesystem root; the retained file is beneath the repository root.

Context Used: For every finding, write a red test with proof and... (source)

Fix in Claude Code Fix in Codex


# Secure AdGuard Home with Pomerium

Expand Down Expand Up @@ -65,7 +66,9 @@ Zero manages the route's TLS certificate behind your starter domain, so there's

Create a `config.yaml`. It routes `adguard.yourdomain.com` to the AdGuard container and injects the basic-auth header on every upstream request.

<Config />
<CodeBlock language="yaml" title="config.yaml">
{Config}
</CodeBlock>

Replace `adguard.yourdomain.com` with your domain, `you@example.com` with your email, and the `Authorization` value with the base64 string from the command above.

Expand All @@ -82,7 +85,9 @@ The username and password you pick here are exactly the credentials you base64-e

The Compose file runs Pomerium Core and AdGuard together. Pomerium publishes ports 80 and 443 for the protected route, and AdGuard publishes only port 53 for DNS; the AdGuard web UI on port 3000 stays on the internal network so it's reachable only through Pomerium. For Zero, drop the `pomerium` service and use the `compose.yaml` from the Quickstart with your `POMERIUM_ZERO_TOKEN`, keeping the `adguard` service below.

<Compose />
<CodeBlock language="yaml" title="docker-compose.yaml">
{Compose}
</CodeBlock>

Start it:

Expand Down
13 changes: 9 additions & 4 deletions content/docs/guides/cockpit.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ keywords:
description: Put Cockpit, the web-based Linux server management GUI, behind Pomerium so single sign-on gates access before Cockpit's own login screen.
---

import CodeBlock from '@theme/CodeBlock';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';

import Config from '/content/examples/guides/cockpit/config.yaml.md';
import Compose from '/content/examples/guides/cockpit/docker-compose.yaml.md';
import Config from '!!raw-loader!/content/examples/guides/cockpit/config.yaml';
import Compose from '!!raw-loader!/content/examples/guides/cockpit/docker-compose.yaml';

# Secure Cockpit with Pomerium

Expand Down Expand Up @@ -54,7 +55,9 @@ In the [Zero Console](https://console.pomerium.app):

Create a `config.yaml`. It routes `cockpit.yourdomain.com` to the Cockpit container, allows the WebSocket upgrade Cockpit needs, and preserves the host header so Cockpit's origin check passes.

<Config />
<CodeBlock language="yaml" title="config.yaml">
{Config}
</CodeBlock>

Replace `cockpit.yourdomain.com` with your domain and `you@example.com` with your email.

Expand All @@ -81,7 +84,9 @@ On a Linux host running Cockpit as a system service, this file lives at `/etc/co

The Compose file runs Pomerium Core and Cockpit together. Cockpit runs in plain-HTTP "bastion" mode (`--no-tls`) because Pomerium terminates TLS in front of it (for Zero, drop the `pomerium` service and use the `compose.yaml` from the Quickstart with your `POMERIUM_ZERO_TOKEN`, keeping the `cockpit` service below):

<Compose />
<CodeBlock language="yaml" title="docker-compose.yaml">
{Compose}
</CodeBlock>

Put the `cockpit.conf` from the previous section next to the Compose file, then start it:

Expand Down
13 changes: 9 additions & 4 deletions content/docs/guides/code-server.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ keywords: [pomerium, code-server, vscode, sso, oidc, identity aware proxy]
description: Run code-server (VS Code in the browser) in Docker and put authentication and authorization in front of it with Pomerium.
---

import CodeBlock from '@theme/CodeBlock';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';

import Config from '/content/examples/guides/code-server/config.yaml.md';
import Compose from '/content/examples/guides/code-server/docker-compose.yaml.md';
import Config from '!!raw-loader!/content/examples/guides/code-server/config.yaml';
import Compose from '!!raw-loader!/content/examples/guides/code-server/docker-compose.yaml';

# Secure code-server with Pomerium

Expand Down Expand Up @@ -72,7 +73,9 @@ Pomerium Zero uses the hosted authenticate service, so there is nothing else to

Add the route below to your Pomerium `config.yaml`. It uses the hosted authenticate service, so you don't run a separate identity provider, and it requests TLS certificates automatically from Let's Encrypt.

<Config />
<CodeBlock language="yaml" title="config.yaml">
{Config}
</CodeBlock>

Replace `code-server.yourdomain.com` with your own external hostname and `you@example.com` with the email that should be allowed in. `allow_websockets: true` keeps the editor's live connection working through the proxy, and `preserve_host_header: true` forwards the original host so code-server accepts that WebSocket; it checks the connection's origin against the host and rejects it otherwise.

Expand All @@ -95,7 +98,9 @@ If you prefer not to disable code-server's own login, you can instead set `PASSW

The Compose file runs Pomerium and code-server together on a shared network; the `To` address `http://code-server:8080` works because both containers share it.

<Compose />
<CodeBlock language="yaml" title="docker-compose.yaml">
{Compose}
</CodeBlock>

Wire up Pomerium for your deployment, then bring the stack up:

Expand Down
13 changes: 9 additions & 4 deletions content/docs/guides/forgejo.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ keywords:
description: Put a Forgejo instance behind Pomerium and use reverse-proxy header authentication so users sign in once and are auto-provisioned from their Pomerium identity.
---

import CodeBlock from '@theme/CodeBlock';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';

import Config from '/content/examples/guides/forgejo/config.yaml.md';
import Compose from '/content/examples/guides/forgejo/docker-compose.yaml.md';
import Config from '!!raw-loader!/content/examples/guides/forgejo/config.yaml';
import Compose from '!!raw-loader!/content/examples/guides/forgejo/docker-compose.yaml';

# Secure Forgejo with Pomerium

Expand Down Expand Up @@ -74,7 +75,9 @@ In the [Zero Console](https://console.pomerium.app):

Create a `config.yaml`. It routes `forgejo.yourdomain.com` to the Forgejo container, forwards the identity claims as headers, and removes the total request timeout so long Git smart-HTTP transfers aren't cut off.

<Config />
<CodeBlock language="yaml" title="config.yaml">
{Config}
</CodeBlock>

Replace `forgejo.yourdomain.com` with your domain and `you@example.com` with your user or domain. A few notes:

Expand All @@ -100,7 +103,9 @@ Configure Forgejo to trust and consume the headers. These map to `app.ini` setti

The Compose file runs Pomerium Core and Forgejo together (for Zero, drop the `pomerium` service and use the `compose.yaml` from the Quickstart with your `POMERIUM_ZERO_TOKEN`, keeping the `forgejo` service and its network below):

<Compose />
<CodeBlock language="yaml" title="docker-compose.yaml">
{Compose}
</CodeBlock>

Start it:

Expand Down
13 changes: 9 additions & 4 deletions content/docs/guides/gitlab.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ keywords: [pomerium, gitlab, sso, oidc, identity aware proxy, self-hosted]
description: Put self-hosted GitLab behind Pomerium so every request is authenticated and authorized at the front door before it reaches GitLab.
---

import CodeBlock from '@theme/CodeBlock';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';

import Config from '/content/examples/guides/gitlab/config.yaml.md';
import Compose from '/content/examples/guides/gitlab/docker-compose.yaml.md';
import Config from '!!raw-loader!/content/examples/guides/gitlab/config.yaml';
import Compose from '!!raw-loader!/content/examples/guides/gitlab/docker-compose.yaml';

# Secure GitLab with Pomerium

Expand Down Expand Up @@ -70,7 +71,9 @@ In the [Zero Console](https://console.pomerium.app):

Create a `config.yaml`. It routes `gitlab.yourdomain.com` to the GitLab container and preserves the host header so GitLab's redirects stay correct.

<Config />
<CodeBlock language="yaml" title="config.yaml">
{Config}
</CodeBlock>

Replace `gitlab.yourdomain.com` with your domain and `you@example.com` with the email (or switch to a group or domain match) that should be allowed through.

Expand Down Expand Up @@ -108,7 +111,9 @@ Keep the `pomerium` service shown below and place the `config.yaml` from the pre
</TabItem>
</Tabs>

<Compose />
<CodeBlock language="yaml" title="docker-compose.yaml">
{Compose}
</CodeBlock>

```bash
docker compose up -d
Expand Down
13 changes: 9 additions & 4 deletions content/docs/guides/grafana.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ keywords:
description: Add single sign-on and per-route authorization to Grafana with Pomerium, forwarding a signed identity JWT so Grafana signs users in automatically.
---

import CodeBlock from '@theme/CodeBlock';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';

import Config from '/content/examples/guides/grafana/config.yaml.md';
import Compose from '/content/examples/guides/grafana/docker-compose.yaml.md';
import Config from '!!raw-loader!/content/examples/guides/grafana/config.yaml';
import Compose from '!!raw-loader!/content/examples/guides/grafana/docker-compose.yaml';

# Secure Grafana with Pomerium

Expand Down Expand Up @@ -88,7 +89,9 @@ Zero manages the route's TLS certificate and the signing key behind its starter

Create a `config.yaml`. It routes `grafana.yourdomain.com` to the Grafana container, passes identity headers, and sets a `signing_key` so Pomerium publishes a JWKS that Grafana can verify the forwarded assertion against.

<Config />
<CodeBlock language="yaml" title="config.yaml">
{Config}
</CodeBlock>

Replace `grafana.yourdomain.com` with your domain, `you@example.com` with your email, and generate your own `signing_key` with the command in the comment. With Core, Grafana's JWKS URL is the route's own well-known endpoint (`https://grafana.yourdomain.com/.well-known/pomerium/jwks.json`), which is what the Compose file below uses.

Expand Down Expand Up @@ -121,7 +124,9 @@ Keep the `pomerium` service shown below and place the `config.yaml` from the pre
</TabItem>
</Tabs>

<Compose />
<CodeBlock language="yaml" title="docker-compose.yaml">
{Compose}
</CodeBlock>

```bash
docker compose up -d
Expand Down
13 changes: 9 additions & 4 deletions content/docs/guides/guacamole.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ description: Put Apache Guacamole behind Pomerium and sign users in automaticall
# cSpell:ignore guacd guacamole guacadmin initdb POSTGRESQL psql
---

import CodeBlock from '@theme/CodeBlock';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';

import Config from '/content/examples/guides/guacamole/config.yaml.md';
import Compose from '/content/examples/guides/guacamole/docker-compose.yaml.md';
import Config from '!!raw-loader!/content/examples/guides/guacamole/config.yaml';
import Compose from '!!raw-loader!/content/examples/guides/guacamole/docker-compose.yaml';

# Secure Apache Guacamole with Pomerium

Expand Down Expand Up @@ -51,7 +52,9 @@ In the [Zero Console](https://console.pomerium.app):

Create a `config.yaml`. It routes `guacamole.yourdomain.com` to the Guacamole container, passes identity headers, and forwards the user's email as `X-Pomerium-Claim-Email`:

<Config />
<CodeBlock language="yaml" title="config.yaml">
{Config}
</CodeBlock>

Replace `guacamole.yourdomain.com` with your domain and `you@example.com` with your email. The `jwt_claims_headers` mapping is what produces the `X-Pomerium-Claim-Email` header that Guacamole's header-auth extension expects.

Expand Down Expand Up @@ -86,7 +89,9 @@ The Compose file below mounts that `init/` directory into PostgreSQL so the sche

The Compose file runs Pomerium Core alongside Guacamole's three services (for Zero, drop the `pomerium` service and use the `compose.yaml` from the Quickstart with your `POMERIUM_ZERO_TOKEN`, keeping the rest below):

<Compose />
<CodeBlock language="yaml" title="docker-compose.yaml">
{Compose}
</CodeBlock>

Start it:

Expand Down
13 changes: 9 additions & 4 deletions content/docs/guides/hedgedoc.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ description: Put HedgeDoc behind Pomerium so single sign-on and per-route author
# cSpell:ignore hedgedoc USESSL ADDPORT
---

import CodeBlock from '@theme/CodeBlock';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';

import Config from '/content/examples/guides/hedgedoc/config.yaml.md';
import Compose from '/content/examples/guides/hedgedoc/docker-compose.yaml.md';
import Config from '!!raw-loader!/content/examples/guides/hedgedoc/config.yaml';
import Compose from '!!raw-loader!/content/examples/guides/hedgedoc/docker-compose.yaml';

# Secure HedgeDoc with Pomerium

Expand Down Expand Up @@ -54,7 +55,9 @@ In the [Zero Console](https://console.pomerium.app):

Create a `config.yaml`. It routes `hedgedoc.yourdomain.com` to the HedgeDoc container, allows the WebSocket upgrade the editor needs, and limits access with a policy.

<Config />
<CodeBlock language="yaml" title="config.yaml">
{Config}
</CodeBlock>

Replace `hedgedoc.yourdomain.com` with your domain and `you@example.com` with the email (or group, or domain) that should be allowed in. The `allow_websockets: true` line is required: without it HedgeDoc's real-time editor can't open its connection.

Expand All @@ -75,7 +78,9 @@ HedgeDoc stores its notes in PostgreSQL, so the Compose file below also runs a `

The Compose file runs Pomerium Core, HedgeDoc, and its PostgreSQL database together. For Zero, drop the `pomerium` service and use the `compose.yaml` from the Quickstart with your `POMERIUM_ZERO_TOKEN`, keeping the `hedgedoc` and `database` services below. Either way, the Pomerium container and the `hedgedoc` container must share a Docker network so that `to: http://hedgedoc:3000` resolves.

<Compose />
<CodeBlock language="yaml" title="docker-compose.yaml">
{Compose}
</CodeBlock>

Start it:

Expand Down
13 changes: 9 additions & 4 deletions content/docs/guides/jellyfin.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ description: Put a self-hosted Jellyfin media server behind Pomerium so every br
# cSpell:ignore jellyfin chromecast DLNA
---

import CodeBlock from '@theme/CodeBlock';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';

import Config from '/content/examples/guides/jellyfin/config.yaml.md';
import Compose from '/content/examples/guides/jellyfin/docker-compose.yaml.md';
import Config from '!!raw-loader!/content/examples/guides/jellyfin/config.yaml';
import Compose from '!!raw-loader!/content/examples/guides/jellyfin/docker-compose.yaml';

# Secure Jellyfin with Pomerium

Expand Down Expand Up @@ -72,7 +73,9 @@ In the [Zero Console](https://console.pomerium.app):

Create a `config.yaml`. It routes `jellyfin.yourdomain.com` to the Jellyfin container, allows WebSockets for the web client, preserves the host header so Jellyfin's links stay correct, and removes the total request-time cap for long playback and downloads.

<Config />
<CodeBlock language="yaml" title="config.yaml">
{Config}
</CodeBlock>

Replace `jellyfin.yourdomain.com` with your domain and `you@example.com` with the email (or switch to a group or domain match) that should be allowed through. Restart Pomerium after saving.

Expand All @@ -88,7 +91,9 @@ Two settings in the Compose file keep Jellyfin's URLs correct behind the proxy:

The Compose file runs Pomerium Core and Jellyfin together. For Zero, drop the `pomerium` service and use the `compose.yaml` from the [Quickstart](/docs/get-started/quickstart) with your `POMERIUM_ZERO_TOKEN`, keeping the `jellyfin` service; put `jellyfin` on the same Docker network as the Quickstart's `pomerium` service (the Quickstart names it `main`) so Pomerium can resolve `jellyfin` by name.

<Compose />
<CodeBlock language="yaml" title="docker-compose.yaml">
{Compose}
</CodeBlock>

## Run the stack

Expand Down
13 changes: 9 additions & 4 deletions content/docs/guides/jenkins.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ keywords: [pomerium, jenkins, sso, oidc, jwt, identity aware proxy]
description: Put Jenkins behind Pomerium for single sign-on, forwarding a signed identity JWT that the Jenkins JWT Auth plugin verifies to sign users in automatically.
---

import CodeBlock from '@theme/CodeBlock';
import TabItem from '@theme/TabItem';
import Tabs from '@theme/Tabs';

import Config from '/content/examples/guides/jenkins/config.yaml.md';
import Compose from '/content/examples/guides/jenkins/docker-compose.yaml.md';
import Config from '!!raw-loader!/content/examples/guides/jenkins/config.yaml';
import Compose from '!!raw-loader!/content/examples/guides/jenkins/docker-compose.yaml';

# Secure Jenkins with Pomerium

Expand Down Expand Up @@ -62,7 +63,9 @@ Zero manages the route's TLS certificate and the signing key behind its starter

Create a `config.yaml`. It routes `jenkins.yourdomain.com` to the Jenkins container, passes identity headers, and sets a `signing_key` so Pomerium publishes a JWKS that the JWT Auth plugin can verify the forwarded assertion against.

<Config />
<CodeBlock language="yaml" title="config.yaml">
{Config}
</CodeBlock>

Replace `jenkins.yourdomain.com` with your domain, `you@example.com` with your email, and generate your own `signing_key` with the command in the comment. With Core, the JWKS URL is the route's own well-known endpoint (`https://jenkins.yourdomain.com/.well-known/pomerium/jwks.json`).

Expand Down Expand Up @@ -102,7 +105,9 @@ Save and restart Jenkins.

The Compose file runs Pomerium Core and Jenkins together (for Zero, drop the `pomerium` service and use the `compose.yaml` from the Quickstart with your `POMERIUM_ZERO_TOKEN`, keeping the `jenkins` service below):

<Compose />
<CodeBlock language="yaml" title="docker-compose.yaml">
{Compose}
</CodeBlock>

Start it:

Expand Down
8 changes: 6 additions & 2 deletions content/docs/guides/jit.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ keywords: [pomerium, jit, just-in-time access, ppl, date matcher, authorization]
description: Grant time-limited, Just-In-Time access with Pomerium by using the PPL date matcher, and automate the request and approve workflow with the jit-example app.
---

import Compose from '/content/examples/guides/jit/docker-compose.yaml.md';
import CodeBlock from '@theme/CodeBlock';

import Compose from '!!raw-loader!/content/examples/guides/jit/docker-compose.yaml';

# Just-In-Time Access With Pomerium

Expand Down Expand Up @@ -94,7 +96,9 @@ With this setup, any user reaches `https://jit-example.yourdomain.com`, but only

The Compose file below runs Pomerium Zero (driven by your `POMERIUM_ZERO_TOKEN`) alongside `jit-example`. Zero is used because the `date` matcher is a Zero/Enterprise feature; routes and the time-limited policy are managed in the Zero Console as described above, not in a local config file. `jit-example` is itself the application the date-gated policy protects.

<Compose />
<CodeBlock language="yaml" title="docker-compose.yaml">
{Compose}
</CodeBlock>

Clone the app, save the file above next to it as `docker-compose.yaml`, replace the `REPLACE_WITH_*` values with your own, then start the stack:

Expand Down
Loading