Help! Is There an Updated GCS Storage Adapter for Ghost 6.65?

I’m running Ghost CMS 6.65 on Google Cloud Run.

Because of an issue with GCS storage, my current workaround is to bind/mount the storage inside the container and re-upload/sync the files every 300 seconds.

This worked when the site was small, but the site is now growing and I’m starting to notice increasing lag and slower response times.

Has anyone found a better way to properly configure Ghost 6.65 + Google Cloud Run + Google Cloud Storage (GCS) without having to periodically sync the files?

I’d especially appreciate recommendations for a production-friendly setup that won’t add unnecessary latency or resource usage.

You probably don’t need an adapter anymore. Cloud Run can mount a GCS bucket directly as a volume (Cloud Storage FUSE), so you can point content/images at the bucket and drop the 300s sync completely.

I’d only mount images/media/files that way though, not the whole content folder. FUSE writes are slowish, fine for uploads, not for a database.

Are you on SQLite? On Cloud Run that gets messy fast once it scales past one instance. Cloud SQL with MySQL 8 would save you a lot of pain there.

I’ve gotta be honest, having read your threads here so far: This sounds like a world of pain for something that isn’t necessarily a problem :grimacing:

You’re effectively working around Ghost’s architecture, as far as I understand (without using Google Cloud and therefore only having a general understanding of what Google Cloud Run does).

Having dabbled with quite a lot of different setups over the years, I’d recommend the boring one. The official Docker setup, a persistent volume (which you’ll need regardless of a storage adapter, because theme files, logs, etc. cannot use storage adapters) and a MySQL database.

Working around that will work somehow. But it will break eventually, because the Ghost core isn’t tested against it. If the reason is price, I’d argue that the time spent on figuring all of this out costs more than the price of managed hosting (yes, I am biased in that) or a VPS (even in days of crazy prices for these).

thanks for the reply,

Before, I was also mounting SQLite3, but I’ve already moved to Aiven MySQL 8, and the setup was pretty easy.

Now I’m digging into Cloud FUSE. I’ll check it out and see if it’s the best fit.

I’m mainly using Cloud Run because I like the quick CI/CD workflow and how easy it is for me to deploy and roll back containers. It’s less about trying to avoid the “boring” setup and more about fitting Ghost into the infrastructure I’m already using.

The GCS storage issue is definitely the part I’m not happy with. as i have said i moved to aiven MYSQL8

100% working now :flexed_biceps: Thanks a lot for the solution! Really appreciate you taking the time to explain it. I was definitely focusing too much on finding a GCS adapter workaround when the simpler approach was right there. :sweat_smile:

Honestly, this would be a great addition to the Ghost documentation, it would probably save a lot of people the same headache. :folded_hands:

in addition you will might encounter this error while posting with images:

you have to properly set:

Screenshot 2026-09-27 031556

Sounds like you’ve got it working, but in case you do end up wanting to go the adapter route, the S3Storage adapter that ships with Ghost natively can be used with GCS via its S3-compatible API.

Setup:

  • Create HMAC keys for a service account (Cloud Storage → Settings → Interoperability). These become accessKeyId and secretAccessKey. Plain service-account JSON or ADC won’t work, because the adapter only accepts static key pairs or ambient AWS credentials.
  • Set endpoint: 'https://storage.googleapis.com'.
  • Set region: 'auto'. Any value works, but the SDK needs one.
  • Set forcePathStyle: true. It’s safer with dotted bucket names.

example config:

"storage": {
  "media": {
    "adapter": "S3Storage",
    "bucket": "my-bucket",
    "endpoint": "https://storage.googleapis.com",
    "region": "auto",
    "forcePathStyle": true,
    "accessKeyId": "GOOG1E...",
    "secretAccessKey": "...",
    "staticFileURLPrefix": "content/media",
    "cdnUrl": "https://storage.googleapis.com/my-bucket",
    "multipartUploadThresholdBytes": 52428800,
    "multipartChunkSizeBytes": 10485760
  }
}

This is great bro!

Thankyou for this solution

Will try and test this out for my local build.