Compile Assets With Capistrano
Hi there!
I have a project with lots of compiled assets: sprites, stylesheets and javascripts. This causes big pain in our deployment process due to overall instability in nodejs world. I actually cannot figure out why my asset-builder just fails without any reason on production server.
By the way, compiling assets on server-side is quite a bad idea just because developer has less control on production server than on his own machine. That’s why I think it’s better to compile the assets on developer side.
The process
Let’s start from explaining how assets are compiled here in my project:
# Install npm dependencies
npm install
# Install bower dependencies. Have no idea why we need both of them. It's our frontend guy choice.
node_modules/.bin/bower install
# Actualy compilation
node_modules/.bin/broccoli build tmp
And then we need to copy compiled assets under web folder.
Capistrano tasks
Ok, let’s create a bit of capistano tasks:
namespace :assets do
set :tmp_dir, '.capistrano/assets'
set :npm, 'npm'
set :bower, 'node_modules/.bin/bower'
set :broccoli, 'node_modules/.bin/broccoli'
#desc Build assets locally
task :build_local do
run_locally do
invoke "assets:cleanup"
execute fetch(:npm), 'install'
execute fetch(:bower), 'install'
execute fetch(:broccoli), 'build', fetch(:tmp_dir)
end
end
#desc Copy all the assets to our :web servers
task :copy do
on roles(:web) do
Dir["#{fetch(:tmp_dir)}/webpub/*"].each do |f|
upload! f, "#{release_path}/webpub/", recursive: true
end
end
end
#desc Clean up all the stuff left from compilation
task :cleanup do
run_locally do
execute 'rm', '-rf', fetch(:tmp_dir)
end
end
end
Capistrano workflow
And now we need to inject these tasks into deployment process:
before "deploy:starting", "assets:build_local"
before "deploy:publishing", "assets:copy"
before "deploy:finished", "assets:cleanup"
Actually, that’s all we need to do.