I'm building 2 variants of the final container a full version and the slim version. And both variants build their containers in 2 steps:
Both full/slim builds have an identical second step, they just use a different base container. And I would like to generalize the second step so I wouldn't have two Dockerfiles containing the same content with just different FROM field.
So I wonder what would be the best approach to have the last step as a single Dockerfile which would generate 2 images and only switch between 2 different FROM. I was thinking about a couple of different ways doing it:
But I wonder, is there any better approach? Or do I miss something?
Using multi-stage dockerfiles, you can use several base images as well as previous intermediate image layers to build a new image layer.
Docker doesn't do merges of the images, but there isn't anything stopping you combining the dockerfiles if available, and rolling into them into a fat image which you'd need to build.
On your machine, use docker pull to download the images from Docker Hub. Then, use docker history to get the commands that were used to build them. Then, open these two files. You can then see the command stack of each image.
With Docker compose, you can configure and start multiple containers with a single yaml file. This is really helpful if you are working on a technology stack with multiple technologies.
You could use build-time configuration with ARG.
FROM instructions support variables that are declared by any ARG instructions that occur before the first FROM. An ARG declared before a FROM is outside of a build stage, so it can’t be used in any instruction after a FROM. To use the default value of an ARG declared before the first FROM use an ARG instruction without a value inside of a build stage:
Dockerfile:
ARG imagename
FROM $imagename
RUN echo $imagename
Run with two different base images:
docker build --build-arg imagename=alpine .
outputs:
Step 1/3 : ARG imagename
Step 2/3 : FROM $imagename
latest: Pulling from library/alpine
ff3a5c916c92: Pull complete
Digest: sha256:e1871801d30885a610511c867de0d6baca7ed4e6a2573d506bbec7fd3b03873f
Status: Downloaded newer image for alpine:latest
---> 3fd9065eaf02
Step 3/3 : RUN echo $imagename
---> Running in 96b45ef959c3
Removing intermediate container 96b45ef959c3
---> 779bfc103e9e
Successfully built 779bfc103e9e
Alternatively:
docker build --build-arg imagename=busybox .
results in:
Step 1/3 : ARG imagename
Step 2/3 : FROM $imagename
latest: Pulling from library/busybox
07a152489297: Pull complete
Digest: sha256:141c253bc4c3fd0a201d32dc1f493bcf3fff003b6df416dea4f41046e0f37d47
Status: Downloaded newer image for busybox:latest
---> 8c811b4aec35
Step 3/3 : RUN echo $imagename
---> Running in 6027fe4f5b7b
Removing intermediate container 6027fe4f5b7b
---> 28640f123967
Successfully built 28640f123967
See also this blogpost for more ideas.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With