30

我正在使用 docker-compose,我想为不同服务的构建步骤使用不同的 Dockerfile。文档似乎建议将不同的 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/

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

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

4

4 回答 4

39

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

services:
  service1:
    build:
        context: .
        args:
            - NODE_ENV=local
        dockerfile: Dockerfile_X
    ports:
        - "8765:8765"
于 2018-04-13T07:51:30.217 回答
16

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

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

请参阅:Dockerfile

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

service1:
    build: service1

service2:
    build: service2

请参阅:码头工人撰写

更新:

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

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

FWIW:关注点分离ftw :)

于 2015-04-23T23:43:01.307 回答
10

您可以dockerfile在您的参数中使用参数docker-compose.yml来为特定服务指定备用选项。

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

我昨天试过了,它对我有用。它是我的项目的基本目录,Dockerfile并且Dockerfile-service3docker-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.

于 2018-04-13T06:36:00.677 回答
3

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

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

有更多复杂的解决方案可能对您使用 ShutIt 有用,很高兴离线讨论这个问题,因为我认为这有点离题。ShutIt 是为这种用例编写的,因为我可以看到这将是一个常见问题,因为 Dockerfiles 在微服务空间之外的实用性有限。

于 2015-05-11T10:13:29.940 回答