VMCompose Reference
A VMCompose file is a YAML manifest that defines a multi-VM environment. It declares services (virtual machines), networks, and their relationships in a single file — enabling declarative orchestration of complex VM topologies with networking, cloud-init provisioning, resource overrides, and dependency ordering.
Minimal Example
apiVersion: vmregistry.io/v1alpha1
kind: VMCompose
name: my-project
services:
web:
image: myuser/web-server:latestFull Example
apiVersion: vmregistry.io/v1alpha1
kind: VMCompose
name: ziti
networks:
ziti-private-a:
mode: isolated
subnet: 192.168.70.0/24
gateway: 192.168.70.1
ziti-public:
mode: nat
subnet: 10.170.0.0/24
gateway: 10.170.0.1
services:
ziti-server-a-1:
image: nixos-server/nixos-k3s-vm:ziti
diskSize: "20G"
resources:
cpu: 2
memory: "8GiB"
networks:
- name: ziti-private-a
staticIp: 192.168.70.10
gateway: 192.168.70.1
- name: ziti-public
staticIp: 10.170.0.10
gateway: 10.170.0.1
cloudInit:
userData: |
#cloud-config
hostname: ziti-server-a-1
fqdn: ziti-server-a-1.local
manage_etc_hosts: true
ziti-server-a-2:
image: nixos-server/nixos-k3s-vm:ziti
diskSize: "20G"
resources:
cpu: 2
memory: "8GiB"
dependsOn:
- ziti-server-a-1
networks:
- name: ziti-private-a
staticIp: 192.168.70.11
gateway: 192.168.70.1
cloudInit:
userDataFile: ./cloud-init/server-a-2.yaml
restartPolicy: on-failureSchema
Top-Level Fields
| Field | Type | Required | Description |
|---|---|---|---|
apiVersion | string | yes | API version of the VMCompose format. Valid values: vmregistry.io/v1alpha1, v1 |
kind | string | no | Document kind. Must be VMCompose if specified. |
name | string | no | Name of the compose project. Used to namespace all resources created by this compose file. |
services | map | yes | Map of service definitions. Each key is a service name and the value is the service configuration. |
networks | map | no | Map of network definitions. Each key is a network name and the value is the network configuration. |
services.<name>
Each service defines a single virtual machine within the compose project.
| Field | Type | Required | Description |
|---|---|---|---|
image | string | yes | VM image to use. Can be a local image name or a registry reference (e.g., namespace/image:tag). |
resources | object | no | Resource overrides for this service (CPU, memory). If omitted, the image's defaults are used. |
network | object | no | Single network configuration. Use network for one interface or networks for multiple. |
networks | list | no | List of network configurations. Use when the VM needs multiple network interfaces. |
cloudInit | object | no | Cloud-init configuration for guest OS provisioning. |
ephemeral | boolean | no | Whether the VM's disk is ephemeral — changes are discarded on stop. Default: false. |
dependsOn | list | no | List of service names that must be started before this service. Cyclic dependencies are not allowed. |
restartPolicy | string | no | Restart policy for the VM: always, on-failure, never, or unless-stopped. |
diskSize | string | no | Override disk size for the VM (e.g., 20G, 100GiB). |
services.<name>.resources
| Field | Type | Required | Description |
|---|---|---|---|
cpu | integer | no | Number of virtual CPUs. Must be between 1 and 64. |
memory | string | no | Amount of RAM. Format: <number><unit> where unit is MiB, GiB, or TiB. |
services.<name>.network / services.<name>.networks[]
Each network entry attaches the VM to a virtual network with optional static addressing.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | no | Name of the network to attach to. Must reference a network defined in the top-level networks section or an existing libvirt network. |
mode | string | no | Network mode for this interface: nat, isolated, routed, bridge, open, macvtap, or default. |
staticIp | string | no | Static IP address to assign. Format: IPv4 dotted-decimal (e.g., 192.168.100.10). |
gateway | string | no | Gateway IP address for this interface. Format: IPv4 dotted-decimal. |
dns | list | no | List of DNS server IP addresses. |
mac | string | no | MAC address to assign. Format: colon-separated hex (e.g., 52:54:00:12:34:56). |
parentDev | string | no | Host parent device for macvtap mode (e.g., enp3s0, eth0). Required when mode is macvtap. |
services.<name>.cloudInit
Cloud-init enables guest OS provisioning at first boot. Supports inline content or file references for each data source.
| Field | Type | Required | Description |
|---|---|---|---|
userData | string | no | Inline cloud-init user-data content (YAML cloud-config or script). |
userDataFile | string | no | Path to a cloud-init user-data file. Can be absolute or relative to the compose file. |
metaData | string | no | Inline cloud-init meta-data content. |
metaDataFile | string | no | Path to a cloud-init meta-data file. Can be absolute or relative to the compose file. |
networkConfig | string | no | Inline cloud-init network configuration (v2 format). |
WARNING
Do not specify both userData and userDataFile for the same service — if both are present, the inline userData content takes precedence. The same applies to metaData / metaDataFile.
networks.<name>
Each network entry defines a libvirt virtual network that services can attach to.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | no | Display name override for the network. |
mode | string | no | Network mode: nat, isolated, routed, bridge, open, or macvtap. Default: nat. |
driver | string | no | Network driver: bridge, nat, isolated, or macvtap. |
subnet | string | no | Subnet in CIDR notation (e.g., 192.168.100.0/24). |
gateway | string | no | Gateway IP address (e.g., 192.168.100.1). |
bridge | string | no | Host bridge interface name. Required when mode is bridge. |
dhcp | boolean | no | Whether to enable DHCP on this network. Default: false. |
parentDev | string | no | Host parent device for macvtap mode. Required when mode is macvtap. |
Network Modes
| Mode | Description |
|---|---|
nat | NAT with host masquerade. Guests can reach external networks through the host. This is the default mode. |
isolated | Isolated network with no external connectivity. Guests can only communicate with each other on this network. |
routed | Routed network with static routes. No NAT — requires external routing to be configured on the host. |
bridge | Bridged to an existing host bridge interface. Guests appear directly on the host's physical network segment. Requires the bridge field. |
open | Open/unrestricted forwarding. No firewall rules are applied to network traffic. |
macvtap | Direct attachment via macvtap to a host physical interface. Requires the parentDev field. Provides near-native network performance. |
Restart Policies
| Policy | Description |
|---|---|
always | Always restart the VM regardless of how it exited. |
on-failure | Restart only when the VM exits with a non-zero status. |
never | Never automatically restart the VM. |
unless-stopped | Restart the VM unless it was explicitly stopped by the user. |
Service Dependencies
The dependsOn field establishes startup ordering between services. The daemon resolves the dependency graph and starts services in topological order — all dependencies of a service are started before the service itself.
services:
database:
image: myuser/postgres-vm:latest
backend:
image: myuser/api-server:latest
dependsOn:
- database
frontend:
image: myuser/web-ui:latest
dependsOn:
- backendIn this example, database starts first, then backend, then frontend.
WARNING
Cyclic dependencies are detected at validation time and will cause the compose operation to fail. For example, if service A depends on B and B depends on A, the daemon will report a validation error.
Path Resolution
File paths in userDataFile and metaDataFile support both absolute and relative paths:
- Absolute paths are used as-is
- Relative paths are resolved from the directory containing the VMCompose file
Validation
The daemon validates VMCompose files when vmr compose up or vmr compose validate is invoked. The following checks are performed:
apiVersionis present and matches a known versionservicesis present and contains at least one service- Each service has a valid
imagefield - Network mode values are one of the supported modes
- Restart policy values are one of the supported policies
subnetfields use valid CIDR notationgatewayandstaticIpfields use valid IPv4 formatmacfields use valid colon-separated hex formatdependsOnreferences point to service names that exist in the file- No cyclic dependencies exist between services
- Networks referenced by services are either defined in the top-level
networkssection or exist as pre-existing libvirt networks
For real-time validation in your editor as you write VMCompose files, see the LSP component.