Working Capistrano recipe for uploading precompiled Rails 3.1 assets to Amazon S3
We have a Rails 3.1 app that allows users to upload photos to Amazon S3. Since we're using S3 in production I'd like to automatically (on cap deploy
) also upload the precompiled assets (application.js & application.css & images) to our S3 bucket where they'll be served. Simple enough.
Beyond setting config.action_controller.asset_host = "http://assets.example.com"
In short, I'm looking for some examples of a working "recipe" for Cap开发者_运维知识库istrano to do so but can't seem to find any modern (3.1 asset pipeline compatible) ones. We are successfully precompiling the assets but how to move them to S3? And, ideally, only the ones that have changed?
"Meat" of current "recipe":
...
after "deploy:update_code", "deploy:pipeline_precompile"
before "deploy:finalize_update", "deploy:copy_database_config"
namespace :deploy do
task :start do ; end
task :stop do ; end
task :restart, :roles => :app, :except => { :no_release => true } do
run "#{try_sudo} touch #{File.join(current_path,'tmp','restart.txt')}"
end
# copy database.yml into project
task :copy_database_config do
production_db_config = "/path_to_config/#{application}.yml"
run "cp #{production_db_config} #{current_release}/config/database.yml"
`puts "replaced database.yml with live copy"`
end
task :pipeline_precompile do
run "cd #{release_path}; RAILS_ENV=production bundle exec rake assets:precompile"
end
end
While this doesn't directly answer the question of uploading your assets to S3 on deploy, I think the following approach may address your goals and be a little simpler to implement.
The primary benefits of hosting assets on S3 and using the config.action_controller.asset_host
directive include (among others):
- allowing additional simultaneous downloads of assets
- serving assets from a cookie-free domain
Rather than using s3, you can use the CloudFront CDN to achieve the same benefits. The new rails asset pipeline plays very nicely with CloudFront. Here are the steps I am currently using in production:
Create a new CloudFront distribution
- Delivery Method should be Download
- Choose Custom Origin and point it to your web server
- For Distribution Details you can add addition CNAME records such as
cdn01.mydomain.com
etc. - Default Root Object can be left empty
If your site is served over SSL, you will need to use the x12whx1751nfir.cloudfront.net
style hostname as custom certificates are not available yet as they are with ELB and your users will see certificate hostname mismatch errors. If you don't use SSL, you can use the either the default hostname or any CNAMEs prodvided.
Once this is setup, the initial object requests will be fetched from your server and placed within CloudFront. The digest fingerprints generated by the asset pipeline will handle your requirement for only sending assets which have changed.
Update capistrano and include the following in your deploy file
load 'deploy/assets'
Check out the asset_sync gem if you want to use S3. I am trying to get mine to work with Rackspace Cloud Files, but having a few problems.
You can use jammit-s3 gem. I configured and using it. It's perfect and has very simple configuration.
精彩评论