Rails - How to host static assets on S3 with Heroku - ruby-on-rails

I have a rails 5 app I'm about to deploy.
the image folder is over 300 Mb (over the limit of heroku's deploy size) So I've uploaded all the images to S3 however, Heroku is still precompiling and the build is failing because of the slug size.
Can anyone point me to articles or help me solve the following problems?
Precompile Assets and send them to S3
Use CloudFront with my S3 Bucket (Do I need cloud front?)
How to Understand bucket policies and how they relate to cloud front / hosting.
Actually bypass the 300Mb limit of slug size on heroku and get this app deployed
much appreciated!

Heroku aready had a document about this. Please check it out here.
You should delete assets files was already in your repo
Ignore them from git and push to Heroku
Follow above article and check whether it works or not

Related

Images in public folder not found after each push on heroku

I am having issues with my Rails App on Heroku.
After every push to heroku any images I uploaded with paperclip Gem return a 404 error message.
How I resolve this?
You cannot use the local file system on Heroku to store uploaded files, because you get a new instance each time you deploy. I advise to read about Ephemeral filesystem on Heroku.
To fix your problem you show store uploaded files on an external service like Amazon S3. You might want to follow Heroku's documentation about uploading to S3

Deploying a Rails app at heroku with its assets being located at Amazon S3

I'm trying to make a Rails app server its assets at S3. I'm not using any gems because want to do it manually to better understand the process. My questions regarding serving the static assets are:
Which assets should I upload to my S3 bucket: from my_app/assets or from my_app/public/assets?
If the second option, it means I have to precompile them first, right? And then upload the whole folder my_app/public (or my_app/public/assets?) ?
Since right now I'm deploying the website at heroku and the max size of the repo at heroku is 300Mb and the size of my assets is much bigger, how and should I at all make the app somehow "understand" that its assets are located at S3 so that when I say "git push heroku master" it won't upload all them from its my_app/assets or my_app/public/ folder?
You will need to change the config.action_controller.asset_host option on the Rails Configuration. Take a look at http://guides.rubyonrails.org/configuring.html#rails-general-configuration
You will indeed need to precompile the assets and sync them to S3. Remember to use RAILS_ENV=production. A good place to look at and then replicate manually would be in the asset_sync gem.

How to Host Rails Assets Through a CDN without pushing assets to Heroku

So I currently have too many assets to push to my free heroku account. I am currently hosting them on a hostgator server which is problematic as, by making a remote request for each image, and the server itself not being of the nature of say Amazon CloudFront which expedites and caches things explicitly for CDN, it visibly loads all the images all slow-like in the DOM. My question is, how can I serve my assets through CloudFront without pushing them to my heroku account?
The best solution is to create a custom deployment script that has a step specifically for uploading your assets to S3, then serve the assets from S3 via CloudFront.(have a look at https://github.com/rumblelabs/asset_sync for ideas)
Specifically:
Add your assets to your .gitignore
Set your asset host correctly in your production.rb file
Step 1 in deploying is copy changed assets to your S3 bucket in the same folder structure that rails expects
Step 2 in deploying is your push to repo with the standard command git push heroku master -- which will not push your assets if they are ignored correctly.

How to remove old rails assets on heroku?

My rails app is working but its slug size is huge (220mb).
I am storing all assets on cloudfront with config.assets.digest = true and config.action_controller.asset_host = "something.cloudfront.net"
heroku run bash
In the slug, there is 30 times application-onedigest.js in public/assets, and same thing for stylesheets and images, so now the slug size is 220 mb.
Maybe one of my gem is doing middleware things (Rails asset_host, cloudfront and heroku) or maybe heroku is trying to optimize things (https://devcenter.heroku.com/changelog-items/328), but i don't think so. I don't want to exceed the maximum heroku slug size that is 300 mb, and i feel that is not normal.
How to remove old rails assets on heroku ?
EDIT
I made little commits in a css file, push to heroku, and compared slug. In the deploy process, there is those lines:
Running: rake assets:precompile
INFO -- : Writing /tmp/build_ff4eb6d7-303e-444d-9c88-938ab504ea8a/public/assets/application-700c7e1849c55312a94a353e60312500.css
Asset precompilation completed (9.60s)
Cleaning assets
Running: rake assets:clean
INFO -- : Removed application-48375ba5495e14b36afab9d4b9d97033.css
This is what i want. But when i compare the old and the new slug, there is the new application-700....css, and an another new mysterious application-a9b33ae58934ad161038cb3ebcee146c.css
And this one is actually used is the heroku webapp (when i explore css resources from the browser, after clearing cache).
So i guess precompile is done twice somewhere?
Temporary solution : heroku fork the app, i am back to 40 mb but there is still the problem.
EDIT
It seems it works when i precompile locally, but i don't like it as it violates 12factors.
Some things you'll want to consider:
rake assets:clobber
Heroku's file system
CDN
rake assets:clobber is an inbuilt way to remove old asset files from your public/assets directory. By running this command, either locally or on Heroku, you'll be able to actively remove the precompiled asset files on your system, allowing you to repopulate the folder with new files
Secondly, you have to remember Heroku runs an ephemeral file system. This means that each time you push your application to Heroku, it will just overwrite any of the files you had before, meaning (importantly), that it's not going to store your last assets. Each time you push, it will precompile the assets for you - which should ensure minimal space taken up with them.
--
Finally, if you find that your assets are taking up too much space on your application server, you may consider using a content delivery network (CDN) to serve the assets you need. You can use the asset_sync gem to push your assets to your CDN of choice
Most people tend to use a CDN with storage system to serve their assets. We use S3 with Cloudfront currently, but are looking to move to Rackspace's file serve system!
You can use the Heroku repo plugin (https://github.com/heroku/heroku-repo) and the repo:purge command to clean all the build assets out of your slug.
Using asset_sync gem is not ideal as you can run into deploy timeouts pushing all the assets over to S3 plus you end up with assets in two places. Remember S3 is not a content delivery network, you're better off using a CloudFront distribution and have it cache the assets directly from your application. See https://devcenter.heroku.com/articles/using-amazon-cloudfront-cdn for more details.
This solve it for me, in production.rb :
config.assets.compile = false
Heroku is no longer generating useless assets. I don't know how to remove the old assets in the same heroku app, but i used "heroku fork" to create a brand new heroku app with the same config / database and without old assets.
heroku run rake assets:clobber

Is there a way to asset pipeline assets to s3 when pushing to heroku?

Is there an easy way to you this with the asset pipeline and deploying to heroku / s3?
I would like my local rails app to use image/css/js locally as per normal.
And when you pre-compile, is there an easy way for the production app to serve it's assets from s3 (while dev assets are local). And also when you pre-compile / deploy to heroku, the newly compiled assets are sent up to s3 automatically?
This is so the developer (me :D ) does not have to keep manually updating s3 with the new deployed files?
Thanks.
I believe this is what you're looking for:
http://ckdake.com/content/2011/rails-31-assets-on-s3-with-https.html
Make sure you use up-to-date gems, as this guide is for rails 3.1 (in case you use 3.2+)
Heroku has good docs on this now, here:
https://devcenter.heroku.com/articles/cdn-asset-host-rails31
Which recommends this gem:
https://github.com/rumblelabs/asset_sync

Resources