0

Is it possible to use a multi-stage Dockerfile where the first base image pertains to Ubuntu, then the second one pertains to Alpine. I know that the end image resulting from the build using this Dockerfile cannot be executed on an Ubuntu platform since it also contains Alpine instructions and the same if you execute it on Alpine. But I would still like to confirm if that is the case

For example, here is my sample Dockerfile:

FROM some-ubuntu-base-image:latest 

RUN apt-get update && apt-get install -y my-ubuntu-package

FROM some-alpine-base-image:latest

RUN apk add my-alpine-package

............
.............
Leonardo Dagnino
  • 2,914
  • 7
  • 28
Ashley
  • 1,447
  • 3
  • 26
  • 52
  • Yes, it is. In fact, the official [multi-stage build example](https://docs.docker.com/develop/develop-images/multistage-build/) uses golang (based on debian) and alpine. Your assertion that you can't run a binary on multiple platforms is also not true. – chash Jun 16 '20 at 17:39
  • But how is that possible? I mean from a build perspective it doesn't work since if you are declaring an ubuntu base image at the top and then running a couple of apt-get for dependencies and then later down the file you use FROM some-alpine-image and then use few apk for that, and if the build is run on an ubuntu based server, it won't recognize apk. So the build will fail right away. Now coming back to container execution , how would that work, if you are packaging two different linux OS based images under one final image and then running that as a container? – Ashley Jun 16 '20 at 17:46
  • 1
    The final image only includes the last stage of the build - all the previous stages are not in the final image. They are there so you can do thing in them and then only keep small parts of it in the final image - like compiling your program without having to keep a compiler in the final image. – Leonardo Dagnino Jun 16 '20 at 17:53
  • 1
    It _does_ work. Whether the build is "run on an ubuntu based server" is completely irrelevant to whether `apk` works in a Dockerfile. – chash Jun 16 '20 at 17:58

2 Answers2

3

First, there's nothing preventing an Alpine image from running on a Ubuntu docker host. These are different filesystems running on top of the same Linux kernel, and the shared kernel doesn't impact the ability to run different distribution binaries/libraries.

From the multi-stage part, you can use whatever image you want for each state, these are each independent from each other. Multi-stage is not a way to merge images, at the start of the second stage (unless that stage is from the first stage output) you have nothing from the first stage in the filesystem of that second stage.

The issue you will encounter is if you copy files between stages that have dependencies on other files (e.g. libraries) on the filesystem. The most common issue is trying to run binaries compiled against libc on an Alpine system that uses musl.

BMitch
  • 231,797
  • 42
  • 475
  • 450
  • Thanks BMitch! But then how do you build a docker image like the one in my question. If i run it on a CI platform like jenkins that uses ubuntu OS, it fails to recognize apk commands declared under FROM some-alpine-base-image:latest – Ashley Jun 16 '20 at 18:01
  • @Ashley I'm not able to reproduce your error here. Can you provide a reproduceable Dockerfile that others can run to generate the error you are seeing? – BMitch Jun 16 '20 at 18:04
  • @Ashley Be sure to include the error message with the reproducible Dockerfile too. – BMitch Jun 16 '20 at 18:14
  • Looks like i was looking at the wrong one. It does build fine on my jenkins that is basically using a pod template with few containers to support OS specific libraries needed for the builds. So the dockerfile as in example above builds fine on the ubuntu platform or alpine platform doesn't matter what linux platform you use. – Ashley Jun 16 '20 at 19:31
1

Yes, it it. It may cause problems, however: if you use dynamic linking, you may be copying an executable that requires a version of a library that was available in the stage you made it at, but not at your final image's distribution. This is not a big problem for languages/programs compiled statically however (like Go), since they essentially bundle the libraries they use into the executable.

If you can, you should avoid doing this, though. Except for specific cases, it's an incompatibility risk that doesn't have much value to offer.

Leonardo Dagnino
  • 2,914
  • 7
  • 28