It’s always said, “Do not try to re-invent the wheel!”
When working with Docker, it is a good practice to search for some ready-to-use images on Docker Hub before building you own. It is very powerful to have your software architecture distributed in a set of containers, each one does one job. And the best building block of your distributed application is to use official images from Docker Hub. You can trust their functionalities.
In some cases, you may want to have one container do two different jobs. In other few cases, you may want one Docker image to contain dependencies from two different Docker images. This is easily done as long as you have the Dockerfile of each image. Simply, organize them in one file and build it!
However, if you spend most of the time using ready images from Docker Hub, you do not have their source Dockerfile. I spent some time searching for a tool to use it to merge (or flatten) two different Docker images; that I don’t have their Dockerfiles. I was searching for something to do the following:
image1 --
\
---> merged_image_12
/
image2 --
Although this issue was closed before in two different threads (1, 2), it arises in some scenarios when you want to do something like that!..
Is it possible? ..
So, is there any tool that one can use to act like: docker merge image1 image2 merged_image ?
No!
You can not even build a Dockerfile like:
FROM image1 FROM image2
Simply, because you cannot have multiple base images in a Dockerfile.
But, I need this feature!
The only solution yo have is to get the Dockerfile of these images and organize them in one file, then build. So, can I get the Dockerfile of an image on Docker Hub? The happy news is YES. It is not available online, but you can reverse-engineer it with docker history command.
How to use it?
On your machine, use docker pull to download the images from Docker Hub.
docker pull image1 docker pull image2
Then, use docker history to get the commands that were used to build them.
docker history --no-trunc=true image1 > image1-dockerfile docker history --no-trunc=true image2 > image2-dockerfile
Then, open these two files. You can then see the command stack of each image. This holds true because of the fact that Docker images are structured into layers (read more). That is, each command you type in the Dockerfile builds a new image on top of previous images from previous commands. Therefore, you can reverse-engineer images.
Restrictions
The only scenario when you will not be able to reverse-engineer an image is when the maintainer of the image has used ADD or COPY commands in his Dockerfile. You will see a line like:
ADD file:1ac56373f7983caf22 or ADD dir:cf6fe659e9d21535844
This is because you cannot get what local files the maintainer used on his machine to include in this image.
Happy Reverse-Engineering 🙂
As to ADD/COPY, you should still be able to see the file or directory in the image, so you could extract it back out of the image using docker cp
LikeLiked by 1 person
Thank you Ben for your comment.
I believe that we can still see the file or directory in the image, but do you know how to locate it? I mean how can I know which directory or file in the image was added at this step? All what I see is
ADD file:1ac56373f7983caf22
or ADD dir:cf6fe659e9d21535844
which doesn’t reveal information about the path. What do you think?
LikeLike
Hi, I think that would be possible by using a combination of the good ol’ unix diff (use –recursive), and a combination of the docker import/export and load/save commands. With these you can export images. And as you know, each layer is an image.
So, by extracting each image and diff-ing them, you should be able to reverse engineer the changes.
Never tried it though, so this is just theory 🙂
LikeLiked by 2 people
Hi,did you get a way to find out the directory of ADD file?
LikeLike
Haven’t attempted it yet. You can check other replies here for possible solutions
LikeLike
using docker in docker, it is possible to ‘combine’ two docker images together by running them both in a docker in docker container.
LikeLike
CenturyLinkLabs script dockerfile-from-image https://github.com/CenturyLinkLabs/dockerfile-from-image
LikeLiked by 2 people
One possible workaround to your solution – build a dockerfile using FROM image1 and install image2 in dockerfile.
LikeLiked by 1 person
How can i install python image after making ubuntu a base image.
LikeLike
You can look for a python image on Docker Hub
LikeLike
How can I install image2 in dockerfile?
LikeLike
By installing all environment dependencies and libraries as if you are building the image from scratch; but you are building it based on image1
LikeLike
The idea looks good.
However if the two images to be merged have specified different commands to run, after we merge them in such way and start up a container on the result image, which command should it run?
LikeLike
The best answer is to try this out. Note that this post is over three year old. Docker has not been as mature as it is now. Probably, they have a different solution for it now; or the merging concept is not a valid deployment practice now.
LikeLike