我正在尝试构建一个ARM(arm32v7)容器,但使用的是x86_64主机。虽然我知道有一些非常酷的东西,比如Resin使用Qemu shenanigans,Multiarch进行通用容器的交叉构建,但我有一个小问题:我尝试构建的容器开始作为multiarch,所以Docker总是在FROM
指令中选择x86图像。
我想在x86主机上从Multi-arch Rust image构建一个ARM容器。问题是,我找不到任何明确说明我想从ARM容器开始并从中构建的文档,而不是x86容器。此外,图片上的标签不会消除歧义,因此我无法使用它们来选择起始容器。
我已尝试编辑/etc/docker/daemon.json
文件以包含:
{
"labels": [ "os=linux", "arch=arm32v7" ],
"experimental": true
}
但这根本没有帮助。 docker pull
仍然会检索x86图像。所有这一切的目的是为了最终在Raspberry Pi上运行的容器的编译时间增加;编译时间非常缓慢。
有没有办法明确说我想从ARM图像开始构建?
答案 0 :(得分:1)
通过为该体系结构使用适当的基本映像,可以为另一个体系结构(“交叉编译”)构建简单的Docker容器。简单来说,我的意思是在他们的Dockerfile中不需要RUN
命令来构建图像。这是因为Docker无法在另一个体系结构的容器中实际运行命令。虽然这听起来有限制,但与multi-stage builds结合使用时,它可以非常强大,以交叉编译代码。
让我们一步一步地完成这个步骤。首先,让我们为Docker客户端启用实验模式,通过向docker manifest
添加以下选项来启用~/.docker/config.json
:
{
"experimental": "enabled"
}
然后,我们可以使用docker manifest inspect debian:stretch
来显示包含我们要为其构建的体系结构中的图像摘要的fat manifest。例如,arm32v7图像在"architecture": "arm"
键下指定了"variant": "v7"
和platform
。使用jq,我们可以以编程方式提取此图像的摘要:
docker manifest inspect debian:stretch | jq -r '.manifests[] | select(.platform.architecture == "arm" and .platform.variant == "v7") | .digest'`
然后可以在Dockerfile中的FROM
命令中使用此摘要:
FROM debian@sha256:d01d682bdbacb520a434490018bfd86d76521c740af8d8dbd02397c3415759b1
然后可以COPY
交叉编译二进制到图像中。这个二进制文件可以来自您机器上的交叉编译器,也可以来自多阶段构建中的另一个容器。要删除Dockerfile的FROM
行中的硬编码摘要,可以通过Docker build argument (ARG
)将其外部化。