'Can I run an intermediate layer of a Docker image?

When I fetch a Docker image from a repository I see that it pulls a bunch of layers with some ids, but when I try to run them using docker run it tells me that it can't find it.

Can I run a certain layer of a Docker image that I can see through docker history < image_id >, like a paleontologist digging to find something interesting?

What I tried:

docker pull ruby
Using default tag: latest
latest: Pulling from library/ruby
693502eb7dfb: Already exists
081cd4bfd521: Already exists
5d2dc01312f3: Already exists
54a5f7da9a4f: Pulling fs layer
168cf3f33330: Pulling fs layer
021d84fef638: Pulling fs layer
168c3c107cd1: Waiting
f001b782a027: Waiting

Then:

docker run --rm -it 5d2dc01312f3 bash
Unable to find image '5d2dc01312f3:latest' locally

The question popped to me when I was pulling an image that I have build and published. I could see it clearly that one layer had almost 1.2 GB of size. It was the layer where I copied some files from the machine I used to build the image and on the next layer I cleaned and deleted some of those files as I was cleaning the image, but the total size of the image was about 1.5 GB which means that the big fat layer is of 1.2 GB is there. I just want to see if I can peek into that fat layer.



Solution 1:[1]

You can run an intermediate image of a Docker layer, which is probably what you want.

During your build you might need to inspect an image at certain point (step) in the build process e.g. in your Docker build output you'll see:

Step 17/30 : RUN rm -rf /some/directory
---> Running in 5ab963f2b48d

Where 5ab963f2b48d is an image ID, and when you list your images, you'd see that ID in the list e.g.

$ docker image ls --all
REPOSITORY    TAG      IMAGE ID       CREATED        SIZE
<none>        <none>   5ab963f2b48d   7 minutes ago  1.18GB

To run that image (with a terminal) for example, you can simply:

docker run -i -t 5ab963f2b48d /bin/bash

Also see: Run a Docker Image as a Container

Solution 2:[2]

You can't really run a layer. You can only run an associated image if it exists. Each layer would have an intermediate image associated with it if the image was built on the same host machine. You can show these layers and their associated images by running docker history <image-id>

The digests you see when you pull the image are digests of the layers they are not intermediate images. In that case, docker history will show the value <missing> in the image column to indicate that there are no images associated with these layers. Hence there is nothing to run.

Here is a typical scenario:

  1. You build an image on a host: An intermediate image will be created for each layer (this is done for docker build cache)
  2. You push the image to a registry: Only the final image is pushed (which references all the layers), but none of the intermediate images are pushed.
  3. You pull the image on another host: Only the final image is available now on that other Docker host.

The Docker daemon will not allow access to these layers unless the image was built on same docker host (or the Docker cache was distributed).

You can read more about layers at explaining-docker-image-ids.

Solution 3:[3]

Yes, this is possible, but if you are using Docker 1.10 or later, only with self build images. E.g., docker history ruby will output <missing> for all but the topmost layer, because they doesn't have a tag.

If you build it yourself they will have a tag and you can start them like normal.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Darren Shewry
Solution 2
Solution 3 Peter Mortensen