Operations 15 min read

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

This article presents practical Dockerfile optimization techniques—including clean build contexts, lightweight base images, regional package mirrors, timezone configuration, virtual build environments, and layer minimization—to dramatically reduce image size and improve build efficiency.

Efficient Ops
Efficient Ops
Efficient Ops
Essential Docker Image Building Tips to Shrink Size and Speed Up Builds

Build Context

When running

docker build

, the current working directory is sent as the build context; therefore the directory must be clean. Use a dedicated project folder and place only the resources needed for the image.

You can also use a .dockerignore file to exclude unnecessary files from the context.

Base Images

Choose small base images such as

alpine

or

debian:buster-slim

. For OpenJDK, use

openjdk:xxx-slim

which is based on

debian:xxx-slim

. Note that Alpine uses

musl libc

instead of

glibc

, which may cause compatibility issues for large projects that depend on

glibc

(e.g., OpenJDK, Tomcat, RabbitMQ).

Regional Package Mirrors

Replace default package sources with domestic mirrors to speed up installation. Examples:

<code>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</code>
<code>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</code>
<code>sed -i 's/archive.ubuntu.com/mirrors.huaweicloud.com/g' /etc/apt/sources.list \
 apt update</code>

Timezone Settings

Most base images default to UTC, which differs from Beijing time by eight hours. Set the container timezone via the environment variable

-e TZ=Asia/Shanghai

or install

tzdata

and copy the zoneinfo file.

<code># Alpine example
apk add --no-cache tzdata \
 cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
 echo "Asia/Shanghai" > /etc/timezone \
 apk del tzdata</code>
<code># Debian/Ubuntu example
docker run --rm -it -e TZ=Asia/Shanghai debian date</code>

Adding Source Code Efficiently

Prefer

git

or

wget

to fetch source code during the build and delete it afterwards, rather than using

ADD

or

COPY

which permanently adds the files to a layer.

<code>git clone https://example.com/project.git --depth 1 \
 make && make install \
 rm -rf project</code>

FastDFS Dockerfile Optimization Example

Original Dockerfile (CentOS) results in an image of ~500 MB. After merging all

RUN

commands, using a virtual build environment, and switching to

alpine

, the image size drops to ~30 MB.

<code># 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 \
    && 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"]</code>
<code># Image size comparison
fastdfs   alpine   29.3MB
fastdfs   debian   103MB
fastdfs   centos   483MB</code>

Virtual Build Environment

Install temporary build dependencies with

apk add --no-cache --virtual .build-deps …

and remove them after the build using

apk del .build-deps

. Keep runtime dependencies separate.

Minimizing Layers

Only

RUN

,

COPY

, and

ADD

create image layers. Combine multiple commands in a single

RUN

using

&amp;&amp;

or

;

. Reduce the number of

ADD

instructions by packaging files into a tarball and extracting them in one layer.

<code># Example of reducing many ADDs to one
COPY src.tar.gz /usr/local/src.tar.gz
RUN tar -xvf /usr/local/src.tar.gz -C /usr/local && \
    mv /usr/local/src/conf/* /etc/fdfs && \
    rm -rf /usr/local/src/* /var/cache/apk/*</code>
DockerImage OptimizationtimezoneAlpineDockerfilebuild contextVirtual Build Environment
Efficient Ops
Written by

Efficient Ops

This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.

0 followers
Reader feedback

How this landed with the community

login 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.