How to Use Incus: The Beginner's Guide (First Init, the Storage Lesson, First Container, First VM, and the Profile Rule)

CodexFuse Team · 2026-11-01T05:38:23.946Z · 14 min read

Learn how to use Incus: install the Linux system-container and VM manager, run incus admin init, pick the right storage pool, and launch your first container and VM.

How to Use Incus: The Beginner's Guide (First Init, the Storage Lesson, First Container, First VM, and the Profile Rule)

Learning how to use Incus is the step that turns "I have a spare Linux server" into "I have a private cloud." Incus is the Linux Containers project's system-container and virtual-machine manager: one daemon that launches full Linux systems — containers that behave like lightweight machines, and real VMs with their own kernels — from a single incus command line. Say this up front, because it is the number-one disqualification: the Incus daemon only works on Linux. There are client-only binaries for macOS, Windows, and FreeBSD so you can manage a remote host from your laptop, but you cannot host Incus on those operating systems. If your box runs Linux, though, this incus tutorial for beginners runs the complete ladder: install, the incus-admin group lesson nobody teaches, incus admin init, the storage-pool decision the wizard buries, your first system container, your first VM, the profile rule, and snapshots.

You will build in this order: install Incus on Ubuntu, Debian, or Arch, give your user the right group so you are not typing sudo on every command, initialize the daemon and choose a storage backend with your eyes open, launch your first container from the images server, launch your first VM with --vm, replace one-off flags with profiles, and snapshot before you break things. One fork-history sentence, since every search result leads with it: Incus is the community fork of LXD, created by Aleksa Sarai in 2023 after Canonical took LXD away from the Linux Containers project to build a fully community-led alternative. That is the whole story — the rest of this guide is about using it.

If your mental model is Docker-shaped, draw the line now: our Docker beginner guide covers app containers — one process per container, images built from Dockerfiles. Incus runs system containers: full Linux userlands with init systems, where you apt install things and treat the container like a tiny server. It is not a Docker replacement; it is the machine-layer underneath. Docker 560 is this guide's pillar in the container/virtualization cluster, and the two are never rivals.

How do you use Incus for the first time?

Using Incus for the first time means installing the daemon on Linux, adding yourself to the incus-admin group, running incus admin init to configure storage and networking, then launching instances from the public images server. The whole first arc fits in ten commands, and every step is explained below.

  1. Confirm Linux and KVM. The daemon needs Linux; VMs need hardware virtualization (check for /dev/kvm).
  2. Install Incus. Ubuntu 24.04 and 26.04 ship it in Universe; Ubuntu 22.04, Debian, and friends use the Zabbly repository; Arch has it in Extra.
  3. Join the incus-admin group. sudo adduser $USER incus-admin, then newgrp incus-admin or log out and back in. This is the permission lesson that saves you from a wall of "permission denied" errors.
  4. Run incus admin init. Answer the interactive wizard: networking bridge, and — most importantly — the storage pool driver.
  5. Make the storage decision deliberately. The official docs recommend zfs or btrfs; the --minimal shortcut silently picks dir, which is slower and cannot do fast snapshots.
  6. Launch your first system container. incus launch images:ubuntu/24.04 web1 — a full Ubuntu userland in seconds.
  7. Step inside it. incus exec web1 -- bash puts you at a root shell; install packages like it is a tiny server.
  8. Launch your first VM. incus launch images:debian/12 debian-vm --vm — same command family, a real kernel underneath.
  9. Write the profile rule down. Stop repeating --network and --storage flags; put defaults in a profile and launch with -p.
  10. Snapshot before you experiment. incus snapshot create web1 clean — one command, and you can always go back.

What is Incus, and what is a system container?

Incus is a manager for two things: system containers and virtual machines. A system container shares the host's kernel but runs a complete Linux distribution inside — systemd or its equivalent, a package manager, cron, sshd, the works. Where a Docker container is a wrapped-up application process, an Incus container is a wrapped-up machine without its own kernel. You manage both with the same daemon, the same images server, and mostly the same commands.

