Loading 'deploy/assets' in Capistrano, automatically precompiles:assets
Something that I’ve just figured out after tinkering for a couple of hours.
Hope this will save someone else some trouble.
So I’m running my own custom Capistrano script that on fresh deploy setup a symlink of database.yml on the app instance, so that you don’t need to check in your database.yml file.
So in my config/deploy.rb, I have something like:
after 'deploy:update_code', 'deploy:symlink_db', 'deploy:assets:precompile'
.
.
.
.
desc "Symlinks the database.yml"
task :symlink_db, :roles => :app do
run "ln -nfs #{deploy_to}/shared/config/database.yml #{release_path}/config/database.yml"
end
What happened is that during the first deployment, for some reason, ‘deploy:assets:precompile’ always run after the callback at ‘deploy:update_code’ is run and before ‘deploy:symlink_db’. This causes the entire deployment to fail because, there is no config/database.yml anywhere. (Remember, I haven’t checked it in and put it on ignore).
Reading the documentations, callbacks should be run in precedence and because deploy:symlink_db is placed before deploy:assets:precompile, it should have ran first.
But it didn’t.
Hmm.
Then, I decided to remove ‘deploy:assets:precompile’ and deploy.
It should skip right?
Nope.
Now what?
The next logical step is to comment the entire ‘deploy:assets:precompile’ section out. And deploy again.
It should work. Right, right?
Nope.
So I did some reading up.
Turns out, when you load ‘deploy/assets’, the recipe automatically adds in the precompile at the correct part of your deployment. Bleah!
Solution: uncomment load ‘deploy/assets’ and things miraculously works once again.
So, moral of the story, if you want to make sure assets:precompile don’t get run unless you explicitly tell it to, don’t load deploy/assets.
Word.
Update: So apparently there’s another way to do this, which is definitely much simpler.
Because the failure was happening at the default assets precompile stage where there isn’t a database.yml linked yet, setting a before_callback would solve the problem:
before "deploy:assets:precompile", "deploy:symlink_db"