火库里的藏物

我想知道 eu.artifacts.%PROJECT NAME%.appspot.com是什么。它目前占用了我每天5GB 的限制中的800mb 存储空间。它只包含 < strong > application/octet-stream 类型的文件。这个 bucket 是自动创建的,文件路径是 eu.artifacts....appspot.com/containers/images 的。两个最重的文件重量分别为200mb 和130mb。我试图删除它,但它是自动再次创建。用户可以在我的网站上传图片,但是这个桶目前只需要大约10mb 包含所有用户图片。

所以我的问题是: 这个桶是干什么用的? 为什么它这么重?

17437 次浏览

我是消防员

如果您正在使用云函数,那么您所看到的文件与最近在如何构建运行时(对于 Node 10及以上版本)方面的更改有关。

云函数现在使用 云构建为您的云函数创建运行时(节点10及以上)。而 Cloud Build 则使用 货柜登记处来存储这些运行时,它将它们存储在项目下的一个新的 Cloud Storage bucket 中。

For more on this, also see this entry in the Firebase pricing FAQ on 为什么我需要一个账单帐户来使用 Node.js 10或更高版本的 Firebase 云功能?

关于这些工件,请参阅 邮件列表上的线索


🛑 Update: some other answers suggest deleting artifacts from the Storage buckets, and even setting up lifecycle management on them to do so automatically. This leads to dangling references to those artifacts in the Container Registry, which breaks future builds.

要安全地删除工件,可以从 Container Registry 控制台(位于 gcf文件夹下)或使用 剧本删除容器。然后,这也将从存储桶中删除工件。

自 CLI 版本9.14以来,firebase deploy进程在部署之后自动清除其容器映像。因此,如果升级到最新版本,就不应该再在存储桶中获得额外的构件。

我咨询了 GCP 的支持,这里有一些东西

  • 云功能导致存储使用量激增
  • 由于这些构件不存储在默认存储桶中,所以即使存储的总字节没有达到空闲层限制,它们也会向您收费
  • 根据后勤人员的说法,在 https://console.cloud.google.com/storage/browser移走艺术品桶

关于构件桶,您实际上可以去掉它们,因为它们存储了函数的早期版本。但是,我不建议删除“ gcf-source...”bucket (s) ,因为它包含当前图像,所以删除这个 bucket 会使您的函数出错。

我试着把它整个移除,到目前为止还没有造成麻烦。如果有什么问题,我会更新的。


编辑201118: 请参阅下面的评论,您可能需要保留桶,同时删除所有的内容。

添加到@yo1995的响应中,您可以删除 bucket 中的构件,而不需要进入 GCP。待在 Firebase,你去仓库,然后“添加桶”。从那里,您将看到导入 gcp 和工件桶的选项。接下来,您可以相应地删除桶中的工件。

根据收到的一些评论,重要的是 不要删除桶,而是 delete the artifacts in the bucket only!

Artifact Bucket Location Picture

添加到@yo1995
我咨询了 Firebase Support,他们确认不应该删除构件桶。基本上,这些构件用于帮助构建存储在“ gcf-source”桶中的最终映像。

直接引用他们的话
“您可以随意删除“ XX.works”中的内容,但请不要碰桶,它将在以下部署周期中使用。”

如果您完全删除工件桶,可能会有一些意想不到的行为。
另外,“团队正在努力自动清理这个桶,但是在发布解决方案之前,他们需要解决一些限制。”

目前,我将 bucket 设置为自动删除超过1天的文件。

作为替代方法,您可以创建一个生命周期规则来删除文件夹中的对象。 把年龄设定为1天。所以它会删除文件夹中所有超过一天老化的对象。 lifeCycle rulw

设定条件

2022年初编辑: 这整个答案现在是没有意义的。它可能在过去有效,但是问题的实际根源现在已经在 FirebaseCLI 中修复了。

如何减少贮存量

因此,有一个伟大的 回答的问题,但解决方案,如何修复它需要进一步深入。

为了帮助未来的开发人员切入正题,下面是在 GCP 中将以下规则添加到您的项目后应该看到的结果

completely cleaned up artifact storage

The orange line is the us-artifacts.<your-project>.appspot.com bucket.

解决问题的步骤

  1. 导航到 https://console.cloud.google.com/
  2. 打开与 Firebase 项目对应的 GCP 项目
  3. 在菜单中,选择 Storage-> Browser Navigation menu
  4. 点击令人讨厌的 us-artifacts.<your-project>.appspot.com
  5. 进入“生命周期”选项卡,添加3天的生命周期
  • 添加一条规则
  • 删除 Object
  • 年龄 3lifecycle rule 注意: 24小时之后结果才会出现在使用图中

注意

Firebase 使用的容器会反向引用以前的容器,所以如果你设置了一个3天的周期,你的 Firebase 部署功能开始失败,你需要更新你的函数的本地名称来包含版本控制,并指定一个构建标志来删除旧版本,从你的 Firebase.json 中删除它们,或者手动删除过时的函数。

使用版本化的 API 类型函数

在您的入口点,假设 index.ts,并假设您已初始化的火力基地

admin.initializeApp(functions.config().firebase)
import * as functions from 'firebase-functions'


// define the app as a cloud function called APIv1 build xxxxxx
export const APIv1b20201202 = functions.https.onRequest(main)

在哪里 main是你的应用程序的名称

还有你的 firebase.json

...
"hosting": {
"public": "dist",
"ignore": ["firebase.json", "**/.*", "**/node_modules/**", "**/tests/**"],
"rewrites": [
{
"source": "/api/v1/**",
"function": "APIv1b2021202"
}
]
},
...


