「CONTAINER-IMAGE-BUILDING」- 镜像构建 | 通过 docker build 构建

HTTP Proxy

Running BuildKit using docker buildx behind a proxy – Stack Overflow

docker buildx create --use --driver-opt env.http_proxy=172.17.0.1:3128 --driver-opt env.https_proxy=172.17.0.1:3128 --driver-opt '"env.no_proxy='$no_proxy'"'
docker buildx build ...

通过 Dockerfile 构建镜像 | 推荐

因为通过 Dockerfile 构建镜像具有可重复性、透明性、幂等性,因此推荐使用 Dockerfile 来构建镜像。

新镜像是基于已有进行构建的;

Dockerfile 使用 DSL(Domain Specific Lanaguage)

第一步、编写 Dockerfile 文件

Docker Build (Buildx and BuildKit):Dockerfile

第二步、执行构建命令

docker build –file path/to/Dockerfile –tag name:tag /path/to/build/context/

需要创建一个目录,这个目录称为构建环境,在 Docker 中称之为上下文,构建时该目录的内容会上传到 Docker 守护进程,这样 Docker 守护进程就能直接访问用户想在镜像中存储的任何代码、文件、数据;

在上下文目录中执行 docker build 命令后,docker 或读取 Dockerfile 文件,然后执行其中的指令。可以使用-t选项指定仓库、名称、TAG 信息;

命令类似于:docker build -t “jam/static_web:v1” .

最后的点(.)指出当前目录为上下文目录。如果未指定标签(这里是 v1),则默认的为 latest 标签;

也可以使用 Git 仓库的源地址来指定 Dockerfile 的位置:docker build -t “jam/static_web:v1” git@github.com:jam/static_web

可使用-f 选项指定 Dockerfile 位置,用于处理 Dockerfile 文件名非 Dockerfile 的情况。但是 -f 选项指定的文件必须位于 Build Context中:

docker build -t “jam/static_web:v1” -f /path/to/dockerfile-v1 .

构建的每一步都会提交,在构建结束后,最终会返回一个镜像 ID;

docker build –label “k1=v1” –label “k2-v2” … | 为构建的镜像添加标签。

第三步、查看新镜像的信息(可选)

再次使用 docker image 命令来查看镜像;

如果想深入查看镜像是如何构建的,可以使用 docker history 命令查看镜像的构建历史;

场景 | 提高构建速度 | 构建缓存 | Build Cache

Docker 的构建过程非常聪明,它会将”每一步的构建过程都会将结果提交为镜像“,它会将之前的镜像层作为缓存;

假如某个步骤构建失败,在调整 Dockerfile 重新构建之后,Docker 会直接从该失败的步骤开始。如果之前的步骤发生了变化(例如文件变化),则会从发生变化的位置开始。

通过 docker build –no-cache 选项,能够跳过构建缓存,以应对某些特殊场景;

基于构建缓存的 Dockerfile 模板

「构建缓存」的一个好处是可以实现一个简单的「Dockerfile 模板」:

FROM ubuntu:14.04
MAINTAINER James Thrnbull "jam@exampl.com"
ENV REFRESHED_AT 2014-07-01
RUN apt-get -qq update

对于上面的 Dockerfile,如果我们要更新 apt 缓存,可以修改 REFRESHED_AT 变量,然后 Docker 就会从修改行开始执行,从而更新了 APT 缓存。实质上是,通过使用一个可修改的指令,来控制是否重新执行该指令后面的某些指令;

示例 | 缓存 pip install -r requirement.txt 构建

在最开始时,每次修改当前目录,都会导致 pip install 重新执行:

FROM ubuntu:14.04

ENV WORKDIR="/srv/web"

COPY . ${WORKDIR}
RUN pip install -r requirement.txt

# 因为当前目录发生变化,导致 COPY 缓存失效

我们调整步骤,提前复制 requirements.txt 文件,以利用缓存:

FROM ubuntu:14.04

ENV WORKDIR="/srv/web"

COPY requirements.txt ${WORKDIR}/requirements.txt
RUN apt-get -qq update

COPY . ${WORKDIR}

场景 | 在镜像中添加 OpenJDK 程序

通过多阶段构建技术,复制 OpenJDK 镜像中的程序。

FROM openjdk:24-slim-bullseye AS OpenJDK

FROM nodered/node-red:4.0.5-debian

ENV PATH=/usr/local/openjdk/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
ENV JAVA_HOME=/usr/local/openjdk

COPY --from=OpenJDK /usr/local/openjdk-24/ /usr/local/openjdk/


注意,基础镜像与 OpenJDK 所在进行要保持相近,否则某些依赖库的确实将导致 OpenJDK 无法正常运行。