Creating Custom Docker Images with Dockerfile

Building Custom Docker Images

This guide demonstrates how to create a Dockerfile to customize a Docker image. The process focuses on the build workflow rather than detailed instruction explanations.

Example: Creating a Custom Nginx Image

To create a custom Nginx image with a customized index.html file, follow these steps:

  1. Create an empty directory
  2. Create a file named Dockerfile with the following content:
FROM nginx
RUN echo 'Custom Nginx image built locally' > /usr/share/nginx/html/index.html

Understanding FROM and RUN Instructions

FROM: Specifies the base image for the custom image. All subsequent operations are performed on this base image. In our example, nginx serves as the foundation.

RUN: Executes commands in the shell during the image build process. Two formats are available:

  • Shell format: RUN <command>
  • Exec format: RUN ["executable", "param1", "param2"]

Note: Each Dockerfile instruction creates a new image layer. Excessive layers can lead to bloated images. To minimize layers, combine commands using the && operator:

# Inefficient - creates multiple layers
FROM centos
RUN yum -y install wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN tar -xvf redis.tar.gz

# Efficient - creates single layer
FROM centos
RUN yum -y install wget \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && tar -xvf redis.tar.gz

Building the Image

To build the image from the Dockerfile, navigate to the directory containing the Dockerfile and execute:

$ docker build -t custom-nginx:v1 .

The dot at the end specifies the build context path, which we'll explore next.

Understanding Build Context

The build context path (the final dot in the docker build command) indicates which files Docker should include in the build process. Since Docker operates in a client-server model, the build happens on the Docker daemon, not locally. The context allows you to provide local files to the daemon.

If no context path is specified, Docker defaults to the directory containing the Dockerfile.

Important: Only include necessary files in the build context to avoid slow build times.

Dockerfile Instructions Reference

Instruction Description
FROM Specifies the base image for subsequent instructions
MAINTAINER Specifies the author/maintainer of the Dockerfile (deprecated, use LABEL instead)
LABEL Adds metadata to the image using key-value pairs
RUN Executes commands in the image during build time
CMD Specifies the default command for container startup (can be overridden)
ENTRYPOINT Sets the main command for container startup (not easily overridden)
EXPOSE Declports the container will listen on at runtime
ENV Sets environment variables inside the container
ADD Copies files, directories, or remote URLs to the image
COPY Copies files or directories to the image
VOLUME Creates mount points or declares volumes
WORKDIR Sets the working directory for subsequent instructions
USER Specifies the user context for subsequent instructions
ARG Defines variables passed to the builder during build time
ONBUILD Adds trigger instructions when the image is used as a base for another build
STOPSIGNAL Sets the system call signal to send to the container to exit
HEALTHCHECK Defines commands to check container health periodically
SHELL Overrides the default shell for RUN, CMD, and ENTRYPOINT

Instruction Details

COPY Instruction

The COPY instruction copies files or directories from the build context to the specified path in the container:

COPY [--chown=<user>:<group>] <source>... <destination>
COPY [--chown=<user>:<group>] ["<source>",... "<destination>"]

The --chown parameter changes ownership of copied files. Source paths can use wildcards following Go's filepath.Match rules.

ADD Instruction

ADD is similar to COPY but with additional features:

  • Automatically extracts compressed files (gzip, bzip2, xz)
  • Can fetch files from URLs

However, ADD may invalidate build caches when copying tar files without extraction, potentially slowing builds.

CMD Instruction

CMD specifies the default command to run when a container starts. It can be overridden via command-line arguments. Only the last CMD instruction in a Dockerfile takes effect.

CMD <shell command>
CMD ["<executable>", "<param1>", "<param2>",...]
CMD ["<param1>", "<param2>",...]  # Used as default parameters for ENTRYPOINT

ENTRYPOINT Instruction

ENTRYPOINT sets the main command that runs when the container starts. Unlike CMD, its executable is not easily overridden (requires --entrypoint flag). Only the last ENTRYPOINT instruction takes effect.

ENTRYPOINT can be combined with CMD to provide default parameters:

FROM nginx
ENTRYPOINT ["nginx", "-c"]  # Fixed parameters
CMD ["/etc/nginx/nginx.conf"]  # Variable parameters

ENV Instruction

ENV sets environment variables that can be referenced in subsequent instructions:

ENV <key> <value>
ENV <key1>=<value1> <key2>=<value2>...

ARG Instruction

ARG defines build-time variables that only exist during the build process. They can be overridden using the --build-arg flag:

ARG <name>[=<default value>]

VOLUME Instruction

VOLUME creates anonymous data volumes to persist data outside the container filesystem:

VOLUME ["<path1>", "<path2>"...]
VOLUME <path>

EXPOSE Instruction

EXPOSE declares ports that the container listens on, helping users understand which ports to map:

EXPOSE <port> [<port>...]

WORKDIR Instruction

WORKDIR sets the working directory for subsequent instructions. If the directory doesn't exist, it will be created:

WORKDIR <path>

USER Instruction

USER specifies the user and group to run subsequent commands. The user must already exist in the image:

USER <username>[:<group>]

HEALTHCHECK Instruction

HEALTHCHECK defines commands to monitor container health:

HEALTHCHECK [OPTIONS] CMD <command>
HEALTHCHECK NONE

ONBUILD Instruction

ONBUILD defines trigger instructions that execute when the image is used as a base for another build:

ONBUILD <instruction>

LABEL Instruction

LABEL adds metadata to the image in key-value format:

LABEL <key>=<value> <key>=<value>...

Tags: docker dockerfile containerization devops Image Building

Posted on Sat, 31 Oct 2026 16:50:01 +0000 by vamosbenedikt