Deploying to a host¶
Deployment is a single pyinfra script that takes a bare Linux box to a running service. It's idempotent; re-running upgrades the code and restarts the service without regenerating the token or re-downloading images.
What it sets up¶
- the virtualization stack (KVM, libvirt, QEMU,
cloud-image-utils) and acloudaloneservice user; - the
br-cloudbridge + IPv6 forwarding (withaccept_ra=2so the host keeps its default route) carrying your routed prefix; - on Dedibox, a DHCPv6-PD client that keeps the prefix routed;
- the app (
uv sync --extra libvirt), config + token, thedebian-13base image, and the systemd unit; - optionally, Caddy as a TLS reverse proxy.
1. Prerequisites¶
- A Linux box with KVM and SSH access.
- An IPv6 prefix routed to it: see IPv6 networking for how to get one on your provider.
- For Dedibox specifically: order the free
/48and enable Activate IPv6 SLAAC in the console before deploying.
2. Configure the inventory¶
# deploy/inventory.py
hosts = [
("mybox", {
"ssh_user": "root",
"ipv6_prefix": "2001:db8:abcd:100::/64", # the routed prefix
"dhcpv6_duid": "00:03:00:01:…", # Dedibox only; omit otherwise
"api_host": "api.example.com", # optional, enables TLS
}),
]
Per-host settings (uplink, ipv6_prefix, dhcpv6_duid, bridge, backend) come from host.data; the bridge gateway is derived as <prefix>::1.
3. Smoke-test, then deploy¶
Before touching a real box, run the whole deploy against a throwaway systemd container (no KVM, but it exercises everything else):
Then deploy for real:
4. Verify¶
ssh mybox '
systemctl is-active cloudalone
systemctl is-active cloudalone-dhcpv6 # Dedibox only
ip -6 addr show br-cloud # expect <prefix>::1/…
ping6 -c2 2001:4860:4860::8888' # host reaches the v6 internet
Then create a VM and SSH in (see Your first server).
TLS endpoint¶
When api_host is set, the deploy installs Caddy as a TLS reverse proxy (https://<api_host>/v1 → 127.0.0.1:8000, auto Let's Encrypt) and binds cloudalone to localhost behind it.
DNS first
Add an A record for <api_host> pointing at the box's public IPv4 (and open ports 80/443) before deploying, so Caddy can complete the ACME challenge.
Persistence¶
VMs are set to autostart and the service reconciles DB state against libvirt on startup, so a host reboot brings VMs back and won't leave actions stuck at running. The bridge and forwarding persist via systemd-networkd + sysctl.d.