A Dockerfile is a text document containing a sequence of instructions that Docker uses to assemble a container image. Each line represents a layer, and04 the final image is the result of executing all specified commends in order.
Consider this basic Dockerfile for a Node.js application:
FROM node:18-alpine
LABEL project="my-web-app"
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
ENV NODE_ENV=production
EXPOSE 3000
CMD ["node", "server.js"]
Core Instructions
Setting the Foundation
FROM defines the base image upon which the new image is built. It must appear first in the file, and a valid Dockerfile cannot exist with out it.
FROM ubuntu:22.04
# Multi-stage builds utilize 'AS'
FROM golang:1.21 AS builder
LABEL attaches metadata such as author, version, or description. The old MAINTAINER instruction is deprecated; use LABEL maintainer instead.
LABEL maintainer="team@example.com"
LABEL version="2.1.0" description="Web backend service"
Working with Files
COPY transfers files and directoreis from the build context into the container filesystem. Only source paths within the context are allowed.
COPY --chown=node:node ./app /home/node/app
COPY --from=builder /build/output /app/bin
ADD extends COPY by automatically extracting local tar archives and fetching remote URLs. While convenient, prefer COPY for transparency unless archiving is needed.
ADD https://example.com/data.tar.gz /tmp/
ADD project-files.tar.bz2 /opt/project
Shaping the Environment
WORKDIR sets the working directory for RUN, CMD, ENTRYPOINT, COPY, and ADD that follow. If the directory does not exist, it is created.alter
WORKDIR /app
WORKDIR src # results in /app/src
ENV declares environment variables that persist both at build time and in the resulting container.
ENV DB_HOST=db.example.com \
DB_PORT=5432
ARG variables exist only during the build process. They can be overridden with --build-arg when running docker build.
ARG APP_VERSION=1.0.0
Executing Commands
The RUN instruction executes commands in a new layer and commits the result. Use shell form for convenience or exec form when avoiding shell processing.
RUN apt-get update && apt-get install -y curl
RUN ["/bin/bash", "-c", "echo custom step"]
Container Runtime Settings
CMD provides defaults for a running container. It can be overridden by arguments supplied with docker run. Only the last CMD in a Dockerfile takes effect.
CMD ["nginx", "-g", "daemon off;"]
ENTRYPOINT defines the executable that the container will run. Unlike CMD,16 it cannot be replaced by command-line arguments unless --entrypoint is explicitly given.
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["--help"]
USER switches to a specific user (and optionally group) for all subsequent RUN, CMD, and ENTRYPOINT commands.
USER 1001:1001
Networking and Data
EXPOSE documents which ports the container intends to listen on. It does not publish ports; use -p with docker run for that.
EXPOSE 8080
EXPOSE 443/tcp
VOLUME declares a mount point to persist data or share between containers. This protects15 essential data when the container is removed.
VOLUME ["/var/lib/mysql"]
Advanced Directives
SHELL overrides the default shell used in the shell form of commands. Useful on Windows or when requiring a specific interpreter.
SHELL ["/bin/bash", "-c"]
HEALTHCHECK tells Docker how to verify whether a container is still functioning correctly.
HEALTHCHECK --interval=10s --timeout=5s --retries=3 \
CMD curl -f http://localhost/healthz || exit 1
ONBUILD registers trigger instructions that will be executed when the image is used as a base for another build.
ONBUILD COPY config.yml /etc/app/
STOPSIGNAL sets the system call signal sent tostop the container, defaults to SIGTERM.
STOPSIGNAL SIGTERM
Building an Image with docker build
The docker build command processes a Dockerfile within a build context to generate a layered image.
docker build [OPTIONS] PATH | URL | -
Common flags include:
-t, --tag: assigns a name and an optional tag to the resulting image (e.g.,my-app:1.0).-f, --file: specifies an alternative Dockerfile name.--no-cache: forces a fresh build without using cached intermediate layers.--build-arg: supplies values forARGvariables defined in the Dockerfile.
vBuild an image from the current directory:
docker build -t web-server:2.0 .
Use a differently named Dockerfile and provide a build argument:
docker build --file Dockerfile.prod --build-arg ENV=production -t web-server:prod .
The build context (the path passed as the last argument) is sent to the Docker daemon, so keep it slim to avoid slowing down the transfer.11 Multi-stage builds help produce minimal final images by separating build tools from runtime.