Docker 是一个开源平台,它简化了应用程序的设计、交付和部署。它通过将应用程序的依赖项编译到所谓的容器中,在隔离的环境中运行应用程序。有关 Docker 的更多信息,请参阅。通常情况下,支持应用程序需要多种服务,例如数据库和负载平衡。
本文将介绍 Docker Compose 如何协助设置多项服务。此外,我们还将演示如何安装和使用 Docker Compose。让我们先来简单了解一下 docker-compose。
Docker Compose 将执行基于 YAML 的多容器应用程序。YAML 文件包含部署 Docker Compose 容器所需的所有配置。Docker Compose 与 Docker Swarm 集成,并提供构建和部署容器的指导。使用 Docker Compose,每个容器都构建为在单个主机上运行。
Docker Compose 中的关键概念
Docker Compose 是一款功能强大的多容器应用程序管理工具,掌握其关键组件(例如服务、网络、卷和环境变量)可以极大地提升其使用体验。让我们来详细分析一下这些概念以及它们在 Docker Compose 文件中的工作原理。
Docker Compose 文件(YAML 格式)
Docker Compose 配置主要存储在一个名为docker-compose.yml
的文件中,该文件使用YAML格式定义应用程序的环境。此文件包含设置和运行应用程序所需的所有详细信息,例如服务、网络和卷。要有效地使用 Docker Compose,您必须了解此文件的结构。
YAML 配置的关键元素
-
version:它定义 Compose 文件的格式,确保与特定的 Docker Compose 功能和语法兼容。
-
services:此
services
部分列出了应用程序所需的每个容器化服务。每个服务都有其配置选项,例如要使用的镜像、环境变量和资源限制。 -
networks:在网络部分,您可以定义自定义网络,以实现容器之间的通信。此外,它还允许您指定网络驱动程序和自定义设置,以组织容器交互。
-
volumes:volumes允许在容器重启后保留数据,并可在需要时在容器之间共享。卷使您能够在容器生命周期之外存储数据,这使其适用于共享存储或保存应用程序状态。
**例子**docker-compose.yml**
**
下面是一个示例 Compose 文件,其中定义了两个服务、一个共享网络和一个卷:
version: '3.8'
services:
web:
image: nginx:latest
ports:
- "80:80"
networks:
- frontend
volumes:
- shared-volume:/usr/share/nginx/html
depends_on:
- app
app:
image: node:14
working_dir: /app
command: node server.js # Specify a command
networks:
- frontend
volumes:
- shared-volume:/app/data
networks:
frontend:
driver: bridge
volumes:
shared-volume: # Remove incorrect syntax
解释:
-
web服务运行一个 Nginx 容器,app运行一个 Node.js 容器。
-
两种服务通过frontend网络连接,从而实现通信。
-
shared-volume卷安装在两个容器中,为文件提供共享存储。
Docker Compose 服务
在 Docker Compose 中,应用程序的每个组件都作为单独的服务运行,每个服务都运行一个针对特定角色(例如数据库、Web 服务器或缓存)定制的容器。这些服务在 docker-compose.yml
文件的 services
部分中定义。此部分允许您单独配置每个服务,指定要拉取的 Docker 镜像、环境变量、网络连接和存储选项等详细信息。通过此设置,您可以控制应用程序各个部分的交互方式,确保跨服务顺畅的通信和资源管理。
关键服务配置选项
-
Image:图像选项定义我们将通过 Docker Hub 或任何其他注册表中的服务使用哪个 Docker 图像。
-
Build:无需拉取镜像,您可以通过指定包含 Dockerfile 的目录在本地构建镜像。该构建方式非常适合在应用程序中添加自定义代码。
-
Ports:此设置将容器的内部端口映射到主机上的端口,从而可以从容器外部访问服务。
-
Volumes:卷将持久存储附加到服务,确保即使容器重启时数据仍然可访问。
-
Environment:环境变量允许您将配置或敏感信息(如数据库凭据或 API 密钥)传递给服务。
-
Depends_on: Depends_on 控制服务的启动顺序,确保某些容器在其他容器开始之前运行。
**配置示例 **docker-compose.yml**
**
下面是一个示例配置,演示了如何使用这些选项:
version: '3.8'
services:
db:
image: postgres:13
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
volumes:
- db_data:/var/lib/postgresql/data
web:
build: ./web
ports:
- "5000:5000"
volumes:
- web_data:/usr/src/app
environment:
- DATABASE_URL=postgres://user:pass@db:5432/mydb
depends_on:
- db
volumes:
db_data:
web_data:
解释:
-
db服务运行一个PostgreSQL容器。它使用环境变量设置数据库用户名和密码,并将数据存储在db_data卷上以确保其持久化保存。
-
web服务由./web目录中的 Dockerfile 构建,并公开端口 5000。web_data卷被挂载用于持久存储应用程序文件。它依赖于db服务,确保数据库在 Web 服务启动时可用。
Docker Compose 网络
Docker Compose 部署使用networks来实现服务之间的安全通信。docker-compose.yml 文件中定义的服务默认位于同一个网络中,无需任何额外设置即可相互连接。为了实现更严格的控制,您可以创建其他网络并将服务分配给这些网络,以便控制服务的通信方式,或根据需要将某些服务分组。
关键网络配置选项
-
Driver:Driver 用于网络驱动程序类型,例如
bridge
(本地网络的默认设置)或( Docker Swarmoverlay
中的多主机网络),它决定了服务如何相互连接。 -
驱动程序选项(driver_opts):驱动程序选项允许对网络驱动程序进行附加设置,有助于微调网络行为以满足特定需求。
-
IP 地址管理(ipam):IP 地址管理配置网络级 IP 设置,如子网和 IP 范围,让您更好地控制分配给服务的 IP 地址空间。
自定义网络示例
下面是一个示例 Compose 文件,它设置了两个网络,一个用于数据库通信,另一个用于 Web 访问。
version: '3.8'
services:
db:
image: postgres:13
networks:
- backend
web:
image: nginx:latest
networks:
- frontend
- backend
ports:
- "80:80"
networks:
frontend:
driver: bridge
backend:
driver: bridge
ipam:
config:
- subnet: 172.16.238.0/24
解释:
-
db服务使用backend网络,将其与frontend网络隔离以限制访问。
-
web服务连接到frontend和backend网络,使其能够与db服务通信,同时仍然可通过frontend网络访问。`webbackenddbfrontend`
-
backend网络包括具有特定子网范围的 IPAM 设置,确保自定义 IP 地址管理。
Docker Compose 数据卷
Docker Compose 中的卷用于持久化 Docker 容器创建或使用的数据。这样,即使容器在 Docker Compose 中停止或移除,数据也能持久化。在 docker-compose.yml 文件中,volumes 部分描述了所有连接到服务的卷,让您可以管理独立于容器生命周期的数据。
关键卷配置选项
-
External:设置为 true 表示该卷是在 Docker Compose 之外外部创建的(例如通过
docker volume create
)并且只是在配置中引用。 -
Driver:指示卷应使用哪个卷驱动程序,并控制如何处理这些卷。默认情况下,驱动程序是本地的,但也可以使用其他选项。
-
Driver Options (driver_opts):用于自定义卷驱动程序的附加选项,如文件系统类型或不同的存储参数。
docker-compose 数据卷示例
这里有一个实际的例子,展示如何为 PostgreSQL 数据库配置卷,确保其数据持久存储。
version: '3.8'
services:
db:
image: postgres:13
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
volumes:
- db_data:/var/lib/postgresql/data
volumes:
db_data:
driver: local
driver_opts:
type: none
o: bind
device: /path/to/local/db_data
解释
-
db服务运行一个 PostgreSQL 容器,其数据存储在db_data卷中。此设置可确保在容器重启或删除后数据库信息仍然完整。
-
db_data卷已配置为使用local驱动程序,并且其驱动程序选项已设置为创建指向主机系统上特定路径( /path/to/local/db_data)的绑定挂载。这意味着所有数据库文件都保存在主机上的指定目录中。
-
通过这种方式使用卷,您可以保证重要数据的安全且易于访问,并与容器本身分开。
Docker Compose 环境变量
环境变量是一种简单有效的方法,可以通过 Docker Compose 从主机操作系统传递配置设置来访问服务。您可以使用 environment 部分直接在服务定义上设置这些变量,也可以从外部文件加载它们。
如何在 Docker Compose 中设置环境变量?
-
Inline:您可以在服务定义中直接声明环境变量。这种方法很简单,并且将所有内容集中在一个地方。
-
env_file:此选项允许您从外部文件加载环境变量,从而更容易管理配置,特别是在处理许多变量时。
docker-compose使用环境变量的示例
下面是一个示例,演示了为 Web 应用程序和数据库服务设置环境变量的两种方法。
version: '3.8'
services:
db:
image: postgres:13
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
volumes: - db_data:/var/lib/postgresql/data
web: image: my-web-app:latest
build: ./web
environment:
- DATABASE_URL=postgres://user:pass@db:5432/mydb
env_file:
- .env
volumes:
db_data:
解释
-
在db服务中,和环境变量是内联定义的,直接指定数据库凭据。`dbPOSTGRES_USERPOSTGRES_PASSWORD`
-
该服务使用 的内联变量连接到 PostgreSQL 数据库。此外,它还从名为 的外部文件加载环境变量。该文件可以包含各种设置,例如 API 密钥、应用程序配置和其他敏感信息。`webDATABASE_URL.env`
通过充分理解这些基本原理,开发人员就可以使用 Docker Compose 来管理和编排可能非常复杂且涉及许多 Docker 容器的应用程序。
安装 Docker Compose
我们可以在 macOs、Widows 和 64 位 Linux 上运行 Docker Compose。
-
对于任何重要的活动,Docker Compose 都依赖于 Docker Engine。根据您的安排,我们必须确保 Docker Engine 安装在本地或远程。
-
桌面系统(例如 Mac 和 Windows 版 Docker)预装了 Docker Compose。
-
在开始安装 Docker Compose 之前, 请先按照Linux系统上的Docker 安装中的说明安装 Docker。
在 Ubuntu 上安装 Docker Compose – 分步指南
步骤 1:更新包管理器
- 以下脚本将安装最新版本的 Docker Compose 并更新包管理。
sudo apt-get 更新
第 2 步:下载软件
- 这里我们使用的是Linux操作系统中的Ubuntu版本。因此,包管理器是“apt-get”。如果您想在Redhat Linux中安装它,那么包管理器将是“yum”。
步骤 3:应用权限
- 使用以下命令将可执行权限应用于软件:
sudo chmod +x /usr/local/bin/docker-compose
步骤4:验证下载的软件
- 使用以下命令验证docker compose是否安装成功:
docker-compose --version
Docker容器
Docker 容器是一个基于 Linux 的轻量级系统,它打包了应用程序的所有库和依赖项,这些库和依赖项是预先构建好的,可以直接执行。它是一个独立的运行镜像,让应用程序感觉整个系统都是为其专属的。许多大型组织正在从虚拟机转向容器,因为它们轻量级且易于使用和维护。但是,当将容器用于实际应用程序时,通常一个容器是不够的。例如,假设 Netflix 使用微服务架构。它需要身份验证、登录、数据库、支付等服务,而对于每个服务,我们都希望运行一个单独的容器。容器最好只用于单一用途。
现在,想象一下编写单独的 Docker 文件,并管理每个容器的配置和网络。这时,Docker Compose 就派上用场了,它让我们的工作变得轻松。
为什么选择 Docker Compose?
如前所述,现实世界中的应用程序为其每个服务都有一个单独的容器。我们知道每个容器都需要一个 Dockerfile。这意味着我们可能需要编写数百个 Docker 文件,然后分别管理每个容器的所有内容,这非常繁琐。
因此,我们使用 docker-compose,这是一个帮助定义和运行多容器应用程序的工具。借助 Docker Compose,您可以使用其 YAML 文件来启动和停止服务。Docker-compose 允许我们仅使用几个简单的命令和每个配置一个 YAML 文件来启动和停止所有服务。
与使用 Docker Hub 中预构建的镜像(可以使用 docker-compose.yaml 文件进行配置)不同,如果您使用自定义镜像,则需要在单独的 Dockerfile 中声明其配置。以下是 docker-compose 支持的功能:
-
所有服务均在单个主机上独立运行。
-
仅当发生变化时才会重新创建容器。
-
创建新容器时不会重置卷数据,卷会被保留。
-
环境内的变量和组成的运动。
-
它创建了一个虚拟网络,以便在环境内轻松进行交互。
现在,让我们通过一个简单的项目看看如何使用 docker-compose。
如何使用 Docker Compose?
在这个项目中,我们将创建一个简单的Restfull 应用I,它将返回一个水果列表。我们将使用 Flask 来实现这个功能。一个PHP应用程序将请求此服务并将其显示在浏览器中。这两个服务都将在各自的容器中运行。
步骤1:创建项目目录
- 首先,为我们的完整项目创建一个单独的目录。使用以下命令。
mkdir dockerCompose项目
- 移至目录内。
cd dockerCompose项目
步骤 2:创建 API
我们将创建一个自定义镜像,使用Python来提供下面定义的Restful API。然后,我们将使用Dockerfile进一步配置该服务。
- 然后为该服务创建一个子目录,我们将其命名为产品,并移入其中。
mkdir 产品
cd 产品
- 创造
requirements.txt
在文件夹中product
,创建一个名为的文件requirements.txt
并添加以下依赖项:
烧瓶
烧瓶休息
步骤3:构建Python api.py
-
以下是有助于进行 API 调用的 python 文件:
-
创建一个 Dockerfile 来定义上述 API 将在其中运行的容器。
从 flask 导入 Flask
从 flask_restful 导入 Resource, Api
# 创建一个 flask 对象
app = Flask(__name__)
api = Api(app)
# 为 Fruits 创建一个类,用于保存
# 访问器
class Fruits(Resource):
def get(self):
返回一个包含水果的字典
return {
‘fruits’: [‘Mango’, ‘Pomegranate’, ‘Orange’, ‘Litchi’]
}
# 在根路由添加资源
api.add_resource(Fruits, ‘/’)
# 如果此文件正在执行,则运行服务
if __name__ == ‘__main__’:
运行服务
app.run(host=’0.0.0.0′, port=80, debug=True)
步骤4:为Python API创建Dockerfile
从 python:3
WORKDIR /usr/src/app
复制 requirements.txt .
运行 pip install –no-cache-dir -r requirements.txt
复制 . .
CMD [“python”, “api.py”]
FROM 命令接受镜像名称和 Docker 将从 Docker Hub 下载的版本号。可以使用 copy 命令将当前工作目录的内容复制到服务器期望的代码所在位置。此外,CMD 命令会接受一个命令列表,用于在容器启动后启动服务。
步骤5:创建PHP HTML网站
让我们使用PHP创建一个使用我们的API 的简单网站。
- 移动到父目录并为网站创建另一个子目录。
cd ..
mkdir 网站
cd 网站
索引.php
\
\
\
\
\
\
\
欢迎来到印度水果店\
\
- $fruit\ “;
\ $json = file_get_contents(‘http://fruit-service‘);
$obj = json_decode($json);
$fruits = $obj->fruits;
foreach ($fruits as $fruit){
echo “\
}
?>
\
\
\
-
现在创建一个组合文件,我们将在其中定义和配置两个服务,API 和网站。
-
使用以下代码移出网站子目录。
光盘 ..
- 然后创建文件名为.docker-compose.yaml
步骤6:创建Docker-compose.yaml文件
- 以下是示例docker compose文件代码:
版本:“3”
服务:
水果服务:
构建:./
product 卷:
-./product:/usr /src/
app 端口:
-5001:80
网站:
图片:php:apache
卷:
-./ website:/var/www/html
端口:
-5000:80
取决于:
-水果服务
Docker-compose.yaml 文件
第一行是可选的,我们指定了 docker-compose 工具的版本。接下来的服务定义了我们的应用程序将要使用的服务列表。第一个服务是水果服务,它是我们的 API,第二个服务是我们的网站。水果服务有一个属性 build,其中包含要构建并创建为镜像的 dockerfile。卷定义了主机和容器之间的存储映射,以便我们可以进行实时更改。最后,端口属性通过主机的 5001 端口公开容器的 80 端口。
网站服务不使用自定义镜像,而是从 Docker Hub 下载 PHP 镜像,然后将包含 index.php 的 website 文件夹映射到 /var/www/html(PHP 期望代码位于此位置)。Ports 暴露容器端口。最后,depends_on 指定当前服务所依赖的所有服务。
- 创建所有必需的文件和目录后的文件夹结构如下:
使用 Docker Compose 运行应用程序堆栈
-
现在我们有了 docker-compose.yml 文件,我们可以运行它。
-
要启动应用程序,请输入以下命令。
docker-compose up -d
现在所有服务都将启动,我们的网站将可以在localhost:5000上使用。
- 打开浏览器并输入localhost:5000。
输出
- 要停止应用程序,请按 CTRL + C 或
docker-compose 停止
Docker Compose 的优势
Docker Compose 的优点如下:
-
简化多容器管理:Docker Compose 具有使用单个 YAML 文件定义、配置和运行多个容器等功能,简化了复杂应用程序的管理。
-
促进环境一致性:它促进与降低环境相关问题风险相一致的开发、测试和生产环境。
-
自动化多容器工作流程:使用 Docker Compose,您可以轻松自动化多容器环境的设置和拆卸,使其成为 CI/CD 管道和开发工作流程的理想选择。
-
高效的资源管理:能够跨多个容器高效地分配和管理资源,提高应用程序的性能和可扩展性。
Docker Compose 的缺点
Docker Compose 的缺点如下:
-
可扩展性有限:Docker Compose 不是为大规模扩展机制而开发的,这会限制其管理复杂部署的有效性。
-
单主机限制:Docker Compose 将在单个主机上运行,因此不适合需要多主机编排的分布式应用程序。
-
基本负载平衡:它缺乏 Kubernetes 等更强大的编排工具中提供的高级负载平衡和自动扩展功能。
-
监控功能不够强大:与更全面的解决方案相比,Docker Compose 提供的内置监控和日志记录功能最少。
重要的 Docker Compose 命令
命令 | 描述 | 例子 |
---|---|---|
docker-compose up | 此命令将启动文件中定义的所有服务docker-compose.yml 。如果必要的容器、网络和卷尚不存在,它将创建它们。您可以通过添加-d 选项在后台运行它。 |
docker-compose up -d |
docker-compose down | 使用此命令停止并删除由 创建的所有容器、网络和卷docker-compose up 。当您不再需要运行该应用程序时,这是清理资源的好方法。 |
docker-compose down |
docker-compose ps | 此命令列出与 Compose 应用关联的所有容器,显示其当前状态和其他有用信息。它非常适合监控哪些服务已启动并正在运行。 | docker-compose ps |
docker-compose日志 | 此命令可让您查看服务生成的日志。如果您要关注特定服务,可以指定其名称来过滤日志,这对于故障排除非常有用。 | docker-compose log web |
docker-compose exec | 使用此命令,您可以在正在运行的服务容器中运行命令。这对于调试或直接与服务交互特别有用。 | docker-compose exec db psql -U 用户 -d mydb |
docker-compose构建 | 此命令用于构建或重新构建文件中指定的镜像docker-compose.yml 。当您更改 Dockerfile 或想要更新镜像时,此命令非常方便。 |
docker-compose build |
docker-compose pull | 使用此命令从相应的镜像仓库中拉取服务的最新镜像。它可以确保您在启动应用程序之前拥有最新版本。 | docker-compose pull |
docker-compose 启动 | 此命令会启动 Compose 文件中已定义的容器,而无需重新创建它们。这是一种快速恢复已停止服务的办法。 | docker-compose restart |
docker-compose 停止 | 此命令将停止正在运行的容器但保持它们完好无损,因此您可以稍后使用 重新启动它们docker-compose start 。 |
docker-compose stop |
docker-compose 配置 | 此命令验证并显示文件中的配置docker-compose.yml 。这是在部署应用程序之前检查任何错误的有用方法。 |
docker-compose config |
Docker Compose最佳实践
以下是Docker Compose的一些最佳实践:
-
使用环境变量:建议将配置值和秘密存储在环境变量中,以保持
docker-compose.yml
清洁和安全。 -
保持服务轻量级:最好将每个服务设计为处理单一职责,以确保模块化和易于维护。
-
利用卷:利用卷来增强维护持久数据存储的能力,使数据能够在容器重启和更新后继续保留。
-
对您的 Compose 文件进行版本控制:最好
docker-compose.yml
在版本控制(例如,Git)中维护您的文件,以跟踪更改并有效地与您的团队合作。
Docker Compose 的功能
Docker Compose 的功能如下:
-
多容器部署:它有助于使用单个 YAML 文件轻松定义和运行具有多个容器的应用程序。
-
服务隔离:每个服务运行在自己的容器中,保证服务之间的隔离,减少服务之间的冲突。
-
简化配置:它有助于将所有配置(包括网络、卷和依赖项)集中在
docker-compose.yml
文件中。 -
可扩展性:它可以通过单个命令轻松地扩大或缩小服务规模,从而实现灵活、动态的资源管理。
结论
在本文中,我们了解了 Docker Compose,以及使用它的原因和时机。并通过一个简单的项目演示了它的用法。它通过服务、网络和卷(以及相应的关键字)帮助自动化容器的创建过程。通过使用 Docker Compose,容器及其卷和网络的管理和自动化将变得更加轻松。