使用多个Dockerfile来部署多个服务的docker-compose

46
我正在使用docker-compose,希望在不同的服务构建步骤中使用不同的Dockerfiles。 文档 建议将不同的 Dockerfiles 放在不同的目录中,但我希望它们都在同一个目录中(并且可以使用以下约定进行区分: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)。我想将它添加到db的Dockerfile中,但由于容器的隔离性,我无法在那里使用SQL Alchemy,因为该镜像是基于postgres镜像而不是Python镜像,并且它不包含sqlalchemy包... 我该怎么办?我尝试在postgresdb中使用main服务,但不幸的是它没有携带Python及其包,所以我仍然无法编写一个单一的Dockerfile,既可以通过shell脚本创建Postgres数据库,也可以通过Python脚本创建表格。
4个回答

55

你需要将其添加到构建部分中。 这样,您就可以为每个服务指定不同的替代Dockerfile。

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

对我来说,重要的是要指定Dockerfile文件的路径,因为它在子目录中,即使你有"Dockerfile_X"。例如:dockerfile: api/Dockerfile - Austin Heller

24

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

对于涉及该服务的每个目录,您将需要使用和放置一个Dockerfile在其中作为Docker构建上下文的一部分。

请参见:Dockerfile

您实际上需要一个类似以下内容的docker-compose.yml

service1:
    build: service1

service2:
    build: service2

请查看:docker-compose

更新:

针对您特定的用例--虽然我理解您尝试做什么以及为什么要这样做,但我个人不会这样做。隔离是一件好事,有助于管理期望和复杂性。我会将“数据库创建”作为另一个基于应用程序源代码的容器或应用程序容器本身来执行。

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

FWIW:关注分离各自职责 :)


嘿,詹姆斯——谢谢你!我编辑了问题并添加了我想要这样做的原因;你知道如何扩展服务来解决这个问题吗?再次感谢! - aralar

15
你可以在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构建。


3

我是ShutIt的创始人。很高兴听到人们对它的评价不错。

实话说,如果您需要,我会建议您编写自己的Dockerfile,并使用标准的包管理工具,如apt或yum。在Ubuntu镜像和Python-pip、Python-sqlalchemy的快速检查中,这些软件包是免费提供的。

还有更复杂的解决方案可能适用于使用ShutIt的情况。如果您需要讨论此类问题,请离线联系我,因为我认为这有点超出了主题范围。ShutIt是为此类用例而编写的,因为在微服务空间之外,Dockerfiles的实用性有限,我认为这将是一个常见的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接