Skip to content

Vultr infrastructure images

The repository has three independent Packer entry points. Build each file explicitly, not the whole packer/ directory: they intentionally declare their own provider, variables and manifest.

Server Template Snapshot contract Manifest
Client client/packer/client.pkr.hcl oduflow-image-v1 packer/output/manifest.json
Salt Master packer/master.pkr.hcl oduflow-master-image-v1 packer/output/master-manifest.json
LiteLLM packer/litellm.pkr.hcl oduflow-litellm-image-v1 packer/output/litellm-manifest.json

All templates pin Packer 1.16.0, Vultr plugin 2.7.0 and Ubuntu 24.04 x64 (OS 2284). Infrastructure builders use vc2-1c-1gb with a 25 GB boot disk; this is a build size, not production capacity guidance. The default region is ams. These are dependency images, with fresh enrollment and configuration required on every cloned server.

Contents and Salt reuse

Both new images reuse salt/minion/install.sh to install the pinned Salt 3006.27 and Tailscale 1.102.4 prerequisites from verified repositories.

The Master image adds Salt Master/API 3006.27 and applies control_master.packages for API Python dependencies. The normal control_master state includes that same package state. Headscale, Traefik, backup configuration, certificates, master PKI and API credentials are supplied by the existing master bootstrap workflow after cloning; they are not baked in.

The LiteLLM image installs Docker/containerd and applies litellm.native_packages to install the hash-locked native gateway, generated Prisma client, metering virtualenv and runtime helper files. Native VM installation and the OCI image reuse this state. The ordinary guarded litellm.install chooses packages for the requested runtime. It still requires a valid identity and verified block volume before writing runtime settings. No Client Oduflow/Paseo application build runs in either infrastructure image.

Docker/containerd stay masked. On LiteLLM images, their systemd drop-ins also require /srv/oduflow/data to be a mount point. There are no OCI image caches, databases, gateway settings or application data on the boot disk. The selected LiteLLM container is pulled onto the verified data volume during normal Salt configuration. Python helper files and dependencies under /opt are software, not gateway data.

Build and publish

Run from an isolated checkout of a reviewed commit. Set ODUFLOW_VULTR_API_KEY securely in the builder process environment. Packer does not read this credential from Odoo settings, and does not upload it to the VM. Never place it in shell arguments or committed variable files.

mkdir -p packer/output
packer init packer/master.pkr.hcl
packer validate packer/master.pkr.hcl
packer build -var "source_revision=$(git rev-parse HEAD)" packer/master.pkr.hcl

packer init packer/litellm.pkr.hcl
packer validate packer/litellm.pkr.hcl
packer build -var "source_revision=$(git rev-parse HEAD)" packer/litellm.pkr.hcl

Packer creates a disposable VM, uploads only salt/, installs dependencies and runs cleanup. It then creates a private snapshot on the account owning the API key and removes the builder VM and temporary SSH-key record on successful completion. Each manifest records the snapshot ID and source revision. Inspect failed builds before another attempt; never blindly repeat ambiguous cloud resource creation or delete a machine based only on its name.

Cleanup refuses existing Master/Client identity, control settings, gateway settings, data mounts, master/API keys, Docker data and symlinked protected paths. It reuses the minion cleanup for VPN/minion identity, cloud-init data, SSH host keys and machine ID, removes the uploaded sources and Salt caches, deletes builder authorized keys and locks its temporary root password. The plugin's shutdown behavior and fresh-clone verification requirements are the same as for the Client image.

Use and verification boundary

There is no Packer job runner or publication button in oduflow_vultr. These templates follow the existing external Client build workflow.

The current Odoo plan provisioning accepts the Client contract oduflow-image-v1 only. Do not paste a Master or LiteLLM snapshot into the Client Golden Image field or relabel it as a Client image. Infrastructure snapshots can be used to create a fresh VM in Vultr separately. Register a Master clone with its new SSH host key through the existing oduflow_master installation flow. A LiteLLM clone still needs VPN/minion enrollment and its own verified block volume before the managed LiteLLM Salt configuration runs. Automatic selection of these role-specific snapshots in Odoo is not introduced by these build templates.

Static validation and offline Salt tests establish template/configuration contracts only. Publication and end-to-end provisioning require a real build and a fresh clone with enrollment. No Master or LiteLLM published snapshot ID is claimed by this change.