Use a full virtual machine rather than an LXC container for the default Docker
sandbox provider. Roomote depends on Docker networking, cgroups, packet-filter
rules, and writable-layer quotas that are much easier to operate reliably in
a VM. LXC installations require host-specific privileged-container changes
and are not covered by this guide.
Plan the deployment
The recommended homelab shape separates private administration from public application traffic:- Proxmox VM: runs Roomote, its datastores, and the default Docker task sandboxes
- Tailscale: provides private SSH and administrative access to the VM
- Public HTTPS origin: receives source-control and communications-provider callbacks and serves links generated by Roomote
- Caddy: terminates traffic for the application and task preview hostnames
The default limit for each Docker task is 2 CPUs, 4 GiB of memory, and a 20 GiB
writable layer. Increase the VM resources for concurrent or Docker-heavy tasks,
or use a hosted sandbox provider so task workloads do not compete
with the Roomote services.
Create the Proxmox VM
Create a VM from a Debian or Ubuntu cloud image or installation ISO:- allocate at least 4 vCPU, 8 GB RAM, and 60 GB of disk
- set the CPU type to
hostand use VirtIO for disk and networking - install and enable
qemu-guest-agent - assign a DHCP reservation or static address on the LAN
- enable SSH and apply operating-system updates
Add private administration with Tailscale
Install Tailscale on the VM using the official Linux instructions, then confirm you can reach the host over its tailnet address before changing router or firewall rules. Use Tailscale SSH or regular SSH over the tailnet for host administration. Tailscale does not replace Roomote’s public application origin. GitHub, Slack, and other providers must reach callbacks from outside your tailnet. Live task previews also use per-task hostnames, including wildcard preview DNS in the normal production configuration.Choose public ingress
Choose one stable hostname before completing the setup wizard. Changing it later also means updating source-control, sign-in, and communications-provider redirect and webhook URLs.Public DNS and port forwarding
Create DNS records for the application, preview root, and wildcard previews:preview.<domain>. Use
--preview-domain <host> when your DNS layout differs. If the public address
changes, configure DDNS for all three records. This path does not work behind
carrier-grade NAT unless the ISP supplies a public address.
Cloudflare Tunnel
Cloudflare Tunnel can publish Roomote without forwarding inbound router ports. Install Roomote with Caddy’s internal TLS mode because Cloudflare terminates the public certificate:/opt/roomote/.env and run
sudo roomote up before testing or exposing task previews; the install command
above otherwise retains the default nested preview hostname layout.
Tailscale Funnel
Tailscale Funnel can expose a stable tailnet hostname to public callback providers, but it does not support Roomote’s normal wildcard preview hostname layout. Treat it as a limited dashboard and callback trial, not the default full deployment path. Use public DNS or Cloudflare Tunnel when users need live task previews.Let a local agent prepare the host
Paste the following prompt into a local coding agent running on the VM or one that can SSH to it. The agent prepares the host and installer; you complete credential and authorization steps in Roomote’s browser wizard.Complete setup in the browser
The installer sets up Docker, Compose, generated secrets, Caddy, the Roomote services, a systemd unit, and theroomote host CLI. When it finishes, open the
tokenized setup URL it prints and configure:
- the first admin account
- a source-control provider and repository access
- a ChatGPT subscription or inference provider
- Docker or a hosted sandbox provider
- an optional communications provider such as Slack
- the first environment and Roomote task
Verify the homelab path
After setup:- run
roomote statuson the VM and confirm the services are healthy - open the public Roomote URL from a device outside the home network
- confirm the expected repositories appear in Roomote
- validate the sandbox provider from Settings > Sandboxes
- run a small task and confirm it clones, executes, and uploads an artifact
- test a configured live preview from outside the home network
- if configured, mention the Roomote app in Slack and confirm it replies
- The public URL works on cellular but not on Wi-Fi. The router may not support hairpin NAT. Add split-horizon DNS for LAN clients or use a resolver that returns the correct internal route.
- An
sslip.iohostname does not resolve on the LAN. DNS-rebind protection may reject names that resolve to private addresses. Use a domain you control or allow the exact hostname in the local resolver. - Certificates never issue. Confirm public DNS, router forwarding, and host
firewall rules for ports 80 and 443. With a tunnel, use
--tls-mode internaland check the tunnel-to-Caddy origin TLS settings. - Port forwarding has no effect. Compare the router WAN address with an external public-IP check. Different addresses usually indicate CGNAT; use a tunnel or request a public address from the ISP.
- A task cannot clone a LAN repository. Use a public, worker-reachable source-control hostname. Do not remove the sandbox private-network guard.
Back up and update
Useroomote backup, roomote upgrade, and roomote rollback for supported
day-2 operations. A Proxmox snapshot is useful before host maintenance, but it
does not replace an encrypted Roomote backup stored off the VM with its
passphrase stored separately. See Self-hosting
for backup, restore, and upgrade behavior.