OCI images gone from the store?

I set up an OCI container in late August. The image was listed in the image store (I think).

I went to refresh it today to get the newer container version, and the image store is empty.

I can, of course, make a note of the entire config of the running container, delete it and recreate it, but this seems a bit silly.

Does the image store auto-purge?

Hi!

The Incus project has a repository (a “remote”) with images for system containers and for virtual machines. There are no OCI images in there.

The OCI images are retrieved from their own separate repositories like the Docker Hub.

Let’s have a look. I create an OCI container and then show the configuration. Note the key volatile.container.oci that is set to true. And the key volatile.base_image that has the value (a hash) of 54e66cc1dd1f….

$ incus launch docker:hello-world myhelloworld
Launching myhelloworld
$ incus config show myhelloworld 
architecture: x86_64
config:
  environment.PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
  environment.TERM: xterm
  image.architecture: x86_64
  image.description: docker.io/library/hello-world (OCI)
  image.id: hello-world
  image.type: oci
  oci.cwd: /
  oci.entrypoint: /hello
  oci.gid: "0"
  oci.uid: "0"
  volatile.base_image: 54e66cc1dd1fcb1c3c58bd8017914dbed8701e2d8c74d9262e26bd9cc1642d31
  volatile.cloud-init.instance-id: 28032130-7517-4a9c-9bc1-4852ddeda618
  volatile.container.oci: "true"
...
$

Now let’s see the images that are saved in Incus. Those images are the base images for containers and virtual machines that you have launched. Here, you can see the image from Docker Hub (note the Fingerprint, also known as hash of the image). It is listed as having 0.00MiB size, which I do not know why it happens. The image file is actually located in the Incus storage pool.

$ incus image list -c afdts
+--------------+--------------+---------------------------------------------------+-----------------+------------+
| ARCHITECTURE | FINGERPRINT  |                    DESCRIPTION                    |      TYPE       |    SIZE    |
+--------------+--------------+---------------------------------------------------+-----------------+------------+
| x86_64       | 54e66cc1dd1f | docker.io/library/hello-world (OCI)               | CONTAINER       | 0.00MiB    |
+--------------+--------------+---------------------------------------------------+-----------------+------------+
...
$

Let’s launch a new container from that OCI image. It appears that it works. What’s happening?

$ incus launch 54e66cc1dd1f mysecondhelloworld
Launching mysecondhelloworld
$ incus start mysecondhelloworld
$

It indeed works. Simply this specific image prints text to the console and exits. You need to launch or start with the --console flag. Like this.

$ incus start mysecondhelloworld --console


Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/


Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/


$

Therefore, the image is likely still located in the storage pool (the output of incus image list). There’s indeed some configuration option to purge such images, though check first with the above.

This is kind of what I was trying to get at - the images were listed in incus image list, and no longer are. Thus I can’t refresh them or use the auto-update functionality. I ended up having to delete the running service and re-pull the OCI image from docker.io to get the latest version.

Deleting an OCI base image that’s in active use seems a bit odd/wrong.

incus image list

+-------+--------------+--------+------------------------------------+--------------+-----------+-----------+----------------------+
| ALIAS | FINGERPRINT  | PUBLIC |            DESCRIPTION             | ARCHITECTURE |   TYPE    |   SIZE    |     UPLOAD DATE      |
+-------+--------------+--------+------------------------------------+--------------+-----------+-----------+----------------------+
|       | a6559012296a | no     | docker.io/linuxserver/lidarr (OCI) | x86_64       | CONTAINER | 112.43MiB | 2025/09/17 07:56 IST |
+-------+--------------+--------+------------------------------------+--------------+-----------+-----------+----------------------+

That’s after I deleted and re-pulled the OCI image. So it absolutely ends up in the image storage location when freshly pulled.

Images are cached locally for 10 days since their last use, then the cache expires.

This is generally invisible to the user as the behavior of incus launch docker:hello-world will remain the same whether you have a locally cached image or not. The only difference is that if your locally cached image happens to match the latest image available, then it won’t need to be downloaded and unpacked.

Thanks @stgraber . I found that stop + start didn’t cause a refresh, and I couldn’t trigger a refresh either, since it wasn’t in the local cache. As I understand it, launch is create new - which is basically what I ended up having to do; delete the existing container and recreate it with all the settings for profiles etc.

Am I missing something in terms of being able to launch an image, stop/start/otherwise run for more than 10 days, and without having to delete and recreate, get it to pull the latest version from the upstream store?

You create and start with:

incus launch docker:nginx my-nginx

You rebuild it from the latest image with:

incus rebuild docker:ngixn my-nginx
1 Like

Thank you! :slight_smile: