图解Docker Compose 架构设计分析与全攻略:构建、扩展和综合案例(第二部分)

2 篇文章 0 订阅
1 篇文章 0 订阅

在这里插入图片描述

Docker Compose 是 Docker 官方编排工具,它允许用户通过简洁的 YAML 文件定义多容器的 Docker 应用程序。无论是开发者、系统管理员还是 DevOps 工程师,Docker Compose 都能帮助轻松地管理复杂的服务堆栈。通过本文,将深入了解 Docker Compose 的强大功能和使用场景,探索如何利用它来简化开发、测试和部署流程。无论是初学者还是希望优化现有工作流的高级用户,本文都将为提供实用的指导和技巧。让我们开始这段精彩的 Docker Compose 实战之旅吧!

肖哥弹架构 跟大家“弹弹” 高并发锁, 关注公号回复 ‘mvcc’ 获得手写数据库事务代码

欢迎 点赞,关注,评论。

关注公号Solomon肖哥弹架构获取更多精彩内容

历史热点文章

5. 卷管理

在 Docker Compose 中,卷管理是一个重要的特性,它允许定义和管理数据卷,以实现数据的持久化和在多个容器间共享数据。

5.1 独立卷

在这里插入图片描述
在这里插入图片描述

5.2 共享卷

在这里插入图片描述

5.3. 定义卷

docker-compose.yml 文件中,可以使用 volumes 部分来定义一个或多个卷。这些卷可以被一个或多个服务使用。

5.4. 数据持久化

数据卷用于持久化容器生成的数据。默认情况下,当容器被删除时,与容器相关联的挂载数据也会丢失。通过使用数据卷,可以确保数据在容器生命周期之外持久保存。

5.5. 数据共享

多个容器可以挂载同一个数据卷,从而实现数据的共享。这对于需要多个容器访问同一数据集的应用非常有用,例如分布式缓存或共享配置文件。

5.6. 卷的类型
  • 命名卷:由 Docker 管理,可以在 Docker Host 上的特定位置找到。
  • 匿名卷:没有指定名称的卷,完全由 Docker 管理,不显示在 Docker 的卷列表中。
  • 绑定挂载:将宿主机的文件系统上的一个目录或文件挂载到容器内部。绑定挂载可以是指定的路径或者是当前目录的一个相对路径。
5.7. 使用案例

以下是一个 docker-compose.yml 文件的案例,它定义了两个服务:一个 Web 应用和一个数据库,以及一个用于持久化数据库数据的卷。

version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保语法和功能与 Docker Engine 版本兼容

services:  # 定义服务的根节点
  db:  # 定义一个名为 db 的服务
    image: postgres:13  # 使用官方的 PostgreSQL 镜像,版本为 13
    volumes:  # 定义挂载到此服务的卷
      - db-data:/var/lib/postgresql/data  # 将命名卷 db-data 挂载到容器的 PostgreSQL 数据目录
    environment:  # 设置环境变量,用于配置 PostgreSQL
      POSTGRES_USER: user  # 设置数据库用户
      POSTGRES_PASSWORD: password  # 设置数据库用户密码
      POSTGRES_DB: dbname  # 设置数据库名

  web:  # 定义一个名为 web 的服务
    image: nginx:alpine  # 使用官方的 Nginx 镜像,基于 Alpine Linux,更轻量
    volumes:  # 定义挂载到此服务的卷
      - web-data:/usr/share/nginx/html  # 将命名卷 web-data 挂载到 Nginx 的默认根目录
    ports:  # 定义端口映射
      - "80:80"  # 将容器内部的 80 端口映射到宿主机的 80 端口,实现外部访问

volumes:  # 定义命名卷的根节点
  db-data:  # 定义一个名为 db-data 的命名卷,用于持久化数据库数据
  web-data:  # 定义一个名为 web-data 的命名卷,用于持久化 Web 服务数据
5.8. 卷的高级特性
  • 卷驱动:Docker 允许使用特定的卷驱动来扩展默认的卷功能。例如,可以使用 rexray 或其他卷驱动来提供云存储集成。
  • 访问控制:可以控制哪些容器可以访问特定的卷。
  • 卷的备份和迁移:可以备份和迁移卷以实现数据的灾难恢复。
5.9. 使用卷的注意事项
  • 性能:数据卷的读写性能可能不如容器内部存储,因此对于性能敏感的应用,需要进行适当的测试。
  • 管理:随着卷数量的增加,管理卷的复杂性也会增加。需要定期清理未使用的卷以节省空间。
6. 环境变量和配置

在 Docker Compose 中,环境变量和配置用于在不同环境之间调整服务的行为而无需更改代码。这些配置可以定义在 docker-compose.yml 文件中,也可以通过文件或命令行传递。
在这里插入图片描述

图解释:
  • docker-compose.yml: Docker Compose 的配置文件,定义了所有服务。
  • Web Service, DB Service: 这些是在配置文件中定义的服务。
  • .env 文件: 包含环境变量定义的文件,Web 服务通过 env_file 关键字加载这些环境变量。
  • settings.ini: 包含配置定义的文件,DB 服务通过 configs 关键字加载这个配置文件。
  • /app 卷: 挂载到 Web 服务和 DB 服务的卷,用于代码部署和数据持久化。
6.1. 设置环境变量

环境变量可以在服务定义中直接设置,或者通过一个单独的文件加载。

在服务定义中直接设置

docker-compose.yml 文件中,使用 environment 关键字直接定义环境变量:

version: '3.8'  # 指定 Docker Compose 文件使用的版本,'3.8' 是该文件遵循的格式版本,确保兼容性

services:  # 定义服务的根节点,下面会列出所有的服务

  app:  # 定义一个服务,名称为 app
    image: python:3.8  # 指定服务使用的镜像,这里使用 Python 3.8 的官方镜像
    environment:  # 定义环境变量,这些变量会在容器启动时设置
      - DEBUG=True  # 设置环境变量 DEBUG,并赋予值 True,用于控制是否开启调试模式
      - NODE_ENV=development  # 设置环境变量 NODE_ENV,并赋予值 development,表示当前环境为开发环境
    volumes:  # 定义挂载卷,用于数据持久化或在宿主机和容器间共享数据
      - ./:/app  # 将宿主机当前目录挂载到容器内的 /app 目录,冒号前面是宿主机路径,冒号后面是容器内路径
    ports:  # 定义端口映射,将容器内部的端口映射到宿主机的端口
      - "5000:5000"  # 将容器内的 5000 端口映射到宿主机的 5000 端口,这样可以通过宿主机的 5000 端口访问容器内的应用

