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

Google Cloud Build - Different scopes of Dockerfile and cloudbuild.yaml

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

我创建了一个简单的图像来可视化调用 gcloud builds submit --config=cloudbuild.yaml 时发生的情况。那么,为什么我不能从 cloudbuild.yaml 访问目录 dist/browser,即使它是在创建目录 dist/browserDockerfile 之后处理的?

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

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

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

为了随后使用该目录:

  • 破解一种方法来挂载该步骤生成的(文件系统)图像并从中提取目录(不建议;可能不允许)。
  • 您需要 运行 该图像作为容器,然后 docker cp 文件从它返回到 Cloud Build (VM) 的文件系统(可能在 /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
  • 列表 /testdir 现在包含 freddie.txt
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