Master Dockerfile: Essential Commands and Best Practices for Building Efficient Images
This article explains how Docker images are created, introduces Dockerfile syntax and key instructions such as FROM, COPY, RUN, CMD, and ENTRYPOINT, and provides practical guidelines and real‑world examples for building clean, lightweight containers.
Image Generation Methods
About Dockerfile
Dockerfile is the source code for building Docker images; it is a plain‑text file.
When building an image from a Dockerfile, the file must reside in a specific directory. The filename must start with a capital "D". To exclude files from the build context, a
.dockerignorefile can be defined. Finally,
docker buildcreates the image.
Dockerfile Instructions
FROM
FROM is the first non‑comment line in a Dockerfile and specifies the base image for the build.
The base image can be any available image; if it does not exist locally, Docker pulls it from Docker Hub.
If the image cannot be found,
docker buildreturns an error.
Syntax:
FROM [image[:tag]]or
FROM image@digestMAINTAINER (deprecated)
Provides author information; placement is not restricted but is usually placed after FROM.
Syntax:
MAINTAINER "Name <[email protected]>"LABEL
Syntax:
<code>LABEL key=value key=value ...</code>COPY
Copies files from the build context into the image.
Syntax:
COPY src destor
COPY ["src", "dest"]If the destination path contains spaces, the JSON form should be used.
Files must be inside the build context; directories are copied recursively but the directory itself is not created unless it already exists.
ADD
Similar to COPY but also supports extracting TAR archives and downloading from URLs.
Syntax:
ADD src destor
ADD ["src", "dest"]WORKDIR
Sets the working directory for subsequent RUN, CMD, ENTRYPOINT, COPY and ADD instructions.
Syntax:
WORKDIR /pathVOLUME
Creates a mount point inside the image.
Syntax:
VOLUME /pathor
VOLUME ["/path"]EXPOSE
Documents which ports the container listens on.
Syntax:
EXPOSE 80/tcp 443/tcpENV
Defines environment variables for later instructions.
Syntax:
ENV VAR=valueor
ENV VAR1=value1 VAR2=value2RUN
Executes commands during image build.
Two forms: shell form
RUN commandand exec form
RUN ["executable","param1","param2"]CMD
Specifies the default command to run when a container starts.
Only the last CMD in the Dockerfile takes effect.
Syntax similar to RUN.
ENTRYPOINT
Defines a container's main executable; arguments from
docker runare appended.
Unlike CMD, ENTRYPOINT cannot be overridden unless
--entrypointis used.
Only the last ENTRYPOINT is effective.
USER
Specifies the user (or UID) under which subsequent instructions run.
Default user is root.
HEALTHCHECK
Defines a command to test container health.
Options include
--interval,
--timeout,
--retries, and
--start-period.
Only the last HEALTHCHECK is used.
ONBUILD
Registers a trigger instruction that runs when the image is used as a base for another build.
Cannot be nested and does not trigger FROM or MAINTAINER.
Basic Dockerfile Guidelines
Containers should be short‑lived (ephemeral).
Use
.dockerignoreto exclude unnecessary files (syntax same as
.gitignore).
Prefer multi‑stage builds to reduce final image size.
Avoid installing unnecessary packages.
Each container should do one thing; separate services into separate containers.
Only RUN, COPY, and ADD create image layers; minimize layer count.
Order instructions to maximize cache reuse; use
--no-cacheto force rebuild.
Dockerfile Examples
Build an sshd image
<code># Dockerfile
FROM centos:centos7
LABEL maintainer="hukey<[email protected]>"
RUN yum install -y openssh* net-tools iproute NetworkManager && \
echo "UseDNS no" >> /etc/ssh/sshd_config && \
sed -i '/pam_loginuid.so/d' /etc/pam.d/sshd && \
echo '123123' | passwd --stdin root && \
ssh-keygen -A && yum clean all
EXPOSE 22
CMD ["/usr/sbin/sshd","-D"]
</code>Build a systemd image (based on the sshd image)
<code># Dockerfile
FROM sshd:v0.1-2
LABEL maintainer="hukey<[email protected]>"
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done) && \
rm -f /lib/systemd/system/multi-user.target.wants/* && \
rm -f /etc/systemd/system/*.wants/* && \
rm -f /lib/systemd/system/local-fs.target.wants/* && \
rm -f /lib/systemd/system/sockets.target.wants/*udev* && \
rm -f /lib/systemd/system/sockets.target.wants/*initctl* && \
rm -f /lib/systemd/system/basic.target.wants/* && \
rm -f /lib/systemd/system/anaconda.target.wants/*
VOLUME ["/sys/fs/cgroup"]
CMD ["/usr/sbin/init"]
</code>Build an nginx image
<code># Dockerfile
FROM centos:centos7
LABEL maintainer="hukey<[email protected]>"
ENV NGX_PACKAGE="nginx-1.18.0"
ADD http://192.168.118.45/${NGX_PACKAGE}.tar.gz /usr/local/src/
WORKDIR /usr/local/src/${NGX_PACKAGE}
RUN tar xf /usr/local/src/${NGX_PACKAGE}.tar.gz && \
yum install -y proc-devel gcc gcc-c++ zlib zlib-devel make openssl-devel wget && \
./configure --prefix=/usr/local/nginx \
--with-http_ssl_module \
--with-http_gzip_static_module \
--with-http_stub_status_module \
--with-http_realip_module && \
make -j2 && make install && \
echo "daemon off;" >> /usr/local/nginx/conf/nginx.conf && yum clean all && rm -rf /var/cache/yum/*
EXPOSE 80/tcp 443/tcp
ADD run.sh /run.sh
CMD ["/run.sh"]
</code>Build a tomcat image
<code># Dockerfile
FROM centos:centos7
LABEL maintainer="hukey <[email protected]>"
ADD jdk-8u77-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.61.tar.gz /usr/local/
ENV JAVA_HOME="/usr/local/java" \
JAVA_BIN="/usr/local/java/bin" \
JRE_HOME="/usr/local/java/jre" \
PATH="$PATH:/usr/local/java/bin:/usr/local/java/jre/bin" \
CLASSPATH="/usr/local/java/jre/bin:/usr/local/java/lib:/usr/local/java/jre/lib/charsets.jar"
WORKDIR /usr/local/
RUN mv jdk1.8.0_77 java && mv apache-tomcat-8.5.61 tomcat8
EXPOSE 8080
ENTRYPOINT ["/usr/local/tomcat8/bin/catalina.sh","run"]
</code>These examples illustrate how to define base images, set environment variables, copy files, expose ports, and combine
CMDand
ENTRYPOINTfor flexible container startup.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.