Docker-compose:在生产中用预构建的镜像替换基于 "build" 的服务?

Docker-compose: replace "build"-based service with pre-built image in production?

假设我们有以下 docker-compose.yml:

version: '3'
services:
  db:
    image: "postgres"
    ports:
     - "5432:5432"
    environment:
     - POSTGRES_PASSWORD=mysecretpassword
  web:
    build: web
    depends_on: [ db ]
    ports:
     - "80:80"

第一个服务 db 只是 运行 一个包含来自 Docker Hub 的官方 postgres 图像的容器。

第二个服务,web,首先在一个名为 web 的文件夹中基于 Dockerfile 构建一个新图像,然后 运行 是一个包含该图像的容器.

在开发过程中,我们现在可以(重复)更改 web 文件夹中的任何内容,然后 运行 docker-compose up --build 到 运行 我们本地的应用程序。

假设我们现在要部署到生产环境。我的理解是 docker-compose.yml 现在可以用于 "define a stack in Docker's swarm mode"(参见 answer, for instance). However, for the build step of the web service, Docker's compose file documentation 指出

This option is ignored when deploying a stack in swarm mode with a (version 3) Compose file. The docker stack command accepts only pre-built images.

无论如何,在生产机器上构建映像可能不是一个好主意,因为这会留下构建工件(源代码);这应该发生在构建服务器上。

我的问题是,是否有推荐的方法来修改 docker-compose.yml 在生产途中以某种方式将 build: web 换成 image: <id>

Use Compose in production 上什么都没有。总的来说,我的方法有问题吗?

正确的方法(即我的方法 :P)是使用不同的 docker-compose 文件;例如,docker-compose.dev.ymldocker-compose.prod.yml。然后,您可以将生产就绪图像推送到存储库,比如 Docker Hub,并在 docker-compose.prod.ymlweb 服务中引用该图像。您可以一直使用 dev docker-compose 文件(带有 build 选项的文件)进行本地开发。

此外,如果您考虑过这一点,则不能将环境变量用作 docker-compose 中的键(参见 here)。因此无法有条件地设置 imagebuild 选项。

docker-compose.yml 应该只包含规范的服务定义。

任何特定于构建环境(例如开发与生产)的内容都应在单独的文件中声明 docker-compose.override.yml。每个构建环境都可以有自己的文件版本。

build: web 声明不属于 docker-compose.yml,因为它只应该 运行 在本地(并且可能在构建服务器上),而不是在生产中。

因此,在上面的示例中,docker-compose.yml 应该是这样的:

version: '3'
services:
  db:
    image: "postgres"
    ports:
     - "5432:5432"
    environment:
     - POSTGRES_PASSWORD=mysecretpassword
  web:
    depends_on: [ db ]
    ports:
     - "80:80"

这将是本地开发的默认 docker-compose.override.yml

version: '3'
services:
  web:
    build: web

运行 docker-compose up --build -d 现在将构建最新的代码更改并在本地启动我们的应用程序。

可能还有另一个版本 docker-compose.override.build.yml,针对 build/CI 服务器:

version: '3'
services:
  web:
    build: web
    image: mydockeruser/web

运行 docker-compose -f docker-compose.yml -f docker-compose.override.build.yml push 将构建最新的代码更改并将图像推送到其 registry/repository.

终于可以有另一个版本了docker-compose.override.prod.yml:

version: '3'
services:
  web:
    image: mydockeruser/web

部署到生产环境(仅部署到单个 Docker 主机,而不是集群)现在可以像仅复制 docker-compose.ymldocker-compose.override.prod.yml 以及 运行 一样简单宁docker-compose -f docker-compose.yml -f docker-compose.override.prod.yml up -d.