或者,手动更新

# Deploy new function called APIv11
$ firebase deploy --only functions:APIv11


# Wait until deployment is done; now both APIv11 and APIv10 are running


# Delete APIv10
$ firebase functions:delete APIv10

经过一些研究,并与消防队的电子邮件,这是什么建议给我。

We are aware that Cloud Build is not automatically deleting old artifacts so it's size keeps on increasing, as a workaround I’d recommend deleting the files inside the bucket in order to reduce any possible charges.

您可以删除文件到提到的桶去 GCP 控制台(使用相同的凭据作为 Firebase 控制台)-> 选择正确的项目-> 从左上角菜单选择存储-> 浏览器。 您将看到属于您的项目的所有桶,单击您喜欢的桶,然后您可以从中删除文件。

您可以尝试的另一种选择是管理 bucket 的对象生命周期。当对象满足生命周期规则中指定的所有条件时,有一个删除对象的选项,下面是一个 link,其中有一个关于这个选项的示例。这样,bucket 对象将被自动删除。

I have created a configuration file I named storage_artifacts_lifecycle.json with contents:

{
"lifecycle": {
"rule": [
{
"action": { "type": "Delete" },
"condition": {
"age": 21
}
}
]
}
}

我使用以下命令配置我的存储生命周期:

gsutil lifecycle set ./firebase/storage_artifacts_lifecycle.json gs://us.artifacts.${MY_PROJECT_ID}.appspot.com

and I validate its results after running with

gsutil lifecycle get gs://us.artifacts.${MY_PROJECT_ID}.appspot.com

希望这对你有所帮助!

我对这个主题做了一些研究,找到了最适合我的解决方案——我在每次部署 Firebase 函数之前都会运行一个脚本。这个脚本扫描我的容器图像,然后:

  • 保持与 latest标签的那些。
  • 删除除最后一个以外的所有图像。

这种方法是半自动化的,存储只有在我部署的时候才会增长,所以它对我来说非常有用。

该脚本是用 JavaScript 编写的,用于具有节点和 gcloud cli 的环境。

const spawn = require("child_process").spawn;


const KEEP_AT_LEAST = 2;
const CONTAINER_REGISTRIES = [
"gcr.io/<your project name>",
"eu.gcr.io/<your project name>/gcf/europe-west3"
];


async function go(registry) {
console.log(`> ${registry}`);
const images = await command(`gcloud`, [
"container",
"images",
"list",
`--repository=${registry}`,
"--format=json",
]);
for (let i = 0; i < images.length; i++) {
console.log(`    ${images[i].name}`);
const image = images[i].name;
let tags = await command(`gcloud`, [
"container",
"images",
"list-tags",
image,
"--format=json",
]);
const totalImages = tags.length;
// do not touch `latest`
tags = tags.filter(({ tags }) => !tags.find((tag) => tag === "latest"));
// sorting by date
tags.sort((a, b) => {
const d1 = new Date(a.timestamp.datetime);
const d2 = new Date(b.timestamp.datetime);
return d2.getTime() - d1.getTime();
});
// keeping at least X number of images
tags = tags.filter((_, i) => i >= KEEP_AT_LEAST);


console.log(`      For removal: ${tags.length}/${totalImages}`);
for (let j = 0; j < tags.length; j++) {
console.log(
`      Deleting: ${formatImageTimestamp(tags[j])} | ${tags[j].digest}`
);
await command("gcloud", [
"container",
"images",
"delete",
`${image}@${tags[j].digest}`,
"--format=json",
"--quiet",
"--force-delete-tags",
]);
}
}
}


function command(cmd, args) {
return new Promise((done, reject) => {
const ps = spawn(cmd, args);
let result = "";


ps.stdout.on("data", (data) => {
result += data;
});


ps.stderr.on("data", (data) => {
result += data;
});


ps.on("close", (code) => {
if (code !== 0) {
console.log(`process exited with code ${code}`);
}
try {
done(JSON.parse(result));
} catch (err) {
done(result);
}
});
});
}


function formatImageTimestamp(image) {
const { year, month, day, hour, minute } = image.timestamp;
return `${year}-${month}-${day} ${hour}:${minute}`;
}


(async function () {
for (let i = 0; i < CONTAINER_REGISTRIES.length; i++) {
await go(CONTAINER_REGISTRIES[i]);
}
})();

它运行以下命令:

# finding images
gcloud container images list --repository=<your repository>


# getting metadata
gcloud container images list-tags <image name>


# deleting images
gcloud container images delete <image name>@<digest> --quiet --force-delete-tags

这里有一篇描述我的发现的博客文章 https://krasimirtsonev.com/blog/article/firebase-gcp-saving-money

Firebase 表示,他们已经发布了一个补丁(截至2021年6月) :

Https://github.com/firebase/firebase-tools/issues/3404#issuecomment-865270081

Fix 是在 Firebase-tools 的下一个版本中,今天应该会出现。

修正:

  1. 运行 npm i -g firebase-tools

  2. Browse your contains in Cloud Storage https://console.cloud.google.com/storage/browser/ (look for a bucket named gcf-sources-*****-us-central1)

  3. Any deleted functions via firebase deploy --only functions seem to remove artifacts automatically, but if you delete them through the UI, they artifacts remain.

添加到@d-_-b

2022年7月7日

现在 Firebase 支持页面也宣布了这一消息:

如果您看到云存储的使用量超出预期,这就是 可能是由已知的工件清理问题引起的 in the function deployment process.

这个问题现在已经解决了; 如果您仍然看到意外的使用, 更新 Firebase CLI 并重新部署云函数