如果 CloudBuild 失败,则在 Cloud Build 中使用 2 个 Dockerfile 重新使用中间步骤映像

Using 2 Dockerfiles in Cloud Build to re-use intermediary step image if CloudBuild fails

Cloud Build 因超时错误而失败(我正在尝试使用 Prophet 部署 CloudRun)。因此,我试图将 Dockerfile 分成两部分(在两者之间保存图像以防失败)。我会像这样拆分 Dockerfile:

cloudbuild.yaml应该是什么样子:

  1. 如果有以前可用的图像,则跳过该步骤,否则 运行 使用 Dockerfile_one 的步骤并保存图像
  2. 使用步骤 (1) 中的图像,向其添加更多依赖项并保存图像以进行部署

这是 cloudbuild.yaml 现在的样子

steps:
#  create gcr source directory
- name: 'bash'
  args:
    - '-c'
    - |
      echo 'Creating gcr_source directory for ${_GCR_NAME}'
      mkdir _gcr_source
      cp -r cloudruns/${_GCR_NAME}/. _gcr_source

# Build the container image
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/$PROJECT_ID/${_GCR_NAME}', '.']
  dir: '_gcr_source'

# Push the container image to Container Registry
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'gcr.io/$PROJECT_ID/${_GCR_NAME}']

# Deploy container image to Cloud Run
- name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: gcloud
  args:
  - run
  - deploy
  - ${_GCR_NAME}
  - --image=gcr.io/$PROJECT_ID/${_GCR_NAME}

非常感谢!

不是答案,而是解决方法。如果有人有同样的问题,使用 Python3.8 而不是 3.9 对 Cloud Build 有效。

这是 Dockerfile 的样子:

RUN pip install --upgrade pip wheel setuptools

# Install pystan
RUN pip install Cython>=0.22
RUN pip install numpy>=1.7
RUN pip install pystan==2.19.1.1

# Install other prophet dependencies
RUN pip install -r requirements.txt
RUN pip install prophet

尽管弄清楚如何为 CloudRun 迭代构建图像,那真的很棒。

为什么您的云构建因超时错误而失败?

在 docker 中构建图像时,保持图像尺寸小很重要。通常会创建多个 docker 文件来处理图像大小限制。在您的情况下,您无法减小图像大小并仅包含所需内容。

如何纠正它?

  • 根据这个 documentation,多阶段构建,(在 Docker 17.05) 允许您在第一个“构建”中构建您的应用程序 容器并在另一个容器中使用结果,同时使用 相同的 Docker 文件。
  • 您在 Docker 文件中使用了多个 FROM 语句。每个来自 指令可以使用不同的基数,并且它们中的每一个都开始一个新的 构建阶段。您可以有选择地从一个阶段复制工件 到另一个,在决赛中留下你不想要的一切 图片。要显示其工作原理,请遵循此 link.
  • 您只需要一个 Docker 文件。
  • 结果是和以前一样的小生产图像,有一个 显着降低复杂性。您无需创建任何 中间图像,你不需要提取任何伪影 您的本地系统。

它是如何工作的?

  • 你可以name your build stages。默认情况下,阶段不是 命名,你通过它们的整数来引用它们,从 0 开始 对于第一个 FROM 指令。但是,您可以通过以下方式命名您的阶段 将 AS 添加到 FROM 指令。
  • 构建图像时,不一定需要构建 整个 Docker 文件,包括每个阶段。您可以指定一个 目标 建造阶段.
  • 使用多阶段构建时,您不仅限于从 您之前在 Docker 文件中创建的阶段。您可以使用 COPY——从指令到copy from a separate image,要么 使用本地图像名称、本地可用的标签或 Docker 注册表或标记 ID。
  • 您可以pick up where a previous stage通过参考 使用 FROM 指令时。
  • Google documentation中有一个docker文件的例子 它使用多阶段构建。 hello 二进制文件首先构建 容器并注入第二个容器。因为第二个容器 基于scratch,生成的图片只包含hello 二进制文件,而不是执行期间所需的源文件和目标文件 建造.
FROM golang:1.10 as builder

WORKDIR /tmp/go
COPY hello.go ./
RUN CGO_ENABLED=0 go build -a -ldflags '-s' -o hello

FROM scratch
CMD [ "/hello" ]
COPY --from=builder /tmp/go/hello /hello
  • 这里是 tutorial 以了解多阶段构建的工作原理。

您需要有 2 个管道

  1. 第一个创建基础图像。这样,您可以在每次需要重建此基础映像时触发它,其生命周期可能与您的应用程序生命周期不同。类似的东西
steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'gcr.io/<PROJECT_ID>/base-image', '-f', 'DOCKERFILE_ONE', '.']
images: ['gcr.io/<PROJECT_ID>/base-image']
  1. 然后,在您的第二个 dockerfile 中,从基础映像开始并使用第二个 Cloud Build 管道来构建、推送和部署它(就像您在问题的最后 3 个步骤中所做的那样)
FROM gcr.io/<PROJECT_ID>/base-image
COPY .....
....
...