Docker-compose:在生产中用预先构建的映像替换基于“构建”的服务?

时间:2018-12-21 21:54:59

标签: docker docker-compose docker-swarm

假设我们有以下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首先基于Dockerfile在也称为web的文件夹中构建新图像,然后使用该图像运行容器。

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

假设我们现在要部署到生产环境。我的理解是,docker-compose.yml现在可以用来“以Docker的群集模式定义堆栈”(例如,参见this答案)。但是,对于build服务的web步骤,Docker的compose file documentation指出

  

在以(版本3)撰写文件以群集模式部署堆栈时,将忽略此选项。 docker stack命令仅接受预构建的图像。

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

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

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

2 个答案:

答案 0 :(得分:1)

执行此操作的正确方法(即:P)是使用不同的docker-compose文件;例如docker-compose.dev.ymldocker-compose.prod.yml。然后,您可以将准备就绪的映像推送到Docker Hub的存储库中,并在docker-compose.prod.yml的{​​{1}}服务中引用该映像。一直以来,您都可以使用dev docker-compose文件(带有web选项的文件)进行本地开发。

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

答案 1 :(得分:0)

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一样简单。