恒美微站 Logo 恒美微站
  • 首页
  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心
  • 联系我们

Docker 停止容器怎么启动?start 与 run 区别及排查

  • 首页
  • 资讯中心
  • /
  • Docker 停止容器怎么启动?start 与 run 区别及排查

相关资讯

工控Linux系统保险丝:OverlayFS+OTA+恢复出厂实战 2026/9/18 20:17:18
Cloudflare Workers `request_signal_passthrough` 兼容性标志:让入站请求的 AbortSignal 自动传导至子请求 2026/9/18 20:17:18
Security-101 IAM 能力指南:目录服务与 8 大身份保护控制(MFA/SSO/RBAC/自适应/PAM/IGA/行为分析) 2026/9/18 20:17:18

最新资讯

a标签点击失效?从事件拦截到样式遮挡再到传参,一篇搞定
零代码AI赋能中秋营销:从自动化流程到私域转化的实战指南
Altium Designer快捷键精选:原理图与PCB布线效率提升实战
vue-print-designer 实战:轻量化 Web 打印模板设计与集成方案
不想被官方通道限住,Harness 插件改 TaoToken Base URL
Claude Code 插件遥测实践:内置 telemetry mod 与 `$.telemetry` 接口完全解析

今日推荐

2026年AI设计工具在PPT制作中的核心应用与评测
Matlab手写逻辑回归:从数学原理到多变量概率预测模型实现
高值医用耗材研报PDF:用Python完成字段抽取、清洗与趋势预测

本周热门

AI SDK Harness 依赖更新指南:掌握 harness 包 SDK 依赖的升级、桥接同步与一致性校验
Refine v5 Ant Design NumberField 组件实战:基于 Intl 的本地化数字格式化
Flutter应用改名全指南:从Android到iOS的配置与工具实践

本月精选

自研推理加速器Redwood:两周内实现PyTorch模型高效部署的实战教程
V4L2摄像头采集实战:从camera_client.rar到出图全流程解析
从“谁发明了钢琴键”到知识问答智能体:RAG与记忆工程实践

Docker 停止容器怎么启动?start 与 run 区别及排查

