Skip to content

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 -itdocker attach
原理在容器里新建一个进程附着到**主进程(PID 1)**的 stdin/stdout
退出后容器继续运行主进程收到信号,容器可能跟着退出
脱离方式exitCtrl+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.0

3. 精简镜像里没有 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}}' <容器>
是不是 OOMdocker 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 当成插值表达式,构建直接报错。

用 VitePress 构建