Skip to content

Cloudflare

Two Cloudflare products are in use: Tunnel (traffic routing) and Access (identity/auth perimeter).

Cloudflare Tunnel

The cloudflared container runs a persistent QUIC tunnel to the Cloudflare edge. It routes traffic from web.level147.net to http://level147-net:3000 via Docker’s proxy-net network.

The tunnel config maps the public hostname web.level147.net → origin service http://level147-net:3000.

Dashboard widget: reads metrics from CLOUDFLARED_METRICS_URL (set in .env).

Cloudflare Access

Cloudflare Access acts as the network perimeter — all requests to web.level147.net must pass identity verification before reaching the app. Authentik OIDC is the identity provider.

Docs site access

docs.level147.net is deployed to Cloudflare Pages and also protected by a separate Cloudflare Access application. The pages.dev preview domain is disabled to prevent Access bypass.

See Docs Site for the full deployment setup.

Auth flow

Security is enforced at two independent layers:

  1. Cloudflare Access — network perimeter. Blocks all unauthenticated requests before they reach the app. Enforces Cloudflare identity policy at web.level147.net.
  2. NextAuth v5 + Authentik OIDC — application layer. src/middleware.ts guards all /api/* routes (except /api/auth/* and /api/health) as the framework-level choke point. Each API route handler also calls requireSession() (src/lib/require-session.ts) for defense-in-depth, ensuring new routes are protected by default even if middleware config changes.

The app does not rely solely on Cloudflare Access — both layers must pass independently.

Troubleshooting 522

SymptomCauseFix
522 on web.level147.netAccess app scoped to wrong domainCheck Zero Trust → Applications → hostname
Container healthy but 522Tunnel ingress pointing to wrong originCheck tunnel public hostname service URL = http://level147-net:3000
Tunnel disconnectedcloudflared QUIC timeoutdocker restart cloudflared

Full incident diagnosis steps: Incident Response.

v0.1.0 · d0d7a20 · 2026-06-26