Docker Dockerfile

created:

updated:

tags: docker

What is Dockerfile?

Docker can build images automatically by reading the instructions from a Dockerfile. A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image.

Format

“Docker runs instructions in a Dockerfile in order. A Dockerfile must begin with a FROM instruction.”

Example:

# syntax=docker/dockerfile:1
FROM node:18-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]
EXPOSE 3000

Environment Variable

In Dockerfile, we can declare environment variables by using ENV command:

FROM busybox
ENV FOO=/bar

We can access environment variables through $variable_name or ${variable_name} syntax.

  • ${variable:-word}:
    • if variable is set, then the result is the value of variable.
    • if variable is not set, then word will be the result as the default value.
  • ${variable:+word}:
    • if variable is set, then word will be the result.
    • if variable is not set, then the result will be the empty string.

.dockerignore file

This is kind of similar to .gitignore file. If this file exists, the docker CLI ignores the files specified in .dockerignore file. This is helpful as it helps not send unnecessary and large files to the docker daemon.

FROM

“The FROM instruction initializes a new build stage and sets the base image.”

RUN

“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.”

RUN has two forms:

  • RUN <command>:
    • ex: RUN /bin/bash -c 'source $HOME/.bashrc && echo $HOME
  • RUN ["executable", "param1", "param2"]:
    • ex: RUN ["/bin/bash", "-c", "echo $HOME"]

CMD

“The main purpose of CMD is to provide defaults for an executing container.”

“There can be only one CMD instruction in a Dockerfile. If you list more than one CMD then only the last CMD will take effect.”

LABEL

“The LABEL instruction adds metadata to an image. A LABEL is a key-value pair.”

“An image can have more than one label.”

EXPOSE

“The EXPOSE instruction informs Docker that the container listens on the specified network ports at runtime. You can specify whether the port listens on TCP or UDP, and the default is TCP if the protocol is not specified.”

“The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports are intended to be published.”

ENV

“The ENV instruction sets the environment variable <key> to the value <value>. This value will be in the environment for all subsequent instructions in the build stage and can be replaced inline in many as well.”

“The environment variables set using ENV will persist when a container is run from the resulting image. You can view the values using docker inspect, and change them using docker run --env <key>=<value>.”

“A stage inherits any environment variables that were set using ENV by its parent stage or any ancestor.”

ADD

“The ADD instruction copies new files, directories or remote file URLs from <src> and adds them to the filesystem of the image at the path <dest>.”

# ADD [--chown=<user>:<group>] [--chmod=<perms>] [--checksum=<checksum>] <src> ... <dest>
# ADD [--chown=<user>:<group>] [--chmod=<perms>] ["<src>", ..., "<dest>"]
ADD home?.txt /mydir/

“The <dest> is an absolute path, or a path relative to WORKDIR, into which the source will be copied inside the destination container.”

COPY

“The COPY instruction copies new files or directories from <src> and adds them to the filesystem of the container at the path <dest>.”

# COPY [--chown=<user>:<group>] [--chmod=<perms>] <src> ... <dest>
# COPY [--chown=<user>:<group>] [--chmod=<perms>] ["<src>", ..., "<dest>"]
COPY home?.txt /mydir/

“The <dest> is an absolute path, or a path relative to WORKDIR, into which the source will be copied inside the destination container.”

ENTRYPOINT

“An ENTRYPOINT allows you to configure a container that will run as an executable.”

The exec form (which is the preferred form):

  • ENTRYPOINT ["executable", "param1", "param2"] The shell form:
  • ENTRYPOINT command param1 param2

“You can override the ENTRYPOINT instruction using the docker run --entrypoint flag.”

“Only the last ENTRYPOINT instruction in the Dockerfile will have an effect.”

VOLUME

“The VOLUME instruction creates a mount point with the specified name and makrs it as holding externally mounted volumes from native host or other containers.”

The format:

  • VOLUME ["/data"]: “The value can be a JSON array, VOLUME ["/var/log/"], or a plain string with multiple arguments, such as VOLUME /var/log or VOLUME /var/log /var/db.”
FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol

“This Dockerfile results in an image that causes docker run to create a new mount point at /myvol and copy the greeting file into the newly created volume.”

WORKDIR

“The WORKDIR instruction sets the working directory for any RUN, CMD, ENTRYPOINT, COPY and ADD instructions that follow it in the Dockerfile. If the WORKDIR doesn’t exist, it will be created even if it’s not used in any subsequent Dockerfile instruction.”

“The WORKDIR instruction can be used multiple times in a Dockerfile. If a relative path is provided, it will be relative to the path of the previous WORKDIR instruction. For example:”

WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd
# output: /a/b/c

“The WORKDIR instruction can resolve environment variables previously set using ENV. You can only use environment variables explicitly set in the Dockerfile. For example:”

ENV DIRPATH=/path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd
# output: /path/$DIRNAME

“If not specified, the default working directory is /.”

ARG

“The ARG instruction defines a variable that users can pass at build-time to the builder with the docker build command using the --build-arg <varname>=<value> flag. If a user specifies a build argument that was not defined in the Dockerfile, the build outputs a warning.”

[Warning] One or more build-args [foo] were not consumed.

“A Dockerfile may include one or more ARG instructions.”

FROM busybox
ARG user1
ARG buildno

“An ARG instruction can optionally include a default value:”

FROM busybox
ARG user1=someuser
ARG buildno=1

“If an ARG instruction has a default value and if there is no value passed at build-time, the builder uses the default.”

References