A Dockerfile is a text file for automatically building Docker images. The instructions written in a Dockerfile are executed sequentially from top to bottom, ultimately creating a Docker image. Here, we explain the major instructions commonly used in Dockerfiles.
FROM
Specifies the base image. This must be the first instruction in the Dockerfile.
FROM <image_name>[:<tag>]
# Example: FROM ubuntu:22.04
# Example: FROM python:3.9-slim-buster
LABEL
Specifies image metadata. Written as key-value pairs, it can attach information about the image (author, version, description, etc.).
LABEL <key>="<value>" [<key>="<value>" ...]
# Example: LABEL maintainer="Your Name <your.email@example.com>"
# Example: LABEL version="1.0" description="My custom web app image"
USER
Specifies the user under which subsequent RUN, CMD, and ENTRYPOINT instructions are executed. The default is root. For security, it is recommended to specify a non-root user for operations that do not require privileges.
USER <username>[:<groupname>]
# Example: USER appuser
WORKDIR
Specifies the working directory for subsequent RUN, CMD, ENTRYPOINT, COPY, and ADD instructions. If specified as a relative path, it is relative to the previous WORKDIR instruction.
WORKDIR /path/to/workdir
# Example: WORKDIR /app
EXPOSE
Specifies the ports the container listens on. This serves as documentation; the docker run -p option is required to actually publish ports.
EXPOSE <port_number> [<port_number>/<protocol> ...]
# Example: EXPOSE 80
# Example: EXPOSE 8080/tcp 8080/udp
COPY
Copies files or directories from the host machine (the machine running the Docker daemon) into the container image.
COPY <host_path> <container_path>
# Example: COPY ./app /app
# Example: COPY requirements.txt /tmp/
ADD
Similar to COPY, but with the following additional features:
- If
host_pathis a URL, it downloads the file and places it in the container. - If
host_pathis a compressed file (tar, gzip, bzip2, etc.), it is automatically extracted in the container.
ADD <host_path_or_URL> <container_path>
# Example: ADD https://example.com/app.tar.gz /app/
Generally, COPY is preferred. Use ADD only when its additional features are needed.
RUN
Executes commands inside the container during image build time. This allows installing software and setting up files in the image.
RUN <command>
# Example: RUN apt-get update && apt-get install -y nginx
# Example: RUN pip install -r requirements.txt
Chaining multiple commands with && in a single RUN instruction reduces the number of image layers and makes efficient use of the build cache.
CMD
Specifies the default command to execute when the container starts. Only one can be specified per Dockerfile. If multiple are present, the last one takes effect.
CMD ["executable", "arg1", "arg2"] # exec form (recommended)
# Example: CMD ["nginx", "-g", "daemon off;"]
# Example: CMD ["python", "app.py"]
CMD command param1 param2 # shell form
# Example: CMD python app.py
In shell form, the command is executed with /bin/sh -c.
ENTRYPOINT
Specifies the command to execute when the container starts. Unlike CMD, ENTRYPOINT is always executed, and CMD is treated as arguments to ENTRYPOINT.
ENTRYPOINT ["executable", "arg1"] # exec form (recommended)
# Example: ENTRYPOINT ["/usr/sbin/nginx"]
ENTRYPOINT command param1 param2 # shell form
# Example: ENTRYPOINT nginx -g "daemon off;"
Combining ENTRYPOINT and CMD allows defining flexible container startup commands. For example, with ENTRYPOINT ["nginx"] and CMD ["-g", "daemon off;"], the container runs nginx -g "daemon off;" at startup. Specifying arguments with docker run overrides the CMD content.
References
- Masaya Aoyama, “Kubernetes Complete Guide 2nd Edition, impress top gear series”, Impress (2021)
- Dockerfile reference | Docker Docs