使用 Docker Compose

未匹配的标注

Docker Compose 是一款旨在帮助定义和共享多容器应用程序的工具。通过 Compose,我们可以创建一个 YAML 文件来定义需要使用的所有服务,并且只需要一个命令就可以启动或停止所有服务。

使用 Compose 的最大优点是你只需在一个文件中定义自己的应用程序栈(即应用程序需要用到的所有服务),然后把这个 YAML 文件放在项目的根目录下,与源码一起受版本控制。其他人只需 clone 你的项目源码之后就可以快速启动服务。实际上,在 GitHub 或 GitLab 上已经有很多项目正在这样做。

我们也来为 todo 应用创建一个 YAML 文件吧。

安装 Docker Compose

如果你使用的是 Windows 或者 Mac 桌面操作系统,在安装 Docker Desktop 之后就已经内置了 Docker Compose。如果你使用的是 Linux 系统,可以参照 此处的说明 安装 Docker Compose

安装完成之后,可以执行以下命令查看它的版本信息:

docker-compose version

创建我们的 Compose 文件

  1. todo-app 项目的根目录下,创建一个名为 docker-compose.yml 的文件

  2. docker-compose.yml 文件的第一行定义 schema version。在大多数情况下,最好使用最新的受支持 schema version。你可以查看 Compose file reference 以获得最新的 schema version 和兼容性列表。

    version: "3.7"
  3. 接下来,我们将定义 todo-app 应用程序依赖的一系列服务(或容器)列表。

    version: "3.7"
    
    services:

接着,我们开始将之前通过命令行执行的命令,翻译成 compose 文件支持的格式。

定义 todo-app 应用服务

回顾一下之前使用过的命令:

docker run -dp 3000:3000 \
  -w /app \
  -v "$(pwd):/app" \
  --network todo-app \
  -e MYSQL_HOST=mysql \
  -e MYSQL_USER=root \
  -e MYSQL_PASSWORD=secret \
  -e MYSQL_DB=todos \
  node:12-alpine \
  sh -c "yarn install && yarn run dev"

如果使用的是 PowerShell,之前使用的是下面这条命令(只是 多行输入 的分隔符不一样而已)

docker run -dp 3000:3000 `
  -w /app `
  -v "$(pwd):/app" `
  --network todo-app `
  -e MYSQL_HOST=mysql `
  -e MYSQL_USER=root `
  -e MYSQL_PASSWORD=secret `
  -e MYSQL_DB=todos `
  node:12-alpine `
  sh -c "yarn install && yarn run dev"
  1. 首先,定义 todo-app 应用服务名称和使用的镜像,可以为它取任何名称,这里简单取成同名 todo-app。该名称将自动作为网络的别名,在后续定义 MySQL 服务时将很有用。

    version: "3.7"
    
    services:
      todo-app:
        image: node:12-alpine
  2. 接着我们把容器启动之后要执行的命令写在靠近定义 image 的地方,尽管不一定按照这样的顺序书写,但是通常都这样做。类似下面这样:

    version: "3.7"
    
    services:
      todo-app:
        image: node:12-alpine
        command: sh -c "yarn install && yarn run dev"
  3. 接着定义端口映射

    version: "3.7"
    
    services:
      todo-app:
        image: node:12-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
  4. 再来将 -w /app 工作目录-v "$(pwd):/app" volume 通过 working_dirvolumes 这两个属性来定义。
    在 Docker Compose 配置文件中定义 volume 的一个优点是我们可以使用基于 docker-compose.yml 文件所在目录的相对路径。

    version: "3.7"
    
    services:
      todo-app:
        image: node:12-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
  5. 最后,通过 environment 定义 todo-app 需要使用到的环境变量。

    version: "3.7"
    
    services:
      todo-app:
        image: node:12-alpine
        command: sh -c "yarn install && yarn run dev"
        ports:
          - 3000:3000
        working_dir: /app
        volumes:
          - ./:/app
        environment:
          MYSQL_HOST: mysql
          MYSQL_USER: root
          MYSQL_PASSWORD: secret
          MYSQL_DB: todos

定义 MySQL 服务

现在,是时候定义 MySQL 服务了。同样先回顾之前启动 MySQL 容器时使用的命令:

docker run -d \
  --network todo-app --network-alias mysql \
  -v todo-mysql-data:/var/lib/mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  -e MYSQL_DATABASE=todos \
  mysql:5.7

如果使用的是 PowerShell,之前使用的是下面这条命令(只是 多行输入 的分隔符不一样而已)

docker run -d `
  --network todo-app --network-alias mysql `
  -v todo-mysql-data:/var/lib/mysql `
  -e MYSQL_ROOT_PASSWORD=secret `
  -e MYSQL_DATABASE=todos `
  mysql:5.7
  1. 先定义一个新服务并将它命名为 mysql,接着指定该服务使用的镜像。

    version: "3.7"
    
    services:
      todo-app:
        # The app service definition
      mysql:
        image: mysql:5.7
  2. 接着定义 named volume 的映射关系。当我们使用 docker run 运行容器时,Docker 会自动创 named volume。但是,使用 Compose 运行时不会自动创建,所以我们需要在配置文件的顶层使用 volumes 属性定义 named volume,然后在 MySQL 服务下的 volumes 指定它的实际挂载点。

    备注:这两个 volumes 出现的位置不一样。第一个是在 compose 文件的顶层,另外一个是在 MySQL 这个服务之下。

    version: "3.7"
    
    services:
      todo-app:
      # The app service definition
    mysql:
      image: mysql:5.7
    volumes:
      - todo-mysql-data:/var/lib/mysql
    
    volumes:
    todo-mysql-data:
  3. 最后,指定启动 MySQL 服务需要的环境变量

    version: "3.7"
    
    services:
      todo-app:
        # The app service definition
      mysql:
        image: mysql:5.7
        volumes:
          - todo-mysql-data:/var/lib/mysql
        environment: 
          MYSQL_ROOT_PASSWORD: secret
          MYSQL_DATABASE: todos
    
    volumes:
      todo-mysql-data:

