Thursday, July 9, 2015

Deploying a Rails 4 application on Heroku.com with the assets on Amazon S3

I had a task to deploy a Rails 4 application to heroku.com and make it serve the assets from Amazon S3. After a couple of days trying to do that through trial and error I eventually made it work. Here's how to do that:

1) Precompile the assets locally

rake asset:precompile

What this command does is:

a) Combines them into the single css and js files
b) Copies them to public/assets
c) Creates public/assets/manifest-.json


2) Upload them to S3 manually. I suggest avoid using gems when possible. The less gem and dependencies you use, the better it is. This is because using gems makes our job even more difficult: not only do they require us to learn their interfaces, they may have errors in them.

For example, the latest version of the most popular gem asset_sync for synchronizing assets was in the state "tests failed" when I was working on the task.

And in general, in order to better understand what's going on under the hood, you have to avoid using high-level stuff.

To upload assets to S3 you can use an utility called s3cmd. I think that's the only way to do it and there's no way to do it via a browser.


cd public

s3cmd . s3://your-bucket-name

where the "." denotes your current directory being public.



3) Make the assets accessible via Internet by making them public. Select them in your AWS S3 dashboard by Ctrl+A and chose make public from the menu.

4) Add your assets, both local and precompiled, to .gitignore to avoid uploading them to heroku.

app/assets

public

5) Exclude the manifest json file(s) from .gitignore. First find them, there can be multiple ones:


find public -iname "manifest*.json"

Then add them to .gitignore preceding their names with the exclamation mark

!public/assets/manifest-8cfe8c0119b8c59c61f3d96900d19963.json

And back to git

git add public/assets/manifest-8cfe8c0119b8c59c61f3d96900d19963.json -f

That's necessary because we have to make heroku understand that we've precompiled the assets ourselves. Otherwise it compiles the assets again and generates a new manifest file which will be used instead our original one.

6) Add this to production.rb. Some of these options are opaque for me. Nonetheless they did work well:



 config.assets.digest = true

 config.assets.enabled = true

 config.assets.compile = false

 config.assets.compress = true

 config.serve_static_assets = false

 config.action_controller.asset_host = "https://s3.amazonaws.com/your-bucket"



Your "s3." might be different.

7) Deploy to heroku:


git push heroku master

  
You'll notice that heroku detects your manifest.json from the folder "public" and thus doesn't compile the assets itself.

 
That's all.

No comments :

Post a Comment