一些背景:
-我是
Docker
新手(从 1 天开始),VM
正在运行 linux/AMD
,并且我拥有一台 M1 Mac (ARM
),为了在 M1 Mac 上构建
prod
的容器,我有以下 Dockerfile
:--platform=linux/amd64
中的 FROM
arg,它可以工作(= 我能够部署)。
FROM --platform=linux/amd64 python:3.10-slim-bullseye
WORKDIR /usr/src/app
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
ENV FLASK_ENV=development
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["flask", "run"]
但是,我怎么能在我的
Dockerfile
中说不使用 --platform=linux/amd64
if 我想为本地开发构建?dockerfile
中看到了一些关于 SO 的帖子,但仅限于 RUN
命令。有什么想法或最佳实践吗?
docker buildx build
或docker build 上的
--platform
参数来设置平台来构建将在 FROM
内的任何
Dockerfile
调用中使用的映像(如果没有其他的话)已指定(请参阅Dockerfile FROM),如文档中所述。 然后,您可以在
Dockerfile
中使用 TARGETPLATFORM
变量来获取它正在构建的平台(如果需要)。如果您想更改构建的默认平台,可以设置DOCKER_DEFAULT_PLATFORM 环境变量。
docker buildx build --platform=linux/arm64 -t myTag .
,或
Dockerfile.intel
和
Dockerfile
),其中定义了各自的平台。这样,任何构建管道都会选择
Dockerfile
作为默认值,但对于本地构建,您可以指定要使用哪一个,如下所示:
docker build -f Dockerfile.intel .
devcontainer.json
中指定图像,然后通过在 VSCode 的命令面板中键入
Reopen in Container
来启动和附加。
tonistiigi/xx
buildx
--platform
语句或任何特定于架构的内容,您可能可以这样做:
docker buildx build -f Dockerfile --platform linux/amd64 --tag my-container:latest --load .
这将使用 QEMU - 但它慢
并且有时会中断(编译器开关等)。这是因为构建本身是在模拟器中运行的(在本例中是模拟 amd64
)
FROM golang:1.20
ADD app /app
ENV CGO_ENABLED=0
RUN cd /app && go build -o app .
WORKDIR /app
ENTRYPOINT [ "/app/app" ]
做成这样:
FROM --platform=$BUILDPLATFORM golang:1.20 AS build
# get gcc cross toolchain
RUN DEBIAN_FRONTEND=noninteractive apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install g++-x86-64-linux-gnu libc6-dev-amd64-cross
RUN DEBIAN_FRONTEND=noninteractive apt-get -y clean
ADD app /app
ARG TARGETOS TARGETARCH
ENV CGO_ENABLED=1
WORKDIR /app
# RUN gcc -dumpmachine with --progress=plain here to see what gcc is used by default
RUN CC=x86_64-linux-gnu-gcc GOOS=$TARGETOS GOARCH=$TARGETARCH go build -o app .
ENTRYPOINT [ "/app/app" ]
注意,我们必须为我们需要的架构安装特定的交叉工具链。这并不理想 - 因为它使我们的 Dockerfile 架构变得特定:/
方法三:使用
tonistiigi/xx工具tonistiigi/xx
包作为基础层。它提供的工具使交叉构建变得更容易并且仍然在本机运行。
FROM --platform=$BUILDPLATFORM tonistiigi/xx AS xx
FROM --platform=$BUILDPLATFORM golang:1.20
RUN DEBIAN_FRONTEND=noninteractive apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install build-essential
RUN DEBIAN_FRONTEND=noninteractive apt-get -y clean
COPY --from=xx / /
ADD app /app
ARG TARGETPLATFORM
RUN xx-apt install -y libc6-dev gcc
ENV CGO_ENABLED=1
WORKDIR /app
RUN xx-go --wrap
RUN go build -o app . && xx-verify app
ENTRYPOINT [ "/app/app" ]
xx-
工具提供了了解 Docker 多平台变量的包装器,然后使用正确的跨工具链构建正确的
TARGETARCH
架构包。这是最好的方法 - 无论您在哪里运行 docker build buildx
命令,它都会产生快速的本机交叉构建。它也应该适用于 Docker Desktop 或安装在 Linux 上的 docker -
aarch64
或 amd64
类似。相同的构建命令:
docker buildx build -f Dockerfile --platform linux/amd64 --tag my-container:latest --load .
用于所有三种方法。
对于 OP - 这意味着他们可以在 Docker 桌面(MacOS 端)上运行命令或使用安装在 Linux 虚拟机中的 docker。
查看我的博客文章:
https://www.izumanetworks.com/blog/build-docker-on-apple-m/