Understanding Dockerfiles: Build Efficient Container Images

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 for ARG variables 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.

Tags: docker dockerfile containerization devops Image Building

Posted on Mon, 11 May 2026 09:14:12 +0000 by Neomech