在Docker构建环境/Dockerfile中如何获取Docker目标平台

89次阅读
没有评论

问题描述

正在使用buildx进行多平台构建,并想知道是否有一种方法可以确定当前正在构建的平台,以便根据不同的环境避免执行某些步骤。
例如,类似于…

# No DOSEMU outside amd64
RUN if [ "$DOCKER_PLATFORM" = "amd64" ]; then \
      apt install dosemu \
    fi

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

通常情况下,这是通过脚本而不是Dockerfile来完成的。脚本(可能是bash或python)可以在构建时运行,以确定它所在的环境,并相应地采取行动。这可以包含在RUN命令中,但这样做可能会变得非常复杂,难以在Dockerfile中阅读。此外,Dockerfile中每个额外的RUNCMD条目都会向镜像添加一个层,这被认为是不良实践。
相反,这个脚本可以使用BUILDPLATFORMTARGETPLATFORM作为RUN命令的参数,如buildx文档中所建议的那样。这样,你可以声明目标,而不是发现目标(并相应地编写脚本),这样用户就可以在不必查看构建内部的情况下准确了解发生了什么。
以下是一个示例脚本:

#!/bin/bash
# 根据目标平台执行不同的操作
if [ "$TARGETPLATFORM" = "linux/amd64" ]; then
  apt install -yqq dosemu
fi

在这个示例中,我们使用TARGETPLATFORM环境变量来确定目标平台,并根据不同的平台执行不同的操作。你可以根据自己的需求编写脚本,并在Dockerfile中使用RUN命令来运行它。

方案2

另一种方法是使用多阶段的Dockerfile结构。如果除了一些不同的步骤之外没有复杂的逻辑(在目标之间),这种方法可以将所有内容都保留在Dockerfile中(一个文件)。
以下是一个示例Dockerfile:

FROM alpine:3.16 as main-linux-armv7
# 在linux/arm/v7上执行与众不同的操作

FROM alpine:3.16 as main-linux-amd64
# 在linux-amd64上执行相应的操作

FROM main-linux-amd64 as main-linux-arm64
# linux-arm64与linux-amd64相同,但需要定义每个目标

FROM main-${TARGETOS}-${TARGETARCH}${TARGETVARIANT}
# 主/最终阶段

在这个示例中,我们使用多阶段的Dockerfile结构来根据不同的目标执行不同的操作。你可以根据自己的需求编写Dockerfile,并在其中定义不同的阶段和操作。
请注意,这种方法可能会导致Docker镜像变得更大,因为每个阶段都会添加一个层。因此,你应该根据自己的需求和限制选择适合的方法。
以上是两种解决方案,你可以根据自己的需求选择其中之一。希望对你有所帮助!

正文完