编写 dockerfile 的零散技巧

本文由作者手工编写,无 AI 参与。

【1】用小镜像

大部分情况下,基于 debian-slim 的镜像是比较推荐的,如果测试充分并且对镜像大小要求很严格,可以用 apline。

如果是 AI 强相关,老老实实用 GPU 厂商推荐的镜像。例如,英伟达推荐 ubuntu。

【2】secret 采用 build-kit 挂载到构建过程

docker build --secret id=foo,src=/path/to/file ......

切勿使用 COPY 之类的方法放到镜像,因为镜像分层的缘故,需要保密的文件会留在镜像的层中。

【3】难、苦的步骤下沉

假设构建过程中,某个步骤很困难或比较痛苦,则尽量把此步骤前移且放入基础镜像。

FROM debian:13.2

# do_sth_difficult 所依赖的
RUN ...

RUN do_sth_difficult

# 假设构建出的镜像为 foo:1.0

之后构建其他:

FROM foo:1.0

【4】架设内网文件服务器

对于团队管理者,如果发现某个公网文件被团队的构建高频率需要,或者某个公网大文件经常出现在团队的 dockerfile 中,则把它们放到内网服务器。

倒不是为了给公网网站或网络出口减负,从内网下载可以让构建更轻松、更可靠。

【5】用 ADD 下载文件并验证

ADD --checksum=sha256:abc123... https://aaa.com/qwer.tar.gz /qwer.tar.gz

【6】在同一层中删掉下载使用之后不再需要的文件,wget,rm

RUN wget -O /bin/cfssl "xxxxx" && \
    chmod 0755 /bin/cfssl && \
    cfssl ... && \
    rm -f /bin/cfssl

这个例子中,使用 cfssl 做了某个事(如生成证书)之后就不再需要它,就可以在同一层中删掉它,节省不必要的空间。

【7】直接使用软件的具体版本,而不是用动态版本工具

nvm,bazelisk,gradle-wrapper 等软件可以通过项目配置动态下载软件的对应版本,这在本地开发很方便。但在容器环境中,由于每次启动是一个干净的环境,所以每次构建都要重新下载,反而麻烦,还增加了因为网络问题导致构建失败的可能性。

对于一个具体项目,项目需要的构建工具版本必然是已知的,所以直接在基础镜像中放置相应的版本即可。

FROM cr.abc.com/devbase/java17-maven363:1.0

RUN mvn package ...

【8】巧用多阶段构建

对于多二进制项目,可以把基础镜像分叉。

FROM golang:1.25.8 AS builder

RUN apt install ...

FROM builder-base AS svc1
# build service 1

FROM builder-base AS svc2
# build service 2

很多项目,构建所需的依赖明显多于运行,多阶段构建可以节省很多空间。

FROM cr.abc.com/devbase/jdk17-maven363:1.0 AS builder

RUN mvn package ...



FROM cr.abc.com/devbase/jre17:1.0

COPY --from=builder /target/foo.jar /app/foo.jar

CMD ["java", "-jar", "/app/foo.jar"]
posted @ 2026-04-09 10:54  风华神使  阅读(4)  评论(0)    收藏  举报