This distinction decides everything about how you use it. You do not write Dockerfiles for Incus; you launch an Ubuntu or Debian image and configure it like a server. You do not map ports one by one at launch; instances get real addresses on a managed bridge (incusbr0 by default) and behave like machines on a LAN. If you came from the Docker world, the Docker beginner guide stays your reference for app containers — Incus is the layer where you would otherwise be provisioning VPSes or VMs.

Incus is free and open source, maintained by the Linux Containers community at linuxcontainers.org, and as of this writing the current release is v7.6.0 (released 2026-10-30, per the GitHub API for lxc/incus — note the org is lxc, not linuxcontainers — with about 6,500 stars). Versions move roughly monthly on the stable channel, so treat exact version numbers as "current today" rather than gospel.

Can Incus run on macOS or Windows?

No — not as a host. The Incus daemon only works on Linux, full stop, and that is the first thing to check before you fall in love with it. What does exist is a client-only build for macOS, Windows, and FreeBSD: you install the incus CLI on your laptop and point it at a remote Linux server running the daemon. That is genuinely useful — many people run Incus on a home server or VPS and manage it from a Mac — but the workloads themselves always live on Linux.

For the rest of this guide, "your machine" means a Linux box. A spare PC, a home server, or a VPS all work, and the what is VPS hosting guide explains the rental side if you do not have hardware. The only extra requirement, and only for the VM half of the guide, is CPU virtualization support.

What do you need before installing Incus?

Three things, in order of how often beginners get bitten by them. First, a Linux host — Ubuntu 24.04 LTS, Debian 12, or Arch are the smoothest paths, and the install commands below assume one of them. Second, for VMs, hardware virtualization: on Intel or AMD CPUs this is VT-x/AMD-V, and you can check it with ls /dev/kvm. If that file does not exist, containers still work perfectly; only the --vm launches will fail. Cloud VPSes sometimes hide virtualization from guests, so check before you plan a VM lab. Third, disk space with a filesystem decision attached: if you want the recommended zfs or btrfs storage, that storage pool wants either a spare partition/disk or at least honest expectations about loop-backed files (slower, and they cannot shrink).

RAM and CPU are forgiving: a 2 GB VPS comfortably hosts a handful of idle system containers, and containers share the host kernel so their overhead is tiny. VMs are the hungry ones — budget real RAM per VM the way you would for any virtual machine. Install qemu-system alongside Incus if you plan to run VMs; the daemon's feature check looks for qemu-system-x86_64 in your $PATH.

How do you install Incus?

The incus install path depends on your distribution, and picking the wrong instructions is the most common install failure. Here are the three current paths, verified against the official docs and package indexes this week.

Ubuntu 24.04 and 26.04 ship Incus in the Universe repository — the shortest path in the ecosystem:

sudo apt update
sudo apt install incus
sudo apt install qemu-system  # only if you want VMs

Ubuntu 22.04, Debian 11/12+, and other apt distros use the Zabbly repository, which the Incus project recommends for anything not shipping a current build:

sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.zabbly.com/key.asc | sudo gpg --dearmor -o /etc/apt/keyrings/zabbly.asc
# then add the DEB822 source for https://pkgs.zabbly.com/incus/stable
sudo apt update
sudo apt install incus

Zabbly offers three channels — 6.0 LTS, Stable (new release roughly monthly), and Daily — so you choose between long-term calm and fresh features. Arch Linux carries Incus in Extra (sudo pacman -S incus; version 7.5.1 in the package index at the time of writing). Whichever path you take, confirm the daemon is alive with incus version before continuing.

Why does every Incus command fail until you join the incus-admin group?

Because the Incus daemon listens on a local Unix socket, and your user does not own it yet. A fresh install leaves you with a working daemon that only root can talk to — so every incus launch as your normal user dies with a permission error, and beginners conclude the install is broken. The fix is one command, and it is the lesson this guide's title promises:

sudo adduser $USER incus-admin
newgrp incus-admin   # or log out and back in

The incus-admin group grants full control of the daemon; there is also a plain incus group with limited per-user access, which is why adding yourself to the wrong one produces confusing half-working behavior. One security sentence the official docs insist on: local socket access is effectively root on the host — only trusted users belong in incus-admin. Never add a service account or a shared user to it casually.

