Getting started
Bring up the control plane locally and point a worker at it.
This page walks you through bringing up the control plane locally and pointing a worker at it.
What you'll have at the end
A control plane running on your laptop that signs you in with Google, plus a remote Linux host configured as a worker that can build and run a containerised app. Five steps, maybe 20 minutes if you have everything ready.
If a term feels unfamiliar (PaaS, WSS, WireGuard…), check the Glossary first.
Prerequisites
- Go 1.23+
- Docker / Docker Compose (for local Postgres)
- A Google OAuth client (Console → APIs & Services → Credentials)
- One Linux host with root access for the worker (Ubuntu/Debian/Fedora/Arch)
- A DNS zone you control on Cloudflare (one per worker)
1. Bring up Postgres
docker compose up -dCompose starts Postgres on the port from docker-compose.yml. The Go process runs golang-migrate on startup against internal/database/migrations/*.sql, so no manual SQL needs to be applied. A schema_migrations row tracks the applied version.
2. Configure
cp config.yaml.example config.yamlSet at minimum:
| Section | Key | Why |
|---|---|---|
api_server | secret | Used for AES-GCM encryption keys + worker register |
database | password | Postgres password |
google | oauth_client_id / oauth_client_secret | Required for sign-in |
platform | domain | Public domain (used in URLs and CSP) |
webapp | url | HTTPS URL where the dashboard is served |
See Configuration for the full schema.
HTTPS is mandatory for cookies
webapp.url must be HTTPS in production — the wh_session cookie is Secure. In dev you can tunnel through ngrok/cloudflared or run plain HTTP on localhost.
3. Run the control plane
go run .This single binary spins up:
- The HTTP/REST API and worker WSS endpoint
- The scheduler (poll loop + worker-health monitor)
- The alert manager + threshold poller
- The usage recorder (per-app 5-min samples)
- The webhook dispatcher (HTTPS + 22 Shoutrrr channels)
- The dashboard (embedded SPA)
4. Add a worker
Workers reach the control plane over a self-hosted WireGuard mesh (10.50.0.0/24, UDP 51821). On the control-plane host first:
sudo ./scripts/wireguard-setup.sh controlThe script prints the CP public key and the CP public IPv4 — copy both. Then on the worker host:
sudo ./scripts/wireguard-setup.sh worker \
--cp-pubkey '<CP public key>' \
--cp-public-ip '<CP public IPv4>' \
--worker-id 2
curl -fsSL https://raw.githubusercontent.com/Krinali12/hostingbot/master/scripts/worker-setup.sh | sudo bash--worker-id 2 puts this worker at 10.50.0.3 (formula: 10.50.0.{ID+1}). After the worker side runs, paste its public key as a [Peer] block on the CP and reload with sudo wg syncconf wg0 <(wg-quick strip wg0) — see WireGuard mesh for the full key-exchange dance.
The installer downloads the worker binary, installs Podman 5 (alvistack OBS repo on Ubuntu 22.04 / Debian 12), prompts for config on /dev/tty, writes /etc/wisehosting/config.yaml, installs wisehosting-worker.service, creates the wisehosting-build Podman network for build-time DNS, runs Traefik on :8080, and applies iptables egress hardening. Point api_server.url at http://10.50.0.1:8081 (plain HTTP is permitted because the WireGuard tunnel already encrypts every byte; :8081 is the control-plane HTTP port).
For the full wire-up (DNS, Cloudflare Tunnel, custom domains, TLS) see Worker deployment.
5. Verify
# On the control plane host:
journalctl -u wisehosting -f | grep "hub: worker"
# Expect: hub: worker <ID> (<name>) connected via WSSThen open the dashboard at https://<your domain>/, sign in with Google, link a git provider under Git Integrations, and deploy a test repo. 2FA is opt-in under Account → Security.