1.4 生命周期管理:up、down、start、stop


1.4 生命周期管理:up、down、start、stop

本节摘要:Compose 的五个生命周期命令各管一段:up 负责从配置创建并启动,down 负责停止并删除,start 只启动已存在的容器,stop 只停止不删除,restart 是先停后启。本节重点讲清两对最容易混的命令——up 与 start、down 与 stop 的本质区别,并给出一个完整的"开发日"操作序列,让读者形成肌肉记忆式的日常节奏。

阅读收获

  • 能说清 up 与 start 在"是否读配置、是否重建容器"上的差异
  • 能说清 down 与 stop 在"是否删除资源"上的差异
  • 能正确使用 up 的 --build、--force-recreate、--scale、--remove-orphans 等选项
  • 能评估 down -v 和 --rmi all 的破坏性,避免误删数据
  • 能按"开发日"节奏组合使用五个命令,形成自己的日常流程

一、五个命令,各管一段生命周期

先记住一句总纲:up 是"从配置到运行",down 是"从运行到清除",start、stop、restart 是中间态的三个微操。up 与 start 的区别,down 与 stop 的区别,是本节最值得花时间的两组对比。

还有一层关系容易被忽略:up 是幂等的。已经运行的项目再跑一次 up,Compose 会对比当前容器与配置,有差异就重建对应容器,没差异就跳过,不会无脑全部重建。这也是 up 可以当"配置变更的落地命令"用的原因。重建容器时卷不会丢——卷独立于容器生命周期,up 只换容器壳,数据安然无恙。

up 会做全套动作:解析 Compose 文件、按需构建或拉取镜像、创建网络、创建容器、按依赖顺序启动、接入网络。start 只做最后一步:把已经存在的容器从停止状态拉起来。这意味着改完 docker-compose.yml 后跑 start 是无效的——配置变更只有 up 会感知。stop 只是把容器进程停掉,容器、网络、卷都还在;down 则删除容器和网络,项目回到"从未运行"的状态。用一个比喻:up 是装修好房子再入住,start 是回家开门,stop 是出门锁门,down 是退房并清空房间。两两对比还能看出恢复成本差异:stop 之后 start 秒级恢复,因为容器还在;down 之后一切要从头创建,虽然卷和镜像保留,但容器与网络要重建,恢复时间明显更长。日常停用优先 stop,项目下线才 down。

二、up:创建与启动的完整流程

up 的完整语法是 docker compose up [选项] [服务名...],不写服务名就操作全部服务。最常用的几个选项:

docker compose up -d # 后台分离模式运行,终端不被占用 docker compose up --build # 启动前强制重新构建镜像 docker compose up web db # 只启动指定服务 docker compose up --scale web=3 # 把 web 服务扩展到 3 个副本

前台运行(不加 -d)时日志直接打在终端,按 Ctrl+C 会停止所有服务;加了 -d 则容器转入后台,日志用 logs 命令查看。--force-recreate 强制重建容器,即使 Compose 认为配置没变化,适合容器内部状态可疑时用;--no-deps 跳过依赖服务,单独调试某个服务时省得连带启动;--remove-orphans 删除 Compose 文件里已不存在的孤立容器,项目重构后清理残留很好用。

up 的执行顺序值得背下来:先检查配置合法性,再决定是否构建镜像,然后创建网络和容器,按 depends_on 排序启动,最后接入网络。理解了这条链,遇到"容器一直重启"就能顺着链条定位问题出在构建、启动还是网络哪一环。补充一个前台运行的小细节:Ctrl+C 只是向容器发送停止信号,如果容器里有服务不响应优雅停机,可以再按一次 Ctrl+C 强制结束;而 --abort-on-container-exit 选项可以让 up 在任意一个容器退出时自动停止全部服务,写自动化脚本或跑测试时很好用。此外 up 还支持 --env-file 指定环境文件,与 --scale 一样属于高频选项,完整清单见第 6 章速查。

