Zata 扎根技术 · 记录思考 · 见更大的世界

Better CodeA Brighter Tomorrow

保持好奇持续成长

Featured image of post build x86 image in ARM MAC platform and devolopmet to remote server

build x86 image in ARM MAC platform and devolopmet to remote server

在 ARM Mac 上构建 x86 镜像并部署至远程服务器的终极指南

这份指南涵盖了从在 Apple Silicon (M1/M2/M3) Mac 上交叉编译构建 x86 (amd64) Docker 镜像,到将其以不同方式保存和部署的完整流程。


1. 在 ARM Mac 上构建 x86 镜像

由于本地 Mac 是 arm64 架构,而目标服务器通常是 x86_64 (即 amd64),我们需要进行交叉编译构建。Docker Desktop for Mac 内置的 QEMU 模拟器和 buildx 工具使这一切变得简单。

准备工作

  • 一台 Apple Silicon 芯片的 Mac。
  • 安装最新版的 Docker Desktop for Mac。

构建步骤

  1. 创建 Dockerfile 在一个空的项目目录中,创建一个 Dockerfile 文件。明确指定基础镜像的平台是一个好习惯。

    # Dockerfile
    # 使用 --platform 标志确保拉取的是 amd64 版本的镜像
    FROM --platform=linux/amd64 ubuntu:22.04
    
    LABEL maintainer="Your Name"
    LABEL target_architecture="x86_64/amd64"
    
    # RUN 指令会在 QEMU 模拟的 x86 环境中执行
    RUN apt-get update && apt-get install -y curl
    
    # 验证架构
    RUN echo "本镜像架构为:" && uname -m
    
    CMD ["bash"]
    
  2. 执行构建命令 使用 docker build 命令并附带 --platform 标志来指定目标架构。

    # 在包含 Dockerfile 的目录下执行
    # 将 my-x86-app:1.0 替换为你想要的镜像名和标签
    docker build --platform linux/amd64 -t my-x86-app:1.0 .
    
    • 如果构建的时候网络失败,可以先使用 docker pull –platform linux/amd64 <镜像名>:<标签> 提前拉取镜像
    • --platform linux/amd64: 核心参数,告诉 Docker 你要构建的是 x86 镜像。
    • 构建过程会比原生编译慢,因为指令需要通过 QEMU 模拟执行。
  3. 验证本地镜像架构 构建完成后,镜像会保存在你的本地。使用 docker inspect 来确认其架构。

    docker inspect my-x86-app:1.0 | grep Architecture
    

    预期输出应为:

            "Architecture": "amd64",
    

2. 保存与分发构建好的镜像

现在你本地有了一个 x86 架构的镜像 my-x86-app:1.0,接下来可以根据需求将其分发出去。

方案 A: 推送到镜像仓库(团队协作/CI/CD 推荐)

这是最规范、最通用的方法,适用于所有需要网络访问的场景。

  1. 标记镜像 (Tag) 为镜像打上符合仓库规范的标签。以 Docker Hub 为例,格式为 <用户名>/<仓库名>:<标签>。

    docker tag my-x86-app:1.0 your-dockerhub-username/my-x86-app:1.0
    
  2. 登录仓库

    docker login
    
  3. 推送镜像 (Push)

    docker push your-dockerhub-username/my-x86-app:1.0
    

    推送后,任何有权限的人或服务器都可以通过 docker pull 命令拉取此镜像。

方案 B: 直接传输到另一台服务器(最高效的 P2P 方式)

如果你想将在本地构建好的镜像,快速地发送到一台已经配置好 SSH 访问的服务器上,这是最佳选择。此方法不依赖镜像仓库,也不在本地产生中间文件。

  1. 使用 docker save 和 ssh 管道流式传输 这条命令将本地镜像打包后,通过 SSH 管道直接在远程服务器上加载。

    # 将 your-user@your-server 替换为你的 SSH 登录信息
    docker save my-x86-app:1.0 | ssh your-user@your-server 'docker load'
    

    工作原理:

    • docker save my-x86-app:1.0: 将镜像打包成 tar 流输出到标准输出。
    • |: 管道,将左侧命令的输出作为右侧命令的输入。
    • ssh ... 'docker load': 连接到远程服务器,并在服务器上执行 docker load 命令,该命令从标准输入读取 tar 流并加载镜像。
  2. 验证 SSH 登录到你的服务器 ssh your-user@your-server,然后运行 docker images,即可看到 my-x86-app:1.0。

方案 C: 导出为文件后手动传输(离线场景)

适用于完全离线的环境,或者需要将镜像文件存档的场景。

  1. 保存为 .tar 文件

    docker save -o my-x86-app-1.0.tar my-x86-app:1.0
    
  2. 拷贝文件 使用 scp 或其他工具将 my-x86-app-1.0.tar 文件传输到服务器。

    scp my-x86-app-1.0.tar your-user@your-server:/path/to/destination/
    
  3. 在服务器上加载 SSH 登录服务器后,从文件加载镜像。

    ssh your-user@your-server
    # 在服务器上执行
    docker load -i /path/to/destination/my-x86-app-1.0.tar
    

附录: 关于 docker context 的说明

docker context 是一个强大的工具,但它的用途与上述方案 B 和 C 不同。

  • docker context 的作用: 它是用来切换 Docker CLI 的控制目标。当你 docker context use your-server 时,你的本地终端就变成了远程服务器 Docker 的遥控器。
  • 使用场景: 如果你希望构建过程本身就发生在远程服务器上(利用服务器的 CPU 和原生 x86 架构),那么就应该先切换 context,再运行 docker build。
    # 1. 切换控制目标到服务器
    docker context use your-server
    
    # 2. 本地的源码会自动上传到服务器,并在服务器上完成构建
    docker build -t my-app-built-on-server:1.0 .
    
    # 3. 操作完成后切回本地
    docker context use default
    

这与“在本地构建,然后把产物(镜像)发送过去”是两种不同的工作流。


希望这份整合后的指南能清晰地解答你的所有疑问!

使用 Hugo 构建
主题 Stack 由 Jimmy 设计