【问题标题】:Docker-compose: replace "build"-based service with pre-built image in production?Docker-compose:用生产中的预构建映像替换基于“构建”的服务?
【发布时间】:2023-04-04 16:09:01
【问题描述】:

假设我们有以下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 现在可用于“在 Docker 的 swarm 模式下定义堆栈”(例如,请参阅this 答案)。但是,对于web 服务的build 步骤,Docker 的compose file documentation 声明

在使用(版本 3)Compose 文件以 swarm 模式部署堆栈时,将忽略此选项。 docker stack 命令只接受预先构建的图像。

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

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

Use Compose in production 上没有任何内容。总的来说,我的方法有问题吗?

【问题讨论】:

    标签: docker docker-compose docker-swarm


    【解决方案1】:

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

    任何特定于构建环境的内容(例如 dev 与 prod)都应在单独的文件 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,针对构建/CI 服务器:

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

    运行 docker-compose -f docker-compose.yml -f docker-compose.override.build.yml push 将构建最新的代码更改并将映像推送到其注册表/存储库。

    最后,可能还有另一个版本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 一样简单。

    【讨论】:

      【解决方案2】:

      正确的做法(即我这样做的方式: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 文件是要走的路。看起来为了避免docker-compose.dev.ymldocker-compose.prod.yml 之间的重复,建议将所有共享部分保留在docker-compose.yml 中,并创建另一个名为docker-compose.override.yml 的文件的开发/产品特定版本。见docs.docker.com/compose/extends
      • 添加了另一个答案以稍微扩展一下。您肯定在这里为我指明了正确的方向,谢谢!
      猜你喜欢
      • 2021-03-03
      • 2019-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-20
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多