M2 Pro 上 SAM CLI 构建时提示 No such image,如何解决?
结论
SAM 在创建构建容器时,连接的 Docker 服务找不到 public.ecr.aws/sam/build-python3.12:latest-x86_64 镜像。仅凭这一行日志,还无法判断原因是镜像拉取失败、Docker 连接环境不一致,还是其他兼容性问题。
先确认 SAM 和 Docker 命令连接的是同一个服务,再手动拉取报错中的完整镜像,检查容器能否运行。使用 M2 Pro 并不意味着应该直接将镜像改成 ARM64。
为什么 M2 Pro 会使用 x86_64 镜像?
SAM 根据函数的目标架构选择构建镜像。函数未配置 Architectures 时,默认使用 x86_64,不会自动跟随 Mac 的处理器架构。AWS 构建文档
报错中的镜像名表明,SAM 选择的是 Python 3.12、x86_64 构建环境。环境信息中的 python: 3.13.12 是运行 SAM CLI 的本地 Python 版本,不能据此判断函数应该使用 Python 3.13 镜像。
要判断这是否是 SAM CLI 1.154.0 或 Docker 29.2.0 的特定缺陷,还需要查看镜像拉取结果和调试日志。
1. 确认 Docker 服务和连接地址
在执行 sam build 的同一个终端中运行:
docker version
docker info
docker context ls
docker context inspect "$(docker context show)"
printenv DOCKER_HOST DOCKER_CONTEXT DOCKER_DEFAULT_PLATFORM
检查以下几项:
docker version是否同时显示 Client 和 Server 信息。- 当前 context 的 Docker endpoint 是否符合预期。
- 环境变量是否仍指向另一个 Docker 服务。
如果同时安装了 Docker Desktop、Colima 等工具,尤其要核对连接地址。不同 Docker 服务各自管理镜像,在一个服务中拉取的镜像不会自动出现在另一个服务中。Docker CLI 的 context 也会受到 DOCKER_CONTEXT 等环境变量影响。Docker context 文档、Docker CLI 环境变量说明
如果使用 Colima
先检查状态:
colima status
Colima 官方 FAQ 说明,部分应用不会使用 Docker CLI 的 context,需要显式设置 DOCKER_HOST。如果使用默认 profile,且 colima status 显示的 socket 与以下地址一致,可以执行:
unset DOCKER_CONTEXT
export DOCKER_HOST="unix://$HOME/.colima/default/docker.sock"
docker info
如果使用自定义 profile 或配置目录,请填写实际的 socket 路径。后续的 docker pull 和 sam build 都在这个终端中执行。Colima Docker socket 说明
2. 手动拉取报错中的完整镜像
如果函数目标仍然是 x86_64,执行:
docker pull --platform linux/amd64 \
public.ecr.aws/sam/build-python3.12:latest-x86_64
Docker 的 linux/amd64 对应 Lambda 的 x86_64,--platform 用于指定要拉取的镜像平台。Docker pull 文档
拉取成功后检查:
docker image inspect \
public.ecr.aws/sam/build-python3.12:latest-x86_64 \
--format '{{.Os}}/{{.Architecture}}'
输出应为 linux/amd64。:latest 和 :latest-x86_64 是不同标签,只拉取前者,不能证明报错中的镜像已经存在。
如果拉取失败,根据命令返回的错误继续排查:
| 拉取错误 | 排查方向 |
|---|---|
| 超时、DNS 解析失败、TLS 错误 | Docker 服务所在环境的网络、DNS、代理或证书配置 |
manifest unknown | 仓库路径或标签是否存在 |
no matching manifest | 请求的平台是否与镜像支持的平台一致 |
| 鉴权错误 | Docker 凭据配置和完整错误信息 |
代理需要在 Docker 服务一侧正确配置。即使终端能够访问外网,Docker 服务也可能无法正常拉取镜像。Docker 代理说明
3. 验证 x86_64 容器能否在 M2 上运行
镜像拉取成功后,单独测试容器能否启动:
docker run --rm --platform linux/amd64 \
--entrypoint /bin/sh \
public.ecr.aws/sam/build-python3.12:latest-x86_64 \
-c 'uname -m'
正常情况下应输出 x86_64。
如果出现 exec format error 或模拟执行相关错误,需要检查容器后端是否支持跨架构运行。--platform linux/amd64 只指定平台,不能代替模拟执行环境。Docker Desktop 提供跨架构模拟支持,其他后端则需要检查各自的配置。Docker 多平台说明
使用 Colima 时,如果版本和环境符合要求,可以通过 VZ 和 Rosetta 运行 x86_64 容器。官方提供的启动命令是:
colima start --vm-type=vz --vz-rosetta
该配置要求使用 Apple Silicon、macOS 13 或更高版本,以及支持这些选项的 Colima。如果已有实例,先确认当前 VM 配置;停止实例会中断其中运行的容器。Colima 配置说明
4. 确定函数是否应该使用 ARM64
如果部署目标必须保持 x86_64,就继续使用对应镜像,并解决本地跨架构运行问题。
如果函数允许部署到 ARM64,可以在原模板中修改对应函数的属性:
Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Runtime: python3.12
Architectures:
- arm64
# 保留原有的 CodeUri、Handler 等配置
Architectures 是列表,合法值包括 x86_64 和 arm64。AWS SAM 函数属性说明
这项修改也会改变 Lambda 的部署架构。修改前,需要确认依赖包、包含原生代码的 Python 扩展、Lambda Layer 和扩展程序都支持 ARM64,并重新构建。Lambda 架构迁移要求
如果只通过 --build-image 换成 ARM64 镜像,却保留函数的 x86_64 配置,构建环境就会与部署目标不一致。
5. 重新构建,并查看最早出现的错误
确认镜像存在、容器能够启动后,重新执行:
sam build --use-container --debug
必要时,可以指定某个函数的构建镜像。将下面的 MyFunction 替换为模板中的函数逻辑 ID:
sam build MyFunction \
--use-container \
--build-image MyFunction=public.ecr.aws/sam/build-python3.12:latest-x86_64 \
--debug
--build-image 只控制构建镜像,不会修改函数的目标架构。SAM build 参数说明
如果仍然失败,查看 --debug 输出中最终 No such image 之前的第一条错误,尤其留意镜像拉取和 Docker API 请求失败的信息。如果手动启动容器成功,SAM 却仍提示镜像不存在,再次核对 SAM 使用的 Docker endpoint 和完整镜像标签,并检查构建是否从 IDE 或另一个终端启动。
同时检查命令和 samconfig.toml 中是否配置了 skip_pull_image。--skip-pull-image 用于跳过镜像更新,无法解决首次获取镜像失败的问题。SAM build 参数说明
如果连接地址一致,镜像可以拉取,容器也能运行,但问题仍能稳定复现,再对比 SAM CLI 或容器后端的版本,并结合完整调试日志排查兼容性问题。
备注:内容仅供参考。
