DEBUG.WIKI
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
雨云;给项目一台云服务器
RackNerd;$21.99/年 · 1GB KVM

docker export/import 后启动报 No command specified

docker export/import 后启动报 No command specified,通常需要核对镜像启动元数据。区分镜像归档与根文件系统归档,恢复 CMD、ENTRYPOINT 及部署配置。

容器在原主机能运行,经过 docker export、docker import 搬到另一台主机后,启动时报 No command specified。如果启动时没有另行提供命令,先查看导入镜像的 Cmd 和 Entrypoint:导入成功只说明文件系统已经变成镜像,不代表原来的启动配置也恢复了。

这条路径适用于 Linux 容器根文件系统的 export/import 迁移。其他构建错误或 Compose 配置也可能产生相同报错,只有确认使用了这种迁移方式且缺少有效启动命令,才按下面处理。

核对导入前后的镜像配置

用实际镜像引用替换下面的名称:

docker image inspect --format '{{json .Config.Cmd}}' recovered-app:imported
docker image inspect --format '{{json .Config.Entrypoint}}' recovered-app:imported

原镜像还在时,对原镜像执行同样检查,记录两者差异。null 或空数组意味着对应字段没有提供启动内容;仅 Cmd 为空并不一定有问题,还要看 Entrypoint 是否已经给出了可执行命令。

export 输出容器的根文件系统,import 从这个文件系统创建镜像。原镜像的启动命令不是一个自动放在根目录里的文件,因此不能靠这两个命令传回来。即使文件系统中还保留着 Dockerfile,导入时也不会重新构建它。

尤其要检查是否先执行 load 恢复了正确镜像,随后又用 import 写入同一个标签。后一步会让这个标签指向新导入的文件系统镜像,前一步恢复的启动配置便不再是这个标签当前使用的配置。保留原始镜像与归档,不要通过删除它们来反复试错。

搬运已有镜像时,使用 save 与 load

如果目标是原样搬运一个已经构建好的镜像,使用与镜像归档配对的命令。在源主机保存:

docker image save --output app-image.tar example-app:release

将生成的文件可靠地传到目标主机,再加载:

docker image load --input app-image.tar

example-app:release 是原主机上已确认的镜像引用。输出路径应为新文件,避免覆盖唯一的已有备份。加载会恢复归档中的镜像与标签,因此也要预先记录目标机同名标签所指的镜像,保留回退依据。加载后,检查 Cmd、Entrypoint 与原镜像一致,再按原部署定义启动。

不要在这之后再把 export 生成的根文件系统导入同一个标签,也不要把两类 tar 包当成可互换格式。它们都以 .tar 结尾,不代表保存的是同一层信息。

save 保存镜像,不会自动包含容器运行后写入的文件变化。需要保留这些变化时,先确认哪些属于可重建应用内容、哪些属于业务数据,再选用受控构建或明确的镜像快照流程。卷数据、绑定挂载和主机端端口映射仍要按各自的备份与部署定义恢复,不能把镜像归档当作整套服务的备份。

只剩 rootfs 归档时,明确补回启动配置

只有文件系统归档而没有原镜像时,不能从缺失的信息中自动还原完整配置。应从可信 Dockerfile、部署记录或原容器配置中确认命令、参数、工作目录、运行用户与所需环境。

docker import --change 可以设置新镜像的配置。例如,已确认归档中存在 /usr/local/bin/example-app,且它应以 --serve 参数运行时:

docker image import   --change 'CMD ["/usr/local/bin/example-app", "--serve"]'   ./rootfs.tar recovered-app:checked

这是结构示例,程序路径、参数、归档名与标签必须替换成已核实的值。使用新的恢复标签,不覆盖当前工作的镜像标签。若真实应用还依赖 WORKDIR、USER、ENV 或 ENTRYPOINT,也要逐项恢复;只让报错消失并不意味着应用配置完整。

JSON 形式中的程序和每个参数应是分开的数组元素。下面这样的写法会把整段内容当作一个可执行文件名:

CMD ["/usr/local/bin/example-app --serve"]

补了这个错误的 CMD 后,错误可能变成找不到该可执行文件。不要因此判断归档里的程序消失了,先检查参数是否被合并成一个字符串。原配置使用入口脚本时,还要保留入口脚本的作用,不能随意只取它最后调用的程序。

验证启动与数据恢复是两项检查

先只读检查恢复镜像的启动字段、用户和工作目录,再在隔离环境按已确认的部署定义验证。应用能启动后,还应核对挂载、配置和业务数据;export 本身不包含挂载卷内容。

不要为了验证恢复镜像,同时启动两个连接同一生产数据卷的实例。保留原镜像 ID、部署定义和数据备份,验证通过后再切换。若恢复配置仍有遗漏,回退到原镜像与原部署定义;新环境已经写入业务数据时,还需单独处理数据差异,换回镜像不会撤销那些写入。