Why
Running Vole on a server today means reading docs/packaging.md, writing a
vole.toml by hand, discovering that ports 80 and 443 need a capability drop-in,
and knowing that the first instance admin has to be granted on the host. All of
that is documented, and all of it is on the new operator to assemble correctly.
None of it is hard, which is the point: a new instance is one package, one configuration file, one directory, and one account. The work is in not getting it wrong on the first boot, when nobody is watching and a mistake costs a fresh machine.
Scope
Put that assembly in the repository, once, so the same steps are used by everyone and checked by CI:
deploy/cloud-init/vole.yaml— the first-boot file: installs the package, writes the configuration, creates the instance admin, starts the service. Two configurations are staged (acme,proxy) and the script installs the one the caller named.deploy/cloud-init/render.sh— renders it for providers that take user data without Terraform.deploy/terraform/{hetzner,digitalocean,aws}— one complete configuration per cloud: machine, firewall, address, optional DNS record. Each is a root module so the apply isterraform init && terraform applywith three variables.deploy/docker/{Dockerfile,compose.yaml,entrypoint.sh,vole.toml}— the server in one container, with a volume for the instance.docs/deploy/— an index page plus one guide per path, written for someone who has not deployed Vole before.scripts/check-deploy.pyand adeployment filesstep in the verify workflow, so a stray placeholder or a broken boot script fails a push rather than a first boot.
What is deliberately out of scope
- Machine images. A golden image per cloud needs a publishing pipeline and a
per-cloud import, and goes stale between releases. Installing the
.debat first boot is about thirty seconds and always installs the version the operator named. - Configuration management after first boot.
terraform applydoes not upgrade an instance and does not touch its data. The account database migration is one-way, so an upgrade stays an explicit package install with a backup first. The guides say so. - Multi-tenant hosting. Vole is one team on one server; a hosted offering would be a fleet of these, not a change here.
Checklist
- First-boot file, with both TLS arrangements
- Renderer for providers without Terraform
- Terraform configurations for Hetzner Cloud, DigitalOcean, and AWS
- Container image, compose file, and entrypoint
- A guide per path, plus the index page
- CI: template renders with no placeholder left, boot script is valid
sh, Terraform is formatted - Provisioning rehearsed end to end on a Debian container: package install,
configuration, instance admin, idempotent second run,
/healthz - A public download URL for the
.debin the guides (currently a placeholder in the examples, because the release page of the project’s own instance is the distribution channel and the docs do not name one)
Acceptance criteria
terraform applyon a clean account produces a working instance athttps://<domain>with one instance admin, without editing any file.render.shproduces user data that a provider accepts, and the machine comes up configured.- The container serves
/healthzand acceptsdocker compose exec vole admin .... vole workflow run verifychecks all of the above files.- The guides tell an operator what to do first, what to back up, and how to upgrade.