在当今的软件开发领域,Docker 几乎成了基础设施的标配,尤其对于那些需要将应用在不同环境中稳定运行的开发者和数据专家来说。无论是为了本地开发快速启动容器,还是在生产环境部署微服务,熟练掌握 Docker 命令都是一项基本技能。
在这篇文章里,我将以一个老兵的角度,带大家深入了解 18 个核心 Docker 命令。这些命令涵盖了镜像、容器、网络、数据卷以及 Docker Compose 等多个方面。我相信,搞懂这些,你的 Docker 工作流会变得更顺畅,效率自然也就会提升不少。
Docker 是什么?
简单来说,Docker 是一个帮助我们开发、交付和运行应用的平台。它的核心理念就是将应用与底层基础设施解耦,这样一来,软件交付就能更快,管理整个应用环境的方试也像管理应用程序本身一样高效。
Docker 通过一种轻量级的打包方式——“容器”——来运行应用程序。每个容器都包含了应用运行所需的一切,比如依赖库和各种配置,这样能有效节省系统资源。容器的好处有很多:可以轻松地与团队成员共享,同时运行多个,并且能通过 Docker 的工具平台统一管理。
我们用 Docker 可以做不少事情,例如:
- 快速响应的部署与扩容。
- 在相同的硬件上运行更多工作负载。
- 实现应用的快速、一致性交付。
使用 Docker 时,我们主要会和 Docker 对象打交道,这包括镜像(Images)、容器(Containers)、网络(Networks)、插件(Plugins)以及数据卷(Volumes)。这些元素构成了 Docker 运行的基础。在底层,Docker 利用 Linux 内核的特性来实现这些功能。而我们与它交互,只需要在终端敲击一些简单的命令,所有 Docker 命令都以 docker 开头。
如果你刚刚接触 Docker,我推荐你从 Introduction to Docker 这门课开始,它会为你打下一个实用的容器化基础。
Docker 基础命令
讲完 Docker 的基本概念,我们来看看一些最常用的命令。这些命令能帮你日常构建、运行和管理容器。
docker --version 和 docker info
在 Docker 命令中,任何以 -- 开头的东西,我们称之为“标志(flag)”。
举个例子,--version 标志用来显示你当前使用的 Docker CLI 版本。你也可以直接用 docker version(不带标志)来获取所有 Docker 组件的详细版本信息。
它的输出通常分为两部分:
- Client:展示 Docker CLI 及相关工具的信息。
- Server:提供 Docker Engine 及其运行环境的详细信息。
你甚至可以使用 --format 标志配合自定义模板来格式化输出结果。
docker info 命令则能让你对整个 Docker 环境有一个全面的了解。它和 docker system info 的作用一样,只是名字更短。你会看到像内核版本、容器和镜像数量以及其他系统级的详细信息。根据你使用的存储驱动,它可能还会显示存储池名称和数据文件等信息。和 docker version 类似,你也可以使用 --format 或 -f 标志来格式化输出。
docker pull <image>
pull 命令用来从注册表下载 Docker 镜像,通常我们指的是 Docker Hub,这是一个预构建镜像的公共库,你无需自行设置就能直接使用。你可以用 docker pull <image> 或 docker pull 来执行,效果是一样的。
- 完整的语法是这样的:
docker image pull [OPTIONS] NAME[:TAG|@DIGEST]
如果你不指定标签(tag),Docker 会默认使用 :latest。比如,docker image pull debian 会拉取 debian:latest 镜像。
你也可以在命令后面加上选项来定制镜像的拉取方式,比如限制带宽或者跳过镜像验证。下面的图展示了所有可用的选项及其功能。
docker pull 命令的选项。来源: Docker docs
docker run <image>
docker run <image> 命令的作用是从指定的镜像创建一个新容器并启动它。说白了,就是在一个全新的容器里跑你的镜像。它其实是 docker container run 的简写,两者使用起来没啥区别的。
- 基本语法如下:
docker container run [OPTIONS] IMAGE [COMMAND] [ARG...]
如果你之前已经运行过一个容器,只是想让它带着以前的改动重新启动,那应该用 docker start <container>。
run 命令带有很多选项,能让你定制容器的运行方式。接下来,我们不妨看看几个常用的例子:
| Flag | Command example | Description |
|---|---|---|
--name |
docker run --name test -d nginx:alpine |
为容器指定自定义标识符,本例中容器名为 test,使用 nginx:alpine 镜像。 |
-w, --workdir |
docker run -w /path/to/dir/ -i -t ubuntu pwd |
在指定目录(本例为 /path/to/dir/)内执行命令。 |
--pid |
docker run --rm -it --pid=host alpine |
默认情况下,所有容器都启用了 PID 命名空间,提供进程隔离。此示例运行一个 alpine 容器,使用 --pid=host 选项。 |
--cidfile |
docker run --cidfile /tmp/docker_test.cid ubuntu echo "test" |
创建容器并将测试信息打印到控制台。cidfile 标志使 Docker 尝试创建一个新文件并将容器 ID 写入其中。 |
docker stop <container> 和 docker start <container>
docker start <container> 命令用于启动一个或多个已停止的容器。例如,在 docker start my_container 中,my_container 就是我们要启动的容器名称。我们也可以用它的别名:docker container start。
- 它的完整语法是:
docker container start [OPTIONS] CONTAINER [CONTAINER...]
同样地,docker stop 命令用来停止一个或多个正在运行的容器。例如,docker stop my_container 中的 my_container 是一个正在运行的容器名称。
它也有一个别名:docker container stop。
- 它的完整语法是这样的:
docker container stop [OPTIONS] CONTAINER [CONTAINER...]
和 start 命令一样,stop 命令也有不少选项,能让你定制容器停止的方式。下面我来重点讲几个实用的:
docker stop 的选项。来源: Docker docs
玩转 Docker 镜像
镜像,可以说是一个容器的基石。这一节,咱们就来聊聊怎么用那些常用命令来创建、管理和检查 Docker 镜像。
docker build
docker build 命令是 Docker 最常用的功能之一。虽然它属于一个支持高级用法的庞大生态系统,但我们主要关注如何用它从一个简单的 Dockerfile 构建镜像。
Dockerfile 是一个纯文本文件(没有文件扩展名),它包含了 Docker 构建镜像时需要遵循的逐步指令。下面是创建 Dockerfile 的步骤:
-
在应用程序的根目录中,创建一个名为
Dockerfile的文件,内容如下:# syntax=docker/dockerfile:1 FROM node:lts-alpine WORKDIR /app COPY . . RUN yarn install --production CMD ["node", "src/index.js"] EXPOSE 3000这个
Dockerfile从一个包含 Node.js 和 Yarn 的轻量级基础镜像开始。它将你的应用程序源代码复制到镜像中,安装依赖,并定义了如何启动应用程序。 -
现在,使用以下命令构建镜像:
docker build -t getting-started .-t标志允许你给镜像打上标签。在这个例子中,我们将其命名为getting-started。末尾的.告诉 Docker 在当前目录寻找Dockerfile。
docker images
docker images 命令会列出所有你的顶层镜像,包括它们的仓库名、标签和大小。你也可以用它的别名:
docker image listdocker image ls
它的语法是:docker image ls [OPTIONS] [REPOSITORY[:TAG]]
这个命令支持好几个选项。比如,要显示所有镜像,包括那些中间层镜像,你可以加上 -a 或 --all 标志,像这样:docker images -a。
docker rmi <image>
docker rmi <image> 命令用来从你的系统移除一个或多个镜像。如果一个镜像有好几个标签,使用特定标签执行这个命令只会移除那个标签。但如果这个标签是该镜像唯一关联的标签,那么标签和镜像都会被移除。
你也可以使用这些别名中的一个:
docker image removedocker image rm
它的语法是:docker image rm [OPTIONS] IMAGE [IMAGE...]
如果你需要强制删除一个正在被运行容器使用的镜像,那你就得加上 -f 或 --force 选项了。
Docker 容器管理
在应用不断迭代的过程中,我们常常需要管理容器——启动、停止、检查甚至移除它们。所以,我会带着大家过一遍那些日常工作中用来处理容器最实用的 Docker 命令。
docker exec <container> <command>
docker exec 命令允许你在一个正在运行的容器内部执行命令,而无需重启它。这个功能对于调试或者在容器内手动检查某些东西特别有用。你也可以使用它的别名:docker container exec。
这个命令只在容器的主进程(PID 1)正在运行时才有效。如果容器重启了,它不会自动重新执行。
它的语法是:docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
这里有一些可选的标志你可以用。例如,--privileged 会给命令在容器内提供扩展的权限。想看完整的选项列表,可以去官方文档瞧瞧。
这是一个在容器上执行命令的例子:
docker exec -d mycontainer touch /tmp/execWorks
touch 命令会在后台,在正在运行的 mycontainer 容器内部创建一个新文件 /tmp/execWorks。
docker logs <container>
docker logs 命令允许你查看特定容器的日志,它会显示执行时打印到标准输出和错误流中的所有内容。你也可以使用它的别名:docker container logs。
它的语法是:docker container logs [OPTIONS] CONTAINER
有一些实用的选项你可以添加。例如:
--details显示额外的属性,比如环境变量和标签。--until允许你获取到某个特定时间点之前的日志。docker logs -f --until=2s test会持续跟踪test容器的日志输出,并在显示最后两秒的日志后停止。
这里是所有我们可以和 docker logs 一起使用的选项:
docker log <container> 的选项。来源: Docker docs
docker rm <container>
docker rm <container> 命令用于从你的系统移除一个或多个容器。你也可以使用它的别名:
docker container removedocker container rm
它的语法是:docker container rm [OPTIONS] CONTAINER [CONTAINER...]
这个命令有一些可选的标志你可以用。下面列出一些:
docker rm <container> 的选项。来源: Docker docs
举个例子,你可以用 docker rm /redis 来删除由 /redis 链接标识的容器。不过要注意,这个命令只能删除正在运行的容器。
如果你想删除已停止的容器,你需要使用 docker container prune。为了保持环境整洁,建议你看看这篇 Docker prune 教程,学习如何安全地移除未使用的 Docker 资源。
docker restart <container>
docker restart <container> 命令会停止并重新启动一个或多个容器。你也可以使用它的别名:docker container restart。
它的语法是:docker restart [OPTIONS] CONTAINER [CONTAINER...]
restart 命令有几个实用的选项,可以让你定制容器的重启行为。下面是这些选项及其示例。
| Option | Description | Example |
|---|---|---|
-s, --signal |
发送给容器的信号。 | docker restart -s SIGTERM mycontainer |
-t, --timeout |
停止容器前等待的秒数。 | docker restart -t 10 mycontainer |
想要更多实践练习吗?你可以探索这些 Docker 项目想法,从初级到高级都有的。
Docker 网络
容器网络功能使得容器之间以及容器与外部工作负载之间能够互相通信。默认情况下,容器的网络是开启的,并且可以发起对外连接,但它们不会自动知道自己处于哪种网络,或者连接到哪些其他工作负载。
除非你使用 none 网络驱动(它会禁用网络),否则容器可以与 IP 地址、网关和 DNS 等网络元素进行交互。
让我们探索一些你可以使用的常用 Docker 网络命令。
docker network ls
docker network ls 命令会列出 Docker Engine 已知的所有网络,包括集群中跨多个主机的那部分。它的别名是:docker network list。
- 它的语法是:
docker network ls [OPTIONS]
你可以配合使用多个选项,如下图所示:
默认情况下,这个命令会显示每个网络的:
- ID
- 名称
- 驱动
- 范围(Scope)
你可以使用标志来定制输出。例如,--no-trunc 标志会显示完整的网络 ID,而不是截断后的 ID。以下是你使用这个命令的方式:
docker network ls --no-trunc
docker network create <network-name>
docker network create 命令用于创建一个新的 Docker 网络。默认情况下,它会使用 bridge 驱动,除非你通过 --driver(或 -d)标志指定了其他驱动。
Docker 支持内置的网络驱动,比如:
bridge用于单主机网络。overlay用于 Swarm 模式下的多主机网络。
如果需要,你也可以使用第三方或自定义驱动。
- 它的基本语法是:
docker network create [OPTIONS] NETWORK
该命令为不同目的提供了很多选项。你可以查看官方文档来获取完整的选项列表。
这里是一个创建桥接网络的例子:
docker network create -d bridge my-bridge-network
桥接网络通常只限制在单个 Docker Engine 中,所以它们不会连接不同主机上的容器。
一旦启用了 Swarm 模式,你就可以创建一个跨多个 Docker 主机的网络:
docker network create --scope=swarm --attachable -d overlay my-multihost-network
好奇 Docker 和 Kubernetes 有何不同?这篇 Kubernetes vs Docker 的对比文章,深入探讨了它们的关键差异和应用场景。
Docker 数据卷
Docker 数据卷(Volumes)是用来存储需要持久化的数据,即使容器停止或被移除,这些数据也能保留下来。你可以显式地创建它们,也可以让 Docker 在启动容器时自动为你创建。
数据卷存储在宿主系统上,但它们与宿主的核心文件是隔离的。它们以类似于绑定挂载(bind mounts)的方式挂载到容器中,但通常具有更好的可移植性和安全性。
接下来,我们探讨一些相关的 Docker 数据卷命令:
docker volume ls
docker volume ls 命令会列出 Docker 已知的所有数据卷。你也可以使用它的别名:docker volume list。
- 它的语法是:
docker volume ls [OPTIONS]
这个命令支持一些可选的标志,可以帮助你过滤或格式化输出——下面是它们的功能:
docker volume ls 命令的选项。来源: Docker docs
docker volume create <volume-name>
docker volume create 命令用于创建一个新的数据卷,用于存储持久化数据。如果你不提供名称,Docker 会自动为你生成一个。
当你希望数据能够在一个容器生命周期结束后仍然存在时,创建数据卷是一个很常见的步骤。
- 它的语法是:
docker volume create [OPTIONS] [VOLUME_NAME]
我们来看一个创建数据卷,然后配置容器使用它的例子:
docker volume create hello
docker run -d -v hello:/world busybox ls /world
在这个例子中,首先创建了一个名为 hello 的数据卷。然后,它被挂载到容器的 /world 路径。这样,容器就可以从这个数据卷读写数据了。
多个容器可以使用同一个数据卷,这在当你需要一个容器写入数据而另一个容器读取数据时非常有用。
注意:数据卷名称在不同的驱动程序中必须是唯一的。你不能在两个不同的存储驱动程序中使用相同的卷名称。
Docker Compose 命令
Docker Compose 让我得用一个简单的 YAML 文件轻松管理多容器应用程序。它支持不同的环境,像开发、测试、预发布、生产和持续集成(CI)。通过一个命令,你就可以控制服务、设置网络和管理数据卷——所有这些都在一处完成。
我们来探讨一些常用的 Compose 命令:
docker-compose up
docker compose up 命令会为服务构建、(重新)创建、启动并连接到容器。如果容器尚未运行,它还会自动启动任何链接的服务。
- 它的语法是:
docker compose up [OPTIONS] [SERVICE...]
默认情况下,这个命令会合并所有容器的输出。如果你想关注特定服务,你可以:
- 使用
--attach标志连接到某些服务 - 使用
--no-attach标志排除其他服务
例如,docker compose up --no-attach <service-name> 会启动除你从日志中排除的服务之外的所有服务。
当命令结束时,容器也会停止。如果想让它们在后台运行,就用 --detach 标志:
docker compose up --detach
在运行这个命令之前,请确保你已经导航(cd)到 docker-compose.yml 文件所在的目录。
docker-compose down
docker compose down 命令会停止容器并移除由 docker compose up 创建的容器、镜像、网络和数据卷。
- 它的语法是:
docker compose down [OPTIONS] [SERVICES]
你可以使用多种选项,包括以下这些:
docker compose down 命令的选项。来源: Docker docs。
默认情况下,这个命令会移除以下内容:
- Compose 文件中定义的服务容器。
- Compose 文件网络部分定义的网络。
- 如果使用了默认网络,也会被移除。
以下内容默认不会被移除:
- 被定义为外部的网络和数据卷。
- 匿名数据卷,即没有名称的数据卷。
匿名数据卷在你再次运行 docker compose up 时不会自动挂载,因为它们没有名字。如果你需要持久化数据存储,最好使用具名数据卷或绑定挂载。
使用 Docker 命令的最佳实践
Docker 是一种强大的工具,可以用来构建、交付和在容器中运行应用程序。但要用好它,确保你的设置高效且易于扩展,就必须遵循一些最佳实践。
为持久化数据使用 Docker 数据卷
默认情况下,容器文件存储在一个可写层中,当容器被移除时,这个层会丢失!这个层对于每个容器都是唯一的,而且不容易访问。Docker 使用不同类型的挂载来持久化数据,其中一种就是 数据卷(volumes),由 Docker 守护进程管理并存储在宿主上。
数据卷可以让我们:
- 即使在容器被删除后也能保留数据。
- 以宿主系统级的速度存储对性能关键的数据。
- 通过 Docker 轻松管理存储。
它们非常适合长期数据或多个容器需要共享访问的情况。不过要记住,如果你需要直接从宿主访问文件,绑定挂载可能更合适,因为数据卷完全由 Docker 管理。
利用 Docker Compose 实现自动化
手动管理多个容器很快就会让人感到吃不消。Docker Compose 通过让你在一个 YAML 文件中定义所有内容来简化事情,这样你就能把精力放在构建上了。
以下是它值得遵循的最佳实践的原因:
- 一个简单命令搞定:一键启动、停止、扩容或重建你的服务。
- 保持一致性:无论你在开发、测试还是生产环境工作,Compose 都能保持环境一致,避免那些“在我的机器上能跑”的问题。
- 内置网络:Compose 会创建一个共享网络,让你的服务能用服务名而不是 IP 地址轻松通信。
- 轻松扩容:你可以快速使用
--scale标志来扩容或缩减服务,这对测试应用如何处理不同负载很有用。 - 清晰且协作的配置:你的整个设置,包括容器、网络和数据卷,都是版本控制的,而且可读性强。
结语
初学 Docker 可能会让人感到有点不知所措,但一旦你掌握了这些核心命令,它将为你打开许多可能性。从运行你的第一个容器,到管理网络、数据卷和服务,你现在已经有的能力来自信地构建和运行容器化应用程序了。
如果你渴望继续学习,这里有一些很棒的资源可以进一步探索:
- Containerization and Virtualization Concepts – 一门完美的课程,可以构建你的概念基础。
- Introduction to Docker – 一门对初学者友好的入门课程。
- Intermediate Docker – 当你准备深入学习时可以选择这门课程。
- Containerization and Virtualization with Docker and Kubernetes – 技能路径,可扩展到 Kubernetes 和真实世界的编排。
关于
关注我获取更多资讯