docker run是容器启动的第一道关,其核心在于参数与镜像ENTRYPOINT/CMD协同、端口/卷/网络挂载需验证存在性与权限、退出码和日志是定位Created或秒退问题的关键依据。
写对 docker run 命令是容器能跑起来的第一道关。命令本身不复杂,但参数之间有依赖、顺序有讲究、路径和权限稍一错,容器就卡在“created”或秒退。重点不在记命令,而在理解每个参数实际触发了什么动作。
启动命令核心参数必须对齐镜像预期
镜像不是黑盒,它内部定义了 ENTRYPOINT 和 CMD,你的 docker run 命令必须与之协同,否则会直接失败。
- 如果镜像用
ENTRYPOINT ["/bin/sh", "-c"],你传入的命令必须是字符串形式,比如docker run alpine sh -c "echo hello";若写成docker run alpine echo hello,就会因入口脚本找不到echo而报"no such file or directory" - 镜像声明了
CMD ["npm", "start"],但你挂载了一个空 volume 到/app,导致package.json丢失,容器启动后立即退出,退出码为 1 - 使用
--user指定非 root 用户时,要确保该用户在镜像中存在(cat /etc/passwd可查),且挂载目录在宿主机上对该用户可读写
端口、卷、网络三类挂载必须验证存在性与权限
这些不是“配上去就行”的参数,而是运行时真实绑定的动作,出错会直接阻断启动流程。
-
端口冲突:执行
docker run -p 8080:80 nginx前,先运行lsof -i :8080或ss -tuln | grep :8080,确认端口空闲。Windows/macOS 用户还要注意 Docker Desktop 的端口转发是否启用 -
卷路径不存在:
-v /host/path:/container/path中的/host/path必须在宿主机上真实存在,且 Docker 进程有读取权限(Linux 下尤其注意 SELinux 上下文或 rootless 模式限制) -
网络模式误用:用
--network host时,容器将共享宿主机网络命名空间,此时-p参数失效;而--network none下容器无网络栈,无法访问外部,也不接受端口映射
日志与退出码是定位问题的唯二可靠线索
不要靠“重试”或“改个参数再跑”,先看退出状态和原始输出。
- 运行
docker ps -a,找到容器状态。如果是Created,说明镜像加载成功但尚未启动,问题出在挂载、用户、资源限制等前置检查环节 - 如果是
Exited (137),基本可判定是 OOM 被系统 kill,需加--memory=512m限制或调高上限;Exited (1)多为应用自身异常,必须查日志 -
docker logs <容器名>是第一检查项。若日志为空,说明进程根本没执行到 main 函数,问题在启动前——如二进制缺失、动态库链接失败、配置文件路径硬编码错误
调试型启动:绕过默认入口,手动验证关键路径
当常规启动失败又看不出原因时,用临时命令进入容器环境,像运维一样逐层排查。
- 用
docker run -it --rm --entrypoint sh <镜像名>启动一个交互 shell,手动执行原CMD中的命令,观察报错 - 检查关键路径是否存在:
ls -l /app、ls -l /etc/nginx/conf.d、id查当前用户 UID/GID - 验证基础依赖:运行
curl -I http://localhost:8080(如果服务已监听)、ping -c2 google.com测试网络连通性


















