Docker swarm:在堆栈部署期间忽略 Docker compose 文件中的“build”配置。

26

我们创建了一个包含多个服务的Docker Compose文件。这些服务的镜像是使用“build”配置选项在运行时构建的。相应的Dockerfile在各自的目录中给出。

示例Docker Compose文件...

version: '3'
services:
  db2server:
    build: ./db2server
    ports:
      - "50005:50000"
    command: ["db2start"]
  appruntime:
    build: ./appruntime
    depends_on:
     - db2server

这个Docker Compose文件可以使用docker-compose命令。

  • 镜像是在运行时从db2serverappruntime目录中的Dockerfile构建的。
  • 这些镜像被部署在主机上。

但是,当我们尝试在Docker Swarm中部署时,会抛出以下错误...

docker stack deploy -c /home/docker/docker-compose.yml app

Ignoring unsupported options: build

Creating network app_default
Creating service app_db2server
failed to create service app_db2server: Error response from daemon: rpc error: code = InvalidArgument desc = ContainerSpec: image reference must be provided

看起来在docker swarm中堆栈部署期间忽略了“build”配置选项。

我们如何在docker swarm中部署在docker compose文件中定义了“build”选项的这些服务。

3个回答

31
简短的回答是,你不能在使用docker stack deploy命令时使用build命令。
docs中可以看到:

注意:在使用(版本3)Compose文件在swarm模式下部署堆栈时,docker stack命令build选项会被忽略。 docker stack命令只接受预构建的映像。

另一种方法是在部署swarm集群之前构建docker镜像。
使用docker build命令创建docker镜像;将创建的镜像推送到(公共或私有)docker registry中;并在您的docker compose文件中引用它。

4
我发现对于一些小的开发修改,构建和推送镜像需要花费很长时间,有没有更省时的替代方案? - adnanmuttaleb
您可以使用标签来设置开发节点,从而限制堆栈仅在该节点上运行,这样您就不必在构建相同节点上的镜像后再推送它。 - vlizana

25

如果您还需要继续使用此操作,您可以通过设置图像参数以及构建参数来标记compose中的构建镜像,如您在文档的构建部分所见。这里是相关文档。因此,文件应该看起来像这样:

version: '3'
services:
  db2server:
    image: <your registry here>/db2server
    build: ./db2server
    ports:
      - "50005:50000"
    command: ["db2start"]
  appruntime:
    image: <your registry here>/appruntime
    build: ./appruntime
    depends_on:
     - db2server

那么你可以执行:

docker-compose build
docker-compose push
docker stack deploy -c /home/docker/docker-compose.yml app

如果docker stack支持像--build这样的标志就好了,这些标志只有在使用例如--orchestrator none--orchestrator singlenode时才可用。 - Marinos An

11
Compose文件同时服务于docker-compose命令行工具和docker stack命令行工具。在docker-compose中,“build”选项可以使用,但在堆栈命令中会被忽略,而“deploy”选项可以在堆栈命令中使用,但在docker-compose中会被忽略。
Swarm并未设计用于为您构建镜像。它假设您的镜像已经在镜像注册表中可用。Swarm中的多个节点无法互相共享镜像,因此注册表(可以是远程的也可以运行在Swarm本身上)是确保它们可以拉取相同完全镜像的唯一方式。
因此,典型的示例要么是让Docker Hub根据代码提交自动构建图像,要么是让CI/CD平台构建图像并将其推送到注册表。然后,您的stack deploy命令将从该注册表中拉取适当的镜像。

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