All use cases Read in docs
Local cluster + VPS · WireGuard or Tailscale mesh · mTLS over the link
Home + VPS Hybrid
Private dev cluster at home. Public face on a VPS. One registry drives both.
First deploy: ~2–3 hours including mesh VPN
Why pick this shape
- Keep secrets, databases, and dev services at home. Expose only what needs to be public.
- The VPS is just another host in the registry — the only special thing is which side faces the internet.
- mTLS between local and VPS via Portoser's built-in CA; install_ca_on_hosts.sh distributes trust.
Registry skeleton
Copy, replace IPs and ssh_user, point CADDY_REGISTRY_PATH at it.
hosts:
mini1:
ip: 192.168.1.10 # LAN
arch: arm64-apple
roles: [infrastructure, vault, databases]
pi1:
ip: 192.168.1.51
arch: arm64-linux
roles: [internal_services]
vps:
ip: 10.10.0.2 # WireGuard mesh, NOT the public IP
arch: amd64-linux
ssh_user: admin
roles: [public_ingress]
services:
api-public:
hostname: api.example.com # public hostname
current_host: vps
deployment_type: docker
docker_compose: /api/docker-compose.yml
port: 8443Bringing it up
sudo tailscale up # on every host, both sides ./portoser certs init-ca ./install_ca_on_hosts.sh ./portoser certs generate-all-servers ./portoser certs deploy-servers ./portoser deploy mini1 vault api-backend ./portoser deploy vps caddy-public api-public
Common gotchas
- The registry IP for the VPS is the mesh IP, not the public IP. Public DNS is a separate concern.
- mesh VPN becomes load-bearing. If Tailscale or WireGuard is down, deploys to the VPS stop working.
- Cert renewal matters. ./portoser certs list shows expiry — schedule rotation or it lapses.
Read the full VPS Hybrid walkthrough
Deeper version with more code, more gotchas, and links to operations docs.