Dashboard/Setup Guide

Setup Guide

How ProxyOS fits into your homelab and how to expose services to the internet.

The architecture
Internet
  ↓
Cloudflare edge
  ↓
Cloudflare Tunnel (cloudflared container)
  ↓
ProxyOS  ← you are here
  ↓
your services (vaultwarden, gitea, sonarqube, etc.)

Every request from the internet hits ProxyOS. ProxyOS inspects the Host header and forwards to the right internal service. Never configure a Cloudflare Tunnel to point directly at a service — it always points at ProxyOS.

Prerequisite — mount the Docker socket

Mount the Docker socket in ProxyOS's compose so it can auto-discover and join networks:

services:
  proxyos:
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

Once mounted, check the Networks page — all relevant networks should show "Joined". Then the Containers page shows everything ProxyOS can reach.

Step 1 — Put cloudflared on the homelab-edge network

ProxyOS creates a homelab-edge network on startup. Cloudflared must join it so it can reach ProxyOS by container name.

services:
  cloudflared:
    networks:
      - homelab-edge

networks:
  homelab-edge:
    external: true
Step 2 — Create a route in ProxyOS

Open the Containers page, find the service, and click "Create Route" on the relevant port. Fill in:

  • Domain: the public hostname (e.g. vault.yourdomain.com)
  • Upstream: pre-filled from the Containers page (e.g. http://vaultwarden:80)
  • TLS: auto or leave default if Cloudflare terminates TLS at the edge
  • WebSocket: enable if the service uses WebSockets (vaultwarden, sonarqube, etc.)
Step 3 — Add the Cloudflare Tunnel public hostname

Zero Trust → Networks → Tunnels → (your tunnel) → Public Hostname → Add:

Subdomain: vault (matches your ProxyOS route)
Domain: yourdomain.com
Path: (leave empty)
Service Type: HTTP
Service URL: proxyos:80
Important: Always point the Service URL at proxyos:80 for every hostname. Never point it directly at a service — cloudflared isn't on that network, and you'd bypass all of ProxyOS's routing, SSO, and analytics.
Step 4 — Test

Verify each hop works:

# 1. DNS resolves to Cloudflare
dig @1.1.1.1 vault.yourdomain.com +short

# 2. Tunnel routes to ProxyOS and ProxyOS routes to the service
curl -IL https://vault.yourdomain.com
# Expected: HTTP/2 200 (or login redirect), not a 502/503 from Cloudflare

If you get a 502, check docker logs cloudflared — it'll say exactly what it couldn't reach.

Common mistakes
Pointing Cloudflare Tunnel at the service directly

Wrong: Service URL http://vaultwarden:80. Right: Service URL http://proxyos:80. Cloudflared probably can't resolve the container, and even if it could, you'd bypass all ProxyOS features.

Leaving a regex in the Path field

Anything in Path restricts which URLs the tunnel routes. For a full-domain passthrough, leave Path empty.

Using container IPs as upstreams

IPs change when containers restart. Use container names — the Containers page shows you the correct name. They resolve via Docker DNS as long as ProxyOS is on the same network.

Multi-container services with generated names

Compose projects like authentik or zammad create containers named authentik-server-1 or zammad-zammad-nginx-1. Use the exact name shown on the Containers page.

Cheat sheet
Cloudflare Tunnel Service URLhttp://proxyos:80 (every route)
Cloudflare Tunnel Path(empty — don't enter anything)
ProxyOS Upstreamhttp://<container-name>:<port>
Cloudflared networkhomelab-edge (same as ProxyOS)
Docker socket mount/var/run/docker.sock:/var/run/docker.sock