This one is a mouthful! Basically I'm trying to send all of my Rails 3 assets up to the S3 Cloud and use CloudFront as the CDN to deliver it all. I already learned about configuring Rails to pull from an asset server in production mode. The problem I'm running into is finding a good way to automatically package and send everything to the cloud from a rake command or rails gem. The other problem I have is I don't know if using Less CSS with the More gem is going to screw this up. More generates a CSS file from another directory and places it in public/stylesheets. Any ideas or suggestions are much appreciated! Thanks :)
If you are pushing to Heroku and are using the Rails 3.1 assets you are all set.
In the CloudFront configuration on amazon create your distribution and set the origin to your applications URL.
Then in your production.rb file add:
config.action_controller.asset_host = "xxxxxxxxx.cloudfront.net"
The host is the host of your CloudFront distribution.
Then when you deploy make sure you are on the Cedar stack and that assets are being compiled. This will add a unique MD5 into the filenames. When a request is made to your CDN (handled automatically by the setting in your production.rb file), then the CDN will either serve up it's version of the file or pull it from the origin first. This means you don't have to push files up to the CDN, they are pulled in automatically.
If you have a file that doesn't have a unique name for some reason, then you will need to look at how to invalidate the cache in CloudFront, but other than that it's pretty easy.
Related
I've started learning rails and I've already built two apps, one simple blog app and one store app. Now I ran into a term precompile assets when uploading to heroku, can someone explain it to me is that necessary when deploying an app to production, because i've uploaded my store app to heroku without any problems?
Assets is your css + JS. Precompile assets mean that they get joined into single .css and another single .js. file (to load it in one HTTP request). And special mechanism of minifying get applied to both these files (to make them smaller). Rails by default is setup in a way, that it uses average files in dev and compiled files in prod. You can easily change this in configs, but you shouldn't do this unless you really know what you do.
If you want you can compile this files locally running rake assets:precompile and then put it into git. I think that you can disable/enable precompile during heroku deploy in heroku config. But, in general, I would stick with the very defaults.
More info on asset pipeline: http://guides.rubyonrails.org/asset_pipeline.html
Rails has an assets pipeline which consists of Sprockets and the assets helpers.
The assets pipeline will concat and minify your CSS and javascript and takes care of setting the correct paths to images and other assets. This is known as compiling the assets.
In development this is done on the fly for each request which lets you immediately see changes.
In production this would be far to slow so instead the assets should be compiled once at deploy time. Heroku does this automatically for you in a post-commit hook.
Pre-compiling is when you run rake assets:precompile locally and then upload or push the result to a server. This is done if you are deploying to a server without the support for the assets pipeline. For example if the production server does not have a javascript runtime which is required to run uglifier.
It adds tons of noise to the git change history and manually doing anything is a common source of user error. So pretty much it sucks and you only do it if you have to.
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.
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.
I have a Rails app running on a shared web host under a folder in my root direction called 'mintrus-ror/'. There is a symbolic link 'public_html/' that points to 'mintrus-ror/public/'. My Rails app loads in the browser but the stylesheets don't load. Looking at the rendered source I noticed the assets path it is using is '/mintrus-ror/assets/application.css'. I am trying to figure out how to change it so it does not include the 'mintrus-ror/' directory in the assets path. Any ideas?
You can try playing with the config.assets.manifest configuration option in config/environments/production.rb. There are other variables that influence this, one being the web server configuration. I've got no recent (less than six years ago) experience with shared hosts, but I've read that on some systems, you can edit the .htaccess file.
I also presume that you're running in production mode and have previously compiled the assets with rake assets:precompile during your deployment step. Capistrano does this automatically when the asset pipeline integration is turned on.
The Rails Guide on the Asset Pipeline may be useful.
Your best bet may be to host on Heroku. It's free for small sites and a lot less hassle.
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