Search code examples
ruby-on-railsrubygoogle-app-enginegoogle-cloud-storagerails-activestorage

Loading images from Google Cloud Storage for Ruby on Rails app on Google App Engine


I have a Ruby on Rails web application (deployed on Google App Engine) using Spree/Solidus core, which is connected to Google Cloud Storage for file storage. We have an admin dashboard for our app where we can upload images related to objects and we have a webpage in which we show those images. The images show up at first when we recently deployed the project, but they fail to show up after a while! We get the following 400 error for the images shown on the console:

Failed to load resource: the server responded with a status of 400 ()

When we check the admin dashboard, the same images are still visible, but they are shown as broken on the homepage. Our Google Cloud Storage bucket has public access (though I don't think it really needs it, since the app is on the same project and we have the GC_access JSON file deployed).

We are using the following code to show the images:

<% if image_url = image.try(:url, size)  %>
  <%= image_tag image_url %>
<% else %>
  <span class="image-placeholder <%= size %>"></span>
<% end %>

I will appreciate any help or advice on what to try to fix this issue! I'm not sure what other information may be helpful, but if you think more information on something can be helpful I can add more details.


Solution

  • There are multiple things you can check in order to make sure your images are correctly being allowed to be shared publicly. The first one would be to enable Bucket Uniform Level Access. This type of access is general for all the objects in your bucket instead of per-object ACLs, and the objects should be set for public access. The next thing to verify is whether the image URLs are being correctly created for public viewing, according to the documentation, the URLs should be in this format:

    https://storage.googleapis.com/BUCKET_NAME/OBJECT_NAME

    If your URL has a long string of data, it could be that you are using signed URLs on your website. These URLs have an expiration date, which could explain why they seem to have worked at first and then they stopped showing up for the public. In the ActiveStorage documentation, it says that the config/storage.yml file will default to private access by creating signed URLs:

    By default, Active Storage assumes private access to services. This means generating signed, single-use URLs for blobs. If you'd rather make blobs publicly accessible, specify public: true in your app's config/storage.yml

    This related SO thread also talks about URLs expiring and Signed URLs.