【问题标题】:Docker-compose.yml file that builds a base image, then children based on it?构建基础镜像的 Docker-compose.yml 文件,然后基于它的子镜像?
【发布时间】:2017-07-18 17:34:47
【问题描述】:

为了澄清,当我说基础镜像时,我是指具有所有通用配置的父镜像,因此基于它的子镜像不需要单独下载依赖项。

据我了解,docker-compose.yml 文件是运行时配置,而 Dockerfiles 是构建时配置。但是,有一个使用 docker-compose 的 build 选项,我想知道如何使用它来构建基础映像。

截至目前,我使用一个运行其他 shellscript 的 shellscript。一个从它也创建的基本图像构建我所有的图像。另一个将它们作为具有必要配置的容器运行。但是,基本映像永远不会作为容器运行。

目前,我希望将 shellscript 改成 docker-compose 文件,如下所示:

echo "Creating docker network net1"
docker network create net1

echo "Running api as a container with port 5000 exposed on net1"
docker run --name api_cntr --net net1 -d -p 5000:5000 api_img

echo "Running redis service with port 6379 exposed on net1"
docker run --name message_service --net net1 -p 6379:6379 -d redis

echo "Running celery worker on net1"
docker run --name celery_worker1 --net net1 -d celery_worker_img

echo "Running flower HUD on net1 with port 5555 exposed"
docker run --name flower_hud --net net1 -d -p 5555:5555 flower_hud_img

制作图片的shellscript如下:

echo "Building Base Image"
docker build -t base ../base-image

echo "Building api image from Dockerfile"
docker build -t api_img  ../api

echo "Building celery worker image"
docker build -t celery_worker_img ../celery-worker

echo "Building celery worker HUD"
docker build -t flower_hud_img ../flower-hud

我的问题归结为一件事,我能否在不使用 docker-compose 在容器中运行它的情况下创建此基础映像。 (所有 Dockerfile 都以 FROM base:latest 开头,而不是基础本身)。我希望对其他人来说尽可能简单,以便他们只需要运行一个命令。

编辑:我使用的是版本 3,根据文档,build: 被忽略,并且 docker-compose 只接受预构建的图像。

【问题讨论】:

    标签: docker docker-compose dockerfile docker-stack


    【解决方案1】:

    是的,有点。像这样使用它:

    version: '2'
    
    services:
    
        wls-admin:
            container_name: wls-admin
            image: weblogic-domain
            build:
                context: wls-admin
                args:
                    - ADMIN_PORT=${WLS_ADMIN_PORT}
                    - CLUSTER_NAME=${WLS_CLUSTER_NAME}
                    - PRODUCTION_MODE=dev
            networks:
                - wls-network
    

    image 子句使docker-compose build 为该服务生成名为weblogic-domain 的docker 镜像。这个镜像可以被其他服务的 Dockerfile 重用,即使在同一个构建过程中。

    【讨论】:

    • 是的,但是docker-compose up 会尝试从中运行容器,我想避免它,因为它只是其他服务的基础映像。
    • @Mišo 是的,docker-compose doesn't support this 到目前为止。显然,当前的解决方案是使用多个 yaml 文件,您首先使用build,然后使用up
    • 您可以将基础 Dockerfile 中的 CMD 设置为“echo”。这样,您的基础映像确实会启动,但会很快退出。不理想,但它有效。
    【解决方案2】:

    根据文档,服务的build 选项将目录作为参数,其中包含著名的Dockerfile。无法构建基础镜像,然后构建服务的实际镜像。

    Docker 是您的应用程序运行的环境。当你创建一个基础镜像时,它应该有一些不会经常改变的东西。然后您需要构建一次 baseiamge 并上传到您的存储库并在 Dockerfile 中使用FROM baseimage:latest

    例如,如果您正在构建一个 python 应用程序,您可以从 python 创建它并安装要求:

    FROM python:3.6
    COPY requirements.txt .
    RUN pip install -r requirements.txt
    

    这里,python:3.6基本映像,不会经常更改,因此您无需在每次运行 docker compose 命令时都构建它

    【讨论】:

    • 最好先构建基本映像,然后在单独的命令中执行 docker-compose up,如果我要使用一个命令,则让 shellscript 运行这两个命令-什么都做?
    • @WillParzybok 这似乎是一个更好的主意,并且适合您的目的。
    • 我就是这么做的。 Jenkins 构建了我的基础镜像并将其放入一个私有镜像仓库中。如果您使用版本号正确标记它们,您始终可以控制。这是一个相当简单的处理过程。
    【解决方案3】:

    除了运行 docker-compose,您可以实现一个脚本,使用特定标签 docker build ... -t your_tag 构建映像,然后运行 ​​docker-compose。在儿童 dockerfiles 中,您可以使用 FROM your_tag

    【讨论】:

      【解决方案4】:

      只是对Kanedias' 答案的一个小补充。如果您选择遵循他的方法(这是我的选择),您可以避免使用 docker-compose up 命令中的 --scale 标志为基本映像实例化容器:

      docker-compose up --scale wls-admin=0
      

      来自up 命令documentation

          --scale SERVICE=NUM        Scale SERVICE to NUM instances. Overrides the
                                     `scale` setting in the Compose file if present.
      

      需要注意的重要一点是,docker-compose.yml 中的 scale 设置在 v3 中已被删除,因此在 v3 中实际上没有什么可覆盖的。

      【讨论】:

        【解决方案5】:

        从制作图像的 shellscript 中,我们可以看到您在不同的目录中有不同的 dockerfile。您可以使用它来创建 docker-compose.yml 文件。 build 设置用于告诉 docker 应该如何构建镜像。

        您可以通过这种方式在 compose 文件中使用这些 dockerfile:

        version: '3'
        services:
        
          api_cntr:
            image: api_img
            build:
              context: ./api
            container_name:api_cntr
            ports:
              - 5000:5000
        

        在这里,我假设您的docker-compose.yml 文件位于一个文件夹中,该文件夹还包含一个名为base-image 的目录。而base-image 有一个dockerfile 用于构建镜像。

        这可以是您的一项服务的结构。以类似的方式,您也可以创建其他服务。在使用 docker-compose 时,您无需为每个服务指定网络,因为在 docker-compose.yml 文件中声明的所有服务都是隔离网络的一部分。

        【讨论】:

        • 我误解了这个问题吗?
        • 有点,这可能是我措辞不佳的错。 base-image 目录包含一个 Dockerfile,它创建一个名为 base 的图像。所有其他容器都有自己的目录和自己的 Dockerfile,该目录在其FROMstatement 中引用此基础。换句话说,基础本身永远不会作为容器运行,而是所有其他图像的预构建基础。
        • @ayushya 您的撰写文件将使用base-image 目录作为上下文来构建图像并将其标记为api_img。 @WillParzybok 想要的是在他在撰写文件中启动任何服务时构建基础图像。
        • @vedarthk 我的错,我正在构建 api,但不知道我是如何提供基本图像的上下文的。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-20
        • 2017-12-31
        • 2023-01-28
        • 2020-02-26
        • 2017-09-29
        • 2017-04-24
        相关资源
        最近更新 更多