ComfyUI Node

Upload Image To GCS

Push a ComfyUI Image Straight to Google Cloud Storage — Public URL Included

By papcorns·Created about a year ago·Updated about a year ago· 0
Upload Image To GCS
  • image
  • public_url
bucket_namemy-bucket
service_account_pathservice-account.json

Sometimes a generated image needs to leave the machine. You're building a pipeline that posts results to a site, a bot that shares to a chat channel, or a backend that needs images in object storage instead of on local disk. Upload Image To GCS is the pack's cloud node: you feed it an image, tell it your GCS bucket and service-account file, and it returns a public URL to the uploaded PNG. That's the whole flow - image in, URL out, no shelling out to gsutil or babysitting a script between ComfyUI and your bucket.

How it works

The node takes your IMAGE tensor, converts the first frame to a PIL image, and saves it to a temp file with a random UUID name. It then:

  1. Sets GOOGLE_APPLICATION_CREDENTIALS to your service_account_path (this is how the Google client library finds your credentials).
  2. Initializes storage.Client() and grabs the bucket.
  3. Uploads the file, calls blob.make_public(), and returns blob.public_url.
  4. Cleans up the temp file either way.

Inputs: image, bucket_name (default my-bucket - you'll change it), and service_account_path (default service-account.json). Output: a single STRING named public_url - which is also how errors surface, because the node returns an Error uploading to GCS: ... string in that same slot when something fails.

What you need before it works

This is the highest-friction node in the pack, because none of the setup is ComfyUI's job:

  • A GCS bucket that already exists. The node doesn't create it.
  • A service account with at least Storage Admin on that bucket, per the README.
  • The service account's JSON key downloaded somewhere the node can read.

The README's GCS section spells all three out, so if you're missing any of them, start there. The pack's requirements.txt includes google-cloud-storage>=2.0.0, so the library is handled by the normal install.

The three gotchas that will actually bite

Relative paths. service_account_path is a plain string. If you type service-account.json, it resolves against ComfyUI's working directory - the same CWD quirk as the pack's audio-save node. Give it an absolute path (/home/you/keys/gcs.json) and save yourself the "File not found" round.

make_public() vs uniform bucket-level access. The node makes your blob public using GCS's legacy ACL system. Buckets created in the last several years default to uniform bucket-level access, which disables per-object ACLs - and make_public() will fail there. If you get an ACL error, either disable uniform access on the bucket or accept that public URLs won't come from this node's default path.

Batch awareness: there is none. It uploads only image[0] - the first image in the batch. Feed it a 10-image stack expecting ten URLs and you get exactly one. If you're generating a batch, loop it or upload per-item.

Also worth knowing: it sets the GOOGLE_APPLICATION_CREDENTIALS environment variable as a side effect every run, so if you switch between service accounts mid-session, the last one executed wins for everything in that process.

Install

Standard pack install:

cd ComfyUI/custom_nodes
git clone https://github.com/papcorns/Papcorns-Comfyui-Custom-Nodes
cd Papcorns-Comfyui-Custom-Nodes
pip install -r requirements.txt

Restart ComfyUI (or search "Papcorns" in ComfyUI Manager).

Should you use it?

If you already live in GCP, this is a genuinely handy glue node - the public-URL output plugs straight into a Show Text node or any downstream API call, and the whole "generate → upload → share" flow stays inside one graph. If you're not on GCP, don't install it for this: S3-flavored upload nodes and catbox/imgbb savers cover the same need with less credential ceremony. It's a cloud-infrastructure convenience node for people who've already chosen their cloud, and it does its job as long as you handle the setup it assumes.

CategoryPapcorns🍿

Inputs (3)

NameTypeDefaultDescription
imageIMAGE
bucket_nameSTRINGmy-bucket
service_account_pathSTRINGservice-account.json

Outputs (1)

NameTypeDescription
public_urlSTRING