多容器应用

说明

启动一个单容器应用很简单。例如,一个执行特定数据处理任务的 Python 脚本可以在一个容器内运行,其中包含所有依赖项。类似地,一个提供静态网站并带有一个小型 API 端点的 Node.js 应用,可以有效地将其所有必要的库和依赖项容器化。然而,随着应用规模的增长,将它们作为单个容器进行管理变得越来越困难。

想象一下,数据处理 Python 脚本需要连接到数据库。突然间,你不仅要管理脚本,还要在同一个容器内管理数据库服务器。如果脚本需要用户登录,你还需要一个认证机制,这会进一步增加容器的大小。

容器的一个最佳实践是每个容器应该只做一件事,并把它做好。尽管此规则有例外情况,但应避免让一个容器做多件事的倾向。

现在你可能会问,“我是否需要单独运行这些容器?如果我单独运行它们,如何将它们全部连接在一起?”

虽然 docker run 是启动容器的便捷工具,但用它来管理日益增长的应用堆栈变得困难。原因如下:

  • 想象一下,针对开发、测试和生产环境,运行多个具有不同配置的 docker run 命令(前端、后端和数据库)。这很容易出错且耗时。
  • 应用通常相互依赖。随着堆栈的扩展,手动按特定顺序启动容器和管理网络连接变得困难。
  • 每个应用都需要自己的 docker run 命令,这使得扩展单个服务变得困难。扩展整个应用意味着可能浪费不需要提升性能的组件上的资源。
  • 持久化每个应用的数据需要在每个 docker run 命令中进行单独的卷挂载或配置。这会造成一种分散的数据管理方法。
  • 通过单独的 docker run 命令为每个应用设置环境变量既繁琐又容易出错。

这就是 Docker Compose 发挥作用的地方。

Docker Compose 在一个名为 compose.yml 的单个 YAML 文件中定义你的整个多容器应用。该文件指定了所有容器及其依赖项、环境变量,甚至卷和网络的配置。使用 Docker Compose,

  • 你无需运行多个 docker run 命令。你只需在一个 YAML 文件中定义你的整个多容器应用。这集中了配置,简化了管理。
  • 你可以按特定顺序运行容器并轻松管理网络连接。
  • 你可以轻松地在多容器设置中扩展或缩减单个服务。这样可以根据实时需求进行高效分配。
  • 你可以轻松实现持久卷。
  • 在你的 Docker Compose 文件中一次性设置环境变量非常简单。

通过利用 Docker Compose 运行多容器设置,你可以构建以模块化、可扩展性和一致性为核心的复杂应用。

亲自尝试

在本实操指南中,你将首先看到如何使用 docker run 命令构建并运行一个基于 Node.js、Nginx 反向代理和 Redis 数据库的计数器 Web 应用。你还将看到如何使用 Docker Compose 简化整个部署过程。

设置

  1. 获取示例应用。如果你安装了 Git,可以克隆示例应用仓库。否则,你可以下载示例应用。选择以下任一选项。


    在终端中使用以下命令克隆示例应用仓库。

    $ git clone https://github.com/dockersamples/nginx-node-redis
    

    导航到 nginx-node-redis 目录

    $ cd nginx-node-redis
    

    在该目录下,你会找到两个子目录 - nginxweb

    下载源代码并解压。

    导航到 nginx-node-redis-main 目录

    $ cd nginx-node-redis-main
    

    在该目录下,你会找到两个子目录 - nginxweb


  2. 下载并安装 Docker Desktop。

构建镜像

  1. 导航到 nginx 目录,运行以下命令构建镜像

    $ docker build -t nginx .
    
  2. 导航到 web 目录,运行以下命令构建第一个 web 镜像

    $ docker build -t web .
    

