
Since version 6.3, Incus is no longer limited to system containers: it can launch OCI images, meaning application containers from Docker Hub and other registries. This guide adds the OCI remote, launches an image (nginx), explains the CONTAINER (APP) type and sets out the limits of that compatibility. Tested on Incus 7.0. For anyone who wants to run application workloads without installing Docker, on the same platform as their system containers and virtual machines.
What you will learn
- Add the OCI remote (
docker:). - Launch an application image from Docker Hub.
- Understand the
CONTAINER (APP)type. - Know the limits compared to Docker.
Prerequisites
- Incus installed and initialised (see the installation).
- Outbound connectivity to the registries (Docker Hub).
Adding the OCI remote
Unlike the images: remote, which is already present, the Docker remote is not configured by default. You add it once, with the oci protocol:
incus remote add docker https://docker.io --protocol ociincus remote list| docker | https://docker.io | oci | none | YES | NO | NO |Launching an OCI image
With the remote in place, incus launch behaves as it does for a system container, pointing at the docker: remote:
incus launch docker:nginx webincus listThe output shows a container of a particular type, CONTAINER (APP):
+------+---------+-----------------------+-----------------+| NAME | STATE | IPV4 | TYPE |+------+---------+-----------------------+-----------------+| web | RUNNING | 10.173.191.174 (eth0) | CONTAINER (APP) |+------+---------+-----------------------+-----------------+Understanding the CONTAINER (APP) type
The (APP) suffix marks an application container, as opposed to the classic system container. The difference is fundamental:
- a system container runs a complete
init(systemd) and a whole distribution; - an application container (APP) runs the image process (nginx here) as PID 1, with no system init.
In practice you do not connect to it with incus shell as you would to a machine: you interact with the application process, exactly as with a Docker container. That is the expected behaviour for an OCI image.
Exposing the service
As for any Incus instance, you publish a port with a proxy device linking a host port to the container:
incus config device add web http proxy \ listen=tcp:0.0.0.0:8080 connect=tcp:127.0.0.1:80The container's nginx becomes reachable on port 8080 of the host. The networking guide covers the proxy device and its options.
The limits compared to Docker
The OCI compatibility of Incus is convenient, but it is not a complete replacement for Docker. Things to keep in mind:
- no image build from a Dockerfile (Incus consumes images, it does not build them);
- no Docker Compose and no native application orchestration;
- the tooling ecosystem (private registries, scanners, CI) is still built around Docker.
For a homelab or a handful of services, running OCI images inside Incus avoids installing Docker. For intensive application work, Docker and its ecosystem remain better suited. See the Incus vs Docker comparison.
Key points
- The OCI remote is added once:
incus remote add docker https://docker.io --protocol oci. incus launch docker:<image>launches an application image from Docker Hub.- The
CONTAINER (APP)type marks an application container (process as PID 1, no init). - You expose a service with a proxy device (
listenandconnect). - Incus consumes OCI images but does not build them: it is not a complete Docker.
FAQ: common questions about OCI containers in Incus
Add the remote, then launch
The Docker remote is not configured by default, so you add it once:
incus remote add docker https://docker.io --protocol oci
incus launch docker:nginx web
Incus downloads the OCI image from Docker Hub and starts an application container. The feature has existed since Incus 6.3.
An application container
The (APP) suffix distinguishes an application container (from an OCI image) from the classic system container:
- a system container runs a complete
init(systemd) and a whole distribution; - an
(APP)container runs the image process (nginx, say) as PID 1, with no init.
You interact with the application process, as with Docker, not with a machine through incus shell.
No, Incus consumes but does not build
Incus consumes OCI images from registries, but does not build them: there is no equivalent of docker build from a Dockerfile.
To build application images, use Docker, Podman or Buildah. Incus stays designed to run system containers and virtual machines; OCI support is a complement for running application workloads without installing Docker.
The proxy device
You publish a port with a proxy device linking a host port to the container:
incus config device add web http proxy \
listen=tcp:0.0.0.0:8080 connect=tcp:127.0.0.1:80
The service (here nginx on port 80 of the container) becomes reachable on port 8080 of the host. It is the same mechanism as for any Incus instance, system container or virtual machine.
Next steps
- Incus networking: make the application service you just launched reachable on the network.
- Incus storage: give a persistent volume to an OCI container whose filesystem is disposable.
- Profiles and projects: keep your application containers in a space separate from your system containers.