docker-compose:为多个服务使用多个 Dockerfile

docker-compose: using multiple Dockerfiles for multiple services

我正在使用 docker-compose,我想对不同服务的构建步骤使用不同的 Dockerfile。 docs 似乎建议将不同的 Dockerfile 放在不同的目录中,但我希望它们都在同一个目录中(并且可能使用以下约定来区分:Dockerfile.postgres、Dockerfile.main ...)。这可能吗?

编辑: 我的场景包含这个 docker-compose 文件:

main:
  build: .
  volumes:
    - .:/code
  environment:
    - DEBUG=true

postgresdb:
  extends:
    file: docker-compose.yml
    service: main
  build: utils/sql/
  ports:
    - "5432"
  environment:
    - DEBUG=true

其中 postgresdb 的 Dockerfile 是:

FROM postgres

# http://www.slideshare.net/tarkasteve/developerweek-2015-docker-tutorial
ADD make-db.sh /docker-entrypoint-initdb.d/

主要是:

FROM python:2.7

RUN mkdir /code
WORKDIR /code
ADD requirements.txt /code/

RUN pip install --upgrade pip
RUN pip install -r requirements.txt
ADD . /code/

这现在有效,但我想通过调用 Python 脚本来扩展 postgresdb 的 Dockerfile,该脚本根据基于 SQL 构建的模型在数据库中创建表Alchemy(Python 脚本将被称为 python manage.py create_tables)。我想将它添加到数据库的 Dockerfile,但由于容器的隔离,我不能在那里使用 SQL Alchemy,因为该图像基于 postgres 图像而不是 Python的,它不包含 sqlalchemy 包...

我能做什么?我尝试在 postgresdb 中使用 main 服务,但不幸的是它没有携带 python 及其包,所以我仍然无法编写一个创建 Postgres 数据库的 Dockerfile (通过 shell 脚本)及其表格(通过 Python 脚本)。

由于 Docker 处理构建上下文的方式,这是不可能的。

您将必须在每个目录中使用并放置一个 Dockerfile,成为 that 服务的 Docker 构建上下文的一部分。

参见:Dockerfile

您实际上需要 docker-compose.yml 看起来像:

service1:
    build: service1

service2:
    build: service2

参见:docker-compose

更新:

解决您的特定用例——虽然我理解您想要做什么以及我个人为什么不这样做。隔离是一件好事,有助于管理期望和复杂性。我会将 "database creation" 作为基于您应用程序源代码的另一个容器或在应用程序容器本身内执行。

或者,您可以查看更多脚本化和模板驱动的解决方案,例如 shutit我没有这方面的经验,但听说过有关 的建议)。

FWIW:关注点分离 ftw :)

这里是 ShutIt 的创建者。很高兴听到人们听到关于它的好消息。

老实说,在您的位置上,我会编写您自己的 Dockerfile 并使用标准包管理,例如 apt 或 yum。使用 ubuntu 图像进行快速检查,python-pip 和 python-sqlalchemy 是免费提供的。

使用 ShutIt 可能会有更多复杂的解决方案适合您,很高兴离线讨论这个问题,因为我认为它有点离题。 ShutIt 是为这种用例编写的,因为我认为鉴于 Dockerfiles 在微服务之外的实用性有限,这将是一个常见问题 space.

您可以在 docker-compose.yml 中使用 dockerfile 参数来为特定服务指定替代参数。

我不知道什么时候添加的,因为讨论是旧的,但是你可以在参考中看到它https://docs.docker.com/compose/compose-file/#dockerfile

我昨天试过了,它对我有用。 它是我项目的基本目录,我有 DockerfileDockerfile-service3 并且在 docker-compose.yml:

version: '2'

services:
    service1:
        build:
            context: .
            args:
                - NODE_ENV=local
        ports:
            - "8765:8765"
        # other args skipped for clarity
    service2:
        build:
            context: .
            args:
                - NODE_ENV=local
        ports:
            - "8766:8766"
        # other args skipped for clarity
    service3:
        build:
            context: .
            dockerfile: Dockerfile-service3
            args:
                - NODE_ENV=local
        ports:
            - "8767:8767"
        # other args skipped for clarity
    service4:
        build:
            context: .
            args:
                - NODE_ENV=local
        ports:
            - "8768:8768"
        # other args skipped for clarity

这样,除了 service3 之外的所有服务都将使用标准 Dockerfile 构建,而 service3 将使用 Dockerfile-service3.

构建

您必须在构建部分添加它。 因此,您可以为每个服务指定不同的替代 dockerfile。

services:
  service1:
    build:
        context: .
        args:
            - NODE_ENV=local
        dockerfile: Dockerfile_X
    ports:
        - "8765:8765"