Verify with incus info. If it prints server details instead of a permission error, your user can drive the daemon, and you never need sudo in front of incus again.

What happens during incus admin init?

incus admin init is the interactive setup wizard, and it asks about five things: whether to cluster (say no on your first host), the storage pool, the network bridge, and a couple of defaults. Two notes on the command itself. First, it is incus admin init — not incus init. Older tutorials say incus init; no current docs page mentions a bare incus init, so treat those tutorials as outdated. Second, there is a --minimal flag that answers everything with defaults and finishes in seconds — convenient, and the source of the single most regretted beginner decision, which is the next section.

The wizard's defaults are sane for networking: it creates the incusbr0 bridge, and new instances get DHCP addresses on a private subnet with NAT to the outside. You can accept all of that on day one. The question to slow down for is storage, because the wizard's answer is load-bearing for months.

How do you choose the right Incus storage pool?

The incus storage pool decision is the money choice of the whole guide, because it is nearly invisible and nearly irreversible. During incus admin init you pick a storage driver for the default pool, and every container and VM you ever launch inherits it. The official docs recommend zfs or btrfs. The --minimal shortcut picks dir — plain directories on the host filesystem — which the docs describe as slower than other drivers and missing fast snapshots, fast copy/launch, quotas, and optimized backups. Beginners who take the shortcut discover months later that snapshots take forever and deleted data never gives disk space back.

DriverSpeedFast snapshotsQuotasBest for
zfsFastYesYesThe recommended default for most hosts; needs a dedicated partition or disk for best results
btrfsFastYesYesThe recommended default when your root filesystem is already btrfs
lvmFastYesYesHosts already built on LVM; thin provisioning available
dirSlowNoNoTesting only — what --minimal silently picks; space is never reclaimed
ceph familyFastYesYesClusters, not single beginner hosts

