Linux Setup Guide - mensfeld/code-on-incus GitHub Wiki
COI's install script (install.sh) works across Linux distributions, but Incus itself requires some distro-specific setup. This guide covers what you need beyond the standard install.
Universal Steps
These apply to all distributions:
# 1. Install COI
curl -fsSL https://raw.githubusercontent.com/mensfeld/code-on-incus/master/install.sh | bash
# 2. Build the COI image
coi build
# 3. Start coding
coi shell
The install script handles Incus initialization, idmap configuration, firewalld setup, and ZFS storage automatically. The sections below cover manual setup for cases where the script can't auto-detect your environment.
Arch Linux / CachyOS / Manjaro
Incus is available in the official Arch repositories.
Install Incus
sudo pacman -S incus
Enable the Service
sudo systemctl enable --now incus.service
Add User to Groups
sudo usermod -aG incus-admin $USER
# Log out and back in for group changes to take effect
Note: Some Arch-based distributions may also require the incus group (in addition to incus-admin). If you get permission errors, try: sudo usermod -aG incus incus-admin $USER.
Initialize Incus
sudo incus admin init --auto
This creates the default bridge network (incusbr0), storage pool, and profile devices. If you need more control:
# Manual setup (equivalent to --auto)
incus network create incusbr0 ipv4.address=auto ipv4.nat=true ipv6.address=none
incus storage create default dir
incus profile device add default root disk path=/ pool=default
incus profile device add default eth0 nic name=eth0 network=incusbr0
Fix Subordinate UID/GID Mapping
Arch does not ship with subordinate UID/GID ranges for root by default. Without this, Incus cannot create unprivileged containers and you'll see:
"System doesn't have a functional idmap setup"
# Add subordinate ranges for root
echo "root:1000000:1000000000" | sudo tee -a /etc/subuid
echo "root:1000000:1000000000" | sudo tee -a /etc/subgid
# Restart Incus to pick up the changes
sudo systemctl restart incus.service
The COI install script detects and offers to fix this automatically.
Enable Firewalld
Firewalld is required for COI's network isolation modes (restricted, allowlist). Without it, only mode = "open" works.
sudo pacman -S firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-masquerade
sudo firewall-cmd --reload
If your bridge isn't getting trusted zone treatment (containers can't get IP addresses):
sudo firewall-cmd --zone=trusted --add-interface=incusbr0 --permanent
sudo firewall-cmd --reload
Verify Setup
coi health
Fedora / RHEL / CentOS Stream
Install Incus
Incus is available via the Zabbly repository on RHEL-based systems:
sudo dnf install incus
sudo systemctl enable --now incus.service
sudo usermod -aG incus-admin $USER
sudo incus admin init --auto
Firewalld
Fedora ships with firewalld enabled by default. Enable masquerade for container internet access:
sudo firewall-cmd --permanent --add-masquerade
sudo firewall-cmd --zone=trusted --add-interface=incusbr0 --permanent
sudo firewall-cmd --reload
Idmap
Fedora typically ships with correct /etc/subuid and /etc/subgid entries. Verify:
grep root /etc/subuid /etc/subgid
If empty, add the ranges as shown in the Arch section above.
openSUSE
sudo zypper install incus
sudo systemctl enable --now incus.service
sudo usermod -aG incus-admin $USER
sudo incus admin init --auto
Firewalld is the default firewall on openSUSE. Enable masquerade:
sudo firewall-cmd --permanent --add-masquerade
sudo firewall-cmd --zone=trusted --add-interface=incusbr0 --permanent
sudo firewall-cmd --reload
Ubuntu / Debian
Ubuntu and Debian are the primary target for COI. The install script handles everything automatically.
Note: Ubuntu ships Incus 6.0.x in its main repository, which may lack required idmapping support. If you see idmap errors, install Incus >= 6.1 from the Zabbly repository.
sudo apt install -y incus
sudo systemctl enable --now incus.service
sudo usermod -aG incus-admin $USER
sudo incus admin init --auto
The install script automatically detects ufw (Ubuntu's default firewall) and offers to replace it with firewalld, which COI requires for network isolation.
Common Issues Across Distros
"System doesn't have a functional idmap setup"
Add subordinate UID/GID ranges for root and restart Incus:
echo "root:1000000:1000000000" | sudo tee -a /etc/subuid
echo "root:1000000:1000000000" | sudo tee -a /etc/subgid
sudo systemctl restart incus.service
Containers Can't Get IP Addresses
Ensure the Incus bridge is in the firewalld trusted zone:
sudo firewall-cmd --zone=trusted --add-interface=incusbr0 --permanent
sudo firewall-cmd --reload
"firewalld is not available or not running"
Either install and enable firewalld (see distro-specific sections above) or use open network mode:
# ~/.coi/config.toml
[network]
mode = "open"
Verify Everything
coi health --verbose
This checks Incus setup, permissions, security posture, network configuration, and monitoring prerequisites.