docker - Google Cloud Build - Dockerfile 和 cloudbuild.yaml 的不同范围

标签 docker google-cloud-build

我最近问了一个关于为什么会收到错误 Specified public directory 'dist/browser' does not exist, can't deploy hosting to site PROJECT-ID 的问题当我尝试在我的 cloudbuild.yaml 中部署到 Firebase 托管时。然而,由于我发现这个问题的信息过于臃肿,我试图将其分解。

我创建了一个简单的图像来可视化当我调用 gcloud builds submit --config=cloudbuild.yaml 时会发生什么。那么为什么我无法访问目录 dist/browser来自cloudbuild.yaml即使它是在 Dockerfile 之后处理的目录 dist/browser 所在位置已创建?

enter image description here

最佳答案

Cloud Build 的最佳概念是一系列以本地文件系统形式应用于数据的函数(步骤)(通常只是 /workspace,因为这是添加到每个步骤的默认卷挂载) ,但您可以添加其他卷安装)和互联网。

每个函数(步骤)的输出都是独立的,除非您明确将数据发布回这两个源之一(步骤的卷安装之一或 Internet)。

在这种情况下,docker build 使用本地文件(示例中未显示)并在生成的图像中生成dist/browser,但此文件夹 可在该图像中访问;没有添加任何内容,例如您可以在后续步骤中使用的 /workspace

为了随后使用该目录:

  • 破解一种方法来挂载该步骤生成的镜像(的文件系统)并从中提取目录(不建议;可能不允许)。
  • 您需要将该镜像作为容器运行,然后将其中的 docker cp 文件返回到 Cloud Build(虚拟机)的文件系统(可能位于 /workspace)中>).
  • 首先不要将目录放入图像中(见下文)

提案

不要使用 docker build 构建包含目录的镜像,而是将 Dockerfile 解构为一系列 Cloud Build 步骤。这样,您想要的工件(如果写入该步骤的卷安装之一下的某个位置)将在后续步骤中可用:

steps:
- name: gcr.io/cloud-builders/npm
  args:
  - install
- name: gcr.io/cloud-builders/npm
  args:
  - run
  - build:ssr # Presumably this is where dist/browser is generated?
- name: firebase
  args:
  - deploy # dist/browser

NOTE Every Cloud Build step has an implicit:

- name: some-step
  volumes:
  - name: workspace
    path: /workspace

证明

这是一个最小的 Cloud Build 配置,它使用名为 testdir 的卷,该卷映射到 Cloud Build VM 的 /testdir 目录。

NOTE The example uses testdir to prove the point. Each Cloud Build step automatically mounts /workspace and this could be used instead.

配置:

  • 列出空的 /testdir
  • /testdir 中创建文件 freddie.txt
  • 列出现在包含 freddie.txt/testdir
options:
# volumes:
#   - name: testdir
#     path: /testdir

steps:
  - name: busybox
    volumes:
      - name: testdir
        path: /testdir
    args:
      - ash
      - -c
      - "ls -1a /testdir"
  - name: busybox
    volumes:
      - name: testdir
        path: /testdir
    args:
      - ash
      - -c
      - 'echo "Hello Freddie" > /testdir/freddie.txt'
  - name: busybox
    volumes:
      - name: testdir
        path: /testdir
    args:
      - ash
      - -c
      - "ls -1a /testdir"

NOTE Uncommenting volumes under options would remove the need to reproduce the volumes in each step.

编辑后的输出是:

gcloud builds submit \
--config=./cloudbuild.yaml \
--project=${PROJECT}

# Lists (empty) /testdir
Starting Step #0
Step #0: Pulling image: busybox
Step #0: .
Step #0: ..

# Creates /test/freddie.txt
Starting Step #1
Step #1: Already have image: busybox
Finished Step #1

# List /testdir containing freddie.txt
Starting Step #2
Step #2: .
Step #2: ..
Step #2: freddie.txt
Finished Step #2

关于docker - Google Cloud Build - Dockerfile 和 cloudbuild.yaml 的不同范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66714188/

相关文章:

docker - Google Cloud Build - 摘要状态显示失败,所有步骤均成功

google-cloud-platform - Google Cloud Build 获取身份 token

python - 在 amazon/aws-cli docker 镜像上安装 python 3.9

Docker 推送到 Heroku "Unexpected HTTP status: 500 internal server error"

docker - 使用 Docker 的标准 Go 项目布局导致构建上下文问题

部署到 Google Compute Engine 的 Docker 镜像不断重启

google-cloud-sql - 在使用私有(private) IP 连接到云 sql 的云构建上运行数据库迁移

docker - Docker引擎群模式|在撰写中使用 “extra_hosts”的替代方法

linux - 如何在 alpine 的 apk 中禁用 SSL 验证?

Dockers 容器镜像更新