5

I am saving my image to a tar file something like this

docker save myimage:latest > myimage.tar.gz and then I am trying to use this tar file in my Dockerfile like this

FROM scratch
ADD myimage.tar.gz

However the build is failing. Could someone please help me here how can I send tar file in Dockerfile

Madhuri
  • 101
  • 1
  • 5
  • 11

2 Answers2

3

If you have a docker save tarball, you need to docker load it before it can be used. When you do, that will print out the name(s) and tag(s) of the image(s) that were loaded. You can then use that in the FROM line of your Dockerfile, like any other local image.

$ docker load -i myimage.tar.gz

Loaded image: my/image:and-its-tag
$ head -1 Dockerfile
FROM my/image:and-its-tag

If you docker push or docker save the resulting image, it will have a complete copy of the original image.

(In normal operation you shouldn't need docker save; prefer a registry service like Docker Hub, something cloud-hosted like GCR/ACR/ECR, or running your own. You can't really directly use the saved image tarfile for anything.)

David Maze
  • 130,717
  • 29
  • 175
  • 215
  • I don't want to do docker save and then use that.. I want to use .tar.gz way only to use as parent image – Madhuri Apr 23 '21 at 14:46
1

For the fun - images are saved with the manifest.json which contains a list of images layers with the path to each tar'd layer. You can ADD the layers to a scratch image.


The manifest.json for the public ubuntu:20.04 that is included in the tar file produced from a docker save:

[
  {
    "Config": "4e2eef94cd6b93dd4d794c18b45c763f72edc22858e0da5b6e63a4566a54c03c.json",
    "RepoTags": [
      "ubuntu:20.04"
    ],
    "Layers": [
      "6d0f49bfc6be64bfab1f9c1fd2ed975f1b31300932f6e6a58431eba145aeef1f/layer.tar",
      "168251688b4a0d65c58c010d18c2e5e7bc7b1288e30e54f651e683fe7af5983c/layer.tar",
      "a48aad357767ae0e674c26ed749956078c003949bcd931af931dfc272cc96a9c/layer.tar",
      "a9d70cfea3838f5442dce79f10ea881c4705f3bbc1123a73317f90d0958341fb/layer.tar"
    ]
  }
]

... the layers can be added to a new image built FROM scratch:

FROM scratch
ADD 6d0f49bfc6be64bfab1f9c1fd2ed975f1b31300932f6e6a58431eba145aeef1f/layer.tar /
ADD 168251688b4a0d65c58c010d18c2e5e7bc7b1288e30e54f651e683fe7af5983c/layer.tar /
ADD a48aad357767ae0e674c26ed749956078c003949bcd931af931dfc272cc96a9c/layer.tar /
ADD a9d70cfea3838f5442dce79f10ea881c4705f3bbc1123a73317f90d0958341fb/layer.tar /
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
CMD ["/bin/bash"]

Note: setting the CMD and ENV from the parent image - the config is available in the file referenced by the manifest.json's Config key.

docker build from layers

... if we docker inspect the image and compare it with the original, the layers are nearly identical:

docker inspect image hackity-hack-hack

... the last layer in the case of the ubuntu:20.04 image contains the /run/systemd/container config - the files md5sum in the built image is identical to that of the original image however the layer hash differs - the image history which is otherwise preserved in the config file is lost (the history is complete if you start FROM ubuntu:20.04, extend the image, save it, untar the file and inspect the config).

/run/systemd/container checksum

Can extend the docker image however you want:

FROM scratch
ADD 6d0f49bfc6be64bfab1f9c1fd2ed975f1b31300932f6e6a58431eba145aeef1f/layer.tar \
    168251688b4a0d65c58c010d18c2e5e7bc7b1288e30e54f651e683fe7af5983c/layer.tar \
    a48aad357767ae0e674c26ed749956078c003949bcd931af931dfc272cc96a9c/layer.tar \
    a9d70cfea3838f5442dce79f10ea881c4705f3bbc1123a73317f90d0958341fb/layer.tar /
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
RUN apt-get update && \
    apt-get install -y --no-install-recommends cowsay && \
    rm -rf /var/cache/apt/lists/*
CMD ["cowsay"]

docker cowsay hello world

masseyb
  • 3,745
  • 1
  • 17
  • 29