如何让 Docker Compose 服务构建依赖于另一个服务?

Dav*_*lia 6 database postgresql jooq docker docker-compose

这就是我的意思。如何编写 docker-compose.yaml 文件,以便在“构建”其中一个服务时,它首先运行另一个服务?

我会尽量说得更具体一些。我正在尝试使用数据库库 JOOQ 构建 Java 应用程序,该应用程序希望在构建时连接到数据库,以便生成与数据库表相对应的 Java 类。我想要 Dockerfile(s) 和 docker-compose.yaml 文件的某种组合,以便以下大致按以下顺序发生。

  1. 启动“数据库”服务(在我的情况下,使用 postgres 图像)。
  2. 数据库是用我的开发仓库中的 SQL 脚本初始化的。
  3. 我的“web”服务的构建阶段运行,它使用同一个 repo 中的 Dockerfile,它调用 Gradle 构建,它告诉 JOOQ 连接到在步骤 1 中启动的数据库服务。这会生成 Java 文件,编译它们,然后执行用于构建容器的所有其他内容。
  4. “web”服务启动,连接到步骤 1 中启动的数据库服务。

这是我正在使用的 docker-compose.yaml 文件

version: '3.7' 
services:
  postgres:
    image: postgres:10.5-alpine
    restart: always
    ports:
      - "6432:5432"
    environment:
      POSTGRES_DB: flashtools
      POSTGRES_USER: flashtools
      POSTGRES_PASSWORD: flashtools
    volumes:
      - ./src/main/scripts/01_init.sql:/docker-entrypoint- 
initdb.d/01_init.sql
  web:
    build: .
    network_mode: host
    depends_on:
      - postgres
    ports:
      - "8080:8080"
Run Code Online (Sandbox Code Playgroud)

我会用更多细节来充实这一点,但希望我要问的是非常简单的。

skp*_*rin 2

现在(技术上)这应该是可能的:

2021 年 4 月 6 日version 1.29.0发行说明链接)

使用service_completed_successfully条件(这是一个“长格式” depends_on选项)

长语法:

长格式语法允许配置无法以短格式表达的附加字段。

  • condition:认为满足依赖性的条件
    • service_completed_successfully:指定在启动依赖服务之前依赖项预计会成功完成

来源- 添加强调)

长语法示例:

depends_on:
  service_name:
    condition: service_completed_successfully
Run Code Online (Sandbox Code Playgroud)

更新您的docker-compose.yml文件:

您需要进行以下更改:

  • 将您的撰写版本提升到3.8
  • 将新service_completed_successfully条件添加到您的depends_on
version: "3.8"
services:
  postgres:
    image: postgres:10.5-alpine
    restart: always
    ports:
      - "6432:5432"
    environment:
      POSTGRES_DB: flashtools
      POSTGRES_USER: flashtools
      POSTGRES_PASSWORD: flashtools
    volumes:
      - ./src/main/scripts/01_init.sql:/docker-entrypoint-initdb.d/01_init.sql
  web:
    build: .
    network_mode: host
    depends_on:
      postgres:
        condition: service_completed_successfully
    ports:
      - "8080:8080"
Run Code Online (Sandbox Code Playgroud)

您可能还需要使用多阶段Dockerfile

多阶段构建信息

多阶段构建通常用于精简最终的 Docker 映像,但它也可用于运行脚本并创建完成构建之前所需的“工件”。

在没有看到您的确切信息的情况下很难建议这一点Dockerfile,但我认为值得一提的是您可能还需要使用它。

  • 我认为这行不通,原因有三个:PostgreSQL 容器将永远运行,因此它永远不会“完成”;一般来说,镜像构建不尊重“depends_on:”(您可以期望每个构建都在任何容器启动之前发生);一般来说,Dockerfile 无法联系其他容器。 (3认同)