Let's say I have two Dockerfiles that I use to create images with respective tags:
Dockerfile.A:
FROM some-image
...
EXPOSE 9000
ENTRYPOINT ["some-script.sh"]
and
Dockerfile.B:
FROM A
...
When I run the image B, does the container also expose the port that I defined in Dockerfile.A
, and run the entrypoint script defined there?
More generally, which instructions are inherited from base Dockerfiles, apart from the file system layers?
A dockerfile contains a set of instructions that are executed step by step when you use the docker build command to build the docker image.
The basic rules that Docker follows are outlined below: Starting with a parent image that is already in the cache, the next instruction is compared against all child images derived from that base image to see if one of them was built using the exact same instruction. If not, the cache is invalidated.
If a relative path is provided, it will be relative to the path of the previous WORKDIR instruction. For example: The USER instruction sets the user name (or UID) and optionally the user group (or GID) to use when running the image and for any RUN , CMD and ENTRYPOINT instructions that follow it in the Dockerfile.
RUN <command> ( shell form, the command is run in a shell, which by default is /bin/sh -c on Linux or cmd /S /C on Windows) The RUN instruction will execute any commands in a new layer on top of the current image and commit the results. The resulting committed image will be used for the next step in the Dockerfile.
These instruction are inherited from the base image along with system files.
EXPOSE
If the base image mentioned these EXPOSE 8080 9090
ports in Dockerfile, then the extend Dockerfile do not to need to expose these port. But there is a difference between exposing and publish
.
ENV
If the base image has some ENV like test-a=abc
then extended image will have these ENVs.
WorkingDir
If the base image have set "WorkingDir": "/root",
then extended iamge will have working direcotry /root
MAINTAINER
MAINTAINER adiii
extended image will have the same author if not overide.
Labels
The extended image will have the same label as the base image
onbuild
Designed to run by extended image.
ENTRYPOINT
Same entrypoint as in the base image, unless you overwrite it.
CMD
The extended image has the same CMD as the base image, as long as you do not overwrite the entrypoint instruction, see below.
You can try it.
Dockerfile A
FROM node:8.16
MAINTAINER adiii
LABEL key=test
EXPOSE 8080 9090
ENV test-a=abc
WORKDIR /root
ENTRYPOINT /root
CMD ["npm", "run", "start"]
Now build docker image B
Dockerfile B
FROM a
docker build -t b .
Inspect the image b docker inspect b:latest
you will see the above instruction iherited from the base image, because Dockerfile B did not overwrite the entrypoint instruction.
If the extended image overwrites the entrypoint, the documentation says CMD
will reset to an empty value and must be redefined if wanted.
Everything is inherited. For example, if you have
# Dockerfile.B
FROM A
And then you
docker build -t B -f Dockerfile.B .
Then these two commands are all but identical
docker run ... A ...
docker run ... B ...
Similarly, it doesn’t matter if you put a given command at the end for a base Dockerfile.A
, or if you start a Dockerfile.B
FROM A
and then have the same command.
(I think the one exception here is that specifying ENTRYPOINT
in a new Dockerfile resets the CMD
to an empty array. I don’t think this happens if you put CMD
before ENTRYPOINT
in the same Dockerfile.)
(Relatedly, you cannot undo a VOLUME
declaration in a derived image, which in turn means you can’t create a MySQL or PostgreSQL image with prepopulated data. I think you also can’t undo EXPOSE
though that’s less of a concern, since that directive has so little effect.)
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