Docker 命令学了忘、忘了学这是绕不过去的坎。镜像、容器、网络、存储、编排指令上百条真正高频用到的其实就那么几十条难的是搞懂每条命令背后对应着 Docker 的哪个环节以及出了问题该怎么反推。这篇文章不谈虚的直接从入门到生产环境把 Docker 的核心指令按场景拆开讲透每个命令都配上实际用法、参数含义和踩坑经验。无论你是刚接触容器化的小白还是已经在生产环境摸爬滚打了几年的运维和开发这里面都有可以直接拿去用的东西。我的做法是先给你建立一张“命令-对象-场景”的对应地图再逐类拆解镜像、容器、网络、数据卷、Compose 编排等核心指令最后附上生产环境问题排查的经验速查表。这样你拿到任意一条命令都能快速判断它属于哪一类、用在什么阶段、报错了该怎么查。1. 先把 Docker 的核心对象搞明白命令才有落点很多人在 Docker 命令上栽跟头不是记不住是没搞清楚命令操作的对象之间是什么关系。Docker 的整套体系其实就围绕着三个核心对象转镜像、容器、仓库。可以类比成编程里的“类、实例、代码仓库”镜像就是只读的模板容器是镜像运行后产生的可写实例仓库则是存放和分发镜像的地方。1.1 镜像、容器、仓库之间的运行链路镜像是一个不可变的静态文件包打包了应用代码、运行时、依赖库和环境变量容器是镜像的运行时实例有自己独立的文件系统、网络栈和进程空间。你执行docker run时Docker 引擎会基于指定镜像创建一个新的容器层在上面启动进程。之后对容器的修改都发生在可写容器层不会改动底层的镜像。还有一点容易被忽略docker commit可以把当前容器的状态保存为一个新镜像。这在排障时很有用比如某个容器是用旧镜像起的你临时在终端里改了配置文件想把带有修改的环境固化下来就可以先 commit 再重新打 tag。不过要记住commit 生成的是黑盒镜像不透明也无法重复构建生产环境不推荐依赖这种方式镜像的生成应该走 Dockerfile 构建流程。1.2 客户端、守护进程与仓库的关系Docker 采用经典的 C/S 架构docker命令只是客户端真正干活的是一台机器上常驻的 Docker daemon。客户端把指令发到守护进程守护进程负责拉取镜像、创建容器、管理网络等。日常说的“启动 docker”本质就是拉起这个守护进程。有一个很常见的本地报错Failed to connect to the Docker API at npipe:////./pipe/docker-desktop-linux或者在 Linux 上执行 docker 命令提示权限不足。前者通常是 Docker Desktop 的 Linux 子系统没起来Windows 上重新启动 Docker Desktop 即可后者多半是当前用户不在 docker 用户组里执行sudo usermod -aG docker $USER然后重新登录就能解决。1.3 用 docker 命令之前先搞清楚版本信息无论你处于哪个阶段建议先养成查环境信息的习惯docker version docker infodocker version会分别显示客户端和守护进程的版本如果守护进程没启动这里会直接报连接错误。docker info输出 CPU、内存、存储驱动、镜像数量、运行中容器数量等关键信息。生产环境遇到异常这两条命令是我必开场的操作先把环境底数摸清再往下查。提示如果你用的是 Docker Desktop历史版本中“设置”里的资源分配CPU/内存直接影响容器运行表现容器莫名变慢先去看资源是否被打满。2. 安装启动与守护进程管理命令没反应多半卡在这一环Docker 的安装分两大流派一是 Docker Desktop适合 Mac 和 Windows 桌面端自带图形界面和 Linux 虚拟机内核二是 Docker Engine纯命令行适合 Linux 服务器。网上一搜“docker 安装教程”会有大量内容我把两个场景的关键差异和启动管理的核心命令讲清楚。2.1 Linux 上安装 Docker Engine 的关键步骤Debian/Ubuntu 系推荐走 apt 官方源安装sudo apt update sudo apt install ca-certificates curl gnupg sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg echo deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release echo $VERSION_CODENAME) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null sudo apt update sudo apt install docker-ce docker-ce-cli containerd.ioCentOS/RHEL 系则是使用 yum 配置仓库后安装 docker-ce。安装完成后的第一件事不是迫不及待跑 hello-world而是把守护进程设置成开机自启并立即启动sudo systemctl enable docker sudo systemctl start docker systemctl status docker命令的排查重点在systemctl status docker这里能直接看到 daemon 是 active (running) 还是 failed。如果是 failed用journalctl -u docker -n 50 --no-pager查看最近日志比反复重启更有效。2.2 启动 Docker 失败时的排查路径Windows 上启动 Docker Desktop 失败常见原因包括未开启 BIOS 虚拟化、WSL2 未安装、Hyper-V 功能未启用。报错里的 “Virtualization support not detected” 就是典型特征。解决路径是进入 BIOS 开启 Intel VT-x 或 AMD-V然后在 Windows 功能里启用“适用于 Linux 的 Windows 子系统”和“虚拟机平台”再安装 WSL2 内核更新包。Linux 上启动失败的原因则更集中在存储驱动、iptables 配置冲突、容器运行时异常这几个方向。如果之前装过别的容器运行时注意/var/run/docker.sock是否被占用daemon 无法绑定 socket 时也会启动失败。2.3 日常守护进程管理命令清单sudo systemctl start docker # 启动 sudo systemctl stop docker # 停止 sudo systemctl restart docker # 重启 systemctl is-active docker # 检查激活状态输出 active 或 inactive sudo dockerd --debug # 前台以 debug 模式启动看完整日志生产环境改 daemon 配置比如改镜像加速器、配置日志轮转之后必须执行sudo systemctl daemon-reload再restart docker否则配置不生效。我因为这个吃过亏改完daemon.json没 reload排查了大半天数据卷权限问题最后发现是配置压根没加载。3. 镜像相关指令拉取、构建、存储、分发一站讲完镜像相关的命令使用频率极高也是构建和发布流程的基石。这块的核心逻辑就一句话Docker 通过“仓库-标签(Repository:Tag)”唯一定位一个镜像默认 Tag 是 latest但生产环境强烈建议显式指定版本号。3.1 拉取与查看pull、images、inspectdocker pull nginx:1.25-alpine docker images docker inspect nginx:1.25-alpinedocker pull从镜像仓库拉取镜像到本地。为什么推荐使用 alpine 版本镜像体积小是一个原因更关键的是减少了攻击面生产基础镜像用 Alpine/Linux 或 distroless 版本能让镜像从几百兆瘦身到几十兆。docker images等价docker image ls列出本地所有镜像重点看 REPOSITORY、TAG、IMAGE ID、SIZE 四列。有个字段容易让人迷惑两个不同名字的镜像可能共用一个 IMAGE ID因为它们是同一镜像的不同 tag。docker inspect输出的是镜像或容器的底层 JSON 元数据包含环境变量、挂载点、网络配置、架构信息等。排查问题时要学会从这里挖信息比如容器里某个服务默认端口是多少docker inspect比翻 Dockerfile 更快。3.2 删除与清理rmi、prunedocker rmi nginx:1.25-alpine docker image prune -f docker system prune -a --volumesdocker rmi删除镜像。如果镜像被某个容器引用会报image is being used by stopped container这时候得先删除引用它的容器或者用-f强制删除。docker system prune是清理神器和“翻车神器”的二合一。加上-a会删除所有未被容器使用的镜像加上--volumes会顺带把匿名卷也清掉。如果你有容器挂载了匿名卷且没有备份这条命令会把数据一并删掉。我的习惯是磁盘空间告急时先用docker system df看哪类对象占空间再决定要不要执行 prune绝对不会无脑加-a --volumes。3.3 构建镜像build、Dockerfile 关键指令docker build -t myapp:1.0.0 .构建的核心是 Dockerfile其中ENTRYPOINT和CMD是两个最容易混淆的指令。简单记忆CMD 提供的参数容易被docker run后面的命令覆盖ENTRYPOINT 则固定了容器的主进程docker run时传的参数会作为参数追加到 ENTRYPOINT 后面。生产中通常把 ENTRYPOINT 设为固定主程序CMD 给默认参数这样在docker run app --configprod.yaml时可以方便地“换参数不换程序”。构建时还有一个高频需求是多阶段构建适用场景是需要在完整编译环境里构建产物但最终运行镜像只需要产物文件。典型的多阶段 Dockerfile 结构是前半段用FROM golang:1.22 AS builder编译 Go 程序第二部分FROM alpine只拷贝编译出的二进制最终镜像体积只有十几兆。这个思路能解决“microservices 镜像越建越肥”的问题。3.4 本地镜像导出与分发save、load、pushdocker save -o mysql_8.0.tar mysql:8.0 docker load -i mysql_8.0.tar docker tag mysql:8.0 registry.example.com/library/mysql:8.0 docker push registry.example.com/library/mysql:8.0save/load主要用于离线环境比如内网机器拉不了外网仓库便携式导出再导入。这里有一个细节如果用docker save导出的是多层压缩包docker load导入后镜像名和 tag 都保留。docker push前一定要先docker login登录到目标仓库而且镜像名必须带仓库地址前缀否则 push 到官方仓库会因命名规则报错。4. 容器生命周期指令从创建、运行到删除的全流程容器的操作命令是整个 Docker 使用体验的核心也是日常出镜率最高的部分。理解容器生命周期是理解这一节的关键created → running → paused → stopped → deleted。4.1 run创建并启动容器的完整参数体系docker run -d \ --name web \ -p 8080:80 \ -e TZAsia/Shanghai \ -v /data/web/html:/usr/share/nginx/html \ --restart always \ nginx:1.25-alpine参数逐个说-d后台运行模式容器在后台跑终端不占用。--name给容器命名不写则 Docker 随机生成名字。-p端口映射映射宿主机 8080 端口到容器 80 端口。容器网络默认 NAT 模式容器自身 IP 不直接对宿主机暴露。-e设置环境变量很多镜像把时区、数据库连接串、密码等敏感配置都通过环境变量注入。-v数据卷挂载把宿主机目录挂到容器内容器写的数据落盘到宿主机。--restart always容器退出或被守护进程重启后自动拉起生产必带这个参数。docker run还有个容易被忽略的--rm参数适合临时测试场景容器退出时自动删除文件系统层不给宿主机留垃圾。如果同时用了--restart always和--rm两者语义冲突后者不会生效所以不要同时加。4.2 查看容器状态ps、top、statsdocker ps docker ps -a docker top web docker statsdocker ps只显示运行中的容器docker ps -a把已停止的也列出来。排障的第一步一定是看容器状态确认 Exited 的容器退出码是多少。STATUS列里的 “Exited (0)” 表示正常退出“Exited (137)” 通常意味着被 SIGKILL 杀掉原因可能是 OOM也可能是有人执行了 kill。docker stats是生产环境定位资源问题的利器实时显示每个容器的 CPU、内存、网络 IO 和磁盘 IO 占用。容器突然变慢或者宿主机资源被打满先跑docker stats看哪个容器是元凶比登进容器猜快得多。4.3 进入容器与执行命令exec、attach、logsdocker exec -it web /bin/sh docker attach web docker logs -f webexec是在运行中的容器里执行新命令-it是交互模式 分配伪终端的组合适合进容器调试。Alpine 镜像没有 bash用/bin/shUbuntu 基础镜像可以/bin/bash。默认情况下docker exec执行命令时执行的 PID 命名空间是容器自己的所以你在容器里ps -ef只能看到容器内的进程看不到宿主机的这是正常现象。attach连接到容器的主进程终端。这里有个非常典型的坑如果容器主进程是命令行交互式程序你attach进去后按了 CtrlC信号会直接发给主进程容器可能直接退出。实际操作中我基本只用 attach 来连接那些输出到 stdout 的应用比如调试一个正在前台运行的 Java 服务普通排障一律用exec。docker logs -f web实时跟踪容器日志。这里的核心经验是生产环境不要依赖docker logs的默认 JSON 文件存储因为 JSON 文件不轮转迟早写满磁盘。建议在 daemon 配置里加上日志轮转参数{ log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 } }这里加一个通俗的类比如果你靠“掏出手机和钥匙就能进家门”来理解 attach 和 exec那两者的区别就是 attach 是“直接接上了正在运行的窗口”exec 则是“另开一个窗户往里面递东西”。绝大多数调试场景应该选择后者。4.4 停止、重启、删除stop、restart、rm、killdocker stop web docker restart web docker kill web docker rm web docker container prunestop发送 SIGTERM 让容器里的主进程优雅退出等待超时默认 10 秒后若未退出再发 SIGKILL。kill是直接 SIGKILL非必要不用可能导致数据未落盘。rm删除已停止的容器正在运行的需要先 stop 或加-f强制删除。一个重要细节删除容器不等于删除数据卷。docker rm web只会删除容器的可写层挂在宿主机目录或命名数据卷里的数据还在。如果你确实需要连带数据卷一起删要么手动docker volume rm要么容器创建时就用匿名卷然后在删除时加-v参数。删除容器前先确认哪些目录是数据卷挂载的别把未来可能要用到的数据一并删了。4.5 文件复制cpdocker cp web:/etc/nginx/nginx.conf ./nginx.conf.bak docker cp ./app.conf web:/etc/nginx/conf.d/docker cp用于宿主机和容器之间拷贝文件。生产场景常见用法容器异常无法启动时用它把容器里的日志或配置文件拷出来分析或者临时修复时把宿主机上的配置塞进容器再重启。这里强调拷入文件后如果不 commit容器重启后修改就丢失了。正确的配置管理姿势应该是把配置放到宿主机挂载目录或走配置中心而不是靠docker cp手动塞。5. 网络与数据卷指令容器互通与持久化的地基容器网络和数据卷是最容易引发生产事故的两个环节。网络不通、数据丢了多半是前期设计时没落地好。5.1 容器网络模型与自定义网络Docker 默认提供几种网络驱动bridge默认单机容器互联、host容器直接复用宿主机网络栈、none无网络、overlay跨主机的 Swarm 网络以后在生产环境用到时再细说。默认情况下同一台宿主机上的容器可以通过服务名互访的前提是位于同一个自定义网络。而使用默认 bridge 网络的容器之间的互通要么通过 IP要么通过--link旧参数但这种方式不稳定容器重启 IP 会变。生产环境的推荐做法是创建自定义 bridge 网络docker network create app-net docker run -d --name app1 --network app-net ... docker run -d --name app2 --network app-net ...创建之后app1 容器内部直接 ping app2 或 curl app2:8080 就能通因为 Docker 内置 DNS 会解析自定义网络中的容器名。这正是服务发现的最朴素实现。5.2 端口映射与网络排查手段docker run -d -p 3306:3306 --name mysql mysql:8.0 docker port mysql-p 3306:3306把宿主机 3306 端口映射到容器的 3306业务通过宿主机 IP 访问。有个高频排查场景宿主机上ss -lntp能看到 3306 在监听但外部访问不通。原因通常有三类云安全组没放行、宿主机防火墙拦截、Docker 端口映射实际绑定在 127.0.0.1。后者的解法是显式写-p 0.0.0.0:3306:3306。排查网络不通的链路建议遵循这个顺序docker ps -a确认容器是否在运行docker logs 容器名看应用是否真的起来了docker exec -it 容器名 ping 目标IP看容器是否到目标机器通在宿主机上nc -vz 容器IP 端口看容器端口是否通检查docker network inspect 网络名看容器是否在预期的网络里5.3 数据卷与持久化volumes、bind mountsdocker volume create mysql-data docker run -d -v mysql-data:/var/lib/mysql --name mysql mysql:8.0 docker volume ls docker volume inspect mysql-data数据卷的核心目的是把容器内动态数据抽离出来保证容器删了重建数据还在。命名数据卷由 Docker 管理存放目录通常在/var/lib/docker/volumes/卷名/_data好处是不需要指定宿主机的具体路径也不受目录权限影响。bind mount 则是直接挂载宿主机目录比如-v /data/web/conf:/etc/nginx/conf.d:ro。末尾的:ro表示容器内只读这是生产环境建议加的防止容器内进程篡改宿主机的配置文件。数据卷和 bind mount 的选择逻辑应用数据用数据卷配置文件直接用 bind mount 挂载更直观改完宿主机文件重启容器即可生效。5.4 MySQL 8.0 与 Redis 主从的典型部署命令热搜里多次出现“docker 安装 mysql8.0 并使用”“docker 安装 redis 主从”这里把两者的高频命令模板给出来。MySQL 8.0docker run -d \ --name mysql8 \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORDMyStrongPass123 \ -e MYSQL_DATABASEappdb \ -v mysql-data:/var/lib/mysql \ --restart always \ mysql:8.0然后进入容器初始化用户docker exec -it mysql8 mysql -uroot -pMyStrongPass123建议在 MySQL 容器内创建独立的业务账号而不要长期用 root 账号连库。创建账号的命令是CREATE USER app% IDENTIFIED BY AppPass456; GRANT ALL PRIVILEGES ON appdb.* TO app%; FLUSH PRIVILEGES;Redis 主从docker run -d --name redis-master -p 6379:6379 redis:7-alpine docker run -d --name redis-slave -p 6380:6379 \ --link redis-master \ redis:7-alpine \ redis-server --replicaof redis-master 6379需要注意新版本 Redis 已经用--replicaof替代了旧版的--slaveof。而且--link是已被标记为 legacy 的用法更推荐的连接方式是把两个容器都加入自定义网络然后通过服务名访问。这里只是演示基础主从拓扑真实部署一定要加密码认证和 TLS 加密。6. Docker Compose多容器编排的必备指令单机环境下部署微服务项目直接逐个docker run会陷入参数地狱这时候必须上 Docker Compose。Compose 的核心价值是用一个 YAML 文件描述整个应用栈用几条命令完成构建、启动、停止、销毁全流程。6.1 compose 的常用命令与部署流程docker compose up -d docker compose ps docker compose logs -f docker compose exec app sh docker compose down docker compose down -v docker compose config docker compose pullup -d按配置文件启动全部服务。ps展示服务状态注意这里的服务名和容器名不一定是同一个概念。exec在指定服务对应的容器里执行命令。down停止并删除容器和默认网络加-v会连数据卷一起删生产环境慎用。docker compose config是个被低估的命令用于校验配置文件并输出最终的渲染结果。如果你的 compose 文件用了环境变量插值和多个 override 文件先用这条命令看渲染结果能避免大量“我明明写了配置为什么不生效”的困惑。6.2 一个可落地的生产级 compose 配置模板下面这个示例包含了 MySQL、Redis、后端服务和 Nginx 四层结构重点演示了依赖关系、健康检查、数据卷、端口映射和资源限制version: 3.8 services: mysql: image: mysql:8.0 container_name: app-mysql environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: ${MYSQL_DATABASE} volumes: - mysql-data:/var/lib/mysql healthcheck: test: [CMD, mysqladmin, ping, -h, localhost] interval: 10s timeout: 3s retries: 5 restart: always redis: image: redis:7-alpine container_name: app-redis command: redis-server --appendonly yes volumes: - redis-data:/data healthcheck: test: [CMD, redis-cli, ping] interval: 10s timeout: 3s retries: 5 restart: always backend: build: ./backend container_name: app-backend environment: SPRING_PROFILES_ACTIVE: prod DB_HOST: mysql REDIS_HOST: redis depends_on: mysql: condition: service_healthy redis: condition: service_healthy ports: - 8080:8080 restart: always deploy: resources: limits: cpus: 1.0 memory: 1G nginx: image: nginx:1.25-alpine container_name: app-gateway ports: - 80:80 - 443:443 volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro depends_on: - backend restart: always volumes: mysql-data: redis-data:这个模板里最值得抄的是健康检查配合depends_on的condition: service_healthy它保证了后端容器只在 MySQL 和 Redis 真正可服务之后才启动。没有这个配置后端大概率会因为连不上依赖而闪退然后restart: always又把它拉起来陷入反复重启的死循环。提示version字段在新版 Docker Compose 里已经可以省略建议省略如果保留也别再用 2.x 的老格式。6.3 微服务部署场景的实用技巧部署微服务项目时除了 compose 本身另有几个命令值得日常熟悉docker compose scale api3一键扩缩容某个服务的实例数。docker compose up -d --scale api3 --no-recreate在保留已有容器的前提下扩增实例但注意这个操作要和负载均衡配合单纯扩多实例没有入口分流是没意义的。docker compose build与up -d --build代码更新后先重新构建镜像再启动新容器。微服务项目的镜像更新流程我在生产环境比较有心得常规做法是改完代码后重新构建镜像并推送到私有仓库再在服务器上执行docker compose pull docker compose up -d如果服务本身有滚动更新需求务实的选择是配合健康检查逐步重启实例而不是一次性全停。7. 生产环境故障排查经验与常见问题速查这一节的内容全是我在真实操作中积累的排查路径都是踩过坑总结出来的。与其散落在前文不如整理成一张速查表遇到问题按图索骥。7.1 “Failed to connect to Docker API”怎么办这个报错在 Windows 上几乎是常态。场景是 Docker Desktop 没启动或后台服务崩溃客户端找不到守护进程。处理路径看系统托盘有没有 Docker 图标没有说明 Desktop 没起双击启动。启动后等待“Engine running”再敲命令。如果图标一直显示 starting去 WSL 里执行wsl --shutdown然后重启 Desktop。仍不行就跑docker desktop start从日志里排查 WSL2 内核问题。Linux 下同样的报错通常是 docker.sock 权限或 daemon 没起来。先systemctl status docker再看当前用户是否在 docker 组。7.2 容器一直重启怎么看原因现象为 RESTARTS 列数字不断增长。排查顺序docker ps -a看退出码137 是 OOM 或被 kill125 是启动参数错误1 是应用自身报错。docker logs --tail 200 容器名看最后输出定位应用层错误。docker inspect 容器名看State.OOMKilled字段是否为 true。如果是 OOM在启动参数里加-m 4g调整内存限制或者优化应用 JVM/Node 堆内存设置。这里有典型的案例公司有个 Java 微服务部署到容器里每隔十来分钟就重启一次RESTARTS 计数很快到两位数。查日志显示 JVM 直接被杀docker inspect里的 OOMKilled 字段为 true最后定位到是容器内存上限设了 512m而 JVM 默认堆大小是按宿主机物理内存百分比的导致堆内存超限被杀。解决方案是显式设置JAVA_OPTS-Xmx256m -Xms256m。7.3 容器日志文件把磁盘写满这是长期跑 Docker 最隐蔽的问题。容器输出的全部日志默认写进宿主机的 json 文件如果不限制大小和轮转几周下来能写满整个磁盘。磁盘满了之后最明显的特征是所有容器开始卡顿新建容器也报 no space left on device。应急解法sudo sh -c truncate -s 0 /var/lib/docker/containers/*/*-json.log du -sh /var/lib/docker/containers/*/*-json.log | sort -rh | head -10根治方案是在/etc/docker/daemon.json里配置日志轮转前文已给出模板并执行systemctl restart docker。重启 daemon 会让所有容器重启一次最好安排在业务低峰期。7.4 端口映射之后外部不通检查路径确认容器监听地址docker exec -it 容器名 netstat -tlnp看进程监听在 0.0.0.0 还是 127.0.0.1。服务监听在 127.0.0.1 的话容器外自然访问不通这是应用配置问题不是 Docker 问题。服务必须监听 0.0.0.0 才能被容器网络转发。在宿主机执行curl 127.0.0.1:8080通的话再确认云安全组和宿主机防火墙。出现“docker 网络不通”的搜索词很多时候其实是容器内的服务监听了 localhost这个问题只需要把应用监听地址改成 0.0.0.0。但我见过有人绕了一大圈最后才发现容器里绑定的 IP 不对。7.5 容器内时间不对定时任务全乱容器默认时区是 UTC如果宿主机在 UTC8容器里date和时间相关的日志会差 8 小时。处理方式有两种启动时注入-e TZAsia/Shanghai大部分带基础镜像的应用会读取这个变量。极端情况挂宿主机时区-v /etc/localtime:/etc/localtime:ro。在起容器时就把TZAsia/Shanghai加上这是成本最低、一劳永逸的做法。7.6 容器退出了但数据卷还在吗这是面向新手的典型困惑。容器删除后已命名的数据卷默认保留匿名卷在docker rm不带-v时也会残留。要想确认哪些卷还占用空间执行docker volume ls -f danglingtrue docker volume rm 卷名我的原则是数据卷宁可多留也不要随意删。真要删卷先确认卷里没有你需要的数据库文件、日志或配置备份。因为被删的数据卷不像容器没有“回收站”概念删了就真的没了。8. 几类特殊指令的补充说明最后集中讲几类容易被热搜词带出来的特殊指令包括 containerd 相关、命令行工具的使用边界以及镜像仓库管理。这些内容不常用但遇到了能省很多时间。8.1 containerd 与 docker 命令的关系containerd 是 Docker 底层使用的容器运行时有的系统上安装的实际上是有 containerd 而无完整 Docker Engine。ctr是 containerd 的原生客户端nerdctl则是兼容 Docker CLI 的 containerd 客户端。如果一台机器只有 containerd 没有 docker 命令最简单的办法是装nerdctl或直接安装 docker-ce 全家桶。生产环境不建议只靠ctr操作镜像因为它的命令风格和 Docker CLI 差异较大团队协作成本高。8.2 镜像仓库管理的常用命令私有仓库的日常操作主要是docker login、docker tag、docker push、docker pull的组合。给镜像打 tag 时不要老用 latest要带上版本号和构建时间比如myapp-api:1.4.0-20240516。这样即使回滚也能精确到具体版本latest 这种临时标签在生产环境意义不大。如果遇到拉不下来镜像、超时或证书错误优先检查是否配置了镜像加速器以及私有仓库的 TLS 证书是否正确。加速器配置写在/etc/docker/daemon.json的registry-mirrors字段里改完记得重启 daemon。8.3 命令易混淆点汇总易混淆命令关键区别docker stopvsdocker kill前者发 SIGTERM 优雅退出超时后 SIGKILL后者直接 SIGKILLdocker rmvsdocker rmirm 删容器rmi 删镜像docker execvsdocker attachexec 在运行容器里开新进程attach 挂到容器主进程的终端docker runvsdocker startrun 创建并启动新容器start 启动已存在的停止状态容器-v挂载目录 vs 数据卷bind mount 指向宿主机具体路径数据卷由 Docker 管理目录这篇 Docker 命令大全是照着“先懂对象、再学操作、后学排查”的路线写的覆盖了从安装启动、镜像构建、容器生命周期、网络数据卷到 Compose 编排的全部核心指令。把上面这些命令真正用过一遍生产环境里的绝大多数容器操作都不会再让你手足无措。我个人实际操作下来的体会是命令本身并不难背难的是理解每个操作背后对应的 Docker 对象和生命周期阶段。遇到报错先别急着到处搜按“守护进程是否正常 → 容器状态是什么 → 配置是否完整 → 资源是否受限 → 日志怎么说”的顺序逐步排查反而最快。这条路径走顺了Docker 从入门到生产也就真正打通了。
阅读完成 · 觉得有帮助?