If you're new to incus-compose, this page helps you translate between Docker Compose, Incus, and incus-compose terms. incus-compose sits between three vocabularies:
compose.yaml (service, network,
volume).The same word sometimes means different things in each, and the same concept sometimes has two names. This page disambiguates them.
flowchart LR
subgraph C["Docker Compose - what you write"]
direction TB
SVC[service]
CPRJ[the compose project]
CNET[network]
CVOL[named volume]
CBIND[bind mount]
CIMG["image, an OCI reference"]
CHC["healthcheck / restart"]
end
subgraph I["Incus - what actually runs"]
direction TB
INST["one instance per replica<br/>web-1, web-2, ..."]
IPRJ["project<br/>sanitized name"]
IBR["managed bridge<br/>hashed if the name is long"]
IVOL["custom storage volume<br/>UID/GID shifted"]
IDISK["disk device<br/>host path, local Incus only"]
IIMG["image<br/>cached, then copied per project"]
HD["ic-healthd sidecar<br/>Incus does not do this itself"]
end
SVC --> INST
CPRJ --> IPRJ
CNET --> IBR
CVOL --> IVOL
CBIND --> IDISK
CIMG --> IIMG
CHC --> HD
| Compose term | Incus term | Notes |
|---|---|---|
| service | instance(s) | One service becomes one or more instances (one per replica). |
| (the compose project) | project | Each compose project maps to its own Incus project. |
| network | network (bridge) | Compose network becomes an Incus managed bridge. |
| named volume | custom storage volume | With automatic UID/GID shifting. |
| bind mount | disk device (host path) | Needs incusd on this machine, or x-incus-compose.seed. |
| image (OCI ref) | image (cached, per-project) | Pulled via an OCI remote, cached, then copied into the project. |
| healthcheck / restart | (enforced by ic-healthd) | Incus does not run these; the sidecar does. |
| - | profile | Incus-only; no compose equivalent. |
services: in your
compose.yaml. It is a definition, not a running thing.deploy.replicas a
single service produces several instances named {service}-{index} (e.g.
web-1, web-2). A service with no replicas still becomes one instance,
{service}-1."Project" is overloaded:
compose.yaml you run against; named
after the directory by default, overridable with -p.networks:.data:/var/lib/app) - becomes an Incus custom storage
volume with automatic UID/GID shifting. Works locally and remotely../config:/etc/app) - mounts a host path directly, so the
path must be on the machine incusd runs on. With
x-incus-compose.seed
the files are copied to the server instead, which works against any remote.
See Volumes.docker.io/nginx:alpine),
pulled through an Incus OCI remote.incus remote add --protocol oci ...
before images can be pulled from it.x-incus-compose.pool.ports: are forwarded (not iptables NAT).healthcheck, restart:, and depends_on: service_healthy. Incus does not
do these itself. It is transparent in normal use but a core component; see
Health Checking and
Debugging ic-healthd.up + down --project runs are fast and avoid registry rate limits.
Configurable via INCUS_COMPOSE_IMAGE_CACHE.x-incus - a compose extension to pass raw Incus options verbatim to
instances, networks, and volumes; see
x-incus.x-incus-compose - a compose extension for incus-compose-specific
features (e.g. healthd, volume pool); see
x-incus-compose.compose.incus.yaml - an optional override file loaded automatically
alongside compose.yaml for Incus-specific settings; see
Incus Override File.These appear in the codebase and architecture docs, not in everyday use. See the Client Package for detail.
Ensure always runs before start/stop/delete. See the
Two-Phase Resource Pattern.--workers
flag).