Docker exec格式错误求助:arm64环境容器启动失败排查
exec format error 已阅读过相关问题帖,遇到的错误完全一致但场景不同。
执行docker image inspect my-image得到镜像信息:
"Architecture": "arm64", "Os": "linux", "Size": 1131886345, "VirtualSize": 1131886345,...
操作流程
- 在AWS arm64/v8实例构建镜像,上传至Gitlab容器仓库
- 在另一台AWS arm64/v8实例下载镜像部署
已添加的--platform配置
Dockerfile中
FROM --platform=linux/arm64/v8 node:14.17.4 as builder
FROM --platform=linux/arm64/v8 keymetrics/pm2:14-jessie
GitLab CI 构建阶段命令
- docker buildx build --platform linux/arm64/v8 -t $CONTAINER_TEST_IMAGE .
GitLab CI 部署阶段命令
- docker run --platform linux/arm64/v8 -e ENV=prod -d -p 3000:3000 $CONTAINER_RELEASE_IMAGE
实际执行的启动命令:
docker run --platform linux/arm64/v8 -e ENV=prod -d -p 3000:3000 $CONTAINER_RELEASE_IMAGE
错误现象
- 执行
docker ps -a可见容器已退出 - 查看日志
docker logs containerid得到错误:exec /usr/local/bin/docker-entrypoint.sh: exec format error
补充说明
Dockerfile中使用的启动命令:
CMD [ "sh", "-c", "pm2 start /path/to/ecosystem.config.js --env ${ENV}" ]
ecosystem.config.js内容:
'use strict'; module.exports = { apps: [ { name: 'service', script: 'dist/main.js', env: { "NODE_ENV": "dev", }, env_prod: { "NODE_ENV": "prod" }, env_docker: { "NODE_ENV": "docker" }, env_qa: { "NODE_ENV": "qa", } } ] };
检查基础镜像
keymetrics/pm2:14-jessie的架构兼容性
虽然指定了--platform=linux/arm64/v8,但部分旧版第三方镜像可能没有正确适配arm64,或者实际拉取的是amd64版本。直接拉取镜像验证架构:docker pull keymetrics/pm2:14-jessie docker image inspect keymetrics/pm2:14-jessie | grep Architecture如果结果不是
arm64,建议更换为官方node:14.17.4基础镜像自行安装pm2,避免依赖第三方镜像的兼容性问题。排查
docker-entrypoint.sh的来源与内容
错误指向的脚本来自keymetrics/pm2:14-jessie镜像,若脚本调用了amd64编译的二进制文件(比如旧版pm2),就会触发格式错误。查看脚本内容:docker run --rm --platform linux/arm64/v8 keymetrics/pm2:14-jessie cat /usr/local/bin/docker-entrypoint.sh检查脚本中是否存在非arm64架构的可执行文件调用。
绕过entrypoint直接启动容器
暂时覆盖镜像的entrypoint,用自定义命令启动,验证是否是entrypoint的问题:docker run --platform linux/arm64/v8 --entrypoint "" -e ENV=prod -d -p 3000:3000 $CONTAINER_RELEASE_IMAGE sh -c "pm2 start /path/to/ecosystem.config.js --env ${ENV}"若容器能正常启动,说明问题出在基础镜像的entrypoint脚本上。
检查构建过程中的native依赖
确认builder阶段的node:14.17.4是arm64版本,同时检查项目依赖的native模块是否为arm64架构编译:docker run --rm --platform linux/arm64/v8 node:14.17.4 node -p process.arch输出应为
arm64,若项目有native依赖,需确保构建时在arm64环境下编译。移除冗余的
--platform参数
构建和部署都在arm64实例上,docker run时无需额外指定--platform,该参数可能干扰镜像的正常运行,去掉后再尝试启动容器。
内容的提问来源于stack exchange,提问作者Lauro182

