Self-hosted deployment
Self-hosted mode gives full operational control of control-plane and gateway components.
Deployment order
Recommended startup order:
- Postgres
- Control plane
- WebUI
- Gateway manager
- Gateway daemon
Environment baseline
Control plane:
export DATABASE_URL=postgres://nanami:nanami@localhost:5432/nanami?sslmode=disable
export JWT_SECRET=change_me_super_secret
export APP_ENV=dev
export APP_MODE=community
Gateway manager:
export CONTROL_PLANE_INTERNAL_PROTOCOL=http
export CONTROL_PLANE_INTERNAL_HOST=localhost
export CONTROL_PLANE_INTERNAL_PORT=8080
export JOIN_KEY=<gateway-manager-join-key>
export TENANT_SLUG=default
export NODE_JOIN_KEY=node-secret-key
Gateway daemon:
export GATEWAY_MANAGER_INTERNAL_PROTOCOL=http
export GATEWAY_MANAGER_INTERNAL_HOST=localhost
export GATEWAY_MANAGER_INTERNAL_PORT=8081
export NODE_JOIN_KEY=node-secret-key
export CONTROL_PLANE_INTERNAL_PROTOCOL=http
export CONTROL_PLANE_INTERNAL_HOST=localhost
export CONTROL_PLANE_INTERNAL_PORT=8080
export GATEWAY_DAEMON_JOIN_KEY=<gateway-daemon-join-key>
export GATEWAY_HOST=<public-dns-host>
In COMMUNITY mode, set gateway WireGuard UDP port from Dashboard -> Gateways -> gateway details (WireGuard UDP Port).
The fixed gateway port pool is 51820-54000; if unset, the default base port is 51820.
Community gateway-daemon runs in host network mode (Docker) so compose port publishing is not required.
Set GATEWAY_HOST (DNS only) and forward the selected UDP port on router/NAT
(example: WAN UDP 53535 -> gateway-host:53535).
If users rely on manual WireGuard configs, they must re-download after port changes.
Manual configs are Limited Mode and user-editable; do not treat client-side AllowedIPs as a security control.
Gateway-side policy and ACL enforcement remain authoritative.
If your gateway DNS is on Cloudflare, use DNS-only records for gateway endpoints: Cloudflare proxied mode does not forward WireGuard UDP.
Diagram (text)
Your Postgres + control plane + webui + gateway-manager + gateway-daemon(s)
Hardening checklist
- Use real secrets and rotate join credentials.
- Terminate TLS in front of public endpoints.
- Restrict management API ingress by network controls.
- Back up Postgres regularly.
- Monitor gateway heartbeat and observed-state freshness.
Known limitations
- Cross-platform managed client coverage is still expanding.
- Some advanced policy UX remains roadmap work.