我最近问了一个关于为什么会收到错误 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
所在位置已创建?
最佳答案
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
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
关于docker - Google Cloud Build - Dockerfile 和 cloudbuild.yaml 的不同范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66714188/