Appearance
Docker 常用命令速查:从拉镜像到线上排障
约定:Docker 24+ / Compose V2(命令是
docker compose,老版本的docker-compose已废弃)。 下文<容器>一律指容器名或 ID,写前几个字符能唯一匹配即可。
这份清单不按字母序排,按你实际遇到问题的顺序排:先看全局 → 玩镜像 → 起容器 → 进容器看日志 → 排障 → 清理磁盘。
一、先看全局(上机器第一件事)
bash
docker version # 客户端 + 服务端版本,连不上 daemon 时先看这个
docker info # 存储驱动、容器数、镜像数、根目录
docker system df # Docker 占了多大磁盘(镜像/容器/卷/构建缓存分项)docker system df 是排查"磁盘怎么又满了"的起点,先看它再决定清哪里。
二、镜像
bash
docker pull nginx:1.25 # 拉镜像(不写 tag 就是 latest,生产别这么干)
docker images # 列出本地镜像
docker images --filter "dangling=true" # 只列悬空镜像(<none>,构建残留)
docker history --no-trunc myapp:1.0 # 看镜像每一层的构建命令(查体积用这个)
docker inspect myapp:1.0 # 镜像的元数据全量 JSON
docker build -t myapp:1.0 . # 构建
docker build -t myapp:1.0 -f Dockerfile.prod . # 指定 Dockerfile
docker build -t myapp:1.0 --no-cache . # 不用缓存,全量重建
docker tag myapp:1.0 registry.example.com/team/myapp:1.0 # 打标签(推送前必做)
docker push registry.example.com/team/myapp:1.0 # 推送到仓库
docker save -o myapp.tar myapp:1.0 # 导出成文件(离线环境搬运用)
docker load -i myapp.tar # 从文件导入
docker rmi myapp:1.0 # 删镜像(有容器在用会报错,先删容器)镜像体积排序(找占地方的大头):
bash
docker images --format "table {{.Repository}}:{{.Tag}}\t{{.Size}}" | sort -h -k2三、容器生命周期
bash
docker run -d --name web -p 8080:80 nginx:1.25 # 后台起一个容器
docker run -d --name web --restart unless-stopped nginx:1.25 # 开机自启策略
docker run -it --rm ubuntu:22.04 sh # 临时跑一个,退出即删除
docker ps # 运行中的容器
docker ps -a # 含已停止的
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" # 只看关键列
docker start web / docker stop web / docker restart web
docker kill web # 直接 SIGKILL,不给收尾时间
docker rm -f web # 强制删除运行中的容器
docker update --memory 512m --memory-swap 1g web # 在线改资源限制--restart 三个常用值:no(默认)、unless-stopped(推荐,手动 stop 后不再拉起)、always(连手动 stop 也会拉起,慎用)。
四、进容器、看日志(日常最高频)
bash
docker exec -it web sh # 进容器(alpine 只有 sh,没有 bash)
docker exec -u root -it web sh # 以 root 进入(容器默认非 root 时)
docker exec web nginx -s reload # 在容器内执行单条命令,不进交互
docker logs web # 看全部日志
docker logs -f --tail 100 web # 跟踪最后 100 行(最常用)
docker logs --since 10m web # 只看最近 10 分钟
docker logs --since "2026-10-03T10:00:00" web # 按时间点过滤exec 和 attach 不是一回事,混用会出事:
docker exec -it | docker attach | |
|---|---|---|
| 原理 | 在容器里新建一个进程 | 附着到**主进程(PID 1)**的 stdin/stdout |
| 退出后容器 | 继续运行 | 主进程收到信号,容器可能跟着退出 |
| 脱离方式 | exit | Ctrl+P 再 Ctrl+Q(不是 Ctrl+C) |
日常排障一律用 exec,attach 只在要看主进程原始输出时才用。
宿主机 ↔ 容器互拷文件(容器里没装编辑器时的救急手段):
bash
docker cp web:/etc/nginx/nginx.conf ./nginx.conf # 拷出来
docker cp ./nginx.conf web:/etc/nginx/nginx.conf # 拷进去五、排障:容器为什么挂了 / 卡了
bash
# 退出原因三连
docker inspect -f '{{.State.Status}}' web # 状态
docker inspect -f '{{.State.ExitCode}}' web # 退出码:0 正常,137=OOM/被 kill,139=段错误
docker inspect -f '{{.State.OOMKilled}}' web # 是不是被 OOM 杀掉(true 就是内存不够)
docker inspect -f '{{.RestartCount}}' web # 重启次数(一直在涨就是反复崩)
# 资源占用
docker stats # 实时看所有容器 CPU / 内存 / IO
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}" # 快照,适合脚本
docker top web # 容器内的进程列表
# 其他
docker port web # 端口映射关系
docker diff web # 容器文件系统相对镜像的改动(A 新增 / C 修改 / D 删除)
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web # 容器 IP退出码 137 = 128 + 9(SIGKILL),八成是 OOM;先用 OOMKilled 确认,再决定加内存还是查内存泄漏。
六、数据卷与网络
bash
# 数据卷(推荐,由 Docker 管理,跨容器复用)
docker volume ls / create mydata / inspect mydata / rm mydata
docker run -d -v mydata:/data myapp:1.0
# 绑定挂载(直接挂宿主机目录,改配置最方便)
docker run -d -v /opt/conf:/etc/nginx:ro nginx:1.25 # ro = 容器内只读
docker run -d --mount type=bind,src=/opt/conf,dst=/etc/nginx,readonly nginx:1.25-v 简写够用;--mount 语法啰嗦但参数写错会直接报错,不会像 -v 那样静默创建一个匿名卷——卷名打错时这个区别能救命。
bash
docker network ls
docker network create app-net
docker network connect app-net web # 把已有容器接入网络
docker network inspect app-net # 看这个网络上挂了哪些容器自定义网络里容器之间可以用容器名互访,这是 compose 之外的多容器通信最省事的做法。
七、Compose(多容器编排)
bash
docker compose up -d # 后台启动全部服务
docker compose -f docker-compose.prod.yml up -d # 指定文件
docker compose up -d --build # 改过 Dockerfile,重新构建再起
docker compose config # 打印合并后的最终配置(排查变量没生效时用)
docker compose ps # 服务状态
docker compose logs -f web # 看单个服务日志
docker compose exec web sh # 进服务容器
docker compose restart web # 重启单个服务
docker compose down # 停止并移除容器、网络
docker compose down -v # ⚠️ 连数据卷一起删(数据库数据会没了)八、清理磁盘(生产上最常干的三件)
bash
docker container prune -f # 清所有已停止的容器
docker image prune -a -f # 清所有未被任何容器引用的镜像
docker volume prune -f # ⚠️ 清未被使用的卷(见下方警告)
docker builder prune -f # 清构建缓存(往往好几个 G)
docker system prune -f # 容器 + 网络 + 悬空镜像(不含未使用镜像和卷)🔴
docker system prune -a --volumes是这条街上最危险的命令:它会删掉所有未被容器引用的数据卷,包括你停掉的数据库容器里存的数据。执行前先docker volume ls确认一遍。 容器的可写层(没挂卷时写在容器里的数据)在docker rm后就没了,没有回收站。
九、几个真正用得上的组合技
bash
# 1. 一把看清所有容器的 IP
docker inspect -f '{{.Name}} {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -q)
# 2. 清理全部已停止容器(不用确认)
docker rm $(docker ps -aq --filter "status=exited")
# 3. 进容器的网络命名空间抓包(容器里没 tcpdump 时)
docker run --net=container:web -it --rm nicolaka/netshoot tcpdump -i any -nn port 80
# 4. 不打镜像也能临时测端口连通性
docker run --rm --network app-net curlimages/curl:latest -sv http://web:80/
# 5. 找出占内存最高的容器
docker stats --no-stream --format "{{.Name}} {{.MemPerc}}" | sort -rn -k2 | head -5十、三个容易踩的坑
1. 容器日志把磁盘写满。 Docker 默认 json-file 日志驱动没有大小上限,跑几个月能把根分区写爆。查是谁:
bash
du -sh /var/lib/docker/containers/*/*-json.log | sort -rh | head临时止血(用 truncate 不要 rm——容器持有文件句柄,rm 后空间不会释放):
bash
truncate -s 0 /var/lib/docker/containers/<容器ID>/<容器ID>-json.log根治要在 /etc/docker/daemon.json 里配:
json
{
"log-driver": "json-file",
"log-opts": { "max-size": "100m", "max-file": "3" }
}改完 systemctl restart docker。⚠️ 这个配置只对新建容器生效,已有容器必须重建才会套用。
2. 容器内时区是 UTC。 日志时间对不上多半是这个,起容器时挂进去:
bash
docker run -d -v /etc/localtime:/etc/localtime:ro -v /etc/timezone:/etc/timezone:ro myapp:1.03. 精简镜像里没有 curl / ping / ps。 别急着往生产镜像里装,用 sidecar 方式临时排查(上面组合技 3、4),或者直接 nsenter 进命名空间用宿主机的工具。
附:命令速查索引
| 我想干什么 | 命令 |
|---|---|
| 看 Docker 占了多少磁盘 | docker system df |
| 起一个后台容器 | docker run -d --name <名> -p 宿主:容器 <镜像> |
| 进容器 | docker exec -it <容器> sh |
| 实时看日志 | docker logs -f --tail 100 <容器> |
| 容器为什么退出 | docker inspect -f '{{.State.ExitCode}}' <容器> |
| 是不是 OOM | docker inspect -f '{{.State.OOMKilled}}' <容器> |
| 看资源占用 | docker stats --no-stream |
| 拷文件出来 | docker cp <容器>:<路径> <本地路径> |
| 起/停全部服务 | docker compose up -d / docker compose down |
| 清磁盘 | docker system prune -f(别加 -a --volumes) |
这张表用
v-pre包住:里面有 Docker 自己的模板变量(形如{{.State.xxx}}), 不包的话会被 Vue 当成插值表达式,构建直接报错。