在这个例子中,app 服务被设置了两个环境变量 DEBUGNODE_ENV

通过文件加载环境变量

创建一个 .env 文件,在文件中定义环境变量:

DEBUG=True
NODE_ENV=development

然后在 docker-compose.yml 文件中引用该文件:

version: '3.8'  # 指定 Docker Compose 文件使用的版本,'3.8' 是该文件遵循的格式版本,确保兼容性

services:  # 定义服务的根节点,下面会列出所有的服务

  app:  # 定义一个服务,名称为 app
    image: python:3.8  # 指定服务使用的镜像,这里使用 Python 3.8 的官方镜像
    env_file:  # 定义从文件中加载环境变量
      - .env  # 指定环境变量文件的路径,文件应该位于 Docker Compose 文件所在的目录或子目录
    volumes:  # 定义挂载卷,用于数据持久化或在宿主机和容器间共享数据
      - ./:/app  # 将宿主机当前目录挂载到容器内的 /app 目录,冒号前面是宿主机路径,冒号后面是容器内路径
    ports:  # 定义端口映射,将容器内部的端口映射到宿主机的端口
      - "5000:5000"  # 将容器内的 5000 端口映射到宿主机的 5000 端口,这样可以通过宿主机的 5000 端口访问容器内的应用
6.2. 使用环境变量

在 Java 代码中读取环境变量:

import java.util.Map;

public class EnvVariables {
    public static void main(String[] args) {
        // 获取系统属性 Map
        Map<String, String> envMap = System.getenv();

        // 从环境变量中获取 'DEBUG' 的值
        String debug = envMap.getOrDefault("DEBUG", "False");
        System.out.println("Debug mode is: " + debug);

        // 从环境变量中获取 'NODE_ENV' 的值
        String nodeEnv = envMap.getOrDefault("NODE_ENV", "production");
        System.out.println("Node environment is set to: " + nodeEnv);
    }
}
6.3. 配置服务

除了环境变量,Docker Compose 还允许通过 configs 关键字来配置服务。这允许将配置文件从服务中分离出来。

创建配置文件

创建一个配置文件 settings.ini

debug = true
log_level = debug
docker-compose.yml 文件中引用配置文件
version: '3.8'  # 指定 Docker Compose 文件使用的版本,'3.8' 是该文件遵循的格式版本,确保兼容性

services:  # 定义服务的根节点,下面会列出所有的服务

  app:  # 定义一个服务,名称为 app
    image: python:3.8  # 指定服务使用的镜像,这里使用 Python 3.8 的官方镜像
    configs:  # 定义服务使用的配置文件
      - my_config  # 引用配置文件的名称,这个名称要与下方的 configs 部分的名称相匹配
    volumes:  # 定义挂载卷,用于数据持久化或在宿主机和容器间共享数据
      - ./:/app  # 将宿主机当前目录挂载到容器内的 /app 目录,冒号前面是宿主机路径,冒号后面是容器内路径
    ports:  # 定义端口映射,将容器内部的端口映射到宿主机的端口
      - "5000:5000"  # 将容器内的 5000 端口映射到宿主机的 5000 端口,这样可以通过宿主机的 5000 端口访问容器内的应用

configs:  # 定义配置文件的根节点
  my_config:  # 定义一个配置文件,名称为 my_config
    file: ./settings.ini  # 指定配置文件的路径,文件应该位于 Docker Compose 文件所在的目录或子目录
6.4. 使用配置文件

容器内部可以通过挂载的卷来读取配置文件,在 Java 代码中读取配置文件:

import java.io.File;
import java.io.FileReader;
import java.util.Properties;

