如何通过Maven获取容器基础镜像的Digest值
解决fabric8 docker-maven-plugin获取基础镜像Digest配置OCI标签的问题
问题背景
我使用fabric8io docker-maven-plugin构建容器镜像,需要配置OCI(Open Container Initiative)规范定义的镜像标签,其中org.opencontainers.image.base.digest标签尤为关键——因为我构建的镜像将作为后续应用的基础镜像,需要为整个容器基础设施递归构建镜像谱系,但不清楚如何在Maven中查询基础镜像的Digest值来配置该标签。
当前的插件配置和Dockerfile如下:
原pom.xml插件配置
<plugin> <groupId>io.fabric8</groupId> <artifactId>docker-maven-plugin</artifactId> <configuration> <images> <image> <name>my/app</name> <build> <dockerFile>${project.basedir}/Dockerfile</dockerFile> <contextDir>${project.basedir}</contextDir> <args> <APP_NAME>app</APP_NAME> <BASE_IMAGE_DIGEST>HOW TO DETERMINE?</BASE_IMAGE_DIGEST> <BASE_IMAGE_NAME>docker.io/library/rockylinux:8.6</BASE_IMAGE_NAME> <BUILD_DATE>${docker.app.image.created}</BUILD_DATE> <GIT_TAG>${docker.app.image.version}</GIT_TAG> <PROJECT_DOC>${docker.app.image.scm.url}#README</PROJECT_DOC> <PROJECT_SCM>${docker.app.image.scm.url}.git</PROJECT_SCM> <PROJECT_URL>${docker.app.image.scm.url}</PROJECT_URL> </args> </build> </image> </images> </configuration> <executions> <execution> <id>build</id> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> <execution> <id>push</id> <phase>deploy</phase> <goals> <goal>push</goal> </goals> </execution> </executions> </plugin>
原Dockerfile内容
ARG BASE_IMAGE_NAME FROM ${BASE_IMAGE_NAME} ARG APP_NAME ARG BASE_IMAGE_DIGEST ARG BASE_IMAGE_NAME ARG BUILD_DATE ARG GIT_TAG ARG PROJECT_DOC ARG PROJECT_SCM ARG PROJECT_URL # Open specifications from the Open Container Initative (OCI) LABEL org.opencontainers.image.base.name=${BASE_IMAGE_NAME} \ org.opencontainers.image.base.ref=${BASE_IMAGE_DIGEST} \ org.opencontainers.image.created=${BUILD_DATE} \ org.opencontainers.image.description="My App" \ org.opencontainers.image.documentation=${PROJECT_DOC} \ org.opencontainers.image.source=${PROJECT_SCM} \ org.opencontainers.image.title="My App Base image" \ org.opencontainers.image.url=${PROJECT_URL} \ org.opencontainers.image.version=${GIT_TAG}
解决方案
可以通过fabric8 docker-maven-plugin的resolve目标提前拉取并解析基础镜像,自动获取其Digest值,再传递给构建参数。
步骤1:修改pom.xml配置
- 定义基础镜像的全局属性,便于统一维护:
<properties> <base.image>docker.io/library/rockylinux:8.6</base.image> </properties>
- 在docker-maven-plugin的executions中添加
resolve执行步骤,用于提前获取基础镜像的Digest:
<execution> <id>resolve-base-image</id> <phase>validate</phase> <goals> <goal>resolve</goal> </goals> <configuration> <images> <image> <name>${base.image}</name> <alias>base-image</alias> </image> </images> </configuration> </execution>
- 修改构建参数,引用插件生成的Digest属性:
将原<BASE_IMAGE_DIGEST>HOW TO DETERMINE?</BASE_IMAGE_DIGEST>替换为:
<BASE_IMAGE_DIGEST>${docker.image.base-image.digest}</BASE_IMAGE_DIGEST>
同时将<BASE_IMAGE_NAME>改为引用全局属性:
<BASE_IMAGE_NAME>${base.image}</BASE_IMAGE_NAME>
修改后的完整插件配置如下:
<plugin> <groupId>io.fabric8</groupId> <artifactId>docker-maven-plugin</artifactId> <configuration> <images> <image> <name>my/app</name> <build> <dockerFile>${project.basedir}/Dockerfile</dockerFile> <contextDir>${project.basedir}</contextDir> <args> <APP_NAME>app</APP_NAME> <BASE_IMAGE_DIGEST>${docker.image.base-image.digest}</BASE_IMAGE_DIGEST> <BASE_IMAGE_NAME>${base.image}</BASE_IMAGE_NAME> <BUILD_DATE>${docker.app.image.created}</BUILD_DATE> <GIT_TAG>${docker.app.image.version}</GIT_TAG> <PROJECT_DOC>${docker.app.image.scm.url}#README</PROJECT_DOC> <PROJECT_SCM>${docker.app.image.scm.url}.git</PROJECT_SCM> <PROJECT_URL>${docker.app.image.scm.url}</PROJECT_URL> </args> </build> </image> </images> </configuration> <executions> <execution> <id>resolve-base-image</id> <phase>validate</phase> <goals> <goal>resolve</goal> </goals> <configuration> <images> <image> <name>${base.image}</name> <alias>base-image</alias> </image> </images> </configuration> </execution> <execution> <id>build</id> <phase>package</phase> <goals> <goal>build</goal> </goals> </execution> <execution> <id>push</id> <phase>deploy</phase> <goals> <goal>push</goal> </goals> </execution> </executions> </plugin>
步骤2:修正Dockerfile的OCI标签
根据OCI规范,正确的基础镜像Digest标签键是org.opencontainers.image.base.digest,而非org.opencontainers.image.base.ref,修改LABEL部分:
LABEL org.opencontainers.image.base.name=${BASE_IMAGE_NAME} \ org.opencontainers.image.base.digest=${BASE_IMAGE_DIGEST} \ org.opencontainers.image.created=${BUILD_DATE} \ org.opencontainers.image.description="My App" \ org.opencontainers.image.documentation=${PROJECT_DOC} \ org.opencontainers.image.source=${PROJECT_SCM} \ org.opencontainers.image.title="My App Base image" \ org.opencontainers.image.url=${PROJECT_URL} \ org.opencontainers.image.version=${GIT_TAG}
工作原理
resolve目标会在Maven的validate阶段执行,提前拉取指定的基础镜像,并将镜像的元数据(包括Digest)存储到Maven属性中,通过<alias>定义的名称可以方便引用对应的属性(格式为${docker.image.<alias>.digest})。- 构建镜像时,插件会将该属性传递给Dockerfile的ARG参数,最终写入OCI标签。
内容的提问来源于stack exchange,提问作者Volker Raschek
相关产品推荐
相关产品推荐

