优化 Docker 构建过程:使用多阶段构建和缓存提升效率
优化 Docker 构建过程:使用多阶段构建和缓存提升效率
本 Dockerfile 展示了如何利用多阶段构建、缓存策略和交叉编译来优化 Docker 镜像的构建过程。
主要特点:
- 多阶段构建: 将构建过程分解为多个阶段,例如使用
gowinres阶段准备构建环境,使用builder阶段进行编译,最后使用精简的基础镜像构建最终镜像,有效减少镜像体积。 - 缓存优化: 通过
--mount=type=cache将 apt 包缓存和 Go 模块缓存挂载到容器中,加速依赖项的安装和编译过程。 - 交叉编译: 利用
xx-交叉编译工具链,可以为不同的目标平台构建 Docker 镜像,例如在 x86 平台上构建 ARM 平台的镜像。
代码解析:
FROM base AS build
COPY --from=gowinres /build/ /usr/local/bin/
WORKDIR /go/src/github.com/docker/docker
ENV GO111MODULE=off
ENV CGO_ENABLED=1
ARG DEBIAN_FRONTEND
# 使用缓存加速 apt 包安装
RUN --mount=type=cache,sharing=locked,id=moby-build-aptlib,target=/var/lib/apt \
--mount=type=cache,sharing=locked,id=moby-build-aptcache,target=/var/cache/apt \
apt-get update && apt-get install --no-install-recommends -y \
clang \
lld \
llvm
ARG TARGETPLATFORM
# 使用缓存加速 apt 包安装
RUN --mount=type=cache,sharing=locked,id=moby-build-aptlib,target=/var/lib/apt \
--mount=type=cache,sharing=locked,id=moby-build-aptcache,target=/var/cache/apt \
xx-apt-get install --no-install-recommends -y \
dpkg-dev \
gcc \
libapparmor-dev \
libc6-dev \
libdevmapper-dev \
libseccomp-dev \
libsecret-1-dev \
libsystemd-dev \
libudev-dev
ARG DOCKER_BUILDTAGS
ARG DOCKER_DEBUG
ARG DOCKER_GITCOMMIT=HEAD
ARG DOCKER_LDFLAGS
ARG DOCKER_STATIC
ARG VERSION
ARG PLATFORM
ARG PRODUCT
ARG DEFAULT_PRODUCT_LICENSE
ARG PACKAGER_NAME
# PREFIX overrides DEST dir in make.sh script otherwise it fails because of
# read only mount in current work dir
ENV PREFIX=/tmp
# 配置交叉编译工具链
RUN <<'EOT'
# in bullseye arm64 target does not link with lld so configure it to use ld instead
if [ "$(xx-info arch)" = "arm64" ]; then
XX_CC_PREFER_LINKER=ld xx-clang --setup-target-triple
fi
EOT
# 使用缓存加速 Go 模块编译
RUN --mount=type=bind,target=. \
--mount=type=tmpfs,target=cli/winresources/dockerd \
--mount=type=tmpfs,target=cli/winresources/docker-proxy \
--mount=type=cache,target=/root/.cache/go-build,id=moby-build-$TARGETPLATFORM <<'EOT'
set -e
target=$([ "$DOCKER_STATIC" = "1" ] && echo "binary" || echo "dynbinary")
xx-go --wrap
PKG_CONFIG=$(xx-go env PKG_CONFIG) ./hack/make.sh $target
xx-verify $([ "$DOCKER_STATIC" = "1" ] && echo "--static") /tmp/bundles/${target}-daemon/dockerd$([ "$(xx-info os)" = "windows" ] && echo ".exe")
xx-verify $([ "$DOCKER_STATIC" = "1" ] && echo "--static") /tmp/bundles/${target}-daemon/docker-proxy$([ "$(xx-info os)" = "windows" ] && echo ".exe")
mkdir /build
mv /tmp/bundles/${target}-daemon/* /build/
EOT
# 在这里添加代理配置,例如:
# ENV http_proxy=http://your.proxy.server:port
# ENV https_proxy=http://your.proxy.server:port
# ... 其他构建步骤 ...
如何在 apt-get update 时使用代理?
您可以通过设置 http_proxy 和 https_proxy 环境变量来为 apt-get update 命令配置代理。
例如,将以下行添加到您的 Dockerfile 中,以便在运行 apt-get update 时使用代理服务器 your.proxy.server:port:
ENV http_proxy=http://your.proxy.server:port
ENV https_proxy=http://your.proxy.server:port
# ... 您的其他 Dockerfile 指令 ...
注意: 将 your.proxy.server:port 替换为您实际的代理服务器地址和端口。
通过使用多阶段构建、缓存和交叉编译,您可以显著减少 Docker 镜像的构建时间和体积,并提高部署效率。
原文地址: https://www.cveoy.top/t/topic/jmsY 著作权归作者所有。请勿转载和采集!