Skip to content

Moving Docker images without base image

I was learning about the new buildkit features as well as researching a doubt which my friend had asked me about how he can move docker image without the base layer such that the shipping size of the docker images can be reduced significantly.

Below I list down some of the steps I followed along the way to achieve this.

Create Dockerfile

FROM alpine:latest

WORKDIR /workdir

RUN echo "Testing removing image layers" > notes.txt

Build the docker image

 docker buildx build -t jijo:1.0 -f Dockerfile .
[+] Building 18.8s (7/7) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                                   0.1s
 => => transferring dockerfile: 129B                                                                                                                                                   0.0s
 => [internal] load .dockerignore                                                                                                                                                      0.1s
 => => transferring context: 2B                                                                                                                                                        0.0s
 => [internal] load metadata for docker.io/library/alpine:latest                                                                                                                      18.5s
 => [1/3] FROM docker.io/library/alpine:latest@sha256:eb3e4e175ba6d212ba1d6e04fc0782916c08e1c9d7b45892e9796141b1d379ae                                                                 0.0s
 => => resolve docker.io/library/alpine:latest@sha256:eb3e4e175ba6d212ba1d6e04fc0782916c08e1c9d7b45892e9796141b1d379ae                                                                 0.0s
 => CACHED [2/3] WORKDIR /workdir                                                                                                                                                      0.0s
 => CACHED [3/3] RUN echo "Testing removing image layers" > notes.txt                                                                                                                  0.0s
 => exporting to image                                                                                                                                                                 0.0s
 => => exporting layers                                                                                                                                                                0.0s
 => => writing image sha256:d1f3300e3448ef5eeb72cf95db5aebff3c8e740e69072bc23b29100bd5311509                                                                                           0.0s
 => => naming to docker.io/library/jijo:1.0

Save the docker image to local

Save the docker image to local and untar the file

docker save jijo:1.0 | gzip > jijo.tar.gz
mkdir -p jijo && tar -xf jijo.tar.gz -C jijo --strip-components 1
 ll
total 2.7M
-rw-r--r-- 1 jijo jijo 92 Aug 24 22:15 Dockerfile
drwxr-xr-x 5 jijo jijo 4.0K Aug 25 09:30 jijo
-rw-r--r-- 1 jijo jijo 2.7M Aug 25 09:30 jijo.tar.gz

Find the base layer from manifest.json

Analyze the contents of manifest.json, the first layer is the base layer. We will remove that folder and zip the file contents again

 cd jijo && cat manifest.json
[{
    "Config": "d1f3300e3448ef5eeb72cf95db5aebff3c8e740e69072bc23b29100bd5311509.json",
    "RepoTags": ["jijo:1.0"],
    "Layers": ["11cbe68173689fb732863a26e9c9217da15b278edc951dcae1effb426247f521/layer.tar", "f65769e67f610c4c0784eb7585bfcbb53d5da988f057363265d7e72675580443/layer.tar", "34a8e8adfac3eb497b3683326e980a62a322094bf8ed85be3c46d73a3cd209e3/layer.tar"]
}]

Remove the base layer folder

Finding first layer

