Migrating to Incus from LXD

Incus is a manager for virtual machines and system containers.

A virtual machine is an instance of an operating system that runs on a computer, along with the main operating system. A virtual machine uses hardware virtualization features for the separation from the main operating system.

A system container is an instance of an operating system that also runs on a computer, along with the main operating system. A system container uses, instead, security primitives of the Linux kernel for the separation from the main operating system. You can think of system containers as software virtual machines.

All these are managed together by Incus. Depending on your requirements, you would select either a virtual machine of a system container. Between the two, system containers are more lightweight and you can fit much more of them on your computer.

Why Incus?

There are many use-cases to go for instances of virtual machines and system containers. They all boil down to the simplicity of installing software and services into instances and not on your main operating system. If you install something in an instance and then want to remove it, you can get rid of the instance. Your main operating system remains nice and clean.

If you keep a server (such a Virtual Private Server/VPS or a baremetal server), you can host many websites on the same server. Each will be on its own Incus instance. Your database server will be in yet another instance, and it will communicate with the websites with instance-to-instance communication. Do you want to setup one of those instant messaging bots? Launch another instance and install the messaging bot there. Are you into weather forecasting and you want to save monthly weather conditions files because they don’t keep historical records? Launch another instance and set up a cron job to keep copies of those monthly files.

Historical weather conditions of one location. Oh, I set this up in 2016 and it is still running fine.

Another use-case is when you are a desktop Linux user and you install software in instances. It keeps your desktop Linux nice and clean. Also opens up many possibilities. Are you stuck with a single Viber desktop? Put’em in instances.

Migrating to Incus

You can either install Incus from scratch or migrate to Incus from LXD. In my case I am migrating an LXD installation with 27 system containers (seven of them running), and I am doing that while writing this blog post.

Setting up the Incus package repository

I am using these installation instructions to install Incus from a package. And these installation instructions for Incus packages that work for either Debian or Ubuntu. I am repeating the instructions here for my convenience.

Incus is packaged are a deb package and we need to add the appropriate repository. First, let’s look at the repository GPG key. We will first look at the repository key and in the next step we import it. Compared to the repository instructions, I am using the --list-packets parameter in order to view the keyid. I can then search on the keyserver that this key exists.

curl -fsSL https://pkgs.zabbly.com/key.asc | gpg --list-packets --fingerprint

The repository key for these Incus packages.

Then, download and install the key on my Debian-style Linux distribution. The first command verifies that there is a /etc/apt/keyrings/ directory. Then, it downloads the actual key as a text file and uses the tee command with sudo to show and save it in the /etc/apt/keyrings/ directory. After you run the commands, you can verify the new file, zabbly.asc is in there.

sudo mkdir -p /etc/apt/keyrings/
curl -fsSL https://pkgs.zabbly.com/key.asc | sudo tee /etc/apt/keyrings/zabbly.asc

Up to now we have added the repository key. The next step is to add the repository itself to our Linux. Create a file with the following content and save it as make-incus-repository-configuration.sh The benefit of running this script is that the details of your Linux distribution are configured automatically.

echo "Enabled: yes"
echo "Types: deb"
echo "URIs: https://pkgs.zabbly.com/incus/stable"
echo "Suites: $(. /etc/os-release && echo ${VERSION_CODENAME})"
echo "Components: main"
echo "Architectures: $(dpkg --print-architecture)"
echo "Signed-By: /etc/apt/keyrings/zabbly.asc"

Now run the following command to install the repository to your system. The command will run the script and create the appropriate configuration for your distribution, and then, again, pipe the output through the sudo tee command to write them to the appropriate location, and also show the output at the same time on your terminal.

sh make-incus-repository-configuration.sh | sudo tee /etc/apt/sources.list.d/zabbly-incus-stable.sources

Installing the Incus server and client

The repository is in place. We need to perform a sudo apt update so that our system refreshes with the newly enabled repository. Then, we install the incus package that includes both the Incus server (the manager) and the incus command line client.

sudo apt update
sudo apt install incus

