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 Capistrano 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):
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
cdn01.mydomain.com
etc.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.