FOLDER_TO_REMOVE=$(jq '.[].Layers[0]' manifest.json | sed s/\"//g  | sed s/\\/layer.tar//g)
rm -r $FOLDER_TO_REMOVE

Zip the contents again

 tar -zcvf jijo.tar.gz .
./
./34a8e8adfac3eb497b3683326e980a62a322094bf8ed85be3c46d73a3cd209e3/
./34a8e8adfac3eb497b3683326e980a62a322094bf8ed85be3c46d73a3cd209e3/VERSION
./34a8e8adfac3eb497b3683326e980a62a322094bf8ed85be3c46d73a3cd209e3/json
./34a8e8adfac3eb497b3683326e980a62a322094bf8ed85be3c46d73a3cd209e3/layer.tar
./f65769e67f610c4c0784eb7585bfcbb53d5da988f057363265d7e72675580443/
./f65769e67f610c4c0784eb7585bfcbb53d5da988f057363265d7e72675580443/VERSION
./f65769e67f610c4c0784eb7585bfcbb53d5da988f057363265d7e72675580443/json
./f65769e67f610c4c0784eb7585bfcbb53d5da988f057363265d7e72675580443/layer.tar
./d1f3300e3448ef5eeb72cf95db5aebff3c8e740e69072bc23b29100bd5311509.json
./repositories
./manifest.json
tar: .: file changed as we read it

Peek the contents of tar file

 tar -tf jijo.tar.gz
./
./34a8e8adfac3eb497b3683326e980a62a322094bf8ed85be3c46d73a3cd209e3/
./34a8e8adfac3eb497b3683326e980a62a322094bf8ed85be3c46d73a3cd209e3/VERSION
./34a8e8adfac3eb497b3683326e980a62a322094bf8ed85be3c46d73a3cd209e3/json
./34a8e8adfac3eb497b3683326e980a62a322094bf8ed85be3c46d73a3cd209e3/layer.tar
./f65769e67f610c4c0784eb7585bfcbb53d5da988f057363265d7e72675580443/
./f65769e67f610c4c0784eb7585bfcbb53d5da988f057363265d7e72675580443/VERSION
./f65769e67f610c4c0784eb7585bfcbb53d5da988f057363265d7e72675580443/json
./f65769e67f610c4c0784eb7585bfcbb53d5da988f057363265d7e72675580443/layer.tar
./d1f3300e3448ef5eeb72cf95db5aebff3c8e740e69072bc23b29100bd5311509.json
./repositories
./manifest.json

Clear the cache and remove the base image

Clear the cache and remove the base image in order to confirm that the docker image doesn't load from tar file without the base image

 docker rmi jijo:1.0
Untagged: jijo:1.0
Deleted: sha256:d1f3300e3448ef5eeb72cf95db5aebff3c8e740e69072bc23b29100bd5311509

 docker rmi alpine:latest
Error: No such image: alpine:latest

 docker system prune
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - all dangling build cache

Are you sure you want to continue? [y/N] y
Deleted Containers:
1df25e5e691b9a3a2d51580b9f44ce9da1f2640aff0d5122bc81d1c85b4a0968
eed8a6031062c25da5e3c32ee6ecfc9f9af7de01f3fef7e69fd9ea19f1839319
9af26acfc97bb38f3bff4bab7a51359c1e1877fa38a427f5647a6c5fb83fed7e
1a69feef5b3e99ac25ca0038ddc51107c8e7ffcfd32bc89796cf0da741629042
21d621a952d4835d3eab684e2864d25428e3ba329e02e4ac0d1ea14e1fdb2ee9
71522ba0ed8714c04297d58c72ef1b6d169f8d0f26ee732e027df301195ce67b
4e9d4aa31c777027cd84d710c0206e155a0428f5f6b668627bc03aa7bb812b9f
9f9ca76b10f4991a3ebd7f1dfa44084797ad9b42d2d3a0fa28187fb0d894b1d5
f08764ce7d21f5b1f5f2b8243e1c77a03455af71268fe3e4685824d9628af1b1
8cc554e54f6b5da73c6273406d9389b664fb84e9b73a16f13f8f260897fa817d
21201d6a53b01d14ec2d588b3a2230fbfb0bc06bce048af2d93099b520873fb7
addf3a8c8ea67b077c1f3f25a6281f77f19a378fe6932afae73b967e9e6adf53
665e592899a8bd7f6feae2a43f56efc3678e898d4e7b506fc113e69edf801759
4a6ce095a4de054e0542bd87a272a523ea85ae7afd5b8a4969fc44deabfb2122
21863ed7a45616c985411af96d709a13ed5c864b1f508fc76a8e9c767acb691d
c0d0179d675efc9655f27ba181736afd6184bf279e4e150f0430b836245935b2
f44631dd1e20e90ad18d9683f5e4de407da1c72eb94dad441146d3d8a6ed1414
587648e36694705ab401c32deb290142b3d58813443c768f5c79454e0ce56438
df3770c68de6bd787cb1e29a30499075f12a7818db50ba28b01322e948361d9e
7889331b1588c03db54c0ec4f0d653811be2f26ff844a56efdefc7e5cb704733
55e09a0770e480e3828ac1a1e662b76e3dca1c7cec56d917aee849554fb088ac

Deleted build cache objects:
xeopt73hh8934sras1f2lenkp
foju7uafxvy2pisuy6yzjvbw1

Total reclaimed space: 34.05kB

 docker buildx prune
WARNING! This will remove all dangling build cache. Are you sure you want to continue? [y/N] y
Total:  0B

First try : Load the docker image

 docker load -i jijo.tar.gz
open /var/lib/docker/tmp/docker-import-816606677/11cbe68173689fb732863a26e9c9217da15b278edc951dcae1effb426247f521/layer.tar: no such file or directory

Second try: Load the docker image

 docker pull alpine:latest
latest: Pulling from library/alpine
29291e31a76a: Pull complete
Digest: sha256:eb3e4e175ba6d212ba1d6e04fc0782916c08e1c9d7b45892e9796141b1d379ae
Status: Downloaded newer image for alpine:latest
docker.io/library/alpine:latest

 docker load -i jijo.tar.gz                                                                                                                          10s
17938a3475fd: Loading layer [==================================================>]  2.048kB/2.048kB
506cf94d07ed: Loading layer [==================================================>]  3.072kB/3.072kB
Loaded image: jijo:1.0

Success !! 🕺


Last update: November 7, 2023
Back to top