public class ConfigReader {
    public static void main(String[] args) {
        // 创建 Properties 对象
        Properties config = new Properties();

        try {
            // 读取配置文件
            config.load(new FileReader(new File("/config/settings.ini")));

            // 获取 'Settings' 区段下的 'debug' 配置项
            String debug = config.getProperty("Settings.debug");
            System.out.println("Debug level is set to: " + debug);

            // 获取 'Settings' 区段下的 'log_level' 配置项
            String logLevel = config.getProperty("Settings.log_level");
            System.out.println("Log level is set to: " + logLevel);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
6.5. 环境变量和配置的应用场景
  • 开发与生产环境分离:在开发环境中,可能需要开启调试模式;而在生产环境中,则需要关闭调试模式并更改日志级别。
  • 多环境配置:不同的部署环境(如测试、预发布、生产)可能需要不同的配置。
  • 敏感信息管理:敏感信息(如数据库密码)不应硬编码在代码中,而是通过环境变量来管理。
7. 扩展和负载均衡

在 Docker Compose 中,通过指定服务的复制数量可以实现服务的扩展和负载均衡。这允许你轻松地对服务进行扩展以处理更多的负载,同时在多个容器之间分配请求。
在这里插入图片描述

图解释:
  • docker-compose.yml: Docker Compose 的配置文件,定义了所有服务和配置。
  • Web Service: 定义的 Web 服务,用于处理应用程序的请求。
  • Load Balancer: 定义的负载均衡器服务,用于分配流量到 Web 服务的多个实例。
  • Config: my_config: 定义的配置文件,包含应用程序的配置设置。
  • 3 replicas: 表示 Web 服务有 3 个副本,即服务被扩展到 3 个容器。
  • Volume: loadbalancer.conf: 负载均衡器的配置文件,定义了如何将流量分配到 Web 服务的多个实例。
  • Port 80: 宿主机的 80 端口映射到负载均衡器的 80 端口,用于访问 Web 服务。
7.1. 扩展服务

在 Docker Compose 中,你可以使用 scale 命令或者在 docker-compose.yml 文件中指定服务的副本数量来扩展服务。

使用 docker-compose scale 命令
docker-compose up -d --scale web=3

这个命令会启动 3 个 web 服务的副本。

docker-compose.yml 文件中指定副本数量
version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  web:  # 定义一个名为 web 的服务
    image: nginx:alpine  # 使用 Nginx 的 Alpine 版本镜像,Alpine 版本的镜像体积小,启动速度快
    deploy:  # Docker Swarm 模式的部署配置,用于管理服务的扩展和更新
      replicas: 3  # 设置服务的副本数量为 3,即启动 3 个相同的服务实例,实现服务的扩展

在这个例子中,web 服务被设置为启动 3 个副本。

7.2. 负载均衡

当服务有多个副本时,Docker Compose 可以使用内置的负载均衡器在容器之间分配流量。
在这里插入图片描述

使用 Docker Compose 的负载均衡

docker-compose.yml 文件中,你可以定义一个负载均衡器服务:

version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  web:  # 定义一个名为 web 的服务
    image: nginx:alpine  # 使用 Nginx 的 Alpine 版本镜像,Alpine 版本的镜像更轻量
    deploy:  # 使用 Docker Swarm 模式的部署配置
      replicas: 3  # 设置服务的副本数量为 3,即启动 3 个相同的服务实例
      # 以下配置为 Docker Swarm 模式下的负载均衡配置
      update_config:  # 定义服务更新的配置
        parallelism: 2  # 指定同时更新的容器数量
        delay: 10s  # 指定更新之间的延迟时间
        failure_action: continue  # 指定更新失败时的行动,继续更新
        order: start-first  # 指定更新的顺序,先启动新容器再停止旧容器

  loadbalancer:  # 定义一个名为 loadbalancer 的服务,用于负载均衡
    image: nginx:alpine  # 使用 Nginx 的 Alpine 版本镜像
    volumes:  # 定义挂载卷
      - ./loadbalancer.conf:/etc/nginx/nginx.conf:ro  # 将宿主机的 loadbalancer.conf 配置文件挂载到容器的 Nginx 配置目录
    depends_on:  # 定义服务的依赖关系,确保 loadbalancer 服务在 web 服务之后启动
      - web  # loadbalancer 服务依赖于 web 服务
    ports:  # 定义端口映射
      - "80:80"  # 将容器的 80 端口映射到宿主机的 80 端口,实现外部访问

configs:  # 定义配置文件的根节点
  my_config:  # 定义一个名为 my_config 的配置
    file: ./settings.ini  # 指定配置文件的路径,文件应该位于 Docker Compose 文件所在的目录或子目录

在这个例子中,loadbalancer 服务使用 Nginx 作为负载均衡器,并且配置文件 loadbalancer.conf 定义了如何在 web 服务的多个副本之间分配流量。

7.3. 服务发现

Docker Compose 允许服务之间通过服务名称进行通信,这使得负载均衡器可以轻松地发现并路由到各个 web 服务实例。
Nginx 负载均衡器的配置文件(loadbalancer.conf)可能包含以下内容:

http {
    upstream web_service {
        server web1;
        server web2;
        server web3;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://web_service;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
    }
}

在这个配置中,upstream 定义了一个服务器组 web_service,包含三个 Web 服务实例(这里假设它们是 web1web2web3,实际名称由 Docker 内部分配)。然后,Nginx 将所有进入的请求转发到这个服务器组。

7.4. 使用场景
  • 高可用性:通过在多个容器之间分配请求,提高应用程序的可用性和可靠性。
    • 高可用性可以通过运行多个服务副本来实现,确保如果一个容器失败,其他容器仍然可以处理请求。
    • docker-compose up: 运行 docker-compose up 命令时,可以使用 -d 标志来启动服务的多个副本。
    • docker-compose scale: 使用 docker-compose scale 命令可以动态调整服务的副本数量,例如 docker-compose scale web=3 将启动 3 个 web 服务的副本。
    • docker service create: 在 Docker Swarm 模式下,使用 docker service create 命令创建服务时,可以指定 --replicas 参数来设置副本数。
  • 高性能:通过扩展服务来处理更多的并发请求,提高应用程序的性能。
  • 灵活的伸缩:根据需求轻松地增加或减少服务的副本数量。
7.5. 注意事项
  • 网络配置:确保所有服务都在同一个网络中,以便它们可以相互通信。
  • 资源管理:考虑宿主机的资源限制,确保有足够的资源来支持多个服务副本。
  • 配置管理:确保负载均衡器正确配置,以便它可以正确地分配流量。
8. 模板和参数化

在 Docker Compose 中,模板和参数化是一种强大的功能,允许使用变量和环境变量来动态替换配置文件中的内容。这样做可以让轻松地调整配置,以适应不同的环境(如开发、测试和生产环境),而无需修改配置文件本身。
在这里插入图片描述

图解释:
  • docker-compose.yml: Docker Compose 的配置文件,定义了所有服务。
  • Web Service: 定义的 Web 服务,用于处理应用程序的请求。
  • .env 文件: 包含环境变量定义的文件,Docker Compose 在启动服务时会加载这个文件。
  • 环境变量 DEBUG, NODE_ENV, APP_IMAGE, APP_NAME: 在 docker-compose.yml 文件中引用的环境变量,它们可以从 .env 文件或外部环境中获取值。
8.1. 环境变量

环境变量是在操作系统级别定义的,Docker Compose 可以读取这些环境变量并将其用于配置服务。

使用环境变量

docker-compose.yml 文件中,可以使用环境变量:

version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  app:  # 定义一个名为 app 的服务
    image: python:3.8  # 指定服务使用的镜像,这里使用 Python 3.8 的官方镜像
    environment:  # 定义环境变量,这些变量会在容器启动时设置
      - DEBUG=${DEBUG}  # 设置环境变量 DEBUG,并从当前环境中获取其值,如果未设置,则为空字符串
      - NODE_ENV=${NODE_ENV}  # 设置环境变量 NODE_ENV,并从当前环境中获取其值,如果未设置,则为空字符串

在这个例子中,DEBUGNODE_ENV 环境变量的值将从运行 Docker Compose 的环境中获取。如果这些环境变量未设置,它们将被当作空字符串处理。

设置环境变量

可以在运行 Docker Compose 命令时设置环境变量:

DEBUG=1 NODE_ENV=development docker-compose up

这将设置 DEBUG1NODE_ENVdevelopment,然后启动服务。

8.2. 变量插值

变量插值允许在 docker-compose.yml 文件中使用其他变量的值。

使用变量插值

docker-compose.yml 文件中定义变量:

version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

# 在文件顶部定义一个变量 x-app-name,并赋予它值 myapp
x-app-name: myapp

services:  # 定义服务的根节点,下面列出了所有的服务

  app:  # 定义一个名为 app 的服务
    image: ${APP_IMAGE:-python:3.8}  # 使用环境变量 APP_IMAGE 来指定服务使用的镜像;如果未设置,则默认使用 python:3.8
    environment:  # 定义环境变量,这些变量会在容器启动时设置
      APP_NAME: ${APP_NAME:-${x-app-name}}  # 设置环境变量 APP_NAME,使用环境变量 APP_NAME 的值;如果未设置,则使用 x-app-name 变量的值

在这个例子中:

  • APP_IMAGE 变量默认为 python:3.8,如果未在环境变量中定义。
  • APP_NAME 变量默认为 myapp,它是从 x-app-name 变量继承的值。
设置变量

可以在运行 Docker Compose 命令时设置变量:

APP_IMAGE=python:3.7 APP_NAME=my-new-app docker-compose up

这将设置 APP_IMAGEpython:3.7APP_NAMEmy-new-app,然后启动服务。

8.3. 使用.env 文件

可以在 .env 文件中定义变量,Docker Compose 会自动加载这些变量。

创建 .env 文件

在项目根目录下创建一个 .env 文件:

DEBUG=1
NODE_ENV=development
APP_IMAGE=python:3.7
APP_NAME=my-new-app
使用 .env 文件

docker-compose.yml 文件中引用这些变量:

version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  app:  # 定义一个名为 app 的服务
    image: ${APP_IMAGE}  # 使用环境变量 APP_IMAGE 来指定服务使用的镜像;如果未设置,则默认为空,可能需要在 .env 文件或环境中提供

    environment:  # 定义环境变量,这些变量会在容器启动时设置
      DEBUG: ${DEBUG}  # 设置环境变量 DEBUG,使用环境变量 DEBUG 的值;如果未设置,则为空
      NODE_ENV: ${NODE_ENV}  # 设置环境变量 NODE_ENV,使用环境变量 NODE_ENV 的值;如果未设置,则为空
      APP_NAME: ${APP_NAME}  # 设置环境变量 APP_NAME,使用环境变量 APP_NAME 的值;如果未设置,则为空

当运行 docker-compose up 命令时,Docker Compose 会自动加载 .env 文件中的变量。

8.4. 使用场景
  • 开发与生产环境分离:在开发环境中,可能需要开启调试模式;而在生产环境中,则需要关闭调试模式并更改日志级别。
  • 多环境配置:不同的部署环境(如测试、预发布、生产)可能需要不同的配置。
  • 敏感信息管理:敏感信息(如数据库密码)不应硬编码在代码中,而是通过环境变量来管理。
9. 多环境配置

Docker Compose 允许使用多个 docker-compose.yml 文件来管理不同环境的配置,例如开发、测试和生产环境。这种方式提高了配置的灵活性和可维护性。

9.1. 使用多个 Compose 文件

可以创建不同的文件,例如 docker-compose.yml(用于开发环境)、docker-compose.prod.yml(用于生产环境)和 docker-compose.test.yml(用于测试环境)。
在这里插入图片描述

图解释:
  • Docker Compose: 表示 Docker Compose 的配置环境。
  • docker-compose.yml: 主要的 Docker Compose 配置文件,可以包含多个环境的配置。
  • .env.development, .env.test, .env.production: 针对不同环境的环境变量文件。
  • Web Service Dev, Web Service Test, Web Service Prod: 表示不同环境下的 Web 服务实例。
  • DEBUG, NODE_ENV: 环境变量,用于控制应用程序的行为。
案例目录结构
project/
├── docker-compose.yml          # 开发环境
├── docker-compose.prod.yml     # 生产环境
├── docker-compose.test.yml     # 测试环境
└── ...
9.2. 环境变量和配置文件

在不同的环境中,可能需要设置不同的环境变量和配置。可以使用 .env 文件来定义这些变量。

案例 .env 文件

创建不同的 .env 文件:

  • .env.development:开发环境变量
  • .env.production:生产环境变量
  • .env.test:测试环境变量
9.3. 使用环境变量

docker-compose.yml 文件中,可以使用环境变量来区分不同环境的配置:

version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  app:  # 定义一个名为 app 的服务
    image: ${APP_IMAGE}  # 使用环境变量 APP_IMAGE 来指定服务使用的镜像;如果未设置,则默认为空,可能需要在 .env 文件或环境中提供

    environment:  # 定义环境变量,这些变量会在容器启动时设置
      DEBUG: ${DEBUG}  # 设置环境变量 DEBUG,使用环境变量 DEBUG 的值;如果未设置,则为空
      NODE_ENV: ${NODE_ENV}  # 设置环境变量 NODE_ENV,使用环境变量 NODE_ENV 的值;如果未设置,则为空
      APP_NAME: ${APP_NAME}  # 设置环境变量 APP_NAME,使用环境变量 APP_NAME 的值;如果未设置,则为空
9.4. 启动不同环境

可以使用以下命令启动不同环境的服务:

# 启动开发环境
docker-compose --env-file .env.development up

# 启动生产环境
docker-compose --env-file .env.production -f docker-compose.prod.yml up

# 启动测试环境
docker-compose --env-file .env.test -f docker-compose.test.yml up
9.5. 不同环境的配置案例
docker-compose.yml(开发环境)
version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  app:  # 定义一个名为 app 的服务
    image: python:3.8  # 指定服务使用的镜像,这里使用 Python 3.8 的官方镜像
    environment:  # 定义环境变量,这些变量会在容器启动时设置
      DEBUG: "1"  # 设置环境变量 DEBUG 为字符串 "1",通常用于开启调试模式
      NODE_ENV: development  # 设置环境变量 NODE_ENV 为 "development",表示当前处于开发环境
    ports:  # 定义端口映射,将容器内部的端口映射到宿主机的端口
      - "5000:5000"  # 将容器内的 5000 端口映射到宿主机的 5000 端口,实现外部访问
    volumes:  # 定义挂载卷,用于数据持久化或在宿主机和容器间共享数据
      - .:/app  # 将宿主机当前目录挂载到容器内的 /app 目录,冒号前面是宿主机路径,冒号后面是容器内路径
docker-compose.prod.yml(生产环境)
version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  app:  # 定义一个名为 app 的服务
    image: python:3.8-slim  # 指定服务使用的镜像,这里使用 Python 3.8 的 slim 版本镜像,slim 版本的镜像包含的文件更少,通常用于生产环境
    environment:  # 定义环境变量,这些变量会在容器启动时设置
      DEBUG: "0"  # 设置环境变量 DEBUG 为字符串 "0",通常用于关闭调试模式,因为在生产环境中我们不希望有详细的错误日志
      NODE_ENV: production  # 设置环境变量 NODE_ENV 为 "production",表示当前处于生产环境
    ports:  # 定义端口映射,将容器内部的端口映射到宿主机的端口
      - "80:5000"  # 将容器内的 5000 端口映射到宿主机的 80 端口,这样可以通过宿主机的常用 HTTP 端口访问容器内的服务
docker-compose.test.yml(测试环境)
version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  app:  # 定义一个名为 app 的服务
    image: python:3.8  # 指定服务使用的镜像,这里使用 Python 3.8 的官方镜像
    environment:  # 定义环境变量,这些变量会在容器启动时设置
      DEBUG: "1"  # 设置环境变量 DEBUG 为字符串 "1",通常用于开启调试模式
      NODE_ENV: test  # 设置环境变量 NODE_ENV 为 "test",表示当前处于测试环境
9.6. 使用场景
  • 开发环境:开发环境中通常需要更详细的日志输出,可以设置 DEBUG=1 来开启调试模式。
  • 测试环境:测试环境中通常需要生产环境的配置,但可能有一些特定的测试配置。
  • 生产环境:生产环境中通常需要关闭调试模式,设置 DEBUG=0 并使用更轻量级的镜像。
10. 健康检查

在 Docker Compose 中,健康检查是一种用于监控容器运行状态的机制。通过定义健康检查指令,可以让 Docker 自动验证容器内的服务是否健康并正常运行。如果健康检查失败,Docker 可以根据的配置选择是否重启容器。
在这里插入图片描述

图解释:
  • docker-compose.yml: Docker Compose 的配置文件,定义了所有服务和健康检查。
  • Web Service: 定义的 Web 服务,用于处理应用程序的请求。
  • Health Check: 定义的健康检查指令,包括测试命令、检查间隔、超时时间和重试次数。
  • Container is Healthy: 如果健康检查通过,容器被认为是健康的。
  • Container is Unhealthy: 如果健康检查失败,容器被认为是不健康的。
  • Restart Container: 如果容器连续失败超过设定的重试次数,Docker 将重启容器。
10.1. 定义健康检查

健康检查可以在 docker-compose.yml 文件中通过 healthcheck 指令来定义。这个指令允许指定一个命令或一系列命令来检查服务的状态。

案例

以下是一个定义了健康检查的 docker-compose.yml 文件案例:

version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  web:  # 定义一个名为 web 的服务
    image: nginx  # 指定服务使用的镜像,这里使用 Nginx 的官方镜像
    healthcheck:  # 定义健康检查指令,用于定期检查容器健康状况
      test: ["CMD", "curl", "-f", "http://localhost"]  # 健康检查命令,使用 curl 访问容器内的 localhost,检查 Nginx 是否正常响应
      interval: 1m30s  # 健康检查的频率,每 1 分 30 秒执行一次检查
      timeout: 10s  # 健康检查命令的超时时间,如果超过 10 秒没有响应则认为检查失败
      retries: 3  # 在最终放弃前,健康检查失败的重试次数,这里设置为 3 次
      start_period: 40s  # 容器启动后等待的时间,确保容器内服务有足够的时间启动并初始化,这里设置为 40 秒
10.2. 健康检查指令详解
  • test: 定义健康检查的测试命令。在这个例子中,使用 curl 命令检查本地服务是否在监听。
    • "CMD": 指定使用容器内部的命令。
    • "curl", "-f", "http://localhost": 尝试无错误地执行 curl http://localhost 命令。
  • interval: 定义健康检查的频率,这里设置为每 1 分 30 秒检查一次。
  • timeout: 定义健康检查命令的超时时间,这里设置为 10 秒。
  • retries: 如果连续失败,定义可以失败多少次后才将容器标记为不健康,这里设置为 3 次。
  • start_period: 在容器启动后,定义等待多长时间才开始健康检查,这里设置为 40 秒。这可以确保容器有足够的时间启动和初始化。
10.3. 健康检查的作用
  • 自动恢复: 如果健康检查失败,并且容器被标记为不健康,Docker 可以根据配置尝试重启容器,从而实现自动恢复。
  • 实时监控: 健康检查提供了一种实时监控容器状态的方法,有助于及时发现并解决问题。
  • 预防性维护: 通过定期检查容器的健康状况,可以预防潜在的问题,避免影响用户体验。
10.4. 使用场景
  • Web 应用: 定期检查 Web 服务器是否正常响应请求。
  • 数据库服务: 检查数据库服务是否可连接。
  • 后台任务: 检查后台任务是否仍在正常运行。
  • 微服务: 在微服务架构中,健康检查可以帮助确保每个服务都在正常运行,从而保证整个系统的稳定性。
11. 资源限制

在 Docker Compose 中,可以对服务使用的 CPU 和内存等资源进行限制,以确保应用程序不会过度使用宿主机的资源。资源限制可以帮助优化宿主机上多个应用程序的资源分配,防止单个应用程序占用过多资源而影响其他应用程序或系统的正常运行。
在这里插入图片描述

解释:
  • docker-compose.yml: Docker Compose 的配置文件,定义了所有服务和资源限制。
  • Web Service: 定义的 Web 服务,用于处理应用程序的请求。
  • 资源限制:
    • CPU 限制: 限制该服务最多只能使用 0.5 个 CPU 核心。
    • 内存限制: 限制该服务最多只能使用 512MB 内存。
    • Kernel 内存限制: 限制该服务内核内存使用,通常用于限制内核级内存占用。
    • 内存+交换空间限制: 限制该服务的总内存和交换空间使用量,设置为 1GB 总和。
11.1. CPU 限制

CPU 限制可以通过 cpus 关键字在 docker-compose.yml 文件中设置。这个关键字可以指定服务可以使用的 CPU 核心数。

案例

限制服务最多使用 0.5 个 CPU 核心:

version: '3.8'
services:
  app:
    image: python:3.8
    cpus: 0.5  # 限制服务最多使用 0.5 个 CPU 核心
11.2. 内存限制

内存限制可以通过 mem_limit 关键字在 docker-compose.yml 文件中设置。这个关键字可以指定服务可以使用的最大内存。

案例

限制服务最多使用 512MB 内存:

version: '3.8'
services:
  app:
    image: python:3.8
    mem_limit: 512m  # 限制服务最多使用 512MB 内存
11.3. Kernel 内存限制

Kernel 内存限制可以通过 kernel_memory 关键字在 docker-compose.yml 文件中设置。这个关键字可以指定服务可以使用的 Kernel 内存。

案例

限制服务最多使用 128MB Kernel 内存:

version: '3.8'
services:
  app:
    image: python:3.8
    kernel_memory: 128m  # 限制服务 Kernel 内存使用
11.4. 内存交换限制

内存交换限制可以通过 memswap 关键字在 docker-compose.yml 文件中设置。这个关键字可以指定服务可以使用的内存加交换空间的总和。

案例

限制服务最多使用 1GB 内存加交换空间:

version: '3.8'
services:
  app:
    image: python:3.8
    memswap: 1g  # 限制服务最多使用 1GB 内存加交换空间
11.5. 资源限制的使用场景
  • 开发环境:在开发环境中,可能不需要严格的资源限制,以便于开发和调试。
  • 测试环境:在测试环境中,可以根据测试需求适当限制资源,确保测试的稳定性和可靠性。
  • 生产环境:在生产环境中,合理设置资源限制非常重要,以确保应用程序的稳定性和高效运行。
11.6. 注意事项
  • 合理配置:资源限制应该根据应用程序的实际需求和宿主机的资源情况进行合理配置。
  • 监控资源使用:在设置了资源限制后,应该监控应用程序的资源使用情况,以确保配置的资源限制不会影响应用程序的性能。
12. 自定义配置

在 Docker Compose 中,自定义配置允许用户扩展和自定义服务以满足特定的需求。这包括与持续集成/持续部署 (CI/CD) 工具、监控系统、日志管理等集成。以下是一些自定义配置的案例和说明:
在这里插入图片描述

图解释:
  • docker-compose.yml: Docker Compose 的配置文件,定义了所有服务。
  • Web Service, Database Service, Cache Service: 这些是在配置文件中定义的服务。
  • CI/CD Tools: 持续集成和持续部署工具,可以与 Docker Compose 集成以自动化构建和部署流程。
  • Monitoring Tools: 监控工具,用于收集服务的性能数据。
  • Logging Tools: 日志管理工具,用于聚合和分析服务的日志。
12.1. 与 CI/CD 工具集成

通过自定义配置,可以在 docker-compose.yml 文件中定义变量和指令,使其与 CI/CD 工具(如 Jenkins、GitLab CI、CircleCI 等)集成。

案例

docker-compose.yml 文件中定义一个多阶段构建,用于 CI/CD 流程:

version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  app:  # 定义一个名为 app 的服务
    build:  # 指定如何构建服务的 Docker 镜像
      context: .  # 构建上下文的路径,这里的 "." 表示当前目录
      dockerfile: Dockerfile.prod  # 指定构建镜像使用的 Dockerfile 文件,这里是 Dockerfile.prod
    image: myapp:${CI_COMMIT_SHA:-latest}  # 指定服务使用的镜像名称
    # 使用 CI 环境变量 CI_COMMIT_SHA 来标记镜像;如果 CI_COMMIT_SHA 未设置,则默认使用 "latest" 标签

在这个例子中,image 的标签使用了 CI 环境变量 ${CI_COMMIT_SHA},这样每个构建都会有唯一的镜像标签。

12.2. 监控系统

自定义配置还可以包括设置环境变量,以便应用程序可以与监控系统(如 Prometheus、Datadog 等)集成。

案例

定义环境变量以启用 Prometheus 监控:

version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  app:  # 定义一个名为 app 的服务
    image: myapp  # 指定服务使用的镜像,这里假设你已经有一个名为 myapp 的镜像
    environment:  # 定义环境变量,这些变量会在容器启动时设置
      - PROMETHEUS_MULTIPROC_DIR=/app/prometheus  # 设置环境变量 PROMETHEUS_MULTIPROC_DIR,用于指定 Prometheus 多进程模式的目录
    volumes:  # 定义挂载卷,用于数据持久化或在宿主机和容器间共享数据
      - prometheus_data:/app/prometheus  # 将名为 prometheus_data 的卷挂载到容器内的 /app/prometheus 目录

  # 定义 Prometheus 服务
  prometheus:  # 定义一个名为 prometheus 的服务
    image: prom/prometheus  # 使用 Prometheus 的官方镜像
    volumes:  # 定义挂载卷
      - ./prometheus/:/etc/prometheus/  # 将宿主机的 ./prometheus/ 目录挂载到容器的 /etc/prometheus/ 目录,用于配置文件共享
    ports:  # 定义端口映射,将容器内部的端口映射到宿主机的端口
      - "9090:9090"  # 将容器内的 9090 端口映射到宿主机的 9090 端口,Prometheus 的默认端口
    command:  # 定义启动容器时执行的命令,覆盖默认的启动命令
      - "--config.file=/etc/prometheus/prometheus.yml"  # 指定 Prometheus 使用的配置文件路径

volumes:  # 定义命名卷的根节点
  prometheus_data:  # 定义一个名为 prometheus_data 的命名卷,用于持久化 Prometheus 的数据
12.3. 日志管理

自定义配置可以包括定义日志驱动和选项,以便更好地与日志管理系统(如 ELK Stack、Graylog 等)集成。

案例

定义日志驱动和选项:

version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  app:  # 定义一个名为 app 的服务
    image: myapp  # 指定服务使用的镜像,这里假设你已经有一个名为 myapp 的镜像
    logging:  # 定义日志配置
      driver: syslog  # 使用 syslog 作为日志驱动,将容器日志发送到 syslog 服务器
      options:  # 定义 syslog 驱动的选项
        syslog-address: "tcp://192.168.0.42:1234"  # 指定 syslog 服务器的地址和端口,使用 TCP 协议
12.4. 自定义脚本

自定义配置还可以包括执行自定义脚本,这些脚本可以在容器启动或停止时运行。

案例

使用 commandentrypoint 来执行自定义脚本:

version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  app:  # 定义一个名为 app 的服务
    image: myapp  # 指定服务使用的镜像,这里假设你已经有一个名为 myapp 的镜像
    command: /app/start.sh  # 指定容器启动后执行的命令,这里使用 /app/start.sh 脚本启动应用
    entrypoint: /app/entrypoint.sh  # 指定容器的入口点,这里使用 /app/entrypoint.sh 脚本作为容器的入口点

在这个例子中,commandentrypoint 被用来指定启动容器时执行的自定义脚本。

12.5. 扩展和自定义

Docker Compose 允许通过 extends 关键字扩展服务配置。

案例

使用 extends 来扩展服务配置:

version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  redis:  # 定义一个名为 redis 的服务
    image: redis:${REDIS_VERSION:-latest}  # 指定服务使用的镜像,使用环境变量 REDIS_VERSION 来指定 Redis 镜像的标签;
                                      # 如果 REDIS_VERSION 未设置,则默认使用 "latest" 标签
    extends:  # 通过 extends 关键字来继承另一个 Compose 文件中的服务配置
      file: redis-compose.yml  # 指定要继承的文件名,这里是 "redis-compose.yml"
      service: redis  # 指定要继承的服务名,这里同样是 "redis"

在这个例子中,redis 服务的配置被扩展自 redis-compose.yml 文件中的 redis 服务。

12.6. 使用场景
  • 开发环境:自定义配置可以简化开发流程,如自动设置开发环境变量。
  • 测试环境:自定义配置可以用于测试特定的应用程序行为,如监控数据。
  • 生产环境:自定义配置可以用于确保应用程序在生产环境中的稳定性和监控。
13. 日志管理

在 Docker Compose 中,日志管理是一个关键功能,它允许方便地查看服务的输出日志,这对于调试和监控服务的状态至关重要。以下是如何在 Docker Compose 中进行日志管理的详细说明:
在这里插入图片描述

解释:
  • docker-compose.yml: Docker Compose 的配置文件,定义了服务和日志配置。
  • Service App: 定义的服务,例如一个 Web 应用。
  • Logging Driver: 指定的日志驱动,例如 syslog,用于处理日志。
  • Logs: 服务生成的日志,可以包括错误、警告、信息等。
  • Console/Files/Syslog: 日志的输出目标,可以是控制台、文件或远程 syslog 服务器。
13.1. 查看日志

Docker Compose 提供了 logs 命令来查看服务的日志输出,这对于实时监控和问题排查非常有用。

命令语法
docker-compose logs [OPTIONS] [SERVICE...]
  • SERVICE:指定服务名称,可以指定一个或多个服务,默认为所有服务。
13.2. 常用选项
  • -f, --follow:持续显示日志输出。
  • --tail:显示最后几条日志,默认为所有日志。
  • --since:显示从特定时间戳开始的日志。
  • --timestamps:在日志中显示时间戳。
13.3. 案例

假设有一个名为 webapp 的服务,需要查看其日志:

查看所有日志
docker-compose logs webapp
持续查看日志输出
docker-compose logs -f webapp
查看最后 10 条日志
docker-compose logs --tail 10 webapp
查看指定时间后的日志
docker-compose logs --since "2023-01-01T12:00:00" webapp
13.4. 配置日志驱动

docker-compose.yml 文件中,可以为服务配置日志驱动,以控制日志的输出方式和位置。

案例配置
version: '3.8'  # 指定 Docker Compose 文件使用的版本,确保文件中的配置与 Docker Engine 兼容

services:  # 定义服务的根节点,下面列出了所有的服务

  app:  # 定义一个名为 app 的服务
    image: myapp  # 指定服务使用的镜像,这里假设你已经有一个名为 myapp 的镜像
    logging:  # 定义日志配置,用于控制容器的日志输出方式
      driver: syslog  # 使用 syslog 作为日志驱动,将容器日志发送到指定的 syslog 服务器
      options:  # 定义 syslog 驱动的选项
        syslog-address: "tcp://192.168.0.42:1234"  # 指定 syslog 服务器的地址和端口,使用 TCP 协议

在这个例子中,日志驱动被设置为 syslog,日志将被发送到指定的 syslog 服务器。

13.5. 使用场景
  • 实时监控:实时查看服务的日志输出,以便快速响应问题。
  • 问题排查:当服务出现异常时,查看日志以确定问题原因。
  • 性能分析:分析日志以了解服务的使用模式和性能瓶颈。
13.6. 注意事项
  • 日志量:对于高流量的服务,日志量可能会很大,需要注意日志的存储和管理。
  • 日志安全:确保日志中不包含敏感信息,或对日志进行适当的加密和保护。
14. 命令执行

在 Docker Compose 中,命令执行功能允许在已经运行的容器服务中执行命令,这对于服务的管理和调试非常有用。以下是如何使用这个功能的详细说明:

14.1. 使用 docker-compose exec 命令

Docker Compose 提供了 exec 命令来在服务的容器中执行命令。这可以用于访问容器环境、检查问题或运行维护任务。
在这里插入图片描述

图解释:
  • 命令执行请求: 用户发出命令执行的请求,比如查看日志、进入容器等。
  • docker-compose exec: Docker Compose 接收到命令执行请求后,使用 exec 命令来在指定的服务容器中执行命令。
  • 选择服务: 根据用户输入的命令,Docker Compose 选择正确的服务,比如 webapp
  • 执行命令: 定义用户希望在容器中执行的具体命令,比如 bash 进入容器的 shell 或 cat 查看文件。
  • 容器内操作: 容器接收到命令后,在容器内部执行相应的操作。
  • 执行结果: 命令执行的结果反馈给用户。
基本语法
docker-compose exec [OPTIONS] SERVICE COMMAND [ARGS...]
  • SERVICE: 指定要执行命令的服务名称。
  • COMMAND: 希望执行的命令。
  • ARGS: 命令的参数。
14.2. 常用选项
  • -d, --detach: 后台运行。
  • -T: 禁用 pseudo-TTY 分配,适用于不需要交互的命令。
14.3. 案例

假设有一个使用 Docker Compose 管理的 Web 应用服务,名为 webapp,并且需要检查其中的日志文件。

进入容器
docker-compose exec webapp bash

这个命令将打开一个 bash shell,让可以与容器交互。

查看日志文件
docker-compose exec webapp cat /var/log/nginx/error.log

这个命令将显示 Nginx 的错误日志。

运行数据库迁移

如果的应用需要运行数据库迁移,并且的服务名称是 db

docker-compose exec db rails db:migrate

这个命令将在 db 服务中运行 Rails 的数据库迁移命令。

14.4. 后台执行命令

如果想在后台执行命令,可以使用 -d 选项:

docker-compose exec -d webapp tail -f /var/log/nginx/access.log

这个命令将持续跟踪 Nginx 的访问日志。

14.5. 使用场景
  • 日志检查:查看应用程序或系统日志以进行故障排除。
  • 维护任务:执行如数据库迁移、数据备份等维护任务。
  • 实时调试:实时查看应用程序的输出或系统状态。
14.6. 注意事项
  • 命令可用性:确保尝试执行的命令在容器的镜像中是可用的。
  • 安全考虑:当执行涉及敏感数据的操作时,确保遵守安全最佳实践。

4、docker-compose 命令列表

类别命令描述
基本命令docker-compose up启动或更新服务。
docker-compose down停止并删除容器、网络、卷和镜像。
docker-compose start启动已存在的服务。
docker-compose stop停止服务。
docker-compose restart重启服务。
docker-compose down --volumes停止服务并删除数据卷。
docker-compose pull拉取服务依赖的镜像。
docker-compose build构建或重建服务依赖的镜像。
docker-compose run在指定服务中运行一个命令。
服务管理docker-compose scale设置指定服务的运行实例数量。
docker-compose up -d以后台模式启动服务。
docker-compose logs获取服务的日志输出。
docker-compose top显示服务的容器运行状况。
docker-compose ps列出服务的容器。
配置和信息docker-compose config校验并查看配置信息。
docker-compose config --services列出所有服务名称。
docker-compose config --volumes列出所有卷名称。
事件和状态docker-compose events获取服务的事件。
docker-compose pause暂停服务中的所有容器。
docker-compose unpause恢复服务中的所有容器。
容器内部命令docker-compose exec在服务的容器中执行命令。
docker-compose exec web bash进入 web 服务容器的 bash 终端。
扩展和清理docker-compose rm删除服务的容器,但保留数据卷。
docker-compose down --rmi type删除镜像,type 可以是 alllocal 或者镜像 ID。
docker-compose system prune删除未使用的资源,包括网络、镜像、停止的容器等。
帮助命令docker-compose --help查看帮助信息。
docker-compose -h查看帮助信息。

5、docker-compose 综合业务案例

5.1 案例一:Web 应用与数据库

这个案例包括一个基于 Nginx 的 Web 服务器和一个基于 PostgreSQL 的数据库服务器。

在这里插入图片描述

目录结构

mywebapp/
├── docker-compose.yml
├── web/
│   ├── Dockerfile
│   └── start.sh
├── api/
│   ├── Dockerfile
│   └── app.py
└── db/
    └── init.sql

docker-compose.yml

version: '3.8'  # 指定 Docker Compose 文件的版本

services:  # 定义服务的根节点
  web:  # 定义一个名为 web 的服务
    build: ./web  # 指定服务的构建上下文在当前目录下的 web 文件夹
    ports:  # 定义端口映射
      - "80:80"  # 将容器的 80 端口映射到宿主机的 80 端口
    depends_on:  # 定义服务依赖
      - api  # web 服务依赖于 api 服务

  api:  # 定义一个名为 api 的服务
    build: ./api  # 指定服务的构建上下文在当前目录下的 api 文件夹
    environment:  # 定义环境变量
      - DATABASE_URL=postgresql://db:5432/mydb  # 数据库连接字符串
    depends_on:  # 定义服务依赖
      - db  # api 服务依赖于 db 服务

  db:  # 定义一个名为 db 的数据库服务
    image: postgres:13  # 使用官方的 PostgreSQL 镜像,版本为 13
    environment:  # 定义环境变量
      - POSTGRES_DB=mydb  # 数据库名
      - POSTGRES_USER=user  # 数据库用户
      - POSTGRES_PASSWORD=password  # 数据库密码
    volumes:  # 定义挂载卷
      - db-data:/var/lib/postgresql/data  # 将名为 db-data 的卷挂载到容器的 PostgreSQL 数据目录

volumes:  # 定义命名卷
  db-data:  # 定义一个名为 db-data 的命名卷,用于持久化数据库数据

web/Dockerfile

FROM nginx:alpine
COPY . /usr/share/nginx/html

web/start.sh

#!/bin/sh
nginx -g 'daemon off;'

api/Dockerfile

FROM python:3.8
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

api/app.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello, API!"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

db/init.sql

CREATE DATABASE mydb;
GRANT ALL PRIVILEGES ON DATABASE mydb TO user;
5.2 案例二:微服务架构

这个案例包括三个微服务:用户服务、产品服务和订单服务,以及一个 RabbitMQ 消息队列服务和一个 Nginx 反向代理服务。
在这里插入图片描述

目录结构

microservices/
├── docker-compose.yml
├── user-service/
│   ├── Dockerfile
│   └── app.py
├── product-service/
│   ├── Dockerfile
│   └── app.py
├── order-service/
│   ├── Dockerfile
│   └── app.py
├── rabbitmq/
│   └── Dockerfile
└── nginx/
    ├── Dockerfile
    └── nginx.conf

docker-compose.yml

version: '3.8'  # 指定 Docker Compose 文件的版本

services:  # 定义服务的根节点
  user-service:  # 定义一个名为 user-service 的服务
    build: ./user-service  # 指定服务的构建上下文在当前目录下的 user-service 文件夹
    ports:  # 定义端口映射
      - "5000:5000"  # 将容器的 5000 端口映射到宿主机的 5000 端口

  product-service:  # 定义一个名为 product-service 的服务
    build: ./product-service  # 指定服务的构建上下文在当前目录下的产品 service 文件夹
    ports:  # 定义端口映射
      - "5001:5001"  # 将容器的 5001 端口映射到宿主机的 5001 端口

  order-service:  # 定义一个名为 order-service 的服务
    build: ./order-service  # 指定服务的构建上下文在当前目录下的 order-service 文件夹
    ports:  # 定义端口映射
      - "5002:5002"  # 将容器的 5002 端口映射到宿主机的 5002 端口
    depends_on:  # 定义服务依赖
      - user-service  # order-service 服务依赖于 user-service
      - product-service  # order-service 服务依赖于 product-service

  rabbitmq:  # 定义一个名为 rabbitmq 的消息队列服务
    image: rabbitmq:3-management  # 使用官方的 RabbitMQ 镜像,版本为 3-management
    ports:  # 定义端口映射
      - "5672:5672"  # 将容器的 5672 端口映射到宿主机的 5672 端口
      - "15672:15672"  # 将容器的 15672 端口映射到宿主机的 15672 端口

  nginx:  # 定义一个名为 nginx 的反向代理服务
    build: ./nginx  # 指定服务的构建上下文在当前目录下的 nginx 文件夹
    ports:  # 定义端口映射
      - "80:80"  # 将容器的 80 端口映射到宿主机的 80 端口
    depends_on:  # 定义服务依赖
      - user-service  # nginx 服务依赖于 user-service
      - product-service  # nginx 服务依赖于 product-service
      - order-service  # nginx 服务依赖于 order-service

volumes:  # 定义命名卷
  db-data:  # 定义一个名为 db-data 的命名卷,用于持久化数据库数据

user-service/Dockerfile

FROM python:3.8
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

user-service/app.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def user():
    return "User Service"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

product-service/Dockerfile

FROM python:3.8
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

product-service/app.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def product():
    return "Product Service"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5001)

order-service/Dockerfile

FROM python:3.8
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

order-service/app.py

from flask import Flask
app = Flask(__name__)

@app.route('/')
def order():
    return "Order Service"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5002)

rabbitmq/Dockerfile

FROM rabbitmq:3-management

nginx/Dockerfile

FROM jwilder/nginx-proxy

nginx/nginx.conf

http {
    resolver 8.8.8.8 valid=300s;
    server {
        listen 80;
        location / {
            proxy_pass http://order-service:5002;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Solomon_肖哥弹架构

你的欣赏就是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值