多容器应用程序
解释
启动单容器应用程序非常简单。例如,执行特定数据处理任务的 Python 脚本在具有所有依赖项的容器中运行。同样,为具有小型 API 端点的静态网站提供服务的 Node.js 应用程序可以有效地容器化其所有必要的库和依赖项。但是,随着应用程序规模的增长,将它们作为单个容器进行管理变得更加困难。
想象一下数据处理 Python 脚本需要连接到数据库。突然之间,您现在不仅要管理脚本,还要管理同一容器中的数据库服务器。如果脚本需要用户登录,您将需要一个身份验证机制,从而进一步增加容器大小。
容器的一个最佳实践是,每个容器都应该做一件事,并且做得好。虽然此规则有例外,但请避免让一个容器执行多项操作的趋势。
现在您可能会问,“我需要单独运行这些容器吗?如果我分别运行它们,我该如何将它们全部连接在一起呢?
虽然是启动容器的便捷工具,但使用它管理不断增长的应用程序堆栈变得困难。原因如下:docker run
- 想象一下,为开发、测试和生产环境运行具有不同配置的多个命令(前端、后端和数据库)。这容易出错且耗时。
docker run
- 应用程序通常相互依赖。随着堆栈的扩展,按特定顺序手动启动容器和管理网络连接变得困难。
- 每个应用程序都需要其命令,因此很难扩展单个服务。扩展整个应用程序意味着可能会将资源浪费在不需要提升的组件上。
docker run
- 为每个应用程序持久保存数据需要在每个命令中进行单独的卷挂载或配置。这会产生一种分散的数据管理方法。
docker run
- 通过单独的命令为每个应用程序设置环境变量既乏味又容易出错。
docker run
这就是 Docker Compose 的用武之地。
Docker Compose 在一个名为 .此文件指定所有容器的配置、其依赖项、环境变量,甚至卷和网络。使用 Docker Compose:compose.yml
- 您无需运行多个命令。您需要做的就是在单个 YAML 文件中定义整个多容器应用程序。这集中了配置并简化了管理。
docker run
- 您可以按特定顺序运行容器并轻松管理网络连接。
- 您只需在多容器设置中扩展或缩减单个服务即可。这允许根据实时需求进行高效分配。
- 您可以轻松实施持久性卷。
- 在 Docker Compose 文件中设置一次环境变量就很容易了。
通过利用 Docker Compose 运行多容器设置,您可以构建以模块化、可扩展性和一致性为核心的复杂应用程序。
试用
在本实践指南中,您将首先了解如何使用命令基于 Node.js、Nginx 反向代理和 Redis 数据库构建和运行计数器 Web 应用程序。您还将了解如何使用 Docker Compose 简化整个部署过程。docker run
建立
获取示例应用程序。如果您有 Git,则可以克隆示例应用程序的存储库。否则,您可以下载示例应用程序。选择以下选项之一。
在终端中使用以下命令克隆示例应用程序存储库。
$ git clone https://github.com/dockersamples/nginx-node-redis
导航到目录:
nginx-node-redis
$ cd nginx-node-redis
在此目录中,您将找到两个子目录 - 和 .
nginx
web
下载并安装Docker 桌面。
构建镜像
通过运行以下命令导航到目录以构建镜像:
nginx
$ docker build -t nginx .
导航到目录并运行以下命令以构建第一个 Web 镜像:
web
$ docker build -t web .
运行容器
在运行多容器应用程序之前,您需要创建一个网络,以便它们都通过它进行通信。您可以使用以下命令执行此操作:
docker network create
$ docker network create sample-app
通过运行以下命令启动 Redis 容器,该命令会将其附加到之前创建的网络并创建网络别名(对于 DNS 查找很有用):
$ docker run -d --name redis --network sample-app --network-alias redis redis
通过运行以下命令启动第一个 Web 容器:
$ docker run -d --name web1 -h web1 --network sample-app --network-alias web1 web
通过运行以下命令启动第二个 Web 容器:
$ docker run -d --name web2 -h web2 --network sample-app --network-alias web2 web
通过运行以下命令启动 Nginx 容器:
$ docker run -d --name nginx --network sample-app -p 80:80 nginx
注意
Nginx 通常用作 Web 应用程序的反向代理,将流量路由到后端服务器。在这种情况下,它会路由到 Node.js 后端容器(web1 或 web2)。
通过运行以下命令验证容器是否已启动:
$ 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
如果您查看 Docker Desktop Dashboard,则可以看到容器并更深入地了解它们的配置。
一切准备就绪并运行后,您可以在浏览器中打开 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 中的实际计数器值仅在响应发送回客户端后才会更新。
您可以使用 Docker Desktop 控制面板通过选择容器并选择 Delete (删除) 按钮来删除容器。
使用 Docker Compose 简化部署
Docker Compose 为管理多容器部署提供了一种结构化且简化的方法。如前所述,使用 Docker Compose,您无需运行多个命令。您需要做的就是在一个名为 .让我们看看它是如何工作的。docker run
compose.yml
导航到项目目录的根目录。在此目录中,您将找到一个名为 .这个 YAML 文件是所有魔法发生的地方。它定义构成应用程序的所有服务及其配置。每个服务都指定其镜像、端口、卷、网络以及其功能所需的任何其他设置。compose.yml
使用以下命令启动应用程序:
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
如果您查看 Docker Desktop Dashboard,则可以看到容器并更深入地了解它们的配置。
或者,您可以使用 Docker Desktop 控制面板通过选择应用程序堆栈并选择 Delete (删除) 按钮来删除容器。
在本指南中,您了解了使用 Docker Compose 启动和停止多容器应用程序是多么容易,相比之下,多容器应用程序容易出错且难以管理。docker run