如果 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:
- Dockerfile_one: python + 先知的依赖
- Dockerfile_two: image_from_Dockerfile_one + prophet + 其他依赖项
cloudbuild.yaml应该是什么样子:
- 如果有以前可用的图像,则跳过该步骤,否则 运行 使用 Dockerfile_one 的步骤并保存图像
- 使用步骤 (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 个管道
- 第一个创建基础图像。这样,您可以在每次需要重建此基础映像时触发它,其生命周期可能与您的应用程序生命周期不同。类似的东西
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']
- 然后,在您的第二个 dockerfile 中,从基础映像开始并使用第二个 Cloud Build 管道来构建、推送和部署它(就像您在问题的最后 3 个步骤中所做的那样)
FROM gcr.io/<PROJECT_ID>/base-image
COPY .....
....
...
Cloud Build 因超时错误而失败(我正在尝试使用 Prophet 部署 CloudRun)。因此,我试图将 Dockerfile 分成两部分(在两者之间保存图像以防失败)。我会像这样拆分 Dockerfile:
- Dockerfile_one: python + 先知的依赖
- Dockerfile_two: image_from_Dockerfile_one + prophet + 其他依赖项
cloudbuild.yaml应该是什么样子:
- 如果有以前可用的图像,则跳过该步骤,否则 运行 使用 Dockerfile_one 的步骤并保存图像
- 使用步骤 (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 个管道
- 第一个创建基础图像。这样,您可以在每次需要重建此基础映像时触发它,其生命周期可能与您的应用程序生命周期不同。类似的东西
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']
- 然后,在您的第二个 dockerfile 中,从基础映像开始并使用第二个 Cloud Build 管道来构建、推送和部署它(就像您在问题的最后 3 个步骤中所做的那样)
FROM gcr.io/<PROJECT_ID>/base-image
COPY .....
....
...