三、down:停止并删除,全量清理

down 与 stop 的最大区别是"删不删"。down 停止所有容器,删除容器本身和项目网络,项目资源基本归零:

docker compose down # 停止并删除容器和网络 docker compose down --rmi all # 额外删除所有服务使用的镜像 docker compose down --rmi local # 只删除没有标签的镜像 docker compose down -v # 额外删除卷,包括命名卷 docker compose down --remove-orphans docker compose down -t 30 # 设置停止容器的超时时间 30 秒

--rmi 的两个取值要分清:all 删除所有相关镜像,local 只删没有 tag 的构建产物镜像,官方镜像不删。默认的 down 不删卷也不删镜像,所以数据还留着;加上 -v 才会连命名卷一起删——这等于删掉数据库里的全部数据,执行前务必确认。down 也支持 --remove-orphans,和 up 的对应选项语义一致。

怎么确认 down 真的把项目清干净了?两个命令配合用:docker compose ls 列出当前所有项目及其状态,down 之后目标项目应从列表消失;docker compose ps -a 列出项目内全部容器,包括已停止的,down 之后应该为空。如果发现容器名还在,多半是 Compose 文件里的服务名和实际运行的项目对不上,检查是不是在错误的目录执行了命令。多项目机器上还有个常见乌龙:在 A 项目目录里执行 down,却把 B 项目同名服务的容器删了——因为 Compose 靠目录名定位项目,目录拷贝改名后新旧项目会共用一套资源前缀,操作前先 ls 确认。

超时参数 -t 控制给容器的停止宽限时间,默认 10 秒。容器里的应用如果有优雅停机逻辑,把 -t 调大能让它从容地完成收尾,避免强制 kill 丢数据。另一个与清理相关的细节:down 默认不删镜像,再次 up 时镜像还在本地,启动快很多;反过来 --rmi all 之后第一次 up 要重新拉取或构建,耗时明显变长。权衡之下,日常清理用裸 down,只有磁盘紧张或镜像确实废弃时才带 --rmi。

四、start、stop、restart:三个中间态微操

这三个命令都不读配置、不建容器、不删资源,纯粹操作现有容器的运行状态。start 启动已经存在但停止的容器,容器不存在时报错;stop 停止运行中的容器,状态变为 stopped;restart 先停后启,等于 stop 加 start 的合成:

docker compose start # 启动全部已停止的容器 docker compose start web db # 只启动指定服务 docker compose stop # 停止全部容器,不删除 docker compose stop web db # 只停止指定服务 docker compose restart # 重启全部服务 docker compose restart web db -t 20

restart 与 up 的另一个区别:restart 不会应用配置文件的新改动,也不会重新创建容器。如果你改了镜像标签或环境变量,restart 是不生效的,必须 up 才能让新配置落地。这三个命令常用于不改变配置的日常开关机场景。stop 的停止过程也不是瞬间断电:Docker 先向容器主进程发 SIGTERM 信号,给应用优雅收尾的机会,超时后再发 SIGKILL 强杀。应用里写了信号处理逻辑(比如保存状态、断开连接池)的,会在这几秒内完成收尾;没写的,就只能靠 -t 参数争取时间。理解这条信号链,排查"为什么容器总在超时后被强杀"时就有方向了。

五、一个典型的"开发日"操作序列

把命令串起来,看一个真实的工作日。假设项目目录里有一份定义 web 和 db 两个服务的 Compose 文件:

services: web: image: nginx:latest ports: - "80:80" depends_on: - db db: image: postgres:13 environment: POSTGRES_USER: example POSTGRES_PASSWORD: example

早晨开工,第一次启动要创建容器,用 up,若镜像还没拉取会先显示下载进度,耐心等它完成:

docker compose up -d

db 会先启动,因为 web 依赖它。接着打开日志跟踪开发过程,重点看启动阶段有没有报错:

