'Rails 6 API + ActiveStorage + Heroku + S3 - image urls not working in production

I have a Rails 6 API with a model Property that has_many_attached :images.

These images are attached to a model in properties_controller#create. In order to return the image to the frontend, I send the url_for(img) for each image attached to a property. ActiveStorage is configured to store the images in AWS S3 in both development and production (there are separate buckets for dev and prod).

In development, these urls look something like "http://localhost:3000/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--126782dcd2003952f1ef243c596824576b86400a/avatar.png", and the images render in the browser (Chrome FWIW).

In production (API is deployed to Heroku), the urls look like "https://the-heroku-project.com/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBCdz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--7d05475d4afbf8e414c9b47ab85bbbaae4a12a8c/simpson_living_room.jpg".

However, in production, broken image links render, rather than the images themselves. Pasting the URL in the browser behaves differently than locally -

  • locally the url takes me to a page consisting only of the corresponding image
  • in production, part of the webpage renders (background, a few other elements) - although the element (and broken image icon) that do render is not actually associated with the image src that I was trying to access... enter image description here

Any idea why the urls wouldn't work in production?


further investigation shows a difference between development and production:

development - redirect happens, url contains s3 bucket enter image description here

production - no redirect, url contains project url, not s3 bucket enter image description here

storage.yml =>

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>

local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
amazon:
  service: S3
  access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
  secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
  region: us-west-2
  bucket: bucketname-<%= Rails.env %>


Solution 1:[1]

For Active Storage to be fully functional, it needs imagemagick library and libvip. Did you add it to Heroku via an AptFile for e.g. ? I had the same issue and it was the missing libraries that was causing the error.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Julie VIGNAUX