incus-contrib/notes/migration-guide.md

9.6 KiB

Migration Guide: Importing Workloads into Incus

This guide covers migrating virtual machines and containers from other hypervisors into Incus. Each section documents a specific migration path with tested procedures where available.

All commands tested with Incus 6.21 on IncusOS.


Overview

Incus provides several ways to import workloads:

Tool Use case
incus-migrate Official migration tool. Imports disk images, running instances, or physical machines
incus import Import from an Incus backup file (.tar.gz)
incus storage volume import Import a raw/qcow2 disk as a storage volume
qemu-img convert Convert between disk formats (vmdk, qcow2, raw, vdi)

General migration workflow

  1. Export the VM disk from the source hypervisor
  2. Convert the disk to raw or qcow2 format (if needed)
  3. Import into Incus via incus-migrate or manual volume import
  4. Configure the Incus instance (network, boot, etc.)
  5. Verify the migrated workload boots and runs correctly

Proxmox VE to Incus

Status: documented, can be tested with lab VMs.

# 1. Identify the disk on Proxmox
ssh root@proxmox pvesm list local-lvm | grep vm-<VMID>

# 2. Export the VM disk as raw
ssh root@proxmox qm disk export <VMID> scsi0 /tmp/disk.raw --format raw

# 3. Copy to the Incus host
scp root@proxmox:/tmp/disk.raw /tmp/disk.raw

# 4. Import as a storage volume
incus storage volume import <remote>:local /tmp/disk.raw migrated-disk --type=block

# 5. Create an empty VM
incus init --empty --vm migrated-vm <remote>:

# 6. Attach the imported disk
incus config device add <remote>:migrated-vm root disk pool=local source=migrated-disk

# 7. Configure for boot
incus config set <remote>:migrated-vm security.secureboot=false  # if source lacks SB
incus start <remote>:migrated-vm

Method 2: Using incus-migrate

# On the Incus host (or any machine with access to both)
incus-migrate

# Interactive prompts:
# 1. Select "Import from disk image"
# 2. Point to the exported raw/qcow2 file
# 3. Select target Incus server and storage pool
# 4. Choose VM instance type

Notes

  • Proxmox ZFS volumes can be exported with zfs send for faster transfer
  • LVM-thin volumes: use qm disk export (abstracts the LVM details)
  • UEFI VMs: ensure the Incus VM is configured with UEFI boot (security.secureboot=false if the source OS lacks Secure Boot support)
  • Network: the VM will get a new MAC address in Incus. Update any static network config inside the VM after migration.
  • Guest agent: install incus-agent inside the VM after migration for full management capabilities.

UTM to Incus

Status: documented (theoretical). Testable when running on macOS.

UTM stores VMs as .utm bundles (directories) containing qcow2 disk images.

Procedure

