-
Notes
Dockerfile contains builds commands that are needed to create a Docker image.
The Dockerfile supports the following instructions:
See these pages for more information:
https://docs.docker.com/reference/dockerfile/
https://docs.docker.com/build/building/best-practices/
Docker introduced new backend for builing images (buildkit) which doesn't expose intermediate containers.
To show intermediate containers, set the environment variable
DOCKER_BUILDKIT before the docker build command:
-
FROM
The FROM instruction creates a new build stage from a base image.
-
ARG
The ARG instruction uses build-time variables (along with their default values).
-
LABEL
The LABEL instruction adds metadata to an image.
Note that the label is using a variable name which, in this case, references the argument defined by the instruction ARG.
Let's use a Dockerfile with the above instructions:
Let's build the Dockerfile:
You can inspect the created image to check the labels:
-
ENV
The ENV instruction sets environment variables (also available as regular variables during build-time).
Let's use a Dockerfile with the above instructions:
Let's build the Dockerfile:
You can inspect the created image to check the labels.
Note that the environment variable was used to set the label.
Also note that this time the label used the default value of the argument because it was not set when the image was created.
Let's check the env variable within the container:
-
RUN
The RUN instruction executes build commands.
You should combine multiple build execution commands into a single instruction whenever possible.
You should also avoid updating the operating system or upgrading libraries.
If necessary, you should use a base image that you can build only when needed.
The base image should also be used, where possible, to install third-party libraries.
-
COPY
The COPY instruction copies files and directories from the local filesystem into a Docker image.
You can copy files or folders.
When copying a folder, only its content is copied.
Let's create few local folders/files:
Let's use a Dockerfile to copy files/folders into the Docker image:
Let's build the Dockerfile:
You can check the copied files/folders
-
CMD
The CMD instruction specifies default commands.
Let's use a Dockerfile:
Let's build the Dockerfile:
You can check the copied files/folders
-
ENTRYPOINT
The ENTRYPOINT instruction specifies default executable.
Let's use a Dockerfile:
Let's build the Dockerfile:
You can check the copied files/folders
-
USER
The USER instruction sets the user that will be used to run the processes inside the container.
By default, if the USER instruction is not set, docker run all processes as root.
Unless there is a real reason for this, you should avoid running containers using root or privileged users.
Let's check the mti existing on the Docker host:
Let's first try a Dockerfile without the USER instruction:
Let's build the Dockerfile:
Let's check the user within the container:
Let's try now a Dockerfile with the USER instruction:
Let's build the Dockerfile:
Let's check the user within the container:
Note that the Dockerfile create the group "tek" with the group id (gid) "1002".
It also create the user "mti" with the user id (uid) "1002" and the group id (gid) "1002".
The image that we create from this Dockerfile will run with the user "mti".
Note that the group and user names are, more or less, just friendly names.
The important part is the uid and gid.
These two elements will map the container's user uid and group gid to the host's user uid and group gid.
So, in the above example, the container will be running using the same uid and gid that match the ones of the Docker host.
In the host I am using the uid 1002 and gid=1002 are mapped to the user and group "mtitek".
This means that the container's user will get the same privileges that the user "mtitek" has.
-
VOLUME
The VOLUME instruction creates volume mounts.
Let's create a Dockerfile that will use the VOLUME instruction to mount a local directory.
I will adapt a bit the nginx Dockerfie to print the logs in a directory.
Here's the Dockerfile (this is for demo purposes only):
Let's build the Dockerfile:
Let's create a local directroy:
Let's run the nginx image (the host's directory ./nginx-loc-dir is mounted to the container's directory /var/log/nginx):
Check the nginx process:
Let's access nginx at the published port 32770:
Check the nginx logs:
-
WORKDIR
The WORKDIR instruction sets the working directory for the remaining build instructions.
This working directory will also be the default directory for all processes running inside the container.
Let's try a Dockerfile with the WORKDIR instruction:
Let's build the Dockerfile:
Let's check the working directory within the container:
-
EXPOSE
The EXPOSE instruction informs Docker that the container should listen on the specified ports.
You still need to manually publish the ports when running the container.
Use the -p flag to publish and map ports.
Use the -P flag to publish all exposed ports and map them to ephemeral higher-order host ports on the host.
By default, ports listen on TCP but you can explicitly set UDP.
Let's try a Dockerfile with the EXPOSE instruction:
Let's build the Dockerfile:
Let's check the exposed port: