How to flatten an image with 127 parents

Newbie question: if I’ve managed to make an image with 127 layers (I know, bad form), is there a way to flatten it?

It seems like most solutions require making a container as the first step, but since I’m already at 127 layers in my image, I can’t do that. When I try to I get an error "“Error response from daemon: Cannot create container with more than 127 parents”

Thanks for any thoughts or suggestions.

1 Like

You can flatten an image with docker export and then docker import. That will take all the existing layers and export them as a single file system image, in a tarball. Then import will bring it back in again as an image.

Steps:

  1. docker run --name mycontainer the image to create a container (the container name mycontainer is just an example)
  2. docker export --output=mycontainer.tar mycontainer the container to a tarball (mycontainer.tar is just an example)
  3. cat mycontainer.tar | docker import - mynewimage:imported the tarball (the image name mynewimage:imported is just an example)

Docs:

Hi Rufus,

Hey thanks for the detailed instructions. My only trouble is that I can’t run my image because of that 127 layer rule. I get an error stating that when I try to run the image.

So I was hoping there was a way to flatten an image without having to build a container on it first. Maybe I’m out of luck…

Ah, now you’re entering into one of the cool characteristics of Docker images, though you might need to do some manual hacking.

Remember how you created all those layers? With RUN commands in a Dockerfile? So that means each layer is a starting point for a runnable container. We can see it in the image history:

$ docker pull supertest2014/nyan
$ docker history supertest2014/nyan
IMAGE               CREATED             CREATED BY                                      SIZE
a61f7f4d8006        10 months ago       /bin/sh -c #(nop) CMD [/bin/sh -c nyancat]      0 B
396a74b5847a        10 months ago       /bin/sh -c apt-get update; apt-get install -y   69.59 MB
ef83896b7fb9        11 months ago       /bin/sh -c #(nop) CMD [/bin/bash]               0 B
99e40d806d07        11 months ago       /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/   1.903 kB
2be841034d7d        11 months ago       /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   194.5 kB
8a1d8569bf87        11 months ago       /bin/sh -c #(nop) ADD file:950097168f2d2e2689   192.5 MB
511136ea3c5a        23 months ago                                                       0 B

# I could do this with any layer, but I'll pick the one that used to have /bin/bash
$ docker tag  ef83896b7fb9 starthere
$ docker run -it -name mycontainertoo starthere /bin/sh
# _

See? If I docker run starthere I begin with that layer and all the other layers above it get ignored. So you could find your 126th layer, tag that, run it, and export it. Let’s say you import it and call it “newbeginning” and it has an image id of deadbeef8f4a6f92648513e5e21573338f7bf7620a20166f368980a02c6c98b3.

If you can recreate layers 127+ with a Dockerfile, you could then start the Dockerfile with FROM newbeginning and comment out the first 126 steps. That’s the “best” way because it doesn’t involve any hacking.

If you want to keep going, you’re heading into hacking territory. The hack is to manually change the parent of layer 127 to be “newbeginning”. In the supertest2014/nyan example, that would mean finding the data for layer 396a74b5847a (the one after the one we tagged as starthere) and editing the json “parent” element to point to deadbeef... instead of ef83896b7fb9.... You’ll find that data in /var/lib/docker/graph/396a74b5847a.../json.

I haven’t done this myself, so I’m only 80% sure it will work. There could be other places where the parent pointer needs to be changed.

Before this kind of hack, I’d suggest making a backup of /var/lib/docker/ just in case you break something valuable. The tag/export/import/build technique is safer because it doesn’t destroy any existing data.

Aha! Awesome. I’ll try that out. Thanks kindly for the detailed help.

Its Awesome but clear METADATA from image.