Expose your apps
You choose how each app is reachable from its Exposure mode. There are three modes, and you can set a different one for each app:
| Exposure mode | Who can reach the app | What you need |
|---|---|---|
| This Machine Only | Anyone on the Hub machineβs network, at the machineβs address and the appβs port, without the Hubβs sign-in. The app gets no public or VPN address | Nothing |
| Private VPN | Your own devices, over Tailscale | Tailscale connected in Settings β Network, accepting the Hubβs changes, with HTTPS certificates enabled for your tailnet, and Tailscale Serve left on (the default) |
| Public Web | Anyone with the URL, through the Cloudflare Gateway | A Hub paired with your CI Account |
Private VPN and Public Web are unavailable until you have set them up. The mode selector shows why when you hover over an unavailable option. A Hub whose .env sets TAILSCALE_SERVE_USER_DISABLED=true never offers Private VPN; see Turning Private VPN off.
This Machine Only publishes the appβs port on every network interface of
the Hub machine, not just the machine itself. Anyone on your local network, and
anyone on your tailnet if the machine is on one, can open
http://<machine address>:<port>, and Hubβs sign-in isnβt in front of it.
Agent apps such as OpenClaw and Hermes, and apps with no login of their own,
are the exception: Hub limits their port to the Hub machine.
Public Web makes an app reachable by anyone with the URL. Keep Enable authentication on β itβs in the appβs advanced settings β or make sure the app has its own login, and never expose an app that still uses default credentials.
Which route to use
Start from who needs access. None of these routes needs port forwarding on your router.
flowchart TD
Q1{"Who needs to reach the app?"}
Q1 -- "Only this machine" --> LO["This Machine Only<br/>the default when nothing else is set up"]
Q1 -- "Only you and your devices" --> TS["Private VPN<br/>Tailscale, no public URL"]
Q1 -- "Anyone on the internet" --> PW["Public Web<br/>Cloudflare Gateway, needs a paired Hub"]
PW -. "want your own domain?" .-> CD["Custom domain in your CI Account"]
click TS "/docs/networking/tailscale"
click PW "/docs/networking/cloudflare-gateway"
click CD "/docs/portal/custom-domains"Change an appβs exposure mode
- Open the appβs details page in the dashboard, and open its Settings.
- Under Exposure mode, choose This Machine Only, Private VPN, or Public Web.
- For Public Web, set the Subdomain. The Hostname preview shows the address the app will get, before you save.
- Select Save. Hub updates the app and registers its route.
If an appβs public route stops matching what Hub expects, the settings show Repair routing, which re-applies the route and restarts the app.
To expose an app when you install it, the install form has the same Exposure mode selector.
Manual port forwarding is no longer supported
Earlier versions of Companion Hub let you publish an app on a domain you own: you forwarded ports 80 and 443 on your router, added an A record, switched on Expose app, and Hub requested a Letβs Encrypt certificate. Production Hubs no longer do this. The install form doesnβt show the option, and Hub turns it off if a request sets it.
Use one of the routes above instead. If you want an app on a domain you own, use a custom domain in your CI Account.