2
votes

First let me start by saying I'm a complete novice when it comes to Ruby & Rails, so hopefully I'm not making a noob mistake.

I've picked up the source for an app which I have successfully deployed to heroku; and running in development mode it works fine but when I switch it to production mode the images are not shown.

The app is using the assets_sync Gem and the images as well as other assets should be served from AWS using an S3 bucket. The css and js files are coming through correctly but not the images. This article explains quite well how it should work https://firmhouse.com/blog/complete-guide-to-serving-your-rails-assets-over-s3-with-asset_sync

As far as I can tell the css and images are precompiles; with the css generated from sass, and the images combined into one sprite. I found this article useful for explaining what was going on here http://compass-style.org/help/tutorials/spriting/ (probably nothing new for experienced rails developers)

If I dig a little deeper and view the css of the running app the background image url property is missing the bucket name from the url.

Here's an example; I'm certain the part //.s3 should be //mybucket.s3:

someclass {
    background: url(http://.s3.amazonaws.com/assets/myicon.png)
}

If I take the url and place directly in the browser address bar - no image!. But as soon as I add the bucket name the image is downloaded. That is, the following works, which confirms the images exist on the s3 bucket.

http://my-bucket.s3.amazonaws.com/assets/myicon.png

This implies the css isn't precompiled correctly and perhaps can't find the bucket name from the config.

I've checked that the heroku config is correct. With the following set:

  • FOG_PROVIDER,
  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • FOG_DIRECTORY
  • FOG_REGION

I've hit a wall with this spending a fair bit of time Googling the issue without result. So has anyone seen this issue before, or suggest ways of working out what could be going wrong?

1

1 Answers

2
votes

Okay, welcome to the Rails community!


Precompile

From using the asset_sync gem ourselves, the best advice I can give is to precompile locally before pushing to Heroku. Further, you have to do several things to get it working:

  1. You need to use the asset_path_helpers in your CSS
  2. You need to change the asset_path for your production environment, to reflect the S3 implementation

Here's what you need to do:

--

Preprocess

#app/assets/stylesheets/application.css.scss #-> notice the SCSS
someclass {
    background: asset_url("myicon.png")
}

You need to use one of the css preprocessors in Rails (basically SCSS), to give you the ability to use the dynamic asset path helpers. This is the first step, as it will then reference your assets correctly.

--

Asset Host

Secondly, you then need to change the asset_host in your /config/environments/production.rb file:

#config/environments/production.rb
config.action_controller.asset_host = "//#{ENV['FOG_DIRECTORY']}.s3.amazonaws.com"

This will allow Rails to prepend the correct URL to your asset paths when you're creating them, thus allowing you to serve them from S3

--

Finally, you should always precompile locally when using asset_sync. I forgot the reason why, but it's essentially to get all the files in the correct order etc:

$ rake assets:precompile RAILS_ENV=production

This allows asset_sync to upload the files it requires to run correctly. Or at least it should :)