使用Docker Compose

预计阅读时间:11分钟

Docker Compose是一款旨在帮助定义和共享多容器应用程序的工具。使用Compose,我们可以创建一个YAML文件来定义服务,并且可以使用一个命令将所有内容旋转或分解。

使用Compose的最大优点是,您可以在文件中定义应用程序堆栈,将其保留在项目存储库的根目录(现在由版本控制)中,并轻松地使其他人为您的项目做出贡献。某人只需要克隆您的存储库并启动撰写应用程序即可。实际上,您可能会在GitHub / GitLab上看到相当多的项目正在执行此操作。

那么,我们如何开始呢?

安装Docker Compose

如果您为Windows或Mac安装了Docker Desktop / Toolbox,则已经有了Docker Compose!Play-with-Docker实例也已经安装了Docker Compose。如果您在Linux机器上,则需要安装Docker Compose

安装后,您应该能够运行以下内容并查看版本信息。

docker-compose version

创建撰写文件

  1. 在应用程序项目的根目录下,创建一个名为的文件docker-compose.yml

  2. 在撰写文件中,我们将从定义模式版本开始。在大多数情况下,最好使用最新的受支持版本。您可以查看 有关当前架构版本和兼容性列表的撰写文件参考

     version: "3.7"
    
  3. 接下来,我们将定义要作为应用程序的一部分运行的服务(或容器)的列表。

     version: "3.7"
    
     services:
    

现在,我们将开始一次将服务迁移到compose文件中。

定义应用服务

记住,这是我们用来定义应用程序容器的命令。

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. 首先,让我们定义服务条目和容器的图像。我们可以为服务选择任何名称。该名称将自动成为网络别名,这在定义我们的MySQL服务时将很有用。

     version: "3.7"
    
     services:
       app:
         image: node:12-alpine
    
  2. 通常,您将看到command接近image定义的位置,尽管没有订购要求。因此,让我们继续将其移动到我们的文件中。

     version: "3.7"
    
     services:
       app:
         image: node:12-alpine
         command: sh -c "yarn install && yarn run dev"
    
  3. 让我们-p 3000:3000通过ports为服务定义来迁移命令的一部分。我们将在此处使用 短语法,但也可以使用更冗长的 长语法

     version: "3.7"
    
     services:
       app:
         image: node:12-alpine
         command: sh -c "yarn install && yarn run dev"
         ports:
           - 3000:3000
    
  4. 接下来,我们将使用和定义迁移工作目录(-w /app)和卷映射(-v "$(pwd):/app")。卷还具有简短的语法和较长的语法。working_dirvolumes

    Docker Compose卷定义的一个优点是我们可以使用当前目录中的相对路径。

     version: "3.7"
    
     services:
       app:
         image: node:12-alpine
         command: sh -c "yarn install && yarn run dev"
         ports:
           - 3000:3000
         working_dir: /app
         volumes:
           - ./:/app
    
  5. 最后,我们需要使用environment键来迁移环境变量定义。

     version: "3.7"
    
     services:
       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服务了。我们用于该容器的命令如下:

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:
       app:
         # The app service definition
       mysql:
         image: mysql:5.7
    
  2. 接下来,我们将定义体积映射。当我们使用来运行容器时docker run,将自动创建命名的卷。但是,使用Compose运行时不会发生这种情况。我们需要在顶级volumes:部分中定义卷 ,然后在服务配置中指定安装点。通过仅提供卷名,即可使用默认选项。但是,还有更多可用的选项

     version: "3.7"
    
     services:
       app:
         # The app service definition
       mysql:
         image: mysql:5.7
         volumes:
           - todo-mysql-data:/var/lib/mysql
    
     volumes:
       todo-mysql-data:
    
  3. 最后,我们只需要指定环境变量即可。

     version: "3.7"
    
     services:
       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:
  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. 确保没有其他app / db副本先运行(docker psdocker rm -f <ids>)。

  2. 使用docker-compose up命令启动应用程序堆栈。我们将添加该-d标志以在后台运行所有内容。

     docker-compose up -d
    

    运行此命令时,应该看到如下输出:

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

    您会注意到,该卷已创建,而且网络也已创建!默认情况下,Docker Compose自动为应用程序堆栈自动创建一个网络(这就是为什么我们没有在compose文件中定义一个网络)的原因。

  3. 让我们使用docker-compose logs -f命令查看日志。您将看到来自每个服务的日志交错成一个流。当您要注意与计时相关的问题时,这非常有用。该-f标志“跟随”日志,因此将在生成日志时为您提供实时输出。

    如果还没有,您将看到如下所示的输出...

     mysql_1  | 2019-10-03T03:07:16.083639Z 0 [Note] mysqld: ready for connections.
     mysql_1  | Version: '5.7.27'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL Community Server (GPL)
     app_1    | Connected to mysql db at host mysql
     app_1    | Listening on port 3000
    

    服务名称显示在该行的开头(通常为彩色),以帮助区分消息。如果要查看特定服务的日志,可以将服务名称添加到logs命令的末尾(例如 docker-compose logs -f app)。

    提示:在启动应用程序之前等待数据库

    当应用程序启动时,它实际上会坐下来等待MySQL启动并准备就绪,然后再尝试连接到该应用程序。Docker没有任何内置支持来等待另一个容器完全启动,运行并准备就绪,然后再启动另一个容器。对于基于节点的项目,可以使用wait-port 依赖项。对于其他语言/框架也存在类似的项目。

  4. 此时,您应该可以打开您的应用程序并看到它正在运行。嘿!我们只用一个命令!

在Docker Dashboard中查看应用程序堆栈

如果我们查看Docker Dashboard,我们将看到有一个名为app的组。这是Docker Compose的“项目名称”,用于将容器分组在一起。默认情况下,项目名称只是所在目录的名称 docker-compose.yml

带有应用程序项目的Docker仪表板

如果旋转应用程序,您将看到我们在撰写文件中定义的两个容器。名称也更具描述性,因为它们遵循的模式<project-name>_<service-name>_<replica-number>。因此,快速查看哪个容器是我们的应用程序以及哪个容器是mysql数据库非常容易。

带有应用程序项目的Docker Dashboard扩展

全部撕下来

当您准备将其全部拆除时,只需docker-compose down在整个应用程序的Docker Dashboard上运行或砸垃圾桶即可。容器将停止并且网络将被删除。

警告

删除卷

默认情况下,运行时不会删除撰写文件中的命名卷docker-compose down。如果要删除卷,则需要添加--volumes标志。

泊坞窗仪表盘并没有在删除应用程序堆栈中删除卷。

拆除后,您可以切换到另一个项目,运行docker-compose up并准备为该项目做贡献!真的没有比这更简单的了!

回顾

在本节中,我们了解了Docker Compose及其如何帮助我们极大地简化了多服务应用程序的定义和共享。通过将所使用的命令转换为适当的撰写格式,我们创建了一个撰写文件。

至此,我们开始总结本教程。但是,我们要介绍一些有关映像构建的最佳实践,因为我们一直在使用的Dockerfile存在一个大问题。所以,让我们来看看!

入门设置方向快速启动简介概念容器码头