Caching and building offline

I am trying to build on an offline / air-gapped computer. I am using Ubuntu 20.04 and Docker version 27.2.0, build 3ab4256, containerd containerd.io 1.7.21 472731909fa34bd7bc9c087e4c27943f9835f111

There is something that I am not understanding about how the cache works or I am doing something wrong.

My minimal Dockerfile is

FROM alpine:3.20.2
RUN apk update && apk add --no-cache python3

Then I’m running

docker build --tag offline:latest --cache-to=type=local,dest=offline-container-cache .

At this point, I’m disabling my NIC (to simulated my air gapped computer) and if I understand correctly, I should to be able to still build using

docker build --tag offline:latest --cache-from=type=local,src=offline-container-cache .

However, I get the following error

[+] Building 0.1s (2/2) FINISHED                                                                                                                                                                                    docker:default
 => [internal] load build definition from Dockerfile
=> => transferring dockerfile: 93B
=> ERROR [internal] load metadata for docker.io/library/alpine:3.20.2
------
 > [internal] load metadata for docker.io/library/alpine:3.20.2:
------
Dockerfile:1
--------------------
   1 | >>> FROM alpine:3.20.2
   2 |     RUN apk update && apk add --no-cache
   3 |     
--------------------
ERROR: failed to solve: alpine:3.20.2: failed to resolve source metadata for docker.io/library/alpine:3.20.2: failed to do request: Head "https://registry-1.docker.io/v2/library/alpine/manifests/3.20.2": dial tcp: lookup registry-1.docker.io on 127.0.0.53:53: server misbehaving

It works offline only if you already pulled the base image that you refer to in your Dockerfile. Or exported online somewhere (docker image save), copied the tar file to the offline environment and load the image there (docker image load)

Doesn’t building it the first time pull the image?

The image layers, yes, but the tag is not pulled so Docker has to look for it online.

Check the output of

docker image ls

alpine:3.20.2 will not be there.

Using DOCKER_BUILDKIT=0 docker build . will cache the images and the tags and allow building locally.
Unfortunately, it is deprecated and you never know for how long it will work.

Another workaround is to pull the images manually by using docker image pull alpine:3.20.2, this will store the tag locally and allow you to build offline. The downside is that this is a manual task and there is always a chance of forgetting it and realizing you lack the image when it is too late.

I have been playing with this for a while but still haven’t found a way to “force” the caching of the images automatically.