Dockerfile
Dockerfile is a text file that contains instructions on how to build a custom image.
A very simple Dockerfile for Springboot app
1 | FROM openjdk:8-jre-alpine |
A Dockerfile for Python app. see Get Started, Part 2: Containers
1 | # Use an official Python runtime as a parent image |
Building Image using Dockerfile
docker build
command builds an image from a Dockerfile and context. Docker Image is consist of read-only layers. Each instruction in a Dockerfile creates one layer on top of the previous layer.
Syntax
1 | docker build -t image_name directory_path |
The build’s context is the set of files at a specified location PATH or URL. The PATH is a directory on your local filesystem. The URL is a Git repository location.
The build is run by the Docker daemon, not by CLI. the context(except for the files and directory exclude by .dockerignore file) is send to the daemon.
Example to build testimage:v1 using ./testapp as the context
1 | docker build -t testimage:v1 ./testapp |
Use -f
option to specify Dockerfile location if Dockerfile is not at the top of the context
1 | docker build -f testapp/dockerfiles/Dockerfile.debug -t testimage:v1 ./testapp |
Dockerfile Format
Comments starts with ‘#’
use backslash() as the escape character.
A Dockerfile usually start with a form
instruction.
Environment Variable
You can get the value of an Environment variable with $variable_name
or ${variable_name}
You can escape string starts with $
by adding a \
before the $
.
Environment variables are supported by the following list of instructions:
- ADD
- COPY
- ENV
- EXPOSE
- FROM
- LABEL
- STOPSIGNAL
- USER
- VOLUME
- WORKDIR
FROM
Syntax
1 | FROM <image>[:<tag>] |
The FROM instruction initializes a new build stage and sets the Base Image for subsequent instructions.
example:
1 | FROM httpd:2.4 |
COPY & ADD
The COPY
and ADD
instruction copies files and folders from host to the image we’re building. ADD
is more powerful, it can unpack tar archive and download from URL and copy to the building image.
example
1 | COPY index.html /var/www/html/ |
Best practice is to use COPY
when copying local files to Docker image because it is more explicit. Use ADD
only for tar files and download from URLs.
WORKDIR
sets the working directory for any RUN
, CMD
, ENTRYPOINT
, COPY
and ADD
instructions that follow it in the Dockerfile.
The WORKDIR
instruction can be used multiple times in a Dockerfile.
1 | RUN mkdir -p /path/to/workdir |
Do not use RUN cd /path/to/workdir
. It has no effect on the image filesystem
RUN
Commonly used instruction. The RUN
instruction will execute any commands in a new layer on top of the current image and commit the results. RUN
instruction is often used to install software packages.
You can have many RUN
instructions in a Dockerfile.
Syntax
1 | RUN <command> |
example
1 | RUN apt-get update \ |
CMD & ENTRYPOINT
Both CMD
and ENTRYPOINT
can be used to start a process. They are very similar. Both CMD
and ENTRYPOINT
has two forms, shell form and exec form.
Two forms of ENTRYPOINT
- ENTRYPOINT command param1 param2 (shell form)
- ENTRYPOINT [“executable”, “param1”, “param2”] (exec form, preferred)
Shell format example
1 | FROM alpine |
exec form example
1 | FROM alpine |
CMD
provide defaults for an executing container. command line arguments will override CMD
instruction.
Three forms of CMD
- CMD command param1 param2 (shell form)
- CMD [“executable”,”param1”,”param2”] (exec form, this is the preferred form)
- CMD [“param1”,”param2”] (as default parameters to ENTRYPOINT, ENTRYPOINT must use exec form in this case)
Shell form example
1 | FROM alpine |
exec form example
1 | FROM alpine |
CMD and ENTRYPOINT can interact. When both instruction are presented,
CMD defines default arguments for an ENTRYPOINT instruction.
Example
1 | FROM alpine |
CMD vs ENTRYPOINT
- CMD sets default command. This command can be easily overriden from commandline
- ENTRYPOINT is often used for a long running process. parameters passed to
docker run
will not override ENTRYPOINT instruction parameters - CMD is used to define a default command to execute. parameters passed to
docker run
will override CMD.
VOLUME
VOLUME
defines a path in the container to the host. Host path can map to the container path using -v
argument when runnning a cotnainer.
1 | VOLUME ["/data/db"] |
Volume allows us to add source and data to the image without commiting them to the image.
EXPOSE
The EXPOSE
instruction informs Docker that the container listens on the specified network ports at runtime. You can have multiple EXPOSE
instruction in a Dockerfile
1 | EXPOSE 80 |
By default, EXPOSE assumes TCP. You can also specify UDP
1 | EXPOSE 80/udp |
ARG
The ARG
instruction defines a variable that users can pass at build-time to the builder with the docker build
command. use --build-arg var=val
option to pass these variables.
ARG instruction can have a default value.
An ARG instruction goes out of scope at the end of the build stage where it was defined.
1 | FROM busybox |
to pass 123456 as argument
1 | docker build --build-arg buildno=123456 . |
Sample output
1 | Sending build context to Docker daemon 2.048kB |
ENV
The ENV instruction sets the environment variable. see Reference
syntax
1 | ENV <key> <value> |
example
1 | ENV foo /bar/baz |
You can also pass environment variable to container using -e flag
1 | docker run -dit -e ENV_VAR_1='foo' -e ENV_VAR_2='bar' -p 80:80 --name test nginx:alpine |
ENV vs ARG
Environment variable are available during the image build stage and when a container is launched from the image. ARG variables is ONLY available during the image build stage.
LABEL
label is a key-value pair.
syntax
1 | LABEL <key>=<value> <key>=<value> <key>=<value> ... |
example
1 | LABEL version="1.0" |
When you use docker inspect
command to get the low level info for a container, you will get the labels for the containers
STOPSIGNAL
sets the signal to send to stop the container using docker stop
command. The default signal is SIGTERM
. If the main process doesn’t exit after a period of time, SIGKILL
will be sent.
1 | STOPSIGNAL SIGKILL |
ONBUILD
syntax
1 | ONBUILD [INSTRUCTION] |
ONBUILD adds a trigger instruction to be executed when the image is used as the base for another build.
This is useful if you are building an image which will be used as a base to build other images
HEALTHCHECK
Tells Docker how to test a container to see if it is working.
syntax
1 | HEALTHCHECK [OPTIONS] CMD command |
example
1 | HEALTHCHECK --interval=5m --timeout=3s \ |
SHELL
the SHELL instruction overrides the default shell. The default shell on Linux is ["/bin/sh", "-c"]
. For windows, it is ["cmd", "/S", "/C"]
Example
1 | # Executed as powershell -command Write-Host hello |
Best practices
use this document for Dockerfile best practice
- use .dockerignore file to filter out the files and directories not being used
- Don’t install unnecessary package
- Minimize layers used. Multi-stage build can be used to achieve that.
- Leverage build cache. Cache can significantly reduce build time. If you don’t want to use cache, set parameter
--no-cache-true
see this blog post for some useful Best practices
Tools
Docker Extension for VS Code provides syntax highlighting, commands, and linting for Dockerfile.
To Install, just search for Docker in VS Code extension tab. Then install the Docker extension from Microsoft.