知其然,知其所以然
Docker 容器原理 2026-10-10

Compose 的环境变量:插值、env_file 与优先级

在 Docker Compose v5.5.1 里实测环境变量的来源与优先级:environment 胜过 env_file;.env 只用于 compose.yaml 里的 ${…} 插值,不进容器;shell 高于 .env;不写值的 environment 项从 shell 透传;docker compose run -e 覆盖一切;--env-file 替换 .env;${VAR:-x}、${VAR-x}、${VAR:?msg} 的区别。

Docker Docker Compose 环境变量 env_file .env 插值 真实验证 动画演示
Docker 容器原理 2026-10-10

Compose 网络:默认网络和多网络隔离

在 Docker Compose v5.5.1 里实测 compose 的网络:默认建「项目名_default」,服务名和容器名都能解析;前后端分网后 proxy 连 db 的名字都解析不了;internal: true 的网络没有默认路由、不能出网;aliases 与 ipv4_address 可以固定名字和地址。

Docker Docker Compose networks internal 别名 固定IP 真实验证 动画演示
Docker 容器原理 2026-10-10

Compose 扩容:scale 与端口冲突

在 Docker Compose v5.5.1 里实测扩缩容:--scale worker=3 得到 worker-1..3,缩到 1 保留编号小的原容器,再扩容补出新容器;服务名解析出所有副本的 IP;deploy.replicas 被 --scale 覆盖;固定宿主机端口映射在扩容时冲突(退出码 1),端口范围或只写容器端口则成功;设了 container_name 就不能扩容。

Docker Docker Compose scale replicas 扩容 端口冲突 真实验证 动画演示
Docker 容器原理 2026-10-10

Compose watch:sync、rebuild 的触发规则

在 Docker Compose v5.5.1 里实测 docker compose watch:sync 改文件约 0.6 秒后容器里生效且容器不重启,新增和删除也同步;sync+restart 先同步再重启同一个容器(约 3.8 秒);rebuild 重新构建镜像并重建容器(约 6.2 秒),新容器里是最新文件。

Docker Docker Compose watch develop.watch 热更新 真实验证 动画演示
Docker 容器原理 2026-10-10

HEALTHCHECK:状态怎么流转、重试与启动宽限

在 Docker Engine 29.8.2 里实测健康检查:interval 1s、retries 3 时一直失败约 3 秒变成 unhealthy,检查通过立刻变回 healthy;慢启动的程序在没有 start-period 时会先变成 unhealthy 再变回 healthy;超时的检查记 ExitCode -1;start-period=6s 把变成 unhealthy 推迟到 7.1 秒;unhealthy 的容器不会被 --restart always 重启。

Docker healthcheck 健康检查 start-period unhealthy 真实验证 动画演示
Docker 容器原理 2026-10-10

json-file 日志:没有轮转时磁盘怎么被写满

在 Docker Engine 29.8.2(Docker Desktop)里实测容器日志:默认驱动是 local(二进制文件 local-logs/container.log,没有 LogPath);显式 json-file 时每行 JSON 带 log / stream / time,超长行按 16384 字节拆开;max-size=10k max-file=3 把 1000 行轮转成只剩 209 行;json-file 默认无上限;容器删除后日志也被删。

Docker 日志 json-file local日志驱动 日志轮转 docker logs 真实验证 动画演示
Docker 容器原理 2026-10-10

日志驱动:local、syslog 与 none 的差别

在 Docker Engine 29.8.2 里实测日志驱动:内置 awslogs、fluentd、gcplogs、gelf、journald、json-file、local、splunk、syslog;--log-driver none 后 docker logs 报不支持读取;gelf 与 syslog 能把日志发到 UDP 接收端(GELF 的 JSON、rfc5424 的 syslog 行),同时 docker logs 仍然可读;TCP 目标连不上时容器直接起不来(125)。

Docker 日志驱动 gelf syslog log-driver 双写日志 真实验证 动画演示
Docker 容器原理 2026-10-10

容器日志延迟:程序 stdout 缓冲与 docker logs

在 Docker Engine 29.8.2 里实测日志延迟:Python 的 print 写到管道时块缓冲,docker logs 里第一行 10.3 秒(进程退出时)才出现;python -u、PYTHONUNBUFFERED=1、flush=True、docker run -t 都在 0.1~0.2 秒内出现;stderr 不缓冲;不 flush 时第一批在累计 8100 字节(约 8 KiB 缓冲区)时出现。

Docker stdout缓冲 Python docker logs PYTHONUNBUFFERED TTY 真实验证 动画演示
Docker 容器原理 2026-10-10

docker events:守护进程事件流里有什么

在 Docker Engine 29.8.2 里实测 docker events:一轮对卷、网络、镜像、容器的操作产生 15 条事件(容器 create → attach → start → die → destroy,卷 create → mount → unmount → destroy,网络 create → connect → disconnect → destroy);事件有 Action、Actor、Type、scope、time、timeNano 字段;--filter type= / event= / container= 过滤;--since 24h 也只能回看到最近的 256 条。

Docker docker events 事件 filter 监控 真实验证 动画演示
Docker 容器原理 2026-10-10

docker stats:数字是从哪个 cgroup 文件读来的

在 Docker Engine 29.8.2 里实测 docker stats:两个满负荷进程的 CPUPerc 是 198.98%(与从 cgroup cpu.stat 算出的 200% 一致,100% 是一个核);MemUsage 不含页缓存(写 200 MiB 文件后 cgroup 的 memory.current 涨了约 200 MiB,docker stats 只涨几 MiB);NetIO 与 eth0 的内核计数一致;BlockIO 记录写入量。

Docker docker stats 监控 CPU百分比 内存页缓存 NetIO 真实验证 动画演示
Docker 容器原理 2026-10-10

docker inspect:一个容器的完整配置长什么样

在 Docker Engine 29.8.2 里实测 docker inspect:容器对象有 24 个顶层键(HostConfig 63 项),镜像对象 14 个;--format 的 json、index、range、printf 取出 PID、环境变量、标签、挂载、端口映射;-s 才有 SizeRw(写 10 MiB 后约 10493952 字节);容器和镜像同名时默认返回容器,要用 --type 区分。

Docker docker inspect Go模板 format SizeRw 真实验证 动画演示
Docker 容器原理 2026-10-10

docker top 与 ps:同一个进程在宿主机和容器里的两个视图

在 Docker Engine 29.8.2 里实测 docker top:它显示的是虚拟机里的 PID(53711),docker exec ps 里是容器里的 PID(1);参数交给虚拟机的 ps;用户名由虚拟机的 /etc/passwd 解析(uid 1 在容器里叫 bin、docker top 显示 daemon);必须含 PID 列;scratch 镜像里没有 ps 也能用 docker top。

Docker docker top 进程 PID NSpid scratch 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号