Docker 命令速查
按排障顺序分组的 Docker 和 Compose 命令表。从「服务好像挂了」一路往下翻就能走完全程,会删数据的操作都单独标了风险。
显示 84 / 84 条命令
容器出问题按这个顺序查
同一个故障有好几种查法,按下面八步走能最快定位到原因,每一步都给出为什么这么查。
| 步骤 | 要确认什么 | 命令 | 为什么这么查 | 复制 |
|---|---|---|---|---|
| 1 | 容器还在吗 | docker ps -a | 先确认是退出了还是重启循环,状态栏和退出码信息量最大 | |
| 2 | 它为什么退出 | docker inspect -f "{{.State.ExitCode}} {{.State.Error}}" 容器名 | 退出码 137 通常是被 OOM 杀掉,1 一般是应用自身报错 | |
| 3 | 日志里写了什么 | docker logs --tail 100 --since 30m 容器名 | 加上时间范围能跳过启动时的正常输出,直接看崩溃前一段 | |
| 4 | 进容器看看 | docker exec -it -u root 容器名 sh | 查配置文件、DNS 解析、磁盘空间,很多问题在里面一眼就能看出来 | |
| 5 | 端口通不通 | docker port 容器名 && ss -tulnp | grep 端口 | 确认映射存在且宿主机确实在监听,常见坑是只绑了 127.0.0.1 | |
| 6 | 资源够不够 | docker stats --no-stream 容器名 | 内存贴着上限就说明该调 --memory 或查内存泄漏了 | |
| 7 | 网络能不能互通 | docker network inspect 网络名 | 容器必须接在同一个自定义网络上才能用服务名互访 | |
| 8 | 磁盘满了没 | docker system df -v | 磁盘写满会让守护进程行为异常,先看清是镜像、日志还是卷占了空间 |
分类说明
| 分类 | 条数 | 包含什么 |
|---|---|---|
| 运行容器 | 12 | 新建、启动、停止、重启和删除容器 |
| 查看与排障 | 10 | 看状态、看日志、看资源占用、进容器里查 |
| 镜像管理 | 10 | 拉取、构建、打标签、查看和清理镜像 |
| 文件与网络传入传出 | 4 | 在宿主机和容器之间拷文件,以及端口与网络映射 |
| 数据卷与挂载 | 8 | 持久化数据、备份卷、清理无用卷 |
| 网络 | 7 | 自定义网络、容器互访、DNS 与服务名解析 |
| Compose 编排 | 11 | 多容器一键起停、查看状态和日志 |
| 构建与镜像仓库 | 7 | Dockerfile 构建、多阶段构建、推拉到仓库 |
| 清理与磁盘 | 7 | 释放空间、清理悬空对象和构建缓存 |
| 系统与上下文 | 8 | 守护进程信息、远程上下文、资源限制 |
命令清单
| 命令 | 作用 | 常用参数 | 示例 | 复制 |
|---|---|---|---|---|
| docker run | 创建并启动一个新容器 | -d 后台运行,-it 交互式终端,--name 起名字,-p 端口映射,-v 挂载卷,-e 环境变量,--restart 重启策略,--rm 退出后自动删除 | docker run -d --name web -p 8080:80 -e TZ=Asia/Shanghai nginx:alpine | |
| docker run --rm | 跑一次性的命令,退出后容器自动删除 | 配 -it 进交互式 shell,配 -v 临时挂目录,适合跑迁移脚本和调试工具 | docker run --rm -it -v "$PWD":/work -w /work node:20 npm ci | |
| docker run --restart | 设置容器退出后的自动重启策略 | no 不重启,always 总是重启,unless-stopped 除非手动停过,on-failure:5 失败时重试 5 次 | docker run -d --restart unless-stopped redis:7-alpine | |
| docker start | 启动已存在的容器 | -a 启动并附加输出,-i 附加标准输入,可一次接多个容器名 | docker start -ai web | |
| docker stop | 优雅停止容器,先发 SIGTERM 再等超时 | -t 等待秒数(默认 10),超时后发 SIGKILL | docker stop -t 30 web | |
| docker restart | 重启容器 | -t 停止前等待秒数,适合改了配置后重载 | docker restart -t 20 web | |
| docker kill | 直接给容器发信号,不给优雅退出的机会 注意:kill 不会等进程收尾,正在写的文件可能半截。优先用 stop;只有当 stop 超时无效时才用 kill。 | -s 指定信号(默认 SIGKILL),常用 HUP 让进程重载配置 | docker kill -s HUP web | |
| docker rm | 删除已停止的容器 注意:rm -f 会直接干掉运行中的容器,服务立刻中断。加 -v 还会删掉匿名卷里的数据,删前先确认数据是否已挂到命名卷或宿主机目录上。 | -f 连运行中的一起强删,-v 同时删掉它的匿名卷,一次可删多个 | docker rm -v web-old | |
| docker rename | 给容器改名 | 两个参数:旧名字 新名字,容器不用停 | docker rename web web-old | |
| docker pause / unpause | 暂停和恢复容器里的所有进程 | pause 用 cgroup freezer 冻结,unpause 恢复;暂停期间端口仍占用 | docker pause web | |
| docker wait | 阻塞等待容器退出并打印退出码 | 接容器名,常用于脚本里等一次性任务结束 | docker wait build-task | |
| docker update | 修改运行中容器的资源限制 | --memory 内存上限,--cpus CPU 配额,--restart 改重启策略,--pids-limit 进程数上限 | docker update --memory 512m --cpus 1.5 web | |
| docker ps | 列出容器 | -a 含已停止的,-s 显示占用大小,--format 自定义输出,-f 按条件过滤,-q 只输出 ID | docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | |
| docker logs | 查看容器日志 | -f 持续跟踪,--tail 只看最后 n 行,-t 加时间戳,--since 指定起始时间,--until 指定结束时间 | docker logs -f --tail 100 --since 30m web | |
| docker inspect | 查看容器或镜像的完整 JSON 详情 | -f 用 Go 模板取字段,--type 指定对象类型,能查到 IP、挂载、环境变量、退出码 | docker inspect -f '{{.State.ExitCode}} {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web | |
| docker stats | 实时查看容器的 CPU、内存、网络和磁盘 IO | --no-stream 只输出一次,--format 自定义列,-a 含已停止容器(显示为 0) | docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}" | |
| docker exec | 在运行中的容器里执行命令 | -it 交互式终端,-u 指定用户,-w 指定工作目录,-e 传环境变量,能开多个互不干扰的会话 | docker exec -it -u root web sh | |
| docker attach | 附加到容器的主进程标准输入输出 | --sig-proxy 转发信号(默认开),退出快捷键是 Ctrl-P Ctrl-Q 而不是 Ctrl-C | docker attach web | |
| docker top | 查看容器里运行的进程 | 接容器名和可选的 ps 参数,输出的是宿主机视角的 PID | docker top web -o pid,etime,cmd | |
| docker diff | 查看容器相对镜像改了哪些文件 | A 新增,C 修改,D 删除;只对容器可写层有效,挂载卷的内容不算 | docker diff web | |
| docker events | 实时监听 Docker 产生的事件流 | --filter 按类型或容器过滤,--since/--until 限定时间,--format 自定义输出 | docker events --filter type=container --filter event=die | |
| docker commit | 把容器的当前状态保存成新镜像 | -m 提交说明,-a 作者,-c 附加 Dockerfile 指令(如改 ENTRYPOINT) | docker commit -m "手工装了调试工具" web web:debug | |
| docker images | 列出本地镜像 | -a 含中间层镜像,-f 过滤(dangling=true 找无标签镜像),--format 自定义,-q 只输出 ID | docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" | |
| docker pull | 从仓库拉取镜像 | --platform 指定架构(如 linux/amd64),-a 拉全部标签,--quiet 减少输出 | docker pull --platform linux/amd64 mysql:8.0 | |
| docker tag | 给镜像打上新的名字和标签 | 源镜像 目标镜像:标签;标签省略时默认 latest,一个镜像可以有多个标签 | docker tag app:latest registry.example.com/team/app:1.4.0 | |
| docker rmi | 删除本地镜像 注意:被容器引用的镜像无法直接删除,-f 会先断开引用关系。更常见的坑是误删了还在用的基础镜像,导致下次构建要重新下载。 | -f 强制删除,-a 配合筛选删多个,--no-prune 保留被删镜像的父层 | docker rmi -f $(docker images -q -f dangling=true) | |
| docker history | 查看镜像的分层构建历史 | --no-trunc 显示完整命令,-H 人类可读大小,能看到每层占多大 | docker history --no-trunc --human app:latest | |
| docker save | 把镜像导出成 tar 文件,便于离线传输 | -o 输出文件,可一次导出多个镜像 | docker save -o app-1.4.0.tar app:1.4.0 | |
| docker load | 从 tar 文件导入镜像 | -i 指定输入文件,-q 安静模式;镜像名和标签随包一起恢复 | docker load -i app-1.4.0.tar | |
| docker tag && push | 打标签后推送到镜像仓库 | 仓库地址/命名空间/镜像名:标签 的命名规则;先 docker login 登录 | docker push registry.example.com/team/app:1.4.0 | |
| docker login | 登录镜像仓库 | -u 用户名,-p 密码(不安全,建议用 stdin),--password-stdin 从标准输入读密码 | echo "$CR_PAT" | docker login ghcr.io -u 用户名 --password-stdin | |
| docker image prune | 清理无标签的悬空镜像 | -a 连没被容器使用的镜像一起清,-f 不询问,--filter until=24h 保留近一天的 | docker image prune -f --filter until=72h | |
| docker cp | 宿主机与容器互拷文件 | 用法是 容器名:路径 或 宿主机路径,两个方向都支持,容器停止也能拷 | docker cp ./dist/. web:/usr/share/nginx/html/ | |
| docker port | 查看端口映射到了宿主机的哪个端口 | 不接端口则列出该容器全部映射,输出形如 0.0.0.0:8080 | docker port web | |
| docker exec 取文件 | 容器里没有工具时,用 tar 流把目录整体取出来 | tar -cf - 打包到标准输出,管道到宿主机的 tar -xf - 解开,省去先拷再解的步骤 | docker exec web tar -cf - -C /var/log nginx | tar -xf - -C ./logs | |
| docker run -p | 把宿主机端口映射到容器端口 | 宿主机端口:容器端口,127.0.0.1:8080:80 只监听本机,-P 随机分配,--publish-all 全部映射 | docker run -d -p 127.0.0.1:8080:80 nginx:alpine | |
| docker volume create | 创建一个命名卷 | -d 指定卷驱动,--label 加标签,--opt 传驱动参数 | docker volume create --label env=prod pgdata | |
| docker volume ls | 列出所有卷 | -f 过滤(dangling=true 找没被使用的),--format 自定义输出,-q 只输出名字 | docker volume ls -f dangling=true | |
| docker volume inspect | 查看卷的详细信息,包括在宿主机的实际路径 | Mountpoint 字段就是宿主机上的真实目录,可直接进去备份 | docker volume inspect -f '{{.Mountpoint}}' pgdata | |
| docker volume rm | 删除指定卷 注意:删卷等于删数据,数据库的卷删掉就真的没了,且不进回收站。删前务必确认已完成备份,或先把它挂到临时容器里导出。 | 卷被容器占用时无法删除,要先停并删掉容器 | docker volume rm pgdata | |
| docker volume prune | 清理没有被任何容器使用的卷 注意:加 -a 之后,命名卷也会被清掉,而命名卷里往往就是数据库和上传文件。执行前先 docker volume ls 看一眼会删什么。 | -a 清所有未被使用的(含命名卷,默认只清匿名卷),-f 不询问,--filter 按标签筛 | docker volume prune -f | |
| docker run -v 命名卷 | 把命名卷挂进容器,数据在容器删除后仍保留 | 卷名:容器内路径,可加 :ro 只读;命名卷比匿名卷更可控,推荐显式命名 | docker run -d -v pgdata:/var/lib/postgresql/data postgres:16 | |
| docker run -v 绑定目录 | 把宿主机目录直接挂进容器 | $PWD 或绝对路径:容器内路径,加 :ro 只读、:z 处理 SELinux;适合开发改代码即时生效 | docker run --rm -v "$PWD/src":/app/src:ro node:20 npm test | |
| docker run --mount | 更明确的挂载写法,可指定只读和卷选项 | type=bind/volume/tmpfs,source 源,target 目标,readonly 只读,bind-propagation 传播模式 | docker run --mount type=bind,source="$PWD",target=/work,readonly node:20 npm ci | |
| docker network create | 创建自定义网络,容器之间可用名字互相访问 | -d 驱动(bridge/overlay/macvlan),--subnet 子网,--gateway 网关,--internal 禁止外部访问 | docker network create --subnet 172.28.0.0/16 app-net | |
| docker network ls | 列出所有网络 | -f 过滤,--format 自定义输出,-q 只输出 ID | docker network ls --format "table {{.Name}}\t{{.Driver}}\t{{.Scope}}" | |
| docker network connect | 把运行中的容器接到另一个网络 | 网络名 容器名,可加 --alias 设访问别名,--ip 指定静态 IP | docker network connect --alias db app-net postgres-1 | |
| docker network disconnect | 把容器从网络里断开 | -f 强制断开,即使容器还在用这个网络 | docker network disconnect -f app-net postgres-1 | |
| docker network inspect | 查看网络详情和接入的容器 | -f 用模板取字段,能看到每个容器的 IP、MAC 和别名 | docker network inspect -f '{{range .Containers}}{{.Name}} {{.IPv4Address}}{{"\n"}}{{end}}' app-net | |
| docker network prune | 清理没有被使用的自定义网络 | -f 不询问,--filter until=24h 只清一天前创建的 | docker network prune -f | |
| docker network rm | 删除指定网络 | 一次可删多个,仍有容器接入时会失败,要先断开 | docker network rm app-net-old | |
| docker compose up | 按 compose 文件创建并启动所有服务 | -d 后台,--build 启动前重新构建,--force-recreate 强制重建容器,--remove-orphans 清理文件里已删掉的服务 | docker compose up -d --build --remove-orphans | |
| docker compose down | 停止并删除容器与网络 注意:加 -v 会把 compose 里定义的命名卷一起删掉,数据库数据随之消失。只想停服务就别带这个参数。 | -v 连命名卷一起删,--rmi local 连本地镜像一起删,--remove-orphans 清理多余容器,-t 停止超时 | docker compose down --remove-orphans | |
| docker compose ps | 查看 compose 项目的容器状态 | -a 含已停止,-q 只输出 ID,--format 自定义输出,--services 只列服务名 | docker compose ps -a | |
| docker compose logs | 查看多个服务的日志 | -f 跟踪,--tail 只看末尾,-t 时间戳,服务名可只指定某一个,--no-log-prefix 去掉服务名前缀 | docker compose logs -f --tail 80 api worker | |
| docker compose exec | 在 compose 的某个服务里执行命令 | 服务名 命令,-u 指定用户,-T 不分配终端(脚本里用),-w 指定工作目录 | docker compose exec -T api npm run migrate | |
| docker compose run | 起一个一次性的服务实例跑命令 | --rm 跑完删除,--no-deps 不启动依赖服务,-e 传环境变量,-v 临时挂目录,适合跑脚本和测试 | docker compose run --rm api npm run seed | |
| docker compose build | 构建 compose 里定义的所有镜像 | --no-cache 不用缓存,--pull 先拉新版基础镜像,--parallel 并行构建,接服务名可只构建一个 | docker compose build --pull --no-cache api | |
| docker compose restart | 重启服务,不重建容器 | 接服务名可只重启一个,-t 停止超时;改了 compose 文件要用 up -d 而不是 restart | docker compose restart -t 20 api | |
| docker compose config | 校验并打印合并后的完整配置 | --services 只列服务名,--volumes 只列卷,--profiles 列出所有 profile,用来确认变量替换结果 | docker compose config --services | |
| docker compose pull | 拉取 compose 里用到的所有镜像 | --ignore-pull-failures 拉失败也继续,--include-deps 连依赖一起拉,--policy 指定拉取策略 | docker compose pull --ignore-pull-failures | |
| docker compose cp | 在宿主机和 compose 服务之间拷文件 | 写法是 服务名:路径 与宿主机路径,两个方向都支持 | docker compose cp api:/app/logs/app.log ./app.log | |
| docker build | 按 Dockerfile 构建镜像 | -t 打标签(可多次),-f 指定 Dockerfile 路径,--build-arg 传构建参数,--target 只构建到某个阶段,--no-cache 不用缓存 | docker build -t app:1.4.0 -f docker/Dockerfile --build-arg NODE_ENV=production . | |
| docker build --platform | 构建指定架构的镜像,或在多架构机器上交叉构建 | --platform linux/amd64 或 linux/arm64,常配 buildx 使用 | docker buildx build --platform linux/amd64,linux/arm64 -t app:1.4.0 --push . | |
| docker buildx build | 用 BuildKit 构建,支持多架构和更好的缓存 | --platform 多架构,--push 构建完直接推,--cache-from/--cache-to 复用远程缓存,--load 载入本地 | docker buildx build --platform linux/amd64 --cache-from type=registry,ref=app:cache --cache-to type=registry,ref=app:cache --push -t app:1.4.0 . | |
| docker buildx bake | 按一份声明文件同时构建多个目标 | -f 指定文件(默认 docker-bake.hcl 或 compose 文件),--set 覆盖变量,--print 只看解析结果 | docker buildx bake -f docker-bake.hcl --print | |
| docker build --target | 多阶段构建里只构建到某个阶段 | 常用于单独构建依赖阶段以复用缓存,或产出调试用镜像 | docker build --target builder -t app:builder . | |
| docker buildx prune | 清理构建缓存 | -f 不询问,--filter until=168h 保留近一周的,--all 全部清理,--keep-storage 保留指定空间 | docker buildx prune -f --filter until=168h | |
| docker manifest | 查看和创建多架构镜像清单 | inspect 查看清单(--verbose 看架构详情),create 创建,annotate 加注解,push 推送 | docker manifest inspect --verbose mysql:8.0 | |
| docker system df | 查看镜像、容器、卷和构建缓存各占多少空间 | -v 列出每一项的明细,先看这个再决定清什么,避免误删 | docker system df -v | |
| docker system prune | 清理已停止容器、无标签镜像、无用网络和构建缓存 注意:默认就会删掉所有已停止的容器和构建缓存。加 -a 会删掉所有没被使用的镜像(下次要重新拉取),加 --volumes 还会删匿名卷。执行前先用 system df -v 看清楚。 | -a 连没被使用的镜像一起清,--volumes 连匿名卷一起清,--filter 按时间筛,-f 不询问 | docker system prune -f --filter until=168h | |
| docker container prune | 只清理已停止的容器 | -f 不询问,--filter until=24h 保留近一天停止的 | docker container prune -f --filter until=72h | |
| docker rm $(docker ps -aq) | 批量删除所有已停止容器 | docker ps -aq 列出全部容器 ID,-f status=exited 可只取已退出的 | docker rm $(docker ps -aq -f status=exited) | |
| docker image prune -a | 清理所有没被容器使用的镜像 注意:所有没被运行中容器使用的镜像都会被删,包括你刚构建好准备部署的那个。清之前先确认当前没有待发布的镜像。 | -f 不询问,--filter until=240h 保留近十天,--filter dangling=false 含带标签的镜像 | docker image prune -a -f --filter until=240h | |
| docker builder prune | 只清理构建缓存 | --all 全部清理,--filter until=24h 按时间保留,--keep-storage 保留指定空间 | docker builder prune -f --keep-storage 5GB | |
| docker system events | 监听系统级事件,排查容器反复重启很有用 | --filter 过滤事件类型,--since 指定起点,配 --format 输出时间与动作 | docker system events --filter event=restart | |
| docker version | 查看客户端与服务端版本 | --format 自定义输出,能同时看到 API 版本和是否连着守护进程 | docker version --format "{{.Server.Version}}" | |
| docker info | 查看守护进程的详细状态 | --format 只取字段,能看到存储驱动、根目录、运行中容器数、总内存和镜像数 | docker info --format '{{.Driver}} {{.DockerRootDir}}' | |
| docker context | 管理连接目标,在本地和远程主机之间切换 | ls 列出,create 新建,use 切换,inspect 查看,rm 删除;适合在本地操作远程 Docker | docker context use remote-prod | |
| docker context create | 新建一个指向远程 Docker 的上下文 | --docker host=ssh://... 用 SSH 连接,创建时 Docker 会复用本机 ~/.ssh/config | docker context create remote-prod --docker host=ssh://deploy@10.0.0.8 | |
| docker run --memory | 限制容器可用的内存,避免拖垮宿主机 | --memory 上限(如 512m),--memory-swap 含交换区上限,--oom-kill-disable 禁止被 OOM 杀掉 | docker run -d --memory 512m --memory-swap 512m --cpus 1 api:1.4.0 | |
| docker run --cpus | 限制容器可用的 CPU 核数 | --cpus 1.5 表示最多用 1.5 个核,--cpuset-cpus 绑定到具体核心(如 0,1) | docker run -d --cpus 2 --cpuset-cpus 0,1 worker:1.4.0 | |
| docker run --health-cmd | 给容器配置健康检查 | --health-cmd 检查命令,--health-interval 间隔,--health-retries 重试次数,--health-timeout 超时 | docker run -d --health-cmd "curl -fsS localhost/health || exit 1" --health-interval 30s --health-retries 3 web | |
| docker daemon.json | 守护进程配置,常用项包括日志轮转和镜像加速 | log-driver 与 log-opts 限制日志大小,registry-mirrors 配镜像源,data-root 换存储目录,default-address-pools 改容器网段 | sudo systemctl restart docker # 改完 /etc/docker/daemon.json 后重启生效 |
docker compose 和 docker-compose 的区别
Compose V2 把命令做成了 Docker CLI 的插件,写法是 docker compose(中间是空格);V1 是一个独立的 Python 程序,写法是 docker-compose(中间是连字符)。V1 从 2023 年起已经停止维护,新装的 Docker 只带 V2。两者配置文件基本兼容,但 version: 字段在 V2 里已经废弃,留着只会打印警告,可以直接删掉。
行为上有一处需要留神:V1 的 up 在配置没变时会复用现有容器,V2 对「配置变更」的判定更严格,有时会重建你不想重建的容器。想在改代码后强制走一遍干净流程,用 docker compose up -d --force-recreate 明确表达意图,比猜它会不会重建更省事。
为什么容器里访问不到其他容器
默认的 bridge 网络只提供 IP 互联,容器名不会被解析成 IP,所以 ping db 必然失败。要按服务名互访,必须自己 docker network create 建一个自定义网络,再把相关容器接进去——Docker 会为自定义网络内置 DNS。Compose 会自动建这样一个网络,所以 compose 里写服务名一直能通,这也解释了为什么单跑 docker run 时就突然不通了。
另一个常见现象是「宿主机的 localhost 连不上容器端口」。容器里的 localhost 指容器自己,宿主机上的 localhost 指宿主机;两者要靠 -p 映射打通。还有一类是映射写成了 127.0.0.1:8080:80,这只监听本机回环,外部访问不到——想对外提供服务要写 0.0.0.0:8080:80 或者干脆省略前面的地址。
8 条会删东西的命令
表里标了「注意」的 8 条里,真正不可逆的集中在卷和容器删除上。容器是可抛弃的,删了重建就行;卷不是,卷里装的是数据库文件和用户上传内容。docker compose down -v 和 docker volume prune -a 是两条最容易被顺手敲下去的删数据命令,前者常被当成「重来一遍」,后者常被当成「清一下磁盘」。
养成一个习惯就能避开绝大多数事故:执行任何 prune 或 down -v 之前,先跑 docker system df -v 和 docker volume ls 看一眼具体会删掉什么。另外,清理前最好把它挂到临时容器里导出一次,命令是 docker run --rm -v 卷名:/data -v "$PWD":/backup alpine tar czf /backup/卷名.tgz -C /data .,导完再删心里就有底了。
这份表的适用边界
命令以 Docker Engine 24 以后、Compose V2 为准。docker buildx bake 和 --cache-from type=registry 这类写法需要 BuildKit(现在默认开启,但老版本或某些发行版的包可能仍是旧构建器,用 docker buildx version 确认)。docker context 走 SSH 远程操作宿主机时,目标机器上的 Docker 版本不能太旧,否则部分子命令会缺失。
Compose 的部分同样以官方 Compose Specification 为准。老教程里常见的 docker-compose -f 文件 -p 项目名 参数在 V2 里改成了全局选项,位置必须在子命令之前写成 docker compose -f 文件 -p 项目名 ps,顺序写反会直接报错。