多容器应用程序
目录
- 概述
- 试一试
- 设置
- 构建镜像
- 运行容器
- 使用 Docker Compose 简化部署
概述
启动单容器应用程序很容易。例如,一个执行特定数据处理任务的 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 的计数器 web 应用程序、一个 Nginx 反向代理和一个 Redis 数据库。然后你会看到如何使用 Docker Compose
简化整个部署过程。
设置
获取示例应用程序。如果你有 Git
,你可以克隆示例应用程序的仓库。否则,你可以下载示例应用程序。选择以下选项之一。
使用 Git 克隆
在终端中使用以下命令克隆示例应用程序仓库。
sh
git clone https://github.com/dockersamples/nginx-node-redis
进入 nginx-node-redis
目录:
sh
cd nginx-node-redis
在这个目录中,你会找到两个子目录 - nginx
和 web
。
下载并安装 Docker Desktop
。
构建镜像
进入 nginx
目录,通过运行以下命令构建镜像:
sh
docker build -t nginx .
进入 web
目录,运行以下命令构建第一个 web
镜像:
sh
docker build -t web .
运行容器
在运行多容器应用程序之前,你需要创建一个网络,以便它们通过该网络进行通信。可以使用 docker network create
命令来创建网络:
sh
docker network create sample-app
运行以下命令启动 Redis
容器,并将其连接到先前创建的网络,并创建一个网络别名(对于 DNS 查找非常有用):
sh
docker run -d --name redis --network sample-app --network-alias redis redis
运行以下命令启动第一个 web
容器:
sh
docker run -d --name web1 -h web1 --network sample-app --network-alias web1 web
运行以下命令启动第二个 web
容器:
sh
docker run -d --name web2 -h web2 --network sample-app --network-alias web2 web
运行以下命令启动 Nginx
容器:
sh
docker run -d --name nginx --network sample-app -p 80:80 nginx
注意
Nginx
通常用作 web 应用程序的反向代理,将流量路由到后端服务器。在这种情况下,它将流量路由到Node.js
后端容器(web1
或web2
)。
运行以下命令验证容器是否已启动:
sh
docker ps
你将看到类似以下的输出:
plaintext
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 Dashboard
中查看,可以看到容器并深入了解它们的配置。
打开浏览器并访问 http://localhost
查看站点。多次刷新页面查看处理请求的主机和请求总数:
plaintext
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
)之间分配传入请求。这意味着每个请求可能会被轮流指向不同的容器。输出显示两个容器的连续递增,并且实际的计数器值在响应发送回客户端后才更新。
使用 Docker Dashboard
删除容器,选择容器并选择删除按钮。
使用 Docker Compose 简化部署
Docker Compose
提供了一种结构化和简化的方式来管理多容器部署。如前所述,使用 Docker Compose
,你不需要运行多个 docker run
命令。你只需在一个名为 compose.yml
的 YAML
文件中定义整个多容器应用程序。让我们看看它是如何工作的。
导航到项目目录的根目录。在这个目录中,你会找到一个名为 compose.yml
的文件。这个 YAML
文件定义了组成应用程序的所有服务及其配置。每个服务都指定了它的镜像、端口、卷、网络及其功能所需的任何其他设置。
使用 docker compose up
命令启动应用程序:
sh
docker compose up -d --build
运行此命令后,你应该看到类似以下的输出:
plaintext
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 Dashboard
中查看,可以看到容器并深入了解它们的配置。
你可以使用 Docker Dashboard
选择应用栈并选择删除按钮来移除容器。
在这个指南中,你学习了如何使用 Docker Compose
更轻松地启动和停止多容器应用程序。