Thursday, July 9, 2015

Deploying a Rails 4 application on with the assets on Amazon S3

I had a task to deploy a Rails 4 application to 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.



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


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 = ""

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