运行容器

  1. 在运行多容器应用之前,你需要为它们创建一个网络以便相互通信。你可以使用 docker network create 命令来完成此操作

    $ docker network create sample-app
    
  2. 运行以下命令启动 Redis 容器,该命令会将其连接到先前创建的网络并创建一个网络别名(这对于 DNS 查找非常有用)

    $ docker run -d  --name redis --network sample-app --network-alias redis redis
    
  3. 运行以下命令启动第一个 web 容器

    $ docker run -d --name web1 -h web1 --network sample-app --network-alias web1 web
    
  4. 运行以下命令启动第二个 web 容器

    $ docker run -d --name web2 -h web2 --network sample-app --network-alias web2 web
    
  5. 运行以下命令启动 Nginx 容器

    $ docker run -d --name nginx --network sample-app  -p 80:80 nginx
    

    注意

    Nginx 通常用作 Web 应用的反向代理,将流量路由到后端服务器。在此示例中,它将流量路由到 Node.js 后端容器(web1 或 web2)。

  6. 运行以下命令验证容器是否已启动

    $ docker ps
    

    你将看到如下输出

    CONTAINER ID   IMAGE     COMMAND                  CREATED              STATUS              PORTS                NAMES
    2cf7c484c144   nginx     "/docker-entrypoint.…"   9 seconds ago        Up 8 seconds        0.0.0.0:80->80/tcp   nginx
    7a070c9ffeaa   web       "docker-entrypoint.s…"   19 seconds ago       Up 18 seconds                            web2
    6dc6d4e60aaf   web       "docker-entrypoint.s…"   34 seconds ago       Up 33 seconds                            web1
    008e0ecf4f36   redis     "docker-entrypoint.s…"   About a minute ago   Up About a minute   6379/tcp             redis
  7. 如果你查看 Docker Desktop 控制面板,你可以看到容器并深入了解它们的配置。

    A screenshot of the Docker Desktop Dashboard showing multi-container applications
  8. 一切就绪并运行后,你可以在浏览器中打开 http://localhost 查看网站。多次刷新页面,查看处理请求的主机和总请求数

    web2: Number of visits is: 9
    web1: Number of visits is: 10
    web2: Number of visits is: 11
    web1: Number of visits is: 12
    

    注意

    你可能已经注意到,Nginx 作为反向代理,很可能以轮询方式在两个后端容器之间分配传入请求。这意味着每个请求可能会轮流指向不同的容器(web1 和 web2)。输出显示 web1 和 web2 容器的计数都在连续增加,并且存储在 Redis 中的实际计数器值仅在响应发送回客户端后才更新。

  9. 你可以使用 Docker Desktop 控制面板,通过选择容器并选择删除按钮来移除容器。

    A screenshot of Docker Desktop Dashboard showing how to delete the multi-container applications

使用 Docker Compose 简化部署

Docker Compose 提供了一种结构化和简化的方法来管理多容器部署。如前所述,使用 Docker Compose,你无需运行多个 docker run 命令。你只需在一个名为 compose.yml 的 YAML 文件中定义你的整个多容器应用。让我们看看它是如何工作的。

导航到项目根目录。在该目录下,你会找到一个名为 compose.yml 的文件。这个 YAML 文件是所有“魔法”发生的地方。它定义了构成你应用的所有服务及其配置。每个服务指定其镜像、端口、卷、网络以及实现其功能所需的任何其他设置。

  1. 使用 docker compose up 命令启动应用

    $ docker compose up -d --build
    

    运行此命令时,你应该会看到类似如下的输出

    Running 5/5
    ✔ Network nginx-nodejs-redis_default    Created                                                0.0s
    ✔ Container nginx-nodejs-redis-web1-1   Started                                                0.1s
    ✔ Container nginx-nodejs-redis-redis-1  Started                                                0.1s
    ✔ Container nginx-nodejs-redis-web2-1   Started                                                0.1s
    ✔ Container nginx-nodejs-redis-nginx-1  Started
    
  2. 如果你查看 Docker Desktop 控制面板,你可以看到容器并深入了解它们的配置。

    A screenshot of the Docker Desktop Dashboard showing the containers of the application stack deployed using Docker Compose
  3. 或者,你可以使用 Docker Desktop 控制面板,通过选择应用堆栈并选择删除按钮来移除容器。

    A screenshot of Docker Desktop Dashboard that shows how to remove the containers that you deployed using Docker Compose

在本指南中,你了解了使用 Docker Compose 启动和停止多容器应用是多么简单,相比之下,使用 docker run 容易出错且难以管理。

更多资源

页面选项