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/browser
的 Dockerfile
之后处理的?
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
我最近问了一个问题,为什么我在 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/browser
的 Dockerfile
之后处理的?
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
中创建文件 - 列表
/testdir
现在包含freddie.txt
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
underoptions
would remove the need to reproduce thevolumes
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