Cloud Native 30 min read

Master Dockerfile: Build Custom Docker Images Step‑by‑Step

This comprehensive guide explains how to create and customize Docker images using Dockerfile, covering base image selection, RUN, COPY, ADD, CMD, ENTRYPOINT, ENV, VOLUME, EXPOSE, and WORKDIR instructions, along with best practices for layer optimization and context handling.

Open Source Linux
Open Source Linux
Open Source Linux
Master Dockerfile: Build Custom Docker Images Step‑by‑Step

Introduction

Hello everyone, this article provides a detailed explanation of Docker custom images, showing how to build your own Docker image and use Dockerfile instructions.

1. Using Dockerfile to Customize Images

1.1 Dockerfile Customization

Customizing an image means defining the configuration and files added in each layer. By writing all commands into a script—called a Dockerfile —you achieve repeatable builds, transparency, and smaller image size.

A Dockerfile is a text file containing a series of instructions, each creating a new layer.

Example using an nginx image:

mkdir mynginx
cd mynginx
touch Dockerfile

The file content:

FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

This simple Dockerfile has two instructions: FROM and RUN.

1.2 FROM – Specify Base Image

Custom images start from a base image. The FROM instruction must be the first line in a Dockerfile and defines the base layer.

Docker Hub offers many official images such as nginx, redis, mongo, mysql, httpd, as well as OS images like ubuntu, debian, centos, fedora, alpine. You can also use the special virtual image scratch, which represents an empty image.

If you use scratch as the base, the first layer starts from an empty image.

1.3 RUN – Execute Commands

The RUN instruction executes shell commands during image build. It has two formats:

shell format: RUN <command> exec format:

RUN ["executable", "arg1", "arg2"]

Example:

RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

Each RUN creates a new layer. Using many separate RUN commands can lead to a large number of layers, increased build time, and larger images. It is better to combine related commands into a single RUN using && and line continuations.

FROM debian:jessie
RUN buildDeps='gcc libc6-dev make' \
    && apt-get update \
    && apt-get install -y $buildDeps \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-3.2.5.tar.gz" \
    && mkdir -p /usr/src/redis \
    && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
    && make -C /usr/src/redis \
    && make -C /usr/src/redis install \
    && rm -rf /var/lib/apt/lists/* \
    && rm redis.tar.gz \
    && rm -r /usr/src/redis \
    && apt-get purge -y --auto-remove $buildDeps

This single RUN builds Redis, cleans up build dependencies, and keeps the image lean.

1.4 Building the Image

After preparing the Dockerfile, build the image with: docker build -t nginx:v3 . The output shows each step, the creation of intermediate containers, and the final image ID.

1.5 Build Context

The final . in the build command specifies the build context—the directory whose contents are sent to the Docker daemon. Only files inside this context can be referenced by COPY or ADD. Using a .dockerignore file can exclude unnecessary files.

2. Dockerfile Instructions

2.1 COPY

Format:

COPY <src>... <dest>
COPY ["<src1>", ... "<dest>"]
COPY

copies files from the build context into the image, preserving metadata. COPY package.json /usr/src/app/ Wildcards are supported using Go's filepath.Match rules.

2.2 ADD

ADD

works like COPY but can also download files from URLs and automatically extract tar archives (gzip, bzip2, xz). Because of its extra behavior, Docker best practices recommend using COPY unless automatic extraction is needed.

2.3 CMD

CMD

defines the default command executed when a container starts. It supports shell and exec forms. The exec form is preferred because it avoids an extra shell layer.

CMD ["nginx", "-g", "daemon off;"]

2.4 ENTRYPOINT

ENTRYPOINT

also defines the container’s startup command but works together with CMD: the CMD arguments are passed as parameters to the ENTRYPOINT. This allows the image to behave like a command where additional arguments can be appended at docker run time. ENTRYPOINT ["curl", "-s", "http://ip.cn"] Running docker run myimage -i adds -i as an argument to curl.

2.5 ENV

ENV

sets environment variables that are available to subsequent instructions and at container runtime. ENV VERSION=1.0 DEBUG=on NAME="Happy Feet" Variables can be referenced in later instructions, e.g., $VERSION.

2.6 VOLUME

VOLUME

declares mount points for external storage. Declaring a volume ensures that data written to that path is stored outside the image’s layered filesystem.

VOLUME /data

2.7 EXPOSE

EXPOSE

documents which ports the container listens on. It does not publish the ports automatically but helps users and enables docker run -P to map them randomly.

EXPOSE 80 443

2.8 WORKDIR

WORKDIR

sets the working directory for subsequent instructions. If the directory does not exist, it is created. WORKDIR /app Using WORKDIR is necessary because each RUN instruction runs in a new container; a previous RUN cd /app does not affect later steps.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Cloud NativeDockerDevOpsContainerDockerfileImage
Open Source Linux
Written by

Open Source Linux

Focused on sharing Linux/Unix content, covering fundamentals, system development, network programming, automation/operations, cloud computing, and related professional knowledge.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.