[docker] Multiple FROMs - what it means

I want to build a docker image for the Linkurious project on github, which requires both the Neo4j database, and Node.js to run.

my first approach was to declare a base image for my image, containing Neo4j. The reference docs do not define "base image" in any helpful manner:

Base image: An image that has no parent is a base image

from which I read that I may only have a base image if that image has no base image itself.

but what is a base image? does it mean that if I declare neo4j/neo4j in a FROM directive, that when my image is run the neo database will automatically run and be available within the container on port 7474?

reading the Docker reference (see: https://docs.docker.com/reference/builder/#from) I see:

FROM can appear multiple times within a single Dockerfile in order to create multiple images. Simply make a note of the last image ID output by the commit before each new FROM command.

do I want to create multiple images? it would seem what I want is to have a single image that contains the contents of other images e.g. neo4j and node.js

I've found no directive to declare dependencies in the reference manual. are there no dependencies like in RPM where in order to run my image the calling context must first install the images it needs?

I'm confused...

This question is related to docker dockerfile

The answer is


The first answer is too complex, historic, and uninformative for my tastes.


It's actually rather simple. Docker provides for a functionality called multi-stage builds the basic idea here is to,

  • Free you from having to manually remove what you don't want, by forcing you to whitelist what you do want,
  • Free resources that would otherwise be taken up because of Docker's implementation.

Let's start with the first. Very often with something like Debian you'll see.

RUN apt-get update \ 
  && apt-get dist-upgrade \
  && apt-get install <whatever> \
  && apt-get clean

We can explain all of this in terms of the above. The above command is chained together so it represents a single change with no intermediate Images required. If it was written like this,

RUN apt-get update ;
RUN apt-get dist-upgrade;
RUN apt-get install <whatever>;
RUN apt-get clean;

It would result in 3 more temporary intermediate Images. Having it reduced to one image, there is one remaining problem: apt-get clean doesn't clean up artifacts used in the install. If a Debian maintainer includes in his install a script that modifies the system that modification will also be present in the final solution (see something like pepperflashplugin-nonfree for an example of that).

By using a multi-stage build you get all the benefits of a single changed action, but it will require you to manually whitelist and copy over files that were introduced in the temporary image using the COPY --from syntax documented here. Moreover, it's a great solution where there is no alternative (like an apt-get clean), and you would otherwise have lots of un-needed files in your final image.

See also


Examples related to docker

standard_init_linux.go:190: exec user process caused "no such file or directory" - Docker What is the point of WORKDIR on Dockerfile? E: gnupg, gnupg2 and gnupg1 do not seem to be installed, but one of them is required for this operation How do I add a user when I'm using Alpine as a base image? docker: Error response from daemon: Get https://registry-1.docker.io/v2/: Service Unavailable. IN DOCKER , MAC How to fix docker: Got permission denied issue pull access denied repository does not exist or may require docker login Docker error: invalid reference format: repository name must be lowercase Docker: "no matching manifest for windows/amd64 in the manifest list entries" OCI runtime exec failed: exec failed: (...) executable file not found in $PATH": unknown

Examples related to dockerfile

standard_init_linux.go:190: exec user process caused "no such file or directory" - Docker What is the point of WORKDIR on Dockerfile? Can't create a docker image for COPY failed: stat /var/lib/docker/tmp/docker-builder error /bin/sh: apt-get: not found COPY with docker but with exclusion Dockerfile if else condition with external arguments Docker build gives "unable to prepare context: context must be a directory: /Users/tempUser/git/docker/Dockerfile" denied: requested access to the resource is denied : docker Understanding "VOLUME" instruction in DockerFile ARG or ENV, which one to use in this case?