Menu

CLI — VMs

metalhost vm (aliases vms, compute) provisions and manages virtual machines — from quick flags or a declarative YAML manifest.

Commands

CommandWhat it does
vm listList VMs in the active project.
vm get NAMEGet a VM by resource name.
vm createProvision from flags (see below).
vm apply -f FILEProvision from YAML/JSON manifest.
vm start|stop|restart NAMEPower actions.
vm delete NAMETear down the VM.
vm resize NAME --vcpus N --ram-gib NChange shape (stop → patch → start).
vm reimage NAMEWipe OS disk and reinstall.
vm clone --source NAME --display-name NEWDisk-level copy.
vm console NAME --type serial|vncShort-lived console URL.
vm metrics NAMECPU / memory / network samples.
vm autorenew NAME --enable|--disableToggle monthly auto-renew.
vm renew NAMERenew a monthly VM immediately.

vm create flags

Use flags for simple single-user VMs. For GPU, multiple users, billing modes, or cloud-init, use a YAML manifest instead.

FlagWhat it does
--vcpus NvCPU count (required).
--ram-gib NRAM in GiB (required).
--cpu-class NAMEe.g. cascadelake (required).
--image IDCatalog image, e.g. ubuntu-24-04.
--boot-url URLRaw image URL (alternative to --image).
--boot-disk-name NAMEExisting disk as boot volume.
--disk-size-gib NBoot disk size (required with image/boot-url).
--gpu-model NAME / --gpu-count NGPU passthrough, e.g. rtx4090.
--hostname NAMEDNS hostname; defaults to a UUID slug.
--user NAME / --password / --sudoSingle login user (use manifest for multiple).
--ssh-key PUBKEYInline public key (repeatable).
--ssh-key-name NAMERegistered key resource name (repeatable).
--user-data YAMLcloud-init user-data — owns user creation.
--network NAMETenant network (default: project's default).
--assign-public-ipv4Attach a public IPv4.
--billing-mode MODEHOURLY, monthly-1monthly-12.
--autorenewAuto-renew for monthly modes.
--waitBlock until the create operation finishes.
metalhost vm create \
  --vcpus 2 --ram-gib 8 --cpu-class cascadelake \
  --image ubuntu-24-04 --disk-size-gib 80 \
  --hostname my-vm \
  --ssh-key-name projects/main/ssh-keys/laptop \
  --assign-public-ipv4 \
  --wait

YAML manifest

Use metalhost vm apply -f vm.yaml when flags aren't enough — multiple users, GPU shapes, prepaid billing, labels, or full cloud-init. Same schema as the dashboard and Go SDK.

Apply a manifest

metalhost vm apply -f vm.yaml --wait

# Omit project/region in the file — fill from profile or flags:
metalhost vm apply -f vm.yaml --project projects/my-app --region datacenters/us-dal-1 --wait

# Pipe from stdin:
cat vm.yaml | metalhost vm apply -f - --wait

metadata.project and spec.region fall back to your active CLI profile (or --project / --region) when omitted. Returns an operation — use --wait to block until provisioning finishes.

Schema

Top-levelRequiredDescription
apiVersionNocompute.metalhost.io/v1
kindNoVirtualMachine
metadataYesname, project, labels, annotations
specYesRegion, compute, boot, network, users, billing, cloud-init

spec.compute

FieldDescription
cpuClasscascadelake, milan, etc.
vcpus / ramGibShape — max 4 GiB RAM per vCPU on CPU VMs
gpu.model / gpu.countWhole-GPU passthrough, e.g. rtx4090

spec.boot

Exactly one of image, imageUrl, or diskName.

spec.network

publicIpv4 defaults to false. IPv6 is always on.

spec.users[]

name, sshKeys, sshPubkey, password, sudo.

spec.billing

mode: BILLING_MODE_HOURLY (default) or BILLING_MODE_MONTHLY_1 through BILLING_MODE_MONTHLY_12. autorenew for monthly modes.

Basic CPU VM

apiVersion: compute.metalhost.io/v1
kind: VirtualMachine
metadata:
  name: web-1
  project: projects/my-app
spec:
  region: datacenters/us-dal-1
  compute:
    cpuClass: cascadelake
    vcpus: 2
    ramGib: 8
  boot:
    image: ubuntu-24-04
    diskGib: 80
  network:
    publicIpv4: true
  users:
    - name: ubuntu
      sshKeys:
        - projects/my-app/ssh-keys/laptop

GPU VM with monthly billing

apiVersion: compute.metalhost.io/v1
kind: VirtualMachine
metadata:
  name: gpu-train-1
  project: projects/my-app
  labels:
    env: prod
spec:
  region: datacenters/us-dal-1
  compute:
    cpuClass: cascadelake
    vcpus: 8
    ramGib: 32
    gpu:
      model: rtx4090
      count: 1
  boot:
    image: ubuntu-24-04
    diskGib: 200
  network:
    publicIpv4: true
  users:
    - name: ubuntu
      sshKeys:
        - projects/my-app/ssh-keys/laptop
  billing:
    mode: BILLING_MODE_MONTHLY_1
    autorenew: true

Multiple login users

apiVersion: compute.metalhost.io/v1
kind: VirtualMachine
metadata:
  name: shared-dev
  project: projects/my-app
spec:
  region: datacenters/us-dal-1
  compute:
    cpuClass: cascadelake
    vcpus: 4
    ramGib: 16
  boot:
    image: ubuntu-24-04
    diskGib: 80
  network:
    publicIpv4: false
  users:
    - name: alice
      sshKeys:
        - projects/my-app/ssh-keys/alice-laptop
      sudo: true
    - name: deploy
      password: "change-me-on-first-login"
      sudo: false

Full cloud-init

apiVersion: compute.metalhost.io/v1
kind: VirtualMachine
metadata:
  name: custom-init
  project: projects/my-app
spec:
  region: datacenters/us-dal-1
  compute:
    cpuClass: cascadelake
    vcpus: 2
    ramGib: 8
  boot:
    image: ubuntu-24-04
    diskGib: 80
  network:
    publicIpv4: true
  cloudInit: |
    #cloud-config
    package_update: true
    packages:
      - nginx
    runcmd:
      - systemctl enable --now nginx
    users:
      - name: ubuntu
        sudo: ALL=(ALL) NOPASSWD:ALL
        ssh_authorized_keys:
          - ssh-ed25519 AAAA... you@host

Round-trip from a running VM

metalhost vm get web-1 -o yaml > vm.yaml
metalhost vm apply -f vm.yaml --wait

vm apply also accepts JSON with the same camelCase field names as the HTTP API.

Snapshots

CommandWhat it does
vm snapshot create --vm NAME --display-name STake a snapshot.
vm snapshot list --vm NAMEList snapshots.
vm snapshot get NAMEGet a snapshot.
vm snapshot delete NAMEDelete a snapshot.
vm from-backup --snapshot NAME ...Provision from a snapshot.

SSH keys

CommandWhat it does
vm ssh-key listList registered keys.
vm ssh-key create --id ID --public-key "ssh-ed25519 ..."Register a key.
vm ssh-key delete NAMEUnregister a key.

What's next