docker compose logs -f web

中午午休不想占资源,但下午还要继续调,用 stop 停掉,容器和卷都保留:

docker compose stop

下午回来,start 直接拉起,秒级恢复:

docker compose start

改了 web 的镜像或端口配置,restart 不够,用 up 让它重建:

docker compose up -d

下班收工,确认数据库数据不要了,可以彻底清理:

docker compose down -v

注意最后一步加了 -v,连卷一起删。工作日收尾我更倾向只跑 down(不删卷),每周做一次数据备份后再执行带 -v 的彻底清理,两头都不耽误。

这套序列里每个命令都踩在正确的语义上:up 管创建、stop 管暂停、start 管唤醒、down 管清理。换个视角看,开发期和生产期对命令的偏好也不同:开发期频繁 up 与 down,享受配置即所得;生产期尽量少动容器,升级走 up 重建、日常维护走 exec 与 logs,down 只在真正停服时才用。把这两套节奏分开,命令就不容易用乱。

六、三个高频坑与判断口诀

把生命周期命令用错,通常集中在三处。第一处是"改了配置没生效":明明改了镜像标签或端口,restart 之后行为没变。原因前面讲过——restart 不读配置,必须 up。判断口诀:动过文件用 up,没动文件才 restart。

第二处是"start 报容器不存在":start 只能启动已经用 up 创建过的容器,全新机器上直接 start 当然报错。如果项目目录是从别人那里拷来的,或者之前 down 过,容器已被删除,start 无从谈起。判断口诀:容器都没了,谈何启动,先 up 后 start。

第三处是"stop 之后端口还被占用":stop 只停进程,端口映射是容器创建时绑定的,容器还在,端口就一直占着。想彻底释放端口,必须 down 删除容器。这解释了为什么有时改了端口配置 up 也报端口占用——旧容器还没删,新容器自然绑不上。判断口诀:端口冲突先 ps 看旧容器,再 down 再 up。

这三条口诀覆盖了生命周期命令八成以上的误用场景,剩下的交给 6.1 节的命令速查表兜底。把口诀和命令的行为差异一起记住,日常操作基本不会跑偏。

生命周期状态转换

五个命令行为对比

命令 读配置 建容器 启动 停止 删容器 删网络 删卷 典型场景
up 需要时 启动应用、应用配置变更
down 仅加 -v 彻底清理项目
start 唤醒已停止的服务
stop 临时停用保留现场
restart 不改变配置的重启

⚠️ 改配置后不要用 restart 代替 up:restart 不重新创建容器,新镜像、新环境变量、新端口全部不生效。判断标准很简单——只要动过 Compose 文件,就老老实实用 up,restart 只适合纯重启场景。

💡 给 down 加 -t 的习惯:生产环境执行 down 前,把停止超时从默认 10 秒调到 30 秒以上,给数据库等有状态服务留足优雅停机时间,能明显减少异常退出带来的数据损坏。

本节速览

  • up 是完整生命周期:解析配置、构建镜像、创建网络与容器、按依赖启动,改配置必须靠它
  • start 只启动不重建:容器必须已存在,配置变更对它无效
  • stop 只停不删:容器、网络、卷全部保留,随时可 start 恢复
  • down 停止并删除:容器和网络被移除,默认保留卷和镜像
  • down -v 会删命名卷:等于删除数据库数据,执行前必须确认备份
  • down --rmi all 删镜像:与 local 的区别是后者只删无标签的构建产物
  • restart 等于先停后启:不读配置,动过文件就用 up 而不用 restart
  • 开发日节奏:早晨 up -d,午间 stop,午后 start,改动 up,收尾 down,定期加 -v 彻底清理

至此,第 1 章的语法与命令已经齐了。从第 2 章开始,我们会把这些基础组装成一个个可以直接抄的部署模板——先从最常用的单服务与多服务模式讲起。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U