The hosted monitor is a thin ingress layer in front of the existing Paperclip and tool containers. It does not introduce a second application stack.

Request Path

Intended Shape

  • obs.sydiolabs.com is the canonical hosted monitor origin
  • tool hostnames are flat subdomains under sydiolabs.com, not nested under obs.sydiolabs.com
  • Cloudflare Access sits in front of the tunnel for private operator authentication
  • cloudflared runs locally and forwards to the obs-proxy container
  • obs-proxy is a hostname router, not a new application layer
  • backend services stay on the Docker network or host loopback, depending on the local stack shape

Routing Model

The proxy keeps the old local ports working while introducing stable hostnames:
  • paperclip.localhost, obs.localhost, and obs.sydiolabs.com -> Paperclip monitor origin
  • langfuse.localhost and langfuse.sydiolabs.com -> Langfuse
  • redash.localhost and redash.sydiolabs.com -> Redash
  • chartdb.localhost and chartdb.sydiolabs.com -> ChartDB
  • telescope.localhost and telescope.sydiolabs.com -> Telescope
  • mindsdb.localhost and mindsdb.sydiolabs.com -> MindsDB
  • bytebase.localhost and bytebase.sydiolabs.com -> Bytebase
  • gigapipe.localhost and gigapipe.sydiolabs.com -> Gigapipe
  • minio.localhost and minio.sydiolabs.com -> Langfuse MinIO API
  • minio-console.localhost and minio-console.sydiolabs.com -> Langfuse MinIO console

Cloudflare Contract

The minimum Cloudflare-side requirements are:
  1. Create or reuse a named tunnel for the local host.
  2. Publish an exact tunnel hostname route for obs.sydiolabs.com.
  3. Publish exact tunnel hostname routes for any tool subdomains you want exposed.
  4. Point the DNS record at the tunnel target with a proxied CNAME record to the tunnel UUID target.
  5. Create a self-hosted Access application for the protected hostnames and attach at least one Allow policy for operators.
Important:
  • Access policies do not replace tunnel publication.
  • A policy on an app that is not bound to the hostname will not make the hostname work.
  • A hostname that resolves to Cloudflare but is not pointed at the tunnel target will not reach cloudflared.
  • If requests return 404/openresty and cloudflared sees no traffic, treat that as a routing or DNS problem first.

Local Operator Notes

  • If port 80 is unavailable, set OBS_PROXY_HTTP_PORT for local-only access to the proxy.
  • Leave CLOUDFLARE_TUNNEL_TOKEN unset if you only want the local hostname router.
  • Set OBS_ENABLE_CLOUDFLARE_TUNNEL=true only when you want to exercise the tunnel container without baking the token into your shell history.
  • Keep the old localhost:port URLs documented until the hosted path has been fully adopted.

Troubleshooting

SymptomLikely layerFirst check
403 from AccessAccess policyIs the app present and does it allow your identity?
1033Tunnel healthIs a connector healthy and is the tunnel publishing the hostname?
404/openresty with no cloudflared logsDNS / hostname bindingIs the DNS record a proxied CNAME to the tunnel target and does the hostname route exist?
Local origin healthy but public host staleTunnel or CloudflareRestart cloudflared and verify the exact published route

Why This Shape

  • it avoids changing the app code for ingress
  • it keeps browser origins stable for auth and passkeys later
  • it gives Cloudflare Tunnel a single origin to target
  • it preserves local development fallbacks while making the hosted path explicit