linuxkit/docs/image-cache.md
Daniel S. 818bccf20f
docs: Add instructions for OCI export from Docker (#4135)
Signed-off-by: Daniel Smith <daniel@razorsecure.com>
2025-06-30 16:27:54 +03:00

90 lines
3.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Image Caching
linuxkit builds each runtime OS image from a combination of Docker images.
These images are pulled from a registry and cached locally.
linuxkit does not use the docker image cache to store these images. This is
for two key reasons.
First, docker does not provide support for different architecture versions. For
example, if you want to pull down `docker.io/library/alpine:3.13` by manifest,
with its signature, but get the `arm64` version while you are on an `amd64` device,
it is not supported.
Second, and more importantly, this requires a running docker daemon. Since the
very essence of linuxkit is removing daemons and operating systems where unnecessary,
just laying down bits in a file, removing docker from the image build process
is valuable. It also simplifies many use cases, like CI, where a docker daemon
may be unavailable.
## How LinuxKit Caches Images
LinuxKit pulls images down from a registry and stores them in a local cache.
It stores the root manifest or index of the image, the manifest, and all of the layers
for the requested architecture. It does not pull down layers, manifest or config
for all available architectures, only the requested one. If none is requested, it
defaults to the architecture on which you are running.
By default, LinuxKit caches images in `~/.linuxkit/cache/`. It can be changed
via a command-line option. The structure of the cache directory matches the
[OCI spec for image layout](http://github.com/opencontainers/image-spec/blob/master/image-layout.md).
Image names are kept in `index.json` in the [annotation](https://github.com/opencontainers/image-spec/blob/master/annotations.md) `org.opencontainers.image.ref.name`. For example"
```json
{
"schemaVersion": 2,
"manifests": [
{
"mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
"size": 1638,
"digest": "sha256:9a839e63dad54c3a6d1834e29692c8492d93f90c59c978c1ed79109ea4fb9a54",
"annotations": {
"org.opencontainers.image.ref.name": "docker.io/library/alpine:3.13"
}
}
]
}
```
## How LinuxKit Uses the Cache and Registry
For each image that linuxkit needs to read, it does the following. Note that if the `--pull` option
is provided, it always will pull, independent of what is in the cache.
1. Check in the cache for the image name in the cache `index.json`. If it does not find it, pull it down and store it in cache.
1. Read the root hash from `index.json`.
1. Find the root blob in the `blobs/` directory via the hash and read it.
1. Proceed to read the manifest, config and layers.
The read process is smart enough to check each blob in the local cache before downloading
it from a registry.
## Imports from local Docker instance
To import an image from your local Docker daemon into LinuxKit, youll need to ensure the image is exported in the [OCI image format](https://docs.docker.com/build/exporters/oci-docker/), which LinuxKit understands.
This requires using a `docker-container` [buildx driver](https://docs.docker.com/build/builders/drivers/docker-container/), rather than the default.
Set it up like so:
```shell
docker buildx create --driver docker-container --driver-opt image=moby/buildkit:latest --name=ocibuilder --bootstrap
```
Then build and export your image using the OCI format:
```shell
docker buildx build --builder=ocibuilder --output type=oci,name=foo . > foo.tar
```
You can now import it into LinuxKit with:
```shell
linuxkit cache import foo.tar
```
Note that this process, as described, will only produce images for the platform/architecture you're currently on. To produce multi-platform images requires extra docker build flags and external builder or QEMU support - see [here](https://docs.docker.com/build/building/multi-platform/).
This workaround is only necessary when working with the local Docker daemon. If youre pulling from Docker Hub or another registry, you dont need to do any of this.