236 lines
7.4 KiB
Markdown
236 lines
7.4 KiB
Markdown
# 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 <network_name> <listen_address>
|
|
```
|
|
|
|
## 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 <pool> <name>
|
|
|
|
# Attach to container
|
|
incus config device add <container> <device-name> disk \
|
|
pool=<pool> source=<volume-name> path=<mount-path>
|
|
|
|
# Mount host directory into container
|
|
incus config device add <container> <device-name> 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 <instance> <snapshot-name>
|
|
incus snapshot restore <instance> <snapshot-name>
|
|
incus snapshot list <instance>
|
|
```
|
|
|
|
### Exports (portable, for off-site backup)
|
|
```bash
|
|
incus export <instance> backup.tar.gz --optimized-storage
|
|
incus import backup.tar.gz <new-instance-name>
|
|
```
|
|
|
|
### Volume Exports
|
|
```bash
|
|
incus storage volume snapshot <pool> <volume> <snapshot-name>
|
|
incus storage volume export <pool> <volume> volume-backup.tar.gz
|
|
incus storage volume import <pool> volume-backup.tar.gz <new-volume-name>
|
|
```
|
|
|
|
### 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 <container> boot.autostart true
|
|
|
|
# Set start order (lower = earlier)
|
|
incus config set <container> boot.autostart.priority 10
|
|
|
|
# Start delay (seconds, for dependency ordering)
|
|
incus config set <container> 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)
|