# Incus Research Notes Research conducted 2026-03-17. Incus development moves fast — verify against latest docs before implementing. ## Incus Version & Status - **Latest**: Incus 6.22 (February 28, 2026) - **LTS**: Incus 6.0 (5 years support) - **Release cadence**: Monthly feature releases - **Debian 13 (Trixie)**: Native packages available (`apt install incus`) ## OCI Container Support - **Added in**: Incus 6.3 (July 2024) — 18+ months mature - **How it works**: Pulls Docker/OCI images from registries, converts them, runs natively - **Setup**: `incus remote add docker https://docker.io --protocol=oci` - **Usage**: `incus launch docker:postgres:16-alpine my-postgres` - **Dependencies**: `skopeo` and `umoci` (included in Debian packages) - **Maturity**: Stable for production use, actively improved each release ## System Containers vs OCI Containers | Aspect | System Containers | OCI Containers | |---|---|---| | Purpose | Full OS simulation | Single application | | Init | systemd (runs until stopped) | Entrypoint process only | | Image size | 150-500MB per container | Smaller, layered | | RAM overhead | ~50-100MB more than OCI | Comparable to Docker | | Use case | Legacy apps, multi-process, full sysadmin | Microservices, pre-built images | ## Networking ### Managed Bridges - Incus creates bridges with dnsmasq for DHCP + DNS - Containers get DNS entries for their instance name automatically - Container-to-container by name works out of the box - Default bridge: `incusbr0` (created during `incus admin init`) ### Port Forwarding — Proxy Devices ```bash # Single port incus config device add container http proxy \ listen=tcp:0.0.0.0:80 connect=tcp:127.0.0.1:80 # Port range incus config device add container ports proxy \ listen=tcp:0.0.0.0:8080-9000 connect=tcp:127.0.0.1:8080-9000 # UDP (for HTTP/3) incus config device add container h3 proxy \ listen=udp:0.0.0.0:443 connect=udp:127.0.0.1:443 ``` ### Network Forwards (alternative to proxy devices) ```bash incus network forward create ``` ## Storage ### Pool Backends | Backend | Pros | Cons | |---|---|---| | `dir` | Simple, no setup | Slower, no snapshots | | `zfs` | Fast snapshots, dedup, compression | Complex setup | | `btrfs` | CoW, snapshots | Less tooling than ZFS | | `lvm` | Reliable, mature | Block-level only | ### Volume Operations ```bash # Create volume incus storage volume create # Attach to container incus config device add disk \ pool= source= path= # Mount host directory into container incus config device add disk \ source=/host/path path=/container/path ``` ## Ansible Integration ### Connection Plugin (community.general.incus) - Exec commands inside containers without SSH - Install: `ansible-galaxy collection install community.general` - Usage: `ansible_connection: community.general.incus` - Variables: `ansible_incus_remote`, `ansible_incus_project`, `ansible_host` ### Inventory Plugin (community.general.incus_inventory) - Auto-discovers running Incus instances - Dynamic inventory source ### Third-Party: kmpm.incus Collection - Dedicated modules: `incus_instance`, `incus_network`, `incus_profile` - Status: Beta/WIP, actively maintained - Install: `ansible-galaxy collection install git+https://github.com/kmpm/ansible-collection-incus.git` ### Practical Approach for This Project Use `ansible.builtin.command` with `incus` CLI directly. Simpler, more transparent, easier to debug than collections. Connection plugin useful for exec-inside-container tasks. ## Incus Initialization (Preseed) Non-interactive setup via `incus admin init --preseed`: ```yaml config: {} networks: - config: ipv4.address: auto ipv4.nat: "true" ipv6.address: none name: incusbr0 type: bridge storage_pools: - config: source: /var/lib/incus/storage-pools/default name: default driver: dir profiles: - config: {} devices: eth0: name: eth0 network: incusbr0 type: nic root: path: / pool: default type: disk name: default ``` ## Environment Variables in OCI Containers Pass via `--config` flags at launch time: ```bash incus launch docker:postgres:16-alpine gitea-db \ --config environment.POSTGRES_DB=gitea \ --config environment.POSTGRES_USER=gitea \ --config environment.POSTGRES_PASSWORD=secretpass ``` Update existing container: ```bash incus config set gitea-db environment.POSTGRES_PASSWORD=newpass incus restart gitea-db ``` ## Backup & Restore ### Snapshots (fast, local only) ```bash incus snapshot create incus snapshot restore incus snapshot list ``` ### Exports (portable, for off-site backup) ```bash incus export backup.tar.gz --optimized-storage incus import backup.tar.gz ``` ### Volume Exports ```bash incus storage volume snapshot incus storage volume export volume-backup.tar.gz incus storage volume import volume-backup.tar.gz ``` ### Database Dumps (same pattern as Docker) ```bash incus exec gitea-db -- pg_dump -U gitea gitea > gitea-db.sql incus exec outline-db -- pg_dump -U outline outline > outline-db.sql ``` ### 6.22 Enhancements - Direct backup streaming (no temporary disk files) - Disk-only snapshot restore (revert storage without config) ## Auto-Start / Restart Policy ```bash # Start container on host boot incus config set boot.autostart true # Set start order (lower = earlier) incus config set boot.autostart.priority 10 # Start delay (seconds, for dependency ordering) incus config set boot.autostart.delay 5 ``` No automatic restart on crash (unlike Docker's `restart: unless-stopped`). Options: - Accept manual restart for crashes (rare) - Add a systemd watchdog timer on the host - Use `incus monitor` to watch for state changes ## Running Docker Inside Incus (for Gitea Runner) If needed for the runner: ```bash incus launch images:debian/13/cloud gitea-runner-host incus config set gitea-runner-host security.nesting true incus exec gitea-runner-host -- apt install docker.io # Then run act_runner inside this system container ``` ## Cloud-init Support System containers with `/cloud` images support cloud-init: ```bash incus launch images:debian/13/cloud my-container \ --config cloud-init.user-data="#cloud-config packages: - curl - git " ``` Note: Cloud-init runs only on first boot. Not applicable to OCI containers. ## Sources - [Incus Documentation](https://linuxcontainers.org/incus/docs/main/) - [Incus 6.22 Release](https://linuxcontainers.org/incus/news/) - [Incus OCI Support (FOSDEM 2025)](https://archive.fosdem.org/2025/schedule/event/fosdem-2025-5742-bringing-application-containers-to-incus/) - [Incus Ansible Connection Plugin](https://docs.ansible.com/projects/ansible/latest/collections/community/general/incus_connection.html) - [kmpm/ansible-collection-incus](https://github.com/kmpm/ansible-collection-incus) - [lxc/incus-deploy](https://github.com/lxc/incus-deploy) - [Incus Backup Strategy (Forum)](https://discuss.linuxcontainers.org/t/incus-backup-strategy-incus-export-or-zfs-snapshot/25188) - [Running OCI Images in Incus (blog.simos.info)](https://blog.simos.info/running-oci-images-i-e-docker-directly-in-incus/) - [Incus Debian Wiki](https://wiki.debian.org/Incus)