此时,完整的 docker-compose.yml 看起来像这样:

version: "3.7"

services:
  todo-app:
    image: node:12-alpine
    command: sh -c "yarn install && yarn run dev"
    ports:
      - 3000:3000
    working_dir: /app
    volumes:
      - ./:/app
    environment:
      MYSQL_HOST: mysql
      MYSQL_USER: root
      MYSQL_PASSWORD: secret
      MYSQL_DB: todos

  mysql:
    image: mysql:5.7
    volumes:
      - todo-mysql-data:/var/lib/mysql
    environment: 
      MYSQL_ROOT_PASSWORD: secret
      MYSQL_DATABASE: todos

volumes:
  todo-mysql-data:

启动我们的完整应用

现在我们已经有了 docker-compose.yml 文件,就可以启动它了!

  1. 确保之前通过命令行启动的应用和 MySQL 容器已经停止并删除了。如何还运行着,可以通过 Docker Desktop 或者使用 docker ps 配合 docker rm -f 删除它们。

  2. 使用 docker-compose up 命令启动应用程序栈(todo-app + mysql)。添加 -d 标志可以让它们保持在后台运行。

    docker-compose up -d

    运行此命令之后,应看到如下输出:

    Creating network "app_default" with the default driver
    Creating volume "app_todo-mysql-data" with default driver
    Creating app_todo-app_1   ... done
    Creating app_mysql_1 ... done

    你应该已经注意到了,volumenetwork 都已经已创建成功。默认情况下,Docker Compose 会自动为应用程序栈自动创建一个网络,这就是为什么我们没有在 compose 文件中显式定义网络的原因。

  3. 让我们使用 docker-compose logs -f 命令查看日志。每个服务的日志汇总统一输出在这里。-f 标志用于实时输出日志。

    如果要查看特定服务的日志,可以将服务名称添加到 logs 命令的末尾(例如 docker-compose logs -f mysql)。

  4. 至此,只用了一个命令就可以启动我们应用程序需要的所有服务了。

在 Docker Dashboard 中查看我们的应用程序栈

如果现在查看 Docker Dashboard,将会看到有一个名为 app 的组,将所有使用到的容器组在一起了。默认情况下,项目名称是 docker-compose.yml 文件所在目录的名称。

Docker Dashboard with app project

如果点击 app 这个分组,将会看到我们在 docker-compose.yml 文件中定义的两个容器。名称也更具描述性,因为它们遵循 < 项目名称 >_< 服务名称 >_< 副本编号 > 的格式。因此,可以很方便的查看哪个容器是我们的 todo 服务以及哪个容器是 MySQL 数据库服务。

Docker Dashboard with app project expanded

删除所有容器

如果要将它们全部删除,只需运行 docker-compose down 或在 Docker Dashboard 上点击垃圾桶图标即可。同时也会删除自动创建的网络。

删除 Volumes
默认情况下,运行 docker-compose down 命令,不会自动删除 docker-compose.yml 文件中定义的 named volumes。如果要删除 volumes,只需添加 --volumes 标志即可。

回顾

在本节中,我们学习了如何利用 Docker Compose 帮助我们极大简化多服务应用程序的定义和分享。我们把之前使用的命令转换为对应的 compose 格式,写入新创建的 docker-compose.yml 文件中。然后,就可以只使用一条命令启动或者删除所有服务了。

下一节让我们更进一步,介绍一些构建镜像的最佳实践。

原始资料:Using Docker Compose

配套视频
www.bilibili.com/video/BV1Jy4y1h7n...

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
讨论数量: 0
发起讨论 只看当前版本


暂无话题~