A drop-in replacement for docker compose that runs your compose.yaml on
Incus - with the full Incus API available
as an escape hatch when you need more than the Compose spec covers.
services:
db:
image: docker.io/postgres:18-alpine
healthcheck:
test: ["CMD", "pg_isready", "-U", "postgres"]
deploy:
resources:
limits:
cpus: "2"
memory: 2G
web:
image: docker.io/nginx:alpine
depends_on:
db: { condition: service_healthy }
ports:
- "8080:80"
deploy:
resources:
limits:
cpus: "1"
memory: 512Mincus-compose upA plain compose file, running unchanged.
- backup in action
- 30-service dependency graph, 30 parallel workers
- Immich - a full photo-management stack
Point it at the compose.yaml you already have and run it against Incus instead
of Docker.
- Use existing
docker-compose.ymlfiles unchanged - no rewrite, no new format to learn - Windows, macOS, and Linux clients drive a remote Incus host over HTTPS - no Docker Desktop, no WSL, no local VM
- Pull Docker/OCI images directly from docker.io, ghcr.io, and other registries via Incus's native OCI registry support
New to Incus? See Why Incus? for what the platform brings over a classic OCI engine setup.
Drop-in. All the commands you know - up, down, start, stop,
restart, pause, logs, exec, cp, top, ps, config, build -
parsing via compose-go with .env interpolation, profiles, depends_on,
secrets, and configs. See the
CLI reference and the
compatibility matrix.
Operable. Health checks, restart policies, and depends_on: service_healthy
ordering via the ic-healthd sidecar; scaling with up --scale; project
isolation; live progress for pulls and lifecycle. See
Health Checking.
Fast images. OCI pulls from any registry, a two-stage cache that survives
down/up and dodges rate limits, and local builds via Podman/Docker. See
Builds.
Air-gapped ready. pull is the only command that needs a registry, so a
project pulls on a connected machine and runs on a disconnected one;
--pull never makes that a guarantee rather than a hope, and the sidecar and
one-off helper images point at your own mirror like any other. See
Air-gapped and Proxied Installs.
Real networking and storage. Bridge networks with static IPs, port publishing via proxy devices or kernel NAT, volumes with UID/GID shifting, seeded bind mounts, and per-volume pool placement.
Incus-native when you want it. Every instance, network, and volume option
passes straight through via x-incus; x-incus-compose adds devices (GPU, USB,
raw disk), project-wide resource limits, and healthd tuning. See
Extras.
Extensions. incus-compose backup snapshots a project's data volumes into a
backup project - create, list, verify, restore, and prune - so a stack's state
survives the project itself, and incus-compose port-forward forwards a local
TCP port into an instance, published or not. See
backup and
port-forward.
Requires Incus 7.0.1 (LTS) or 7.2+, podman or docker for image building and
an Incus https remote (needed for healthchecking) with OCI registries added. See
Getting Started for the full
setup walkthrough.
Install the latest release:
curl -sSfL https://raw.githubusercontent.com/lxc/incus-compose/main/install.sh | sh -s -- -b ~/.local/binOr grab a prebuilt archive from the
Releases Page. On Arch Linux,
install
incus-compose-bin (or
incus-compose-git for
builds from main) from the AUR - maintained by @neitsab and @jochumdev.
Then point it at your existing compose.yaml:
# Start services
incus-compose up -d
# View logs
incus-compose logs -f
# List running services
incus-compose list
# Stop and remove
incus-compose downAll docs: docs.incus-compose.org
- Getting Started - Install and run your first compose project
- CLI Reference - Commands and options
- Compose Compatibility - What works and what doesn't
- Air-gapped - pull once connected, run disconnected
- Extras -
x-incus,x-incus-compose, and thecompose.incus.yamloverride file - Developer - the resource-first design behind incus-compose
- Why Incus? - What Incus brings over a classic OCI engine setup
- Changelog - what changed since 0.0.1-beta1
Descriptions are in our docs while the files are in examples.
The following channels are available for questions and discussion around incus-compose.
You can file bug reports and feature requests at:
https://github.com/lxc/incus-compose/issues/new
Community support is handled at:
https://discuss.linuxcontainers.org
Fixes and new features are greatly appreciated. Make sure to read our contributing guidelines first!
incus-compose wouldn't be what it is without the people who tested it, filed reports, and pushed on ideas along the way: @alien43, @Sagi, @neitsab, @pyrodogg, @kgoetz, @edorgeville, @bburky, @blurry, @stgraber, @ishaan-jindal, @code-by-tanveer, and @Tofil.
It also stands on a few libraries that make maintaining it far easier:
- compose-spec/compose-go - parses and resolves the compose file
- lxc/incus - the container/VM engine and Go client this all talks to
- creativeprojects/go-selfupdate -
powers
self-update - dominikbraun/graph - the
depends_ondependency graph - bradleyjkemp/cupaloy - snapshot testing across the test suite
This project is inspired by
@bketelsen. Some components are
adapted from docker compose. The
install.sh script is adapted from
golangci-lint.
This project has been using AI tools as development aids (drafting, iteration, reviews, tests, and documentation).
Earlier development was on Gitlab.