Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Build 2 images with Docker from a single Dockerfile while using different base images

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:

  1. Get all the requirements for the full/slim version and make a base full/slim container
  2. Install the app on the full/slim base container and make the final full/slim container

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:

  • Have Dockerfile.template and bash generating 2 bespoke Dockerfiles from the template.
  • Have 3 different files. Common logic file and 2 unique Dockerfiles for the full/slim installs which would include the common logic file.
  • There is support for multiple FROM in the Dockerfile, but that looks to me catering to slightly different needs (and all google searches are indicating that).

But I wonder, is there any better approach? Or do I miss something?

like image 581
Anton Krug Avatar asked Jun 28 '18 10:06

Anton Krug


People also ask

Can we have 2 base images in Dockerfile?

Using multi-stage dockerfiles, you can use several base images as well as previous intermediate image layers to build a new image layer.

Can you combine 2 docker images?

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.

How do I put two images in a Dockerfile?

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.

Can we create multiple container from single image in docker?

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.


1 Answers

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.

like image 51
Tom Rijntjes Avatar answered Oct 02 '22 14:10

Tom Rijntjes