Docker-compose.yml 文件构建基础镜像,然后 children 基于它?

Docker-compose.yml file that builds a base image, then children based on it?

澄清一下,当我说基础镜像时,我指的是具有所有通用配置的 parent 镜像,因此基于它的 children 不需要单独下载依赖项.

根据我的理解,docker-compose.yml 文件是 run-time 配置,而 Dockerfile 是 build-time 配置。但是,有一个使用 docker-compose 的 build 选项,我想知道如何使用它来构建基本图像。

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

目前我希望改成docker-compose文件的shellscript,长这样:

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 只接受 pre-built 图像。

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

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

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

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

此处,python:3.6 基本映像,不会经常更改,因此您无需在每次 运行 docker 撰写时构建它命令.

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

您可以通过以下方式在撰写文件中使用这些 docker 文件:

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 文件中声明的所有服务都是隔离网络的一部分。

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

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 图像。这个镜像可以被其他服务的 Dockerfiles 重复使用,即使是在同一个构建过程中。

只是对 答案的一个小补充。如果您选择遵循他的方法(这是我的选择),则可以避免使用 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 中没有什么可以覆盖的。

代替运行 docker-compose,你可以实现一个脚本,构建带有特定标签docker build ... -t your_tag的镜像,然后运行docker-撰写。在儿童 docker 文件中,您可以使用 FROM your_tag.

根据@amiasato 的答案做了更多研究,看起来好像有一个 replicated 键,您可以像这样将其设置为 0

version: "3"
services:
  base-image:
    build:
      context: .
      dockerfile: Dockerfile-base
    deploy:
      mode: replicated
      replicas: 0

https://docs.docker.com/compose/compose-file/compose-file-v3/#replicas