掌握Docker:常用命令实战指南
在当今快速发展的软件开发和运维领域,Docker 已成为一项不可或缺的技术。它通过容器化技术,极大地简化了应用程序的开发、部署和管理流程,实现了“一次构建,处处运行”的理想。掌握 Docker 的核心概念和常用命令,对于提升开发效率、保障环境一致性、优化资源利用率至关重要。本文将作为一份详尽的实战指南,带您深入了解并熟练运用 Docker 的常用命令,助您在容器化的世界里游刃有余。
一、 Docker 核心概念回顾
在深入命令之前,我们先快速回顾一下 Docker 的几个核心概念:
- 镜像 (Image): Docker 镜像是一个轻量级、可执行的独立软件包,包含运行某个软件所需的一切:代码、运行时、库、环境变量和配置文件。镜像是只读的,是创建 Docker 容器的基础。可以将其理解为面向对象编程中的“类”。
- 容器 (Container): 容器是镜像的运行实例。它是一个隔离的、资源受限的进程环境。可以对容器进行创建、启动、停止、删除等操作。每个容器都是相互隔离的,拥有自己的文件系统、网络和进程空间。可以将其理解为面向对象编程中的“对象”或“实例”。
- 仓库 (Repository): Docker 仓库是集中存放镜像文件的地方。最知名的公共仓库是 Docker Hub,用户可以在其中查找、下载和分享镜像。企业也可以搭建私有仓库,用于存储内部使用的镜像。
- Dockerfile: Dockerfile 是一个文本文件,包含了一系列指令,用于自动化地构建 Docker 镜像。通过
docker build
命令,可以根据 Dockerfile 的内容一步步构建出自定义镜像。
理解了这些基本概念,我们就可以开始探索 Docker 的常用命令了。
二、 镜像管理 (Image Management)
镜像是 Docker 的基石,管理镜像相关的命令是日常使用中最频繁的操作之一。
-
docker pull <image_name>[:tag]
: 从仓库拉取镜像- 作用: 从指定的 Docker 仓库(默认为 Docker Hub)下载一个镜像到本地。
- 参数:
<image_name>
: 镜像的名称,例如ubuntu
,nginx
,mysql
。[:tag]
(可选): 镜像的标签,通常代表版本号,如latest
,1.20
,8.0
。如果省略标签,默认使用latest
。
-
示例:
“`bash
# 拉取最新版的 Ubuntu 镜像
docker pull ubuntu拉取指定版本的 Nginx 镜像
docker pull nginx:1.21
拉取指定仓库的镜像 (例如私有仓库或 Docker Hub 上的用户仓库)
docker pull myregistry.com/myapp:v1.0
docker pull username/myimage:latest
``
latest` 标签并不总是代表最新的稳定版,具体含义由镜像发布者决定。建议在生产环境中使用明确的版本标签。
* **注意:**
-
docker images
ordocker image ls
: 列出本地镜像- 作用: 显示本地已经下载或构建的所有 Docker 镜像。
- 常用选项:
-a
,--all
: 显示所有镜像,包括中间层镜像(默认只显示顶层镜像)。-q
,--quiet
: 只显示镜像的 ID。--filter <key>=<value>
: 根据条件过滤镜像,例如docker images --filter "dangling=true"
显示悬空镜像(没有被任何标签引用的镜像)。
-
示例:
“`bash
# 列出所有顶层镜像
docker images只列出镜像 ID
docker images -q
列出所有悬空镜像
docker images –filter “dangling=true”
“`
-
docker rmi <image_id_or_name>[:tag]
: 删除本地镜像- 作用: 从本地删除一个或多个指定的镜像。
- 参数: 可以是镜像的 ID (短 ID 或完整 ID) 或
名称:标签
。 - 常用选项:
-f
,--force
: 强制删除镜像,即使有容器正在使用它(不推荐,除非明确知道后果)。
-
示例:
“`bash
# 删除指定 ID 的镜像
docker rmi b750fe79269d删除指定名称和标签的镜像
docker rmi ubuntu:latest
同时删除多个镜像 (使用空格分隔)
docker rmi image_id1 image_id2 imagename:tag
删除所有悬空镜像 (常用技巧)
docker rmi $(docker images -f “dangling=true” -q)
“`
* 注意: 如果一个镜像被正在运行或已停止的容器所使用,默认情况下无法直接删除。需要先删除使用该镜像的容器。
-
docker build -t <image_name>[:tag] <path_to_dockerfile_directory>
: 使用 Dockerfile 构建镜像- 作用: 根据指定路径下的 Dockerfile 文件及其上下文(该目录下的文件)构建一个新的 Docker 镜像。
- 常用选项:
-t
,--tag
: 为构建的镜像指定名称和标签。-f
,--file
: 指定 Dockerfile 的路径(默认为上下文目录下的Dockerfile
)。--no-cache
: 构建过程中不使用缓存。.
(点): 表示 Dockerfile 的上下文目录是当前目录。
-
示例:
“`bash
# 在当前目录下查找 Dockerfile 并构建名为 myapp:v1.0 的镜像
docker build -t myapp:v1.0 .使用指定路径下的 Dockerfile 构建镜像
docker build -t myapp:v1.0 -f /path/to/custom/Dockerfile /path/to/context
“`
-
docker tag <source_image>[:tag] <target_image>[:tag]
: 为镜像打标签- 作用: 为本地一个已有的镜像创建一个新的标签。这常用于在推送镜像到仓库前,将其标记为符合仓库命名规范的名称和标签。
- 示例:
bash
# 为本地的 myapp:v1.0 镜像打上 myregistry.com/username/myapp:v1.0 的标签
docker tag myapp:v1.0 myregistry.com/username/myapp:v1.0 - 注意:
docker tag
并没有创建一个新的镜像副本,只是增加了一个指向原镜像的引用(标签)。
-
docker push <image_name>[:tag]
: 将镜像推送到仓库- 作用: 将本地的一个镜像上传到指定的 Docker 仓库(需要先登录)。
- 前提: 镜像名称需要符合目标仓库的命名规范(例如
docker.io/username/imagename:tag
或myregistry.com/imagename:tag
)。通常需要先使用docker tag
命令。 -
示例:
“`bash
# 推送之前打好标签的镜像到 Docker Hub
docker push username/myapp:v1.0推送到私有仓库
docker push myregistry.com/myapp:v1.0
``
docker login
* **登录:** 推送前可能需要使用` 命令登录到目标仓库。
-
docker history <image_name>[:tag]
: 查看镜像构建历史- 作用: 显示指定镜像的构建历史,即构成该镜像的每一层及其对应的 Dockerfile 指令。
- 示例:
bash
docker history nginx:latest
-
docker inspect <image_id_or_name>[:tag]
: 获取镜像的详细元数据- 作用: 以 JSON 格式返回镜像的详细信息,包括层、环境变量、入口点、构建信息等。
- 示例:
bash
docker inspect ubuntu:latest
三、 容器生命周期管理 (Container Lifecycle Management)
容器是镜像的运行实例,管理容器的生命周期是 Docker 操作的核心。
-
docker run [OPTIONS] <image_name>[:tag] [COMMAND] [ARG...]
: 创建并启动一个新容器- 作用: 这是 Docker 中最核心、最复杂的命令之一。它首先会在本地查找指定的镜像,如果不存在则尝试从仓库拉取,然后基于该镜像创建一个新的容器并启动它。
- 常用选项 (非常重要):
-d
,--detach
: 后台运行容器,并返回容器 ID。-i
,--interactive
: 保持标准输入 (STDIN) 打开,即使没有附加(通常与-t
一起使用)。-t
,--tty
: 分配一个伪终端(pseudo-TTY),通常与-i
结合使用 (-it
),提供一个交互式的 Shell 环境。-p <host_port>:<container_port>
: 将主机的端口映射到容器的端口。例如-p 8080:80
将主机的 8080 端口映射到容器的 80 端口。-v <host_path>:<container_path>[:ro]
or--volume
: 将主机的目录或文件挂载到容器中,实现数据持久化或共享。:ro
表示只读挂载。也可以挂载命名的卷。--name <container_name>
: 为容器指定一个易于记忆的名称。--rm
: 容器退出时自动删除该容器。常用于临时任务或测试。-e <key>=<value>
or--env
: 设置环境变量。--network <network_name>
: 将容器连接到指定的网络。--restart <policy>
: 配置容器的重启策略,如no
,on-failure[:max-retries]
,always
,unless-stopped
。
-
示例:
“`bash
# 启动一个后台运行的 Nginx 容器,并将主机 80 端口映射到容器 80 端口
docker run -d -p 80:80 –name mynginx nginx:latest启动一个交互式的 Ubuntu 容器,并在退出后自动删除
docker run -it –rm ubuntu /bin/bash
启动一个 MySQL 容器,设置密码,并将数据目录挂载到主机
docker run -d –name mysql-db -e MYSQL_ROOT_PASSWORD=mysecretpassword -v /my/own/datadir:/var/lib/mysql mysql:8.0
运行一个执行特定命令的临时容器
docker run –rm ubuntu echo “Hello Docker”
“`
-
docker ps
: 列出正在运行的容器- 作用: 显示当前正在运行的容器列表。
- 常用选项:
-a
,--all
: 列出所有容器,包括已停止的容器。-q
,--quiet
: 只显示容器 ID。-s
,--size
: 显示容器占用的磁盘空间。--filter <key>=<value>
: 根据条件过滤容器,例如docker ps --filter "status=exited"
显示已退出的容器,docker ps --filter "name=mynginx"
显示名称为 mynginx 的容器。
-
示例:
“`bash
# 列出正在运行的容器
docker ps列出所有容器 (包括已停止的)
docker ps -a
只列出正在运行容器的 ID
docker ps -q
“`
-
docker stop <container_id_or_name>
: 停止一个或多个运行中的容器- 作用: 向容器发送 SIGTERM 信号,请求其优雅地停止。如果容器在默认超时(10秒)内没有停止,则发送 SIGKILL 信号强制停止。
-
示例:
“`bash
# 停止名为 mynginx 的容器
docker stop mynginx同时停止多个容器
docker stop container_id1 container_id2
“`
-
docker start <container_id_or_name>
: 启动一个或多个已停止的容器- 作用: 将处于停止状态的容器重新启动。
- 示例:
bash
# 启动名为 mynginx 的已停止容器
docker start mynginx
-
docker restart <container_id_or_name>
: 重启一个或多个容器- 作用: 相当于先执行
docker stop
,再执行docker start
。 - 示例:
bash
# 重启名为 mynginx 的容器
docker restart mynginx
- 作用: 相当于先执行
-
docker rm <container_id_or_name>
: 删除一个或多个已停止的容器- 作用: 从 Docker 主机中移除容器。默认情况下,只能删除已停止的容器。
- 常用选项:
-f
,--force
: 强制删除正在运行的容器(发送 SIGKILL)。-v
,--volumes
: 同时删除与容器关联的匿名卷。
-
示例:
“`bash
# 删除已停止的名为 old-container 的容器
docker rm old-container强制删除运行中的容器 (谨慎使用)
docker rm -f mynginx
删除所有已停止的容器 (常用技巧)
docker rm $(docker ps -a -f “status=exited” -q)
“`
四、 容器交互与检查 (Container Interaction & Inspection)
有时我们需要进入运行中的容器执行命令、查看日志或获取容器的详细信息。
-
docker exec [OPTIONS] <container_id_or_name> <command>
: 在运行中的容器内执行命令- 作用: 这是进入正在运行的容器内部进行操作的主要方式,比
docker attach
更常用和灵活。 - 常用选项:
-d
,--detach
: 在后台执行命令。-i
,--interactive
: 保持标准输入打开(通常与-t
一起使用)。-t
,--tty
: 分配一个伪终端(通常与-i
一起使用)。
-
示例:
“`bash
# 在名为 mynginx 的容器中执行 ls /etc/nginx/
docker exec mynginx ls /etc/nginx/进入名为 myapp 的容器的交互式 Shell (常用)
docker exec -it myapp /bin/bash # 或者 /bin/sh
在后台运行一个命令
docker exec -d myapp touch /tmp/exec_marker
“`
- 作用: 这是进入正在运行的容器内部进行操作的主要方式,比
-
docker logs [OPTIONS] <container_id_or_name>
: 获取容器的日志- 作用: 查看容器的标准输出 (STDOUT) 和标准错误 (STDERR) 日志。
- 常用选项:
-f
,--follow
: 持续跟踪日志输出(类似tail -f
)。--tail <number>
: 只显示最后 N 行日志。--since <timestamp>
: 显示指定时间戳之后的日志。--until <timestamp>
: 显示指定时间戳之前的日志。-t
,--timestamps
: 显示时间戳。
-
示例:
“`bash
# 查看名为 myapp 的容器的所有日志
docker logs myapp实时跟踪名为 myapp 的容器日志
docker logs -f myapp
查看最后 100 行日志并带上时间戳
docker logs –tail 100 -t myapp
“`
-
docker cp <host_path> <container_id_or_name>:<container_path>
docker cp <container_id_or_name>:<container_path> <host_path>
: 在主机和容器之间复制文件/目录- 作用: 方便地在 Docker 主机和运行中的容器之间传输文件。
-
示例:
“`bash
# 将主机的 app.conf 复制到 mynginx 容器的 /etc/nginx/conf.d/
docker cp ./app.conf mynginx:/etc/nginx/conf.d/将 mynginx 容器的 /var/log/nginx/access.log 复制到主机的当前目录
docker cp mynginx:/var/log/nginx/access.log .
“`
-
docker inspect <container_id_or_name>
: 获取容器的详细元数据- 作用: 以 JSON 格式返回容器的详细配置和状态信息,包括 IP 地址、端口映射、挂载卷、环境变量等。
-
示例:
“`bash
# 查看名为 mynginx 容器的详细信息
docker inspect mynginx获取容器的 IP 地址 (使用 jq 工具解析 JSON)
docker inspect mynginx | jq -r ‘.[0].NetworkSettings.IPAddress’
“`
-
docker top <container_id_or_name>
: 查看容器内运行的进程- 作用: 显示指定容器内部当前正在运行的进程列表。
- 示例:
bash
docker top myapp
-
docker stats [container_id_or_name...]
: 实时显示容器资源使用情况- 作用: 动态显示一个或多个容器的 CPU、内存、网络 I/O、磁盘 I/O 等资源使用统计。
-
示例:
“`bash
# 实时监控所有运行中容器的资源使用
docker stats实时监控指定容器 myapp 和 mynginx 的资源使用
docker stats myapp mynginx
“`
五、 网络管理 (Network Management)
Docker 允许创建和管理虚拟网络,以便容器之间以及容器与外部世界进行通信。
-
docker network ls
: 列出 Docker 网络- 作用: 显示 Docker 主机上存在的所有网络(包括默认的 bridge, host, none 网络)。
-
docker network create [OPTIONS] <network_name>
: 创建一个新的 Docker 网络- 作用: 创建用户自定义的网络,通常推荐使用自定义 bridge 网络,以提供更好的隔离和 DNS 解析。
- 常用选项:
--driver <driver_name>
: 指定网络驱动,常用bridge
(默认) 或overlay
(用于 Swarm 集群)。--subnet <subnet>
: 指定网络的子网,例如172.18.0.0/16
。--gateway <gateway_ip>
: 指定网络的网关 IP。
- 示例:
bash
# 创建一个名为 my-bridge-net 的自定义 bridge 网络
docker network create my-bridge-net
-
docker network connect <network_name> <container_id_or_name>
: 将运行中的容器连接到网络- 作用: 将一个正在运行的容器添加到一个或多个网络中。
- 示例:
bash
# 将名为 myapp 的容器连接到 my-bridge-net 网络
docker network connect my-bridge-net myapp - 注意: 同一网络内的容器可以通过容器名称直接相互访问。
-
docker network disconnect <network_name> <container_id_or_name>
: 将容器从网络断开- 作用: 从指定网络中移除一个容器。
-
docker network inspect <network_name>
: 显示网络的详细信息- 作用: 以 JSON 格式返回网络的配置和连接到该网络的容器列表。
-
docker network rm <network_name>
: 删除一个或多个网络- 作用: 删除用户自定义的网络。只有当没有容器连接到该网络时才能删除。
六、 数据卷管理 (Volume Management)
数据卷是 Docker 中用于持久化容器数据的推荐方式。
-
docker volume ls
: 列出 Docker 数据卷- 作用: 显示 Docker 主机上存在的所有数据卷。
-
docker volume create [OPTIONS] <volume_name>
: 创建一个新的数据卷- 作用: 创建一个命名的 Docker 数据卷。
- 示例:
bash
# 创建一个名为 my-data 的数据卷
docker volume create my-data
-
docker volume inspect <volume_name>
: 显示数据卷的详细信息- 作用: 以 JSON 格式返回数据卷的元数据,包括其在主机上的挂载点。
-
docker volume rm <volume_name>
: 删除一个或多个数据卷- 作用: 删除指定的数据卷。只有当没有容器正在使用该数据卷时才能删除。
- 注意: 删除数据卷会永久删除其中存储的数据!
-
docker volume prune
: 删除所有未被任何容器使用的本地数据卷- 作用: 清理不再使用的匿名卷和命名卷,释放磁盘空间。会提示确认。
- 常用选项:
-f
,--force
: 强制删除,不提示确认。
七、 Docker Compose 命令
对于需要同时管理多个相互关联的容器的应用(例如 Web 应用 + 数据库 + 缓存),Docker Compose 是一个极其有用的工具。它通过一个 docker-compose.yml
文件来定义和运行多容器 Docker 应用程序。
虽然 docker-compose
是一个独立的工具(现在也集成到 docker compose
子命令中),但其常用命令与 Docker 核心命令密切相关且非常重要。
-
docker-compose up [OPTIONS] [SERVICE...]
(或docker compose up
)- 作用: 根据
docker-compose.yml
文件构建(如果需要)、(重新)创建、启动并附加到服务的容器。 - 常用选项:
-d
: 在后台启动并运行容器。--build
: 在启动容器前强制重新构建镜像。--force-recreate
: 强制重新创建容器,即使配置和镜像没有改变。--no-deps
: 不启动服务所依赖的链接服务。
-
示例:
“`bash
# 在当前目录查找 docker-compose.yml 并启动所有服务 (前台)
docker-compose up在后台启动所有服务
docker-compose up -d
启动指定的 web 服务及其依赖项 (后台)
docker-compose up -d web
“`
- 作用: 根据
-
docker-compose down [OPTIONS]
(或docker compose down
)- 作用: 停止并删除由
docker-compose up
创建的容器、网络、卷(可选)。 - 常用选项:
-v
,--volumes
: 同时删除在docker-compose.yml
中定义的命名卷以及附加到容器的匿名卷。--rmi <type>
: 删除镜像。type
可以是all
(删除所有服务使用的镜像)或local
(仅删除没有自定义标签的镜像)。
-
示例:
“`bash
# 停止并删除容器和网络
docker-compose down停止、删除容器、网络和数据卷
docker-compose down -v
“`
- 作用: 停止并删除由
-
docker-compose ps
(或docker compose ps
)- 作用: 列出 Compose 应用中定义的服务的容器状态。
-
docker-compose logs [OPTIONS] [SERVICE...]
(或docker compose logs
)- 作用: 查看 Compose 应用中服务的日志。
- 常用选项:
-f
,--follow
: 实时跟踪日志。--tail <number>
: 显示最后 N 行日志。
-
docker-compose build [SERVICE...]
(或docker compose build
)- 作用: 构建或重新构建 Compose 应用中服务的镜像。
-
docker-compose pull [SERVICE...]
(或docker compose pull
)- 作用: 拉取 Compose 应用中服务所需的镜像。
-
docker-compose exec <service_name> <command>
(或docker compose exec
)- 作用: 在指定的运行中服务的容器内执行命令(类似于
docker exec
)。 - 示例:
bash
# 进入名为 web 的服务的容器的 Shell
docker-compose exec web /bin/bash
- 作用: 在指定的运行中服务的容器内执行命令(类似于
八、 系统管理与清理 (System Management & Cleanup)
随着时间推移,Docker 主机上可能会积累大量未使用的镜像、容器、卷和网络,占用磁盘空间。定期清理非常重要。
-
docker system df
: 显示 Docker 磁盘使用情况- 作用: 报告 Docker 使用的磁盘空间总量,以及各类对象(镜像、容器、本地卷、构建缓存)分别占用的空间和可回收的空间。
-
docker system prune [OPTIONS]
: 清理未使用的 Docker 资源- 作用: 一键删除所有已停止的容器、所有悬空镜像(dangling images)、所有未被任何容器使用的网络以及所有悬空构建缓存。这是一个非常有用的命令,但使用前请确保了解其作用范围。
- 常用选项:
-a
,--all
: 除了上述内容外,还会删除所有未被至少一个容器使用的镜像(不仅仅是悬空镜像)和所有未使用的卷。请极其谨慎使用此选项!--volumes
: 同时删除所有未使用的本地卷(等同于docker volume prune
)。-f
,--force
: 强制执行清理,不进行确认提示。
-
示例:
“`bash
# 清理停止的容器、悬空镜像、未使用网络和构建缓存 (会提示确认)
docker system prune强制清理,并包括未使用的卷
docker system prune -f –volumes
“`
-
docker info
: 显示 Docker 系统范围的信息- 作用: 提供 Docker 引擎的详细信息,包括容器和镜像数量、存储驱动、网络配置、操作系统信息、内核版本、Docker Server 版本等。
-
docker version
: 显示 Docker 版本信息- 作用: 分别显示 Docker Client 和 Docker Server (Engine) 的版本号和 API 版本等信息。
九、 结语
掌握 Docker 命令是高效使用 Docker 的关键。本文详细介绍了 Docker 的常用命令,涵盖了镜像管理、容器生命周期、交互检查、网络、数据卷、Docker Compose 以及系统清理等多个方面,并提供了丰富的选项和示例。
然而,理论学习只是第一步,真正的精通来自于不断的实践。建议您:
- 动手尝试: 亲自在本地环境或测试服务器上执行这些命令,观察效果。
- 结合场景: 在实际项目开发、测试和部署中应用这些命令,解决具体问题。
- 阅读官方文档: Docker 官方文档是最权威、最全面的参考资料,遇到疑问时务必查阅。
- 探索高级功能: 熟悉常用命令后,可以进一步探索 Docker Swarm(集群管理)、安全性配置、更复杂的网络和存储方案等高级主题。
Docker 的世界广阔而精彩,希望这份实战指南能为您打下坚实的基础,助您在容器技术的浪潮中乘风破浪,高效地构建、交付和运行您的应用程序。不断练习,持续学习,您将能真正“掌握 Docker”!