The practical rule: if you have a spare disk or partition, give it to a zfs pool during init. If your root filesystem is already btrfs, use btrfs and skip the extra disk. If you must use a loop-backed file on your root filesystem (the wizard's fallback when there is no spare block device), know that it is slower and cannot shrink — fine for learning, not for a host you will keep. You can create additional pools later with incus storage create, but migrating the default pool's existing instances is the chore you avoid by deciding well now.

How do you launch your first Incus system container?

An incus launch pulls an image from the public server at images.linuxcontainers.org and starts it as an instance. The syntax is incus launch <remote>:<image> <name>, where the images: remote is the community image server:

incus launch images:ubuntu/24.04 web1
incus list

The first launch downloads the image (a minute or two on a fresh host); later launches from the cached image take seconds. incus list shows your instance running with an IPv4 address on incusbr0. Now step inside — this is the moment the "system container" idea clicks:

incus exec web1 -- bash
# you are root inside a full Ubuntu userland:
apt update && apt install -y nginx
exit

That is the whole container workflow: it behaves like a tiny server because it is one. incus stop web1 and incus start web1 do what they say, incus delete web1 removes it (add --force if it is running), and incus image list images: browses what you can launch — Debian, Fedora, Alpine, Arch, and more, all from the same server. Browse the list once; the breadth of maintained images is the quiet superpower of the ecosystem.

How do you launch your first Incus VM?

The same command, one flag: --vm. An incus VM runs a real kernel under KVM instead of sharing the host's, which is what you want when the workload needs its own kernel — different kernel versions, kernel modules, or just hard isolation.

incus launch images:debian/12 debian-vm --vm
incus list

Two prerequisites, and both bite beginners. First, the host CPU must expose hardware virtualization — ls /dev/kvm must exist. Many cloud VPSes pass it through, many do not; check before you plan a VM lab. Second, qemu-system-x86_64 must be in your $PATH (the qemu-system package from the install section), because the daemon checks for it before enabling VM support. Containers could not care less about either requirement, which is why a host can be perfectly healthy for containers and still refuse VMs.

VMs boot slower than containers (tens of seconds — there is a kernel booting in there) and cost real RAM each, but from the incus CLI they feel identical: incus exec debian-vm -- bash, incus stop, incus snapshot all work the same way. That uniformity is the point of Incus: learn one tool, run both instance types.

System containerVM (--vm)
KernelShares the host kernelIts own kernel under KVM
Start timeSecondsTens of seconds
MemoryShared, tiny overheadAllocated per VM
Needs /dev/kvmNoYes
Use forServices, labs, anything Linux-on-LinuxOther kernels, modules, hard isolation

What are Incus profiles, and why are they the rule?

An incus profile is a named bundle of configuration — devices, resource limits, cloud-init snippets — that you attach to instances at launch instead of repeating flags. The profile rule this guide's title promises is simple: if you type the same launch flags twice, they belong in a profile. The default profile already exists on every fresh host; incus profile show default reveals the two devices every instance inherits — a root disk on your storage pool and an eth0 NIC on incusbr0. That is why a bare incus launch "just works": the defaults live in the profile, not in the command.

incus profile list
incus profile show default
incus profile create web-tier
incus profile device add web-tier root disk path=/ pool=default
incus profile set web-tier limits.cpu=2 limits.memory=2GB
incus launch images:ubuntu/24.04 web2 -p default -p web-tier

Instances accept multiple profiles, applied in order, so you compose behavior: default for the disk and network, web-tier for the sizing. Change the profile once and every instance using it picks up the change; attach a profile to a running instance with incus profile add web1 web-tier. The beginner trap is the opposite habit — launching ten instances with ten slightly different flag soups and then maintaining them by memory. Profiles are also where the LXD muscle memory transfers directly: the concept is unchanged from LXD, which is why migrants feel at home in minutes.

How do Incus snapshots work?

An incus snapshot freezes an instance's state — filesystem and, for VMs, optionally memory — so you can roll back after an experiment goes sideways. The commands are as short as the concept:

incus snapshot create web1 clean
incus snapshot list web1
incus snapshot restore web1 clean
incus snapshot delete web1 clean

The habit to build: snapshot before upgrades, config surgery, and "let me just try this" moments. Name snapshots for the state they capture (clean, before-nginx, pre-upgrade), because "snapshot-2026-11-01" tells future-you nothing. And here the storage lesson comes back with interest: on zfs or btrfs, snapshots are instant and cheap; on a dir pool they are slow copies that eat disk. If you took the --minimal shortcut in the init section, this is where you feel it — and why the guide insisted on the storage decision up front.

How do you reach your Incus instances over the network?

Every instance gets an address on the managed bridge — check incus list for the IPv4 column — and from the host you can reach it directly: curl http://10.x.x.x/ just works. That covers host-to-instance traffic, which is most of homelab life. For moving files in and out without SSH, Incus has its own channel:

incus file push ./site.conf web1/etc/nginx/sites-enabled/
incus file pull web1/var/log/nginx/access.log ./

Incus networking beyond the bridge — custom bridges, routed NICs, OVN overlays — is a deep topic the official docs cover well, and day-one you do not need it. What you may need is reaching the lab from outside your LAN: Incus's bridge is local by design, so pair it with a mesh VPN rather than exposing ports. The Tailscale beginner guide covers exactly that pattern — install the VPN client on the host and your laptop, and your instances become reachable anywhere without touching the Incus network config. Local bridges for the lab, mesh VPN for the road: that division keeps both tools simple.

How do you migrate from LXD to Incus?

Incus ships an lxd-to-incus migration tool that converts an existing LXD installation — instances, profiles, networks, storage pools — to Incus in place. If you are one of the many arriving because of the fork history, this is your on-ramp, and it exists precisely because the project expected LXD users to come. Check the current docs for which LXD versions the tool supports before running it; the supported list moves with releases.

The migration is one-way, so the sane order is: snapshot or back up anything irreplaceable, run the tool on a test host first if you have one, and keep the LXD habit of profiles — they transfer as profiles, which is another reason this guide teaches the profile rule early. Once migrated, everything in this guide applies verbatim, because the CLI kept its shape across the fork.

Incus vs Docker vs LXD: how do you choose?

The incus vs docker question is a category error, and the incus vs lxd question is history — so here is the one table that settles both:

IncusDockerLXD
RunsSystem containers + full VMsApp containers (one process each)System containers + VMs
Unit of workA machineAn applicationA machine
Relationship—Different layer; often runs inside Incus containersIncus is its community fork (2023)
Choose it whenYou want VPS-like machines on your own hardwareYou ship applications as imagesYou are already on it; migrate with lxd-to-incus

Choose Docker — via the Docker guide — when you are packaging applications. Choose Incus when you want the machines those applications run on: build servers, test labs, personal services, a homelab that behaves like a tiny cloud. The two stack beautifully, by the way: Docker runs fine inside an Incus system container, which is a common pattern for giving each project its own Docker host. If your app-container journey started with Docker's alternatives, the Podman beginner guide covers the daemonless branch of that family — still app containers, still not what Incus is for.

What are the beginner mistakes that break an Incus install?

Five, and they account for nearly every "Incus is broken" forum thread. Skipping the incus-admin group — every command fails with permissions and the install looks dead; the fix is adduser, not reinstalling. Taking --minimal blindly — the silent dir pool, slow snapshots, unreclaimable disk, months of regret; rerun the wizard thoughtfully or create a proper pool after. Running incus admin init twice — the second run fights the first; if init went wrong, incus admin init has no undo, so reset with a fresh install or fix the pieces individually. Deleting or gutting the default profile — new launches then fail with missing root disk or network; look before you prune. Planning VMs on a host without KVM — containers work, --vm does not, and no flag fixes missing virtualization.

Avoid those five and Incus is remarkably uneventful — which, for infrastructure, is the highest compliment. The daemon is quiet, the CLI is consistent, and the concepts you just learned (pools, profiles, snapshots) scale from one laptop to a cluster without changing shape.

Sources

Every fact in this guide was verified against a live source during writing on 2026-11-01: Incus v7.6.0 release date and 6,546-star count from the GitHub API (api.github.com/repos/lxc/incus/releases/latest and the repository endpoint); install, group, init, storage, VM, profile, and snapshot behavior from the official docs at linuxcontainers.org/incus/docs/main (installing, tutorial/first_steps, howto/initialize, explanation/storage, explanation/containers_and_vms, reference/manpages/incus/profile); Ubuntu/Zabbly install paths from linuxcapable.com's Ubuntu guide and the Zabbly repository docs via discuss.linuxcontainers.org; Arch package version (7.5.1) from the Arch Linux package search API; the 2023 fork announcement ("a fully community led alternative to Canonical's LXD") from linuxcontainers.org's Incus announcement (2023-08-07) with the first stable 0.1 covered by theregister.com; Debian/ZFS install notes from pieterbakker.com; the one-click installer doc from spiritlhl.net; and the LXD-fork framing cross-checked against the current linuxcontainers.org documentation.

Frequently Asked Questions

Is Incus a replacement for Docker?

No. Incus manages system containers and VMs — whole Linux machines — while Docker packages single applications as app containers. They are different layers, and Docker runs happily inside an Incus container. Learn Docker for shipping apps; learn Incus for running the machines underneath them.

What is the difference between Incus and LXD?

Incus is the community-led fork of LXD, created in 2023 after Canonical moved LXD away from the Linux Containers project. The CLI and concepts (profiles, storage pools, snapshots) kept their shape across the fork, so LXD users feel at home immediately, and the lxd-to-incus tool migrates existing installations.

Can I run Incus on macOS or Windows?

Only the client. The Incus daemon is Linux-only, so your containers and VMs must live on a Linux host. Client-only binaries for macOS, Windows, and FreeBSD let you manage a remote Linux Incus server from your laptop.

Which storage driver should a beginner choose?

zfs if you have a spare disk or partition, btrfs if your root filesystem is already btrfs. Both are officially recommended and give you instant snapshots, quotas, and fast copies. Avoid accepting the dir driver from --minimal on any host you plan to keep — it is slow and never reclaims deleted space.

Do I need to reinstall if incus admin init went wrong?

Usually not. Most init choices — networks, profiles, extra storage pools — can be fixed or recreated with individual incus commands after the fact. The one genuinely painful mistake is the storage-pool driver on a host full of instances, which is why this guide front-loads that decision.

Featured on Twelve Tools Launch Llama Tools Launch your MCP