发布时间:2026/9/18 20:17:18
Docker 停止容器怎么启动?start 与 run 区别及排查 刚学 Docker 那几天我最常干的蠢事就是——容器跑完之后手一抖docker stop了转头想再进去看一眼敲docker ps结果屏幕上干干净净一个字都没有。那一刻我脑子里只有一个念头完了容器是不是被我删了镜像是不是也得重装后来才知道容器只是睡了不是没了用一条docker start就能把它重新叫醒。这篇就把如何启动一个已经停止的容器这件事从头到尾讲透为什么停止后容器还在、start和run到底差在哪、start -a -i什么场景用、启动后又秒退怎么排查、端口为什么还可能连不上以及几条我踩过坑之后养成的日常习惯。内容面向刚上手的新手不需要你懂内核原理跟着敲命令就能复现。1. 先弄清楚容器停止之后到底还在不在1.1 docker ps 里看不到不等于容器被删了新手最大的误解就是把docker ps的空输出当成我的容器没了。其实docker ps这个命令的默认行为是只列出正在运行Up的容器停止的、创建了但没启动的它一律不显示。你要看全部得加-a也就是docker ps -a-a是--all的缩写。敲一下就知道差别有多大# 只看运行中的大概率是空的 docker ps # 看全部包括 Exited 的 docker ps -a输出里你会看到一列STATUS写着类似Exited (0) 3 days ago。这句话的信息量其实很大它是一个停止状态 退出码 停止时间的组合。只要这一行还在就说明容器实体依然躺在你的磁盘上随时可以被docker start拉起来。我习惯用一个类比镜像像是买房时的样板间图纸容器像是照着图纸实际盖出来的一套房子。你docker stop只是把房子里的灯关了、人赶出来了房子本身还在原地只有docker rm才是真把房子拆了。而docker ps相当于只给你看现在亮着灯的房子当然看不到那些关了灯的房子。所以第一件事记住要判断一个容器是不是还存在永远用docker ps -a不要用docker ps。1.2 停止为什么不会丢数据可写层还在原地很多人担心stop之后数据丢了这个担心可以放下。这里得说说 Docker 的分层结构理解了它后面很多坑你都能自己解释。一个容器的文件系统由两部分叠起来底下是镜像的只读层上面是 Docker 在启动容器时给它单独挂的一层可写层。你在容器里新建的文件、改过的配置、装的包全都落在那个可写层里而可写层只属于这个容器自己别的容器看不到。docker stop做的事情是给容器里的主进程发一个停止信号等它退出然后容器进入Exited状态。整个过程完全不碰可写层。所以你下次docker start起来之前写到/tmp、/var/log、改过的nginx.conf只要是在可写层里的都还在。真正会毁掉可写层的只有docker rm。这一点和虚拟机特别像关机不丢盘删虚拟机才丢盘。顺带把几个容易混淆的命令摆在一起对照这个表我建议你抄进笔记命令作用对象对容器的后果数据是否保留docker stop运行中的容器进程优雅退出状态变 Exited保留docker kill运行中的容器直接强杀进程状态变 Exited保留docker start已停止的容器重新拉起主进程保留docker restart运行中的容器stop 再 start 的组合动作保留docker rm已停止的容器删除容器实例和可写层丢失docker rmi镜像删除镜像和容器不是一回事视情况看最后两行要注意区分rm删的是容器rmi删的是镜像。新手经常混删错了对象还以为自己操作的是同一个东西。1.3 Exited 后面那个数字其实是排错的第一个线索Exited (0)、Exited (1)、Exited (137)这些括号里的数字是退出码来自容器里那个主进程退出时返回的状态。它不会直接告诉你哪里错了但能帮你快速缩小范围。Exited (0)主进程自己正常结束了。这里的关键词是正常——对一次性任务跑个脚本、导一次数据这是好事对 nginx、redis 这种本该长期跑的服务这说明它的主进程根本没打算常驻八成是你的启动命令配错了。Exited (1)应用自己报错退出了通常是配置问题、依赖缺失、端口被占。看日志去docker logs里一般有明确的报错行。Exited (137)这个数字是 128 99 就是SIGKILL。含义是被强制杀掉了常见于docker kill、内存超限被系统干掉OOM。如果是 OOMdocker inspect里的OOMKilled字段会是true。Exited (143)128 15收到SIGTERM退出也就是docker stop在超时前正常停掉的结果。记不住也没关系只要养成习惯先看退出码判断方向再去docker logs找具体原因。2. docker start 到底做了什么2.1 start 和 run 的分工一个复用旧容器一个新建容器这是新手最容易混的一对命令我用一句话概括docker run等于创建 启动两步每次都造一个新容器docker start只启动已经存在的旧容器不创建新的。你第一次跑docker run -d --name web nginxDocker 干了这些事找一个叫 nginx 的镜像基于它创建出一个容器随机或指定名字然后启动它。这条命令背后其实包含了docker create加docker start两个动作。第二次你要是再敲一遍同样的docker run -d --name web nginx会直接报错容器名web已经被占用了。因为run又想创建一个叫web的容器名字冲突。这时候正确的做法是docker start web它不会新建任何东西只是把那个已经停止的web容器原地唤醒。容器 ID 不变、名字不变、可写层内容不变、端口映射不变一切照旧。这个区别的重要性在于排错思路。你发现容器起不来了如果用的是run那每次都在一个新容器上试上次改的文件、装的包全都白搭如果用start改一次试一次都在同一个容器上问题定位快得多。2.2 容器怎么被唤起它得有一个不肯退出的主进程理解start的底层逻辑关键是搞懂容器为什么能一直运行。答案是容器里必须有一个前台常驻的主进程在扛着Docker 把它的 PID 视为 1。只要这个进程不退容器就一直是Up它一退容器立刻变Exited。这就是无数新手翻车的地方。拿 Ubuntu 镜像举例你敲docker run -d --name u1 ubuntu然后docker ps一看没有。docker ps -a一看Exited (0)。为什么因为 ubuntu 镜像的默认命令是/bin/bash你没有给它分配终端也没给它输入这个交互式 shell 拿不到任何输入就自己退出了。shell 一退容器自然跟着停。想让它待着就得给它一个不结束的活干或者给它一个能接输入的终端# 方式一让它跑一个不退出的命令 docker run -d --name u1 ubuntu sleep infinity # 方式二开一个交互终端退出前它一直活着 docker run -it --name u2 ubuntu服务型镜像就没这个问题。nginx 镜像的默认命令就是前台启动 nginxredis 的默认命令就是前台跑 redis-servermysql 也是。这些主进程天生不退出所以用-d跑起来之后容器稳稳地Up。理解到这一层你就能自我解释了容器 stop本质上就是主进程结束了。所以 start 能不能成功取决于它的主进程这次能不能撑住。如果一个容器的启动命令本身就是跑完就退的类型那start多少次它都会立刻再退——这不是start有问题是容器设计如此。2.3 start 的三个参数-a、-i、-d以及什么时候该用 execdocker start默认是后台启动也就是加了-d的效果。它还有两个有用的参数配合交互式容器时特别关键-a--attach把容器的标准输出、错误输出接回你的当前终端你能实时看到它的打印。-i--interactive把标准输入接回来你能往里敲东西。两个一起用-a -i就等于重新坐到这台机器面前。于是我前面那个u2容器用-it启动、然后被我CtrlP CtrlQ剥离或者直接停掉的可以这样重新接进去docker start -a -i u2这时你又能看到熟悉的 shell 提示符了退出时敲exit容器再次停止。但我得提醒一句别把start -a -i当成日常进入容器的常规手段。它适合我就是来重新接管这个一次性交互容器的场景。真正跑服务的容器nginx、redis、mysql里你更该用docker exec -it web bashexec的特点是在已经运行的容器里新开一个进程你的操作和容器的主进程互不干扰。你退出 exec 的 shell容器该跑还是跑。而start -a -i是把整个容器的主进程交到你手上你一按CtrlC主进程可能就被你停了容器跟着挂。这张表帮你快速决定场景推荐命令原因后台服务重启docker start web默认后台主进程自己扛重看一个交互容器的输出docker start -a web只接输出不接管输入重新接管一个 bash 容器docker start -a -i u2需要能敲命令进入正在跑的服务容器里看文件docker exec -it web bash不动主进程安全只是想看日志docker logs -f web最轻量不干扰进程3. 手把手把停止的容器启动起来的完整操作3.1 先精准找到目标容器在start之前你得先知道要给谁发指令。目标可以用名字或ID指定。名字是你在run时用--name取的或者 Docker 随机分配的ID 是一长串十六进制一般取前几位能唯一区分就行。日常找容器我最常用的几条命令# 全部容器含已停止 docker ps -a # 只看状态是 Exited 的 docker ps -a --filter statusexited # 只显示最近创建的 3 个 docker ps -a -n 3 # 只要 ID方便脚本里用 docker ps -aq # 自定义输出列看名字和状态 docker ps -a --format table {{.Names}}\t{{.Status}}\t{{.Image}}--filter这个参数值得单独说一下它能按状态、按镜像、按名字前缀筛。容器多起来之后一屏几十行人工找起来很费眼用它就能瞬间收敛。--format用的是 Go 模板语法{{.Names}}、{{.Status}}、{{.Image}}、{{.Ports}}这几个字段用得最多第一次照着抄就行。3.2 用名字还是 ID以及要不要先重命名我强烈建议养成给容器取名的习惯。docker run --name web nginx就多敲这一小段后面省心无数。名字比 ID 好记、好读、好写脚本。docker start web如果当初没命名也可以用 ID 前缀# 先查 ID docker ps -a # 假设看到 3f2a91b8c4d1 docker start 3f2a # 只要前缀能唯一区分即可名字取错了也别慌容器停止状态下可以改名docker rename 老名字 新名字不过改名的成本比一开始取好名字高得多尤其是当你的脚本、文档里已经引用了旧名字。所以讲到底还是那句话--name该加就加。3.3 启动之后用三条线确认它真的起来了docker start web敲完屏幕上只会打印一个web就没了。这个输出不代表成功启动只代表 Docker 接收了你的指令。真正的活了没得从三个角度确认。第一条线看状态docker ps --filter namewebSTATUS列要是显示Up 8 seconds之类的说明主进程撑住了。如果它又变成Exited那一秒是骗你的得往下排查。第二条线看日志看它启动过程做了什么、有没有报错docker logs --tail 50 web # 想持续跟就跟加 -f docker logs -f web--tail 50表示只输出最后 50 行新容器内容多的时候不至于刷屏。-f是 follow实时跟踪跟tail -f一个道理调试时很好用。第三条线看端口和细节# 看端口映射 docker port web # 看容器详细状态 docker inspect --format {{.State.Status}} {{.State.RestartCount}} {{.State.OOMKilled}} webdocker inspect里的State.RestartCount是重启次数OOMKilled表示是不是被内存超限杀过这俩字段排查反复重启和被系统干掉时特别有用。这三条线走完你基本就能确定容器到底是健康、还是可疑、还是根本没好。3.4 批量启动多个容器一次把一排拉起来真实场景里你往往有不止一个容器。用docker-compose up -d自然是主流做法但如果就是几个独立容器命令行也能一次启动# 指定多个名字空格分隔 docker start web redis mysql # 启动全部已停止的容器把状态是 Exited 的 ID 全丢给 start docker start $(docker ps -aq --filter statusexited)第二条命令是个非常实用的一键全启。它先让docker ps -aq --filter statusexited把停止容器的 ID 全列出来再用$()拼成参数交给docker start。不过用之前提醒一句别在机器上堆了几十个实验容器时无脑执行它。把一堆你早就不要的容器全拉起来内存和端口都会打架反而是给自己找麻烦。批量启动前先docker ps -a扫一眼心里有数再敲。4. 启动之后又秒退、连不上高频原因排查链路4.1 现象是Up 一秒就 Exited排查顺序别乱docker start web回车后docker ps短暂看到Up 1 second再刷一下又变回Exited这是新手最崩溃的场景之一。这时候不要东一榔头西一棒槌瞎试按顺序走效率最高先看退出码docker ps -a里Exited括号里的数字。0 说明主进程自己退了1 说明应用报错137 是被强杀或 OOM。再看日志docker logs web绝大多数错误信息都在这。再查配置配置文件路径对不对、环境变量有没有丢、依赖服务在不在线。接着看资源是不是内存超了、磁盘满了。最后才考虑重建确认是可写层或镜像本身状态坏了才考虑rm重新run。这个顺序的核心是从成本最低、信息量最大的动作开始。退出码看一眼只要一秒日志一秒就能拉先做这两步能省下大量瞎猜的时间。4.2 交互式容器启动即退Tty 与 stdin 的锅前面 Ubuntu 的例子已经点过一次这里再展开说透因为这是我明明停好了、为什么 start 又秒退的最高频原因。场景是这样的你之前跑过一个docker run -it --name dev ubuntu的容器在里面装了软件然后exit出来了容器变Exited。现在你想接着用敲docker start dev结果它又Exited了。为什么因为docker start dev是后台启动没有给这个 bash 主进程分配 stdin 和 ttybash 拿不到输入立刻就结束。你之前能进去是因为run时带了-it。正确的姿势是docker start -a -i dev-a接回输出-i接回输入为了能正常交互通常还建议配合-t分配伪终端有些老版本要显式加。如果只是想让它后台待着别退可以换一种活法docker start dev # 它退了那就别用 bash 当主进程 docker run -d --name dev2 ubuntu sleep infinity一句话总结这个坑交互式容器的启动必须带上交互参数后台启动一个 bash 容器等于让它孤独地等待一个永远不会来的输入它只能自己走。4.3 端口连不上start 不会给你补上当初没做的映射这个坑我自己真踩过。当时我在容器里跑了个服务用docker run -d --name app myimage起的没加-p容器里的服务监听 8080我在宿主机怎么访问都连不上。我以为重启一下就好了docker stop app又docker start app结果还是一样。根本原因得说清楚端口映射是在docker create也就是docker run那一刻就固定下来的属于容器的网络配置。docker start只是复用这套已经存在的配置它不会、也无法给你追加新的-p映射。所以当初run时没写-p 8080:8080那这个容器这辈子都没有这个映射start多少次都没用。当初run时写了那start之后映射照旧生效你也不用重新指定。宿主机端口被别的程序占了比如本地也跑了个同端口的服务报的错发生在run那一刻跟start关系不大。那如果当初没映射现在想补怎么办没有直接修改的办法只能把容器另存出来重做# 把当前容器保存成新镜像 docker commit app myimage:fixed # 用新镜像重新 run这次带上端口映射 docker run -d --name app2 -p 8080:8080 myimage:fixeddocker commit会把容器的可写层打包进新镜像你之前改的东西不会丢。但这个方式不算优雅长期看更该用 Dockerfile 把镜像构建流程固化下来。临时救急用它没问题。4.4 数据看起来没了你多半是又 run 了一个新容器还有一种误判特别常见用户stop了容器想恢复数据顺手敲了docker run ...可能还是同一条命令、换了个名字结果打开一看之前装的东西、写的文件全不见了于是得出结论Docker 不持久化数据。其实真相是你run的是一个全新的容器它有自己全新的可写层旧容器里那层数据根本没带过来。旧数据还在旧容器里你用docker start 旧容器名就能看到。想彻底避免这种困惑需要区分两个概念可写层只属于某一个容器容器删了就没了别的容器看不到。数据卷volume或绑定挂载bind mount独立于容器的存储通过-v挂进去容器删了数据还在多个容器也能共享。判断你该用哪种看数据的定位临时产物、跑完就算的扔可写层数据库文件、上传目录、配置这种容器重建后还得留着的必须用-v挂出来。我给新手的一句忠告是凡是你希望下次还在的数据就别放在容器可写层里一开始就用卷。这条我要是早两年懂能少折腾好几天。5. 把停-启用顺手几个值得写进肌肉记忆的设置5.1 --restart 策略让容器自己站起来每次机器重启或者容器意外挂掉都要你手动docker start那也太累了。--restart就是解决这个的。它在docker run时指定也可以在运行后改。策略行为适合谁no从不自动重启默认一次性任务、临时实验on-failure只有非 0 退出码时才重启会偶发崩溃的任务on-failure:3同上最多重启 3 次防止无限重启刷屏always不管怎么退出都重启重启 Docker 也会拉起长期在线的服务unless-stopped类似 always但你手动 stop 之后就不再自动拉起想手动控制停机时机的服务后两个的差别是新手最容易搞混的我用具体场景说always意味着哪怕你手动docker stop了它下次 Docker 守护进程重启比如你重启了宿主机它还是会自己起来。unless-stopped会记住你手动停过不主动打扰你。我个人的偏好是本地开发环境用unless-stopped因为我要的是它能自己扛住意外挂掉但我说停就真停这个语义最贴合开发场景。运行中的容器改策略不需要重建docker update --restartunless-stopped webdocker update也能顺手改内存、CPU 限制属于不改容器就能调参的少数手段之一。5.2 别为了启动而启动分清什么情况该重建新手容易把所有问题都往start上招呼但不是所有情况都能靠start解决的。我总结了一条判断线只是容器停了配置和镜像都没动直接docker start。只是想让某个挂了的服务重新跑docker restart一条更省事它等于 stop 加 start。要更新应用代码、改端口映射、换镜像版本别再启动旧容器了重建才是对的。用 Compose 的话就是docker-compose up -d它会自动判断哪些需要重建。容器文件系统坏了、状态脏了也只能删掉重建。判断核心是问自己一句我想改的东西是运行时状态还是容器定义状态的问题重启能解决定义的问题只能靠重建。这一句话能帮你省下一堆无用的尝试。5.3 停止也有讲究stop 的优雅和 kill 的强硬既然聊启动停止也顺带说清楚因为它们是成对的。docker stop和docker kill的区别不只是温柔和暴力docker stop会给容器主进程发SIGTERM让它有机会做收尾关连接、写盘、清临时文件。默认等 10 秒还没退才升级为SIGKILL。这个时间可以用-t调docker stop -t 30 webdocker kill直接发SIGKILL没有商量余地对数据库这类应用要慎用容易留下不一致的状态。我给的经验是日常一律用stop只有在容器已经卡死、stop 也停不下来的时候才动kill。尤其是跑 MySQL、Postgres 的容器优雅关闭能大幅降低数据损坏风险。这里也顺带呼应一下数据卷那条有了稳定卷优雅停止的意义才更实在。5.4 Exited 容器会越堆越多定期收一收一个隐形问题是你每敲一次docker run就多一个容器实体哪怕它停止了也还占着磁盘的可写层。我见过不少人的机器上躺着上百个 Exited 容器docker ps -a翻半天。定期清理是必要的# 删除所有已停止的容器 docker container prune # 或者更直接把已停止容器的 ID 全删掉 docker rm $(docker ps -aq --filter statusexited)docker container prune会先让你确认删之前看清楚列表。这里有个坑必须提醒如果某个容器的数据你还没挂出来、直接放在可写层里prune一刀下去就没了。所以清理前先确认两件事——这些容器是实验用的、以及重要数据是不是都用-v挂到卷里了。别问我为什么强调这点答案你可能已经猜到了。另外还有一种连锁坑删容器时没注意关联的卷docker rm -v会连带把匿名卷也删掉。默认的docker rm不动卷但如果你加了-v匿名卷就跟着走。用命名卷的项目一般不受影响但临时用-v /data挂匿名卷的场景要格外小心。补充一句和上下文相关的判断逻辑容器停止的原因、容器启动后能否常驻、数据能否跨容器保留这三件事各有各的答案别指望一条命令全解决。退出码告诉你怎么停的主进程类型告诉你能不能常驻卷的配置告诉你数据安不安全。一路写下来我自己最想做的一件事就是让看的人别重走我那条弯路。我第一次用 Docker 的时候为了恢复一个停了的容器硬生生重新run了三遍还把旧容器删了最后发现数据全丢在删掉的可写层里。现在我的习惯固定成三条给容器都起名、重要的数据一律挂卷、停止的排错先看退出码再看日志。这三条不复杂但每一条都帮我省过真正的时间。至于start本身其实就一条命令的事难点从来不在命令本身而在于你清楚它到底在启动什么、以及启动不起来的时候该往哪看。

关于恒美微站

恒美微站专注于为个体商户、工作室提供极简自助建站服务,让每个人都能轻松拥有专业网站。

快速链接

  • 关于我们
  • 建站服务
  • 主题模板
  • 案例展示
  • 资讯中心

服务项目

  • 可视化建站
  • 拖拽编辑
  • 主题定制
  • SEO 优化
  • 网站托管

联系方式

  • 📍 地址:北京市朝阳区建国路 88 号
  • 📞 电话:400-888-8888
  • ✉️ 邮箱:info@hmyw.cn
  • 🕐 时间:周一至周日 9:00-18:00

© 2024 恒美微站 hmyw.cn 版权所有 | 京 ICP 备 12345678 号