Cloud Native 16 min read

Essential Docker Image Building Hacks to Shrink Size and Speed Up Builds

Learn practical Dockerfile optimization techniques—including clean build contexts, choosing minimal base images, configuring Chinese mirrors, setting time zones, consolidating RUN commands, using virtual build environments, and minimizing layers—to dramatically reduce image size and improve build efficiency.

Open Source Linux
Open Source Linux
Open Source Linux
Essential Docker Image Building Hacks to Shrink Size and Speed Up Builds

Building Image Tips

Build Context

When you run docker build, the current working directory is the build context. By default the Dockerfile is in this directory, but you can specify a different Dockerfile with the -f flag. Docker will still send all files in the current directory to the daemon, so the context must be clean.

The proper approach is to create a dedicated folder for the project and place only the resources needed for the image build inside it, e.g.:

mkdir project
cd project
vi Dockerfile   # write Dockerfile
You can also use a .dockerignore file to exclude unnecessary files from the build context.

Base Image

Choose a small base image such as alpine or debian:buster-slim. For Java, openjdk:xxx-slim is based on the corresponding Debian slim image. Note that Alpine uses musl libc instead of glibc, which can cause compatibility issues for large projects that depend on glibc (e.g., OpenJDK, Tomcat, RabbitMQ).

REPOSITORY   TAG          IMAGE ID       CREATED        SIZE
debian       buster-slim  e1af56d072b8   4 days ago    69.2MB
alpine       latest       cc0abc535e36   8 days ago    5.59MB

Domestic Software Mirrors

Replace the default package sources with domestic mirrors (Huawei Cloud, Alibaba Cloud, Tencent Cloud, 163, etc.) to speed up dependency installation.

Alpine mirror configuration:

echo "http://mirrors.huaweicloud.com/alpine/latest-stable/main/" > /etc/apk/repositories \
 echo "http://mirrors.huaweicloud.com/alpine/latest-stable/community/" >> /etc/apk/repositories \
 apk update

Debian mirror configuration:

sed -i 's/deb.debian.org/mirrors.huaweicloud.com/g' /etc/apt/sources.list \
 sed -i 's|security.debian.org/debian-security|mirrors.huaweicloud.com/debian-security|g' /etc/apt/sources.list \
 apt update

Ubuntu mirror configuration:

sed -i 's/archive.ubuntu.com/mirrors.huaweicloud.com/g' /etc/apt/sources.list
apt update

Timezone Settings

Most base images use UTC, which differs from China Standard Time by eight hours. Set the container timezone to avoid log and monitoring discrepancies.

Use the environment variable -e TZ=Asia/Shanghai when running the container, or install tzdata and copy the zoneinfo file for images that do not respect the variable (e.g., Alpine).

Alpine

apk add --no-cache tzdata \
 cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
 echo "Asia/Shanghai" > /etc/timezone \
 apk del tzdata

Debian

docker run --rm -it -e TZ=Asia/Shanghai debian date

Ubuntu

docker run --rm -it -e TZ=Asia/Shanghai ubuntu date

Prefer Adding Source via URL

When the build requires compiling source code, fetch the source with git or wget instead of ADD or COPY. After the build, delete the source to keep the image small.

git & wget source
build
rm -rf source/

FastDFS Dockerfile Example

Original Dockerfile (CentOS 7)

# centos 7
FROM centos:7
# add configuration files
ADD conf/client.conf /etc/fdfs/
ADD conf/http.conf /etc/fdfs/
# add source code
ADD source/libfastcommon.tar.gz /usr/local/src/
... (other ADD commands) ...
RUN yum install git gcc gcc-c++ make ... -y \
    && mkdir /home/dfs \
    && cd /usr/local/src/ \
    && cd libfastcommon/ \
    && ./make.sh && ./make.sh install \
    ...
VOLUME /etc/fdfs
EXPOSE 22122 23000 8888 80
ENTRYPOINT ["/home/fastdfs.sh"]

Optimized Dockerfile (Alpine)

FROM alpine:3.10
RUN set -x \
    && echo "http://mirrors.huaweicloud.com/alpine/latest-stable/main/" > /etc/apk/repositories \
    && echo "http://mirrors.huaweicloud.com/alpine/latest-stable/community/" >> /etc/apk/repositories \
    && apk update \
    && apk add --no-cache --virtual .build-deps gcc libc-dev make perl-dev openssl-dev pcre-dev zlib-dev git \
    && mkdir -p /usr/local/src \
    && cd /usr/local/src \
    && git clone https://github.com/happyfish100/libfastcommon.git --depth 1 \
    && git clone https://github.com/happyfish100/fastdfs.git --depth 1 \
    && git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1 \
    && wget http://nginx.org/download/nginx-1.15.4.tar.gz \
    && tar -xf nginx-1.15.4.tar.gz \
    && cd libfastcommon && ./make.sh && ./make.sh install \
    && cd ../fastdfs && ./make.sh && ./make.sh install \
    && cd ../nginx-1.15.4 && ./configure --add-module=/usr/local/src/fastdfs-nginx-module/src/ && make && make install \
    && apk del .build-deps \
    && apk add --no-cache pcre-dev bash \
    && mv /usr/local/src/fastdfs/docker/dockerfile_network/fastdfs.sh /home/fastdfs.sh \
    && mv /usr/local/src/fastdfs/docker/dockerfile_network/conf/* /etc/fdfs \
    && chmod +x /home/fastdfs.sh \
    && rm -rf /usr/local/src*
VOLUME /home/dfs
EXPOSE 22122 23000 8888 8080
CMD ["/home/fastdfs.sh"]

Build Size Comparison

Using the original Dockerfile produces an image of about 500 MB, while the optimized version reduces the size to roughly 30 MB.

REPOSITORY   TAG      IMAGE ID       CREATED          SIZE
fastdfs     alpine   e855bd197dbe   10 seconds ago   29.3MB
fastdfs     debian   e05ca1616604   20 minutes ago   103MB
fastdfs     centos   c1488537c23c   30 minutes ago   483MB

Minimize Layer Count

Since Docker 1.10, only RUN, COPY, and ADD create layers. Combine multiple commands in a single RUN using && or ; to keep the layer count low.

When many files need to be added, package them into a single archive (e.g., src.tar.gz) and extract it in one RUN step, reducing dozens of ADD layers to one.

FROM alpine:3.10
COPY src.tar.gz /usr/local/src.tar.gz
RUN set -xe \
    && apk add --no-cache --virtual .build-deps gcc libc-dev make perl-dev openssl-dev pcre-dev zlib-dev tzdata \
    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && tar -xvf /usr/local/src.tar.gz -C /usr/local \
    && mv /usr/local/src/conf/fastdfs.sh /home/fastdfs/ \
    && mv /usr/local/src/conf/* /etc/fdfs \
    && chmod +x /home/fastdfs/fastdfs.sh \
    && rm -rf /usr/local/src/* /var/cache/apk/* /tmp/* /var/tmp/* $HOME/.cache
VOLUME /var/fdfs

These practices collectively help keep Docker images small, fast to build, and easier to maintain.

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.

Dockerimage-optimizationContainerTimezoneAlpineDockerfile
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.