We have installed the Incus server but we did not initialize it. We must not initialize it because we want to perform the migration.

Configuring the access to the incus client

When we use a non-root user account on our Linux system, we need to give it special access so that our non-root user account can have access to the Incus server/manager. We do this my adding the said non-root user account to the special incus-admin Unix group. During the installation of the incus package, the installer added two new Unix groups, incus-admin (full admin access) and incus (simple administrative tasks). We are adding our non-root username, which is myusername into the incus-admin Unix group.

sudo adduser myusername incus-admin

We have added our account to the incus-admin Unix group. But is it activated straight away? No, due to the way Unix/Linux works. We either need to restart our desktop session (i.e. logout/login or reboot) or use the newgrp Unix command to enable the new Unix group for the current shell. I’ll do the newgrp trick.

newgrp incus-admin

When you run the command, it will appear as nothing change. However, if you run groups to check what groups you are in, you will notice that incus-admin appears first in the list. If you are prompted to type a password, then you did not run properly the earlier adduser command.

Now we are ready to perform the migration and run incus commands through this newgrp shell.

Migrating to Incus with lxd-to-incus

We have installed the incus package that includes both the Incus server/manager, the incus client utility, and also brought in the lxd-to-incus utility that migrates from LXD to Incus.

While migrating, you are prompted whether to remove the LXD package. If you plan to do so, look into ~/snap/lxd/common/config/ for any important configuration to backup. Removing the snap package may remove any configuration here (such as aliases and remotes). If unsure, do not remove LXD just yet.

There is a LXD installation with 27 system containers (7 are running) that I will YOLO right now to Incus according to the migration instructions. Here is the command. We need the sudo because the command performs all sort of administrative tasks in order to complete the migration. That is, it does way more than the incus tool with incus-admin privileges.

sudo lxd-to-incus

Here is the output of the tool. I timed the migration process. It took 45 seconds to complete. Those system containers that were running, were restarted automatically.

Output of the lxd-to-incus migration tool. A successful migration.

Using Incus

You have just migrated to Incus. Are there any changes to keep in mind?

First, there is by default one network remote, and it’s the images remote.

incus remote list


Default list of remotes in Incus.

Second, is there a list of images? Yes, visit https://images.linuxcontainers.org/

Third, are there default images? No. If you want to launch an instance with Debian or Ubuntu, you need to specify the version as well. For example, the current Debian image is called debian/12. There are not default debian or ubuntu images or such aliases.

Fourth, to see the list of all available images from the command line, run

incus image list images:

Finally, to create a Debian 12 container called mydebian, then stop it, then remove it, do the following.

incus launch images:debian/12 mydebian
incus stop mydebian
incus delete mydebian


We have successfully migrated to Incus. We now use the incus command to perform Incus tasks.

We finish this post with a reference to where the name comes from. The name comes from cumulonimbus incus, which is a type of cloud. Clouds, cloud computing. See?

Cumulonimbus incus, an impressive cloud. It resembles an anvil. If you see such a cloud, it will rain heavily below.

The inception of the name is by Aleksa Sarai who also created the fork. The main maintainer of Incus is Stéphane Graber. If you want to try Incus online through your browser, without installing it, visit the Try it Incus page.


Error: Required command “zfs” is missing for storage pool

You are trying to migrate from LXD to Incus, you have a ZFS storage pool, but you do not have the zfs utility. This is a common case if you have been using the LXD snap package. The snap package includes inside a version of zfs, therefore this utility has not been installed system-wide.

Remedy: Install the zfsutils-linux package.

sudo apt install zfsutils-linux

Permanent link to this article: https://blog.simos.info/migrating-to-incus-from-lxd/


1 pings

    • James Tervit on January 30, 2024 at 14:10
    • Reply

    thanks for the write I just discoverd lxd and now migrating to incus as a result of image support.

  1. […] You should already have a installation of Incus. If you do not have yet, see the official documentation on Incus installation and Incus migration, or my prior posts on Incus installation and Incus migration. […]

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.