# 1. Locate the UTM VM bundle
ls ~/Library/Containers/com.utmapp.UTM/Data/Documents/*.utm/

# 2. Find the qcow2 disk inside the bundle
ls <vm-name>.utm/Data/*.qcow2

# 3. Convert to raw (if needed)
qemu-img convert -f qcow2 -O raw <vm>.utm/Data/disk.qcow2 /tmp/disk.raw

# 4. Transfer to Incus host (if remote)
scp /tmp/disk.raw user@incus-host:/tmp/

# 5. Import into Incus (same as Proxmox method)
incus storage volume import <remote>:local /tmp/disk.raw migrated-disk --type=block
incus init --empty --vm migrated-vm <remote>:
incus config device add <remote>:migrated-vm root disk pool=local source=migrated-disk
incus start <remote>:migrated-vm

Notes

  • UTM supports both Apple Virtualization (arm64 only) and QEMU backends. VMs from the QEMU backend are most compatible with Incus.
  • Apple Virtualization VMs use a different format and may not be directly importable.
  • arm64 VMs from UTM can be imported into arm64 Incus hosts.
  • x86_64 VMs (via QEMU backend on Intel Macs) can be imported into x86_64 Incus hosts.

VMware Fusion to Incus

Status: documented (theoretical). Testable when VMware Fusion is available.

VMware Fusion stores VMs as .vmwarevm bundles containing .vmdk disk files.

Procedure

# 1. Locate the VM bundle
ls ~/Virtual\ Machines.localized/*.vmwarevm/

# 2. Find the VMDK disk
ls <vm-name>.vmwarevm/*.vmdk

# 3. Convert VMDK to raw
qemu-img convert -f vmdk -O raw <vm>.vmwarevm/disk.vmdk /tmp/disk.raw

# 4. Transfer and import into Incus (same workflow)
scp /tmp/disk.raw user@incus-host:/tmp/
incus storage volume import <remote>:local /tmp/disk.raw migrated-disk --type=block
incus init --empty --vm migrated-vm <remote>:
incus config device add <remote>:migrated-vm root disk pool=local source=migrated-disk
incus start <remote>:migrated-vm

OVA/OVF export (alternative)

# VMware Fusion can export VMs as OVA
# File -> Export to OVF...

# Extract VMDK from OVA (OVA is a tar archive)
tar xf machine.ova
ls *.vmdk

# Convert and import as above
qemu-img convert -f vmdk -O raw *.vmdk /tmp/disk.raw

Notes

  • Split VMDK files (multiple .vmdk files): use qemu-img which handles split VMDK chains automatically.
  • VMware Tools: uninstall before migration if possible, or install open-vm-tools equivalent in the guest after migration.
  • Network adapter type changes from vmxnet3 to virtio.

Physical Machine to Incus

Status: documented. incus-migrate supports direct physical-to-virtual.

Run incus-migrate directly on the physical machine:

# On the physical machine (requires root)
sudo incus-migrate

# Interactive prompts guide you through:
# 1. Connect to Incus server
# 2. Select "Migrate this machine"
# 3. Choose instance type (container or VM)
# 4. incus-migrate streams the filesystem/disk to Incus

Method 2: Disk image capture

# 1. Create a disk image from the physical machine
sudo dd if=/dev/sda of=/tmp/disk.raw bs=4M status=progress

# 2. Transfer to Incus host
scp /tmp/disk.raw user@incus-host:/tmp/

# 3. Import as usual
incus storage volume import <remote>:local /tmp/disk.raw migrated-disk --type=block
incus init --empty --vm migrated-vm <remote>:
incus config device add <remote>:migrated-vm root disk pool=local source=migrated-disk

Notes

  • incus-migrate is the cleanest approach for physical machines.
  • Disk image capture preserves everything (bootloader, partitions) but creates very large files. Use compression: dd | gzip > disk.raw.gz
  • Shrink the disk image after transfer: qemu-img convert -O raw disk.raw disk-shrunk.raw (removes trailing zeros).
  • Hardware drivers: the guest may need to regenerate initramfs for the new virtual hardware (virtio drivers).

Container Migration (Docker/Podman to Incus)

Status: documented. Container filesystem import is straightforward.

Docker to Incus container

# 1. Export the container filesystem
docker export <container-id> > /tmp/container-fs.tar

# 2. Import into Incus as a container
incus import <remote>: /tmp/container-fs.tar imported-container

# 3. Start
incus start <remote>:imported-container

Podman to Incus container

# Same approach -- podman export is compatible
podman export <container-id> > /tmp/container-fs.tar
incus import <remote>: /tmp/container-fs.tar imported-container

Docker image to Incus

# Save image as tar
docker save <image-name> > /tmp/image.tar

# Note: docker save creates an OCI image archive, not a filesystem tar.
# incus import expects a filesystem tar. Use docker export (from a running
# container) instead.

Notes

  • Docker containers are typically single-process. Incus containers run a full init system. The imported container may need an init process (systemd, openrc) installed.
  • Networking: Docker networking doesn't translate. The imported container gets Incus networking (bridge-based).
  • Volumes: Docker volumes are NOT exported with docker export. Copy volume data separately.
  • For complex Docker Compose stacks, consider running Docker inside an Incus VM instead of migrating individual containers.

Disk Format Reference

Format Extension Tools Notes
Raw .raw, .img dd, qemu-img No overhead, largest size
QCOW2 .qcow2 qemu-img Sparse, snapshots, common in KVM/QEMU
VMDK .vmdk qemu-img VMware format, may be split across files
VDI .vdi qemu-img VirtualBox format
VHD/VHDX .vhd, .vhdx qemu-img Hyper-V format

Converting between formats

# QCOW2 to raw
qemu-img convert -f qcow2 -O raw input.qcow2 output.raw

# VMDK to raw
qemu-img convert -f vmdk -O raw input.vmdk output.raw

# Raw to QCOW2 (for storage efficiency)
qemu-img convert -f raw -O qcow2 input.raw output.qcow2

# VDI to raw
qemu-img convert -f vdi -O raw input.vdi output.raw

# Check image info
qemu-img info disk.qcow2

Post-Migration Checklist

After importing a workload into Incus:

  • Verify the instance boots and runs correctly
  • Update network configuration (new MAC address, new IP range)
  • Install incus-agent inside VMs for full management
  • Remove source-hypervisor-specific tools (VMware Tools, etc.)
  • Regenerate initramfs if hardware changed significantly
  • Update /etc/fstab if disk device names changed
  • Test application functionality
  • Set up backups in Incus (incus export or snapshots)

References