Docker 容器生命周期 · 启动与运行参数至停止、更新与清理
环境变量、标签与运行基线在创建时一并决定;历史 Go HTTP 构建例见完整练习。Dockerfile 指令解释与镜像仓库操作分别见 Dockerfile 和 镜像仓库。
Docker 容器生命周期
环境变量、标签与运行基线在创建时一并决定;历史 Go HTTP 构建例见完整练习。Dockerfile 指令解释与镜像仓库操作分别见 Dockerfile 和 镜像仓库。
启动与运行参数
生命周期模型
常见状态:
created -> running -> paused
\-> exited
\-> restarting
\-> deaddocker run 是 create 加 start 的便捷组合。容器是否运行取决于 PID 1;主进程退出,容器就退出。
docker create --name demo alpine:3.23 sleep 300
docker start demo
docker stop demo
docker start demo
docker stop demo
docker rm demo运行第一个服务
docker run -d \
--name web \
--restart unless-stopped \
-p 127.0.0.1:8080:80 \
nginx:alpine参数含义:
-d:后台运行。--name:稳定名称,便于日志和监控。--restart unless-stopped:daemon 或宿主机重启后恢复,但人工停止后不自动恢复。-p 127.0.0.1:8080:80:只在本机环回地址暴露。
验证:
docker ps --filter name=web
curl -fsS http://127.0.0.1:8080/
docker logs --tail 50 web前台、后台与交互
# 前台、交互终端、退出即删除
docker run --rm -it alpine:3.23 sh
# 后台
docker run -d --name sleeper alpine:3.23 sleep 1d
# 附着主进程
docker attach sleeperattach 连接的是容器主进程。按 Ctrl+C 可能向主进程发送信号并停止容器;默认分离组合是 Ctrl+P、Ctrl+Q。日常排查更常用 exec。
环境变量
docker run --rm \
-e APP_ENV=uat \
--env-file ./app.env \
alpine envapp.env:
APP_PORT=8080
LOG_LEVEL=info不要通过以下方式传敏感值:
- Dockerfile
ENV; docker run -e SECRET=value的命令行历史;- 提交到 Git 的 env 文件;
docker inspect可见的容器环境变量。
使用专用 Secret 管理,并以文件或短期凭据注入。
标签与元数据
docker run -d \
--name api \
--label com.example.team=platform \
--label com.example.service=api \
--label com.example.release=2026.08.12 \
team-api:2026.08.12筛选:
docker ps --filter label=com.example.team=platform
docker inspect api --format '{{json .Config.Labels}}'容器运行基线
生产运行至少考虑:
docker run -d \
--name api \
--restart unless-stopped \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=64m \
--cap-drop ALL \
--security-opt no-new-privileges=true \
--memory 512m \
--cpus 1.0 \
--pids-limit 256 \
--health-cmd='curl -fsS http://127.0.0.1:8080/healthz || exit 1' \
--health-interval 30s \
--log-opt max-size=20m \
--log-opt max-file=5 \
-p 127.0.0.1:8080:8080 \
team-api@sha256:REPLACE_ME这是模板而非通用答案。应用需要写目录或特定 capability 时,应明确添加最小例外并测试。
观察与排查
列表、过滤与格式化
docker ps
docker ps -a
docker ps --filter status=exited
docker ps --filter health=unhealthy
docker ps --filter label=com.example.team=platform
docker ps --format 'table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
docker ps -q脚本中先检查结果非空,再把 ID 传给其他命令;不要直接把不受控的 docker ps -q 用于批量删除。
检查配置与状态
docker inspect web
docker inspect web --format '{{.State.Status}}'
docker inspect web --format '{{json .State.Health}}'
docker inspect web --format '{{json .Mounts}}'
docker inspect web --format '{{json .NetworkSettings.Networks}}'
docker inspect web --format '{{.HostConfig.RestartPolicy.Name}}'查看主进程:
docker top web
docker container stats --no-stream web宿主机 PID:
docker inspect web --format '{{.State.Pid}}'日志
docker logs web
docker logs --follow web
docker logs --tail 100 web
docker logs --since 30m --timestamps web
docker logs --since '2026-08-12T09:00:00+08:00' web应用应把结构化日志写到 stdout/stderr。不要默认写入容器可写层中的文件;这类日志难收集、难轮转,并会撑满存储。
进入容器
docker exec -it web sh
docker exec web nginx -T
docker exec -u 0 -it web sh
docker exec -w /etc/nginx web ls -la
docker exec -e DEBUG=1 web envexec -u 0 是临时 root 调试,不能替代镜像中正确的用户和权限配置。极简/distroless 镜像可能没有 shell;此时使用:
docker inspect;docker logs;docker cp;- Docker Debug 或经过批准的临时调试容器;
- 在测试环境构建带工具的 debug target。
复制文件
docker cp web:/etc/nginx/nginx.conf ./nginx.conf
docker cp ./nginx.conf web:/tmp/nginx.conf注意:
docker cp可能以 root 所有权写入容器。- 它不是配置发布流程;容器重建后手工修改消失。
- 卷内数据应通过备份方案处理。
- 不要从不可信容器向宿主机高权限路径复制文件。
容器差异与可写层
docker diff web标记:
A:新增;C:修改;D:删除。
它适合发现应用是否把数据、缓存或日志误写进可写层。不能把结果当作完整安全审计。
健康检查
运行时指定:
docker run -d \
--name api \
--health-cmd='wget -qO- http://127.0.0.1:8080/healthz || exit 1' \
--health-interval=30s \
--health-timeout=3s \
--health-retries=3 \
--health-start-period=20s \
team-api:2026.08.12查看状态:
docker inspect api --format '{{json .State.Health}}'
docker ps --filter health=unhealthy健康检查应:
- 快速、稳定、开销小;
- 检查服务能否完成关键的最小工作;
- 有合理超时;
- 不产生副作用;
- 不把所有下游短暂故障都放大为容器重启。
Engine 只记录 health 状态,不会因为 unhealthy 自动重启普通容器。
退出码
docker wait job
docker inspect job --format '{{.State.ExitCode}} {{.State.Error}} {{.State.OOMKilled}}'常见含义:
0:应用正常退出;125:Docker 自身未能启动容器;126:命令不可执行;127:命令不存在;128 + signal:因信号退出,如 137 常与 SIGKILL/OOM/强制停止相关,143 常为 SIGTERM。
退出码只能提供方向,必须结合 OOMKilled、daemon 日志和应用日志判断。
停止、更新与清理
停止、终止与信号
docker stop --timeout 30 web
docker kill --signal SIGTERM web
docker kill --signal SIGQUIT web
docker restart --timeout 30 webstop 先发送镜像/容器配置的停止信号,等待超时后再强制终止。kill 默认发送 SIGKILL,进程无法清理。
应用 PID 1 应:
- 正确接收并处理 SIGTERM;
- 停止接收新请求;
- 等待在途请求或事务;
- 在平台停止超时内退出;
- 回收子进程,避免 zombie。
Shell form 容易让 shell 成为 PID 1 并影响信号转发:
# 不推荐
CMD my-server --port 8080
# 推荐 exec form
CMD ["my-server", "--port", "8080"]重启策略
| 策略 | 行为 |
|---|---|
no | 默认,不自动重启 |
on-failure[:max-retries] | 非零退出时重启 |
always | 总是重启;人工停止后 daemon 再启动也会恢复 |
unless-stopped | 除非被人工停止,否则重启 |
docker update --restart unless-stopped web
docker inspect web --format '{{json .HostConfig.RestartPolicy}}'重启策略不是健康修复机制。进程未退出但已死锁时,需要 healthcheck、外部监控和编排系统处理。
暂停与恢复
docker pause web
docker unpause webpause 通常通过 cgroup freezer 冻结进程。它不会优雅释放连接,长时间暂停可能触发上游超时,不适合常规发布。
重命名与更新
docker rename web web-old
docker update \
--cpus 1.5 \
--memory 768m \
--memory-swap 1g \
web-old不是所有创建时配置都能原地更新。端口、挂载、部分网络或安全配置改变时通常需要重建容器。
自动删除
一次性任务:
docker run --rm alpine:3.23 echo ok后台 --rm 容器停止后也会自动删除,不利于保留现场。生产批处理需要将日志和退出信息写入外部系统。
删除
docker stop web
docker rm web强制删除:
docker rm -f web警告: 强制删除跳过应用的正常停止流程,可能造成事务或文件写入中断。仅在明确了解影响时使用。
删除容器并删除其匿名卷:
docker rm -v stopped-container危险:
-v会删除关联的匿名卷;命名卷通常不会由此删除,但仍应先用docker inspect核对挂载。
继续阅读
- 命令
- 命令
- 故障排查