Developer Tools
Self-host OpenHole
Self-hosted tunnel edge — gives any local port a public HTTPS URL with one command. This runs the server; the openhole CLI connects to it.
Deploy OpenHole with Nixploy
Install Nixploy on any Docker host — a €5 VPS is enough for most of these:
curl -fsSL https://raw.githubusercontent.com/bablilayoub/nixploy/main/install.sh | sudo bash- 1
Open Templates in the panel
Search for OpenHole and open it. The compose file, the variables and the suggested domain are already filled in.
- 2
Give it a domain
Point a DNS record at your server and enter it. Traefik requests the certificate on the first request — there is no separate certbot step and nothing to renew by hand.
- 3
Deploy
Nixploy renders the compose file, validates it against the platform's safety rules, and brings the stack up on a private per-environment network. Live logs stream while it happens.
What this deploys
- Images
- ghcr.io/bablilayoub/openhole-server:main
- Routed to
- openhole:8080
- Variables it asks for
- TUNNEL_ENDPOINT_HOSTHostname the CLI connects to (wss://<host>/tunnel) — attached as this service's domain on deploy
- PUBLIC_TUNNEL_DOMAINDomain the tunnels are served under — *.<domain> is attached as a wildcard domain on deploy (instance admin; its certificate needs a DNS-01 provider in Settings → Platform)
- Secrets Nixploy generates
- REGISTRATION_TOKENSCreated at deploy time and stored encrypted — you never invent or paste them.
Domains from your values
Attached to the stack on deploy, straight from the env values you enter — and, with automatic DNS records on, created at your DNS provider too.
- {TUNNEL_ENDPOINT_HOST} → openhole:8080 · HTTPS
- *.{PUBLIC_TUNNEL_DOMAIN} → openhole:8080 · HTTPS · wildcard
Set it up
What to do once the stack is deployed, in order. The panel shows the same steps on the template's details.
- Before deploying, set the two hostnames:
TUNNEL_ENDPOINT_HOSTis what the CLI connects to (for exampletunnel.example.com) andPUBLIC_TUNNEL_DOMAINis the zone tunnels are served under (for exampletunnels.example.com). Keep the generatedREGISTRATION_TOKENSor paste your own comma-separated list — empty means anyone can open a tunnel on your server. - Both hostnames are attached to this service on deploy, straight from those values: the endpoint host with HTTPS (Let's Encrypt), and
*.<tunnel domain>as a wildcard domain — instance-admin only, and its certificate needs a DNS-01 provider under Settings → Platform → DNS provider (HTTP-01 cannot validate a wildcard; without a provider the wildcard is attached without a certificate, switch it to Let's Encrypt once one is linked). WebSocket upgrades pass through Traefik as-is. - DNS, all pointing at this server and DNS-only (a proxied record breaks tunnel routing): an A record for the endpoint host and a wildcard A record
*.<tunnel domain>. With *Create DNS records automatically* on for the linked provider, both are created for you at deploy; otherwise create them at your provider. Shortcut: make the endpoint host a name under the tunnel domain (tunnel.tunnels.example.com) and the wildcard record covers both. - Install the CLI on your machine (
curl -fsSL https://openhole.dev/install.sh | sh) and open a tunnel:openhole 3000 --server wss://<endpoint host>/tunnel --token <one of REGISTRATION_TOKENS>; add--subdomain myappfor a stable name. The public URL ishttps://<sub>.<tunnel domain>. - Check
https://<endpoint host>/healthanswers{"status":"ok"}. Port 8080 is never published; Traefik is the only way in, which is whyTRUST_PROXY_HEADERSis on — never expose 8080 directly with it set.
What you get with it
Automatic HTTPS through Traefik and Let's Encrypt, renewed for you.
Live logs, a web terminal into the container, and CPU/memory/network history.
Encrypted backups to S3 or disk, on a schedule, with verified restores.
Roll back to the previous version when an update goes wrong.
An MCP endpoint, so an AI agent can deploy, read the logs and diagnose it for you — see the MCP guide.
Why self-host OpenHole?
Running it yourself means the data lives on a disk you control, there is no per-seat price as the team grows, and nothing is retired or repriced by somebody else. The cost is the part Nixploy takes over: a reverse proxy, certificates that renew, a volume that survives a redeploy, backups you can actually restore, and a way to see the logs when it misbehaves.
OpenHole upstream
Nixploy packages the project; it is not affiliated with it. Website · Docs · Source
All 146 templates