Capistrano 3 does not restart after deploy - ruby

I've recently updated my capistrano gem to version 3.1.0, and since then cap production deploy passes fine, but the target deploy:restart is not called.
My server is deployed on Ubuntu 12.10 on Amazon EC2.
Why could that be?

Capistrano 3 no longer runs that task by default as many app servers don't require it. Add this to your config/deploy.rb:
after 'deploy:publishing', 'deploy:restart'
From the release notes:
Breaking changes:
deploy:restart task is no longer run by default.
From this version, developers who restart the app on each deploy need to declare it in their deploy flow (eg after
'deploy:publishing', 'deploy:restart').
Please, check 4e6523e for more information. (#kirs)

If you are using namespaces, you can also do the following:
namespace :deploy do
desc "My description"
task :my_task do
#do something
end
after :publishing, :my_task
end

In my case, in file 'production.rb' I had this roles: %w{web, app, db} which prevent block on roles(:app), in: :sequence, wait: 5 do in file "deploy.rb" from correct execution.You see, it needs to be roles: %w{web app db}

Related

Capistrano 3 change ssh_options inside task

I trying to run capistrano v.3 task in same stage with diferent ssh_options.
my production.rb say:
set :stage, :production
set :user, 'deploy'
set :ssh_options, { user: 'deploy' }
With this configuration capistrano connect with user deploy which is correct for the rest of taks. But I need connect it for one specific task with an_other_user wich is well configured in server.
Then my recipe say:
...
tasks with original user
...
task :my_task_with_an_other_user do
set :user, 'an_other_user'
set :ssh_options, { user: 'an_other_user' }
on roles(:all) do |host|
execute :mkdir, '-p', 'mydir'
end
end
...
other tasks with original user
...
When execute:
cap production namespace:my_task_with_an_other_user
capistrano make ssh conexion with original :user "deploy" (the user declared in production.rb).
How can I change the user and/or ssh_options it inside task?
Capistrano 3
I had hard time finding out a solution. But the solution is much nicer than version 2. Cap team has done a great job. Make sure you have updated Capistrano to 3.2.x+ Here's the trick:
# in config/deploy/production.rb, or config/deploy/staging.rb
# These roles are used for deployment that works with Cap hooks
role :app, %w{deploy#myserver.com}
role :web, %w{deploy#myserver.com}
role :db, %w{deploy#myserver.com}
# Use additional roles to run side job out side Capistrano hooks
# 'foo' is another ssh user for none-release purpose tasks (mostly root tasks).
# e.g. user 'deploy' does not have root permission, but 'foo' has root permission.
# 'no_release' flag is important to flag this user will skip some standard hooks
# (e.g. scm/git/svn checkout )
role :foo_role, %w{foo#myserver.com}, no_release: true
Make sure both 'deploy' & 'foo' user can ssh into the box. Within your tasks, use the on keyword:
task :restart do
on roles(:foo_role) do
sudo "service nginx restart"
end
end
task :other_standard_deployment_tasks do
on release_roles(:all) do
# ...
end
end
Other gotchas:
Make sure some Capistrano tasks skips the additional no release role you added. Otherwise, it might cause file permission issues during deployment. E.g. capistrano/bundler extension need to override the default bundler_roles
set :bundler_roles, %w(web app db) # excludes the no release role.
Read more about no_release flag: related Github issue.
Capistrano 2
I used to have a custom functions to close and reconnect ssh sessions.
Reference Paul Gross's Blog
Place the following methods in deploy.rb. Call with_user to switch ssh session. Slightly simplified version:
def with_user(new_user, &block)
old_user = user
set :user, new_user
close_sessions
yield
set :user, old_user
close_sessions
end
def close_sessions
sessions.values.each { |session| session.close }
sessions.clear
end
Usage:
task :update_nginx_config, :roles => :app do
with_user "root" do
sudo "nginx -s reload"
end
end
Answer of #activars didn't work for me. Because when I defined several roles for one environment - only one was deployed :(
So my solution was to create several enviroments, e.g. production.rb and productionroot.rb.
productionroot has content with no_release=true flag - just as you've specified:
server '146.120.89.81', user: 'root', roles: %w{foo_role}, no_release: true
After that I've created sh script which runs
#/usr/bin/env bash
bundle exec cap production deploy
bundle exec cap productionroot deploy

Mina deployment : invoke task once `current` symlink is updated

I'm using Mina (a simpler alternative to Capistrano) to deploy my ruby websites, and I am trying to run some tasks once the current symlink has been updated.
So far, here's what I have in my deploy.rb file:
desc "Deploys the current version to the server."
task :deploy => :environment do
deploy do
invoke :'git:clone'
invoke :'deploy:link_shared_paths'
invoke :'bundle:install'
to :launch do
invoke :restart
end
end
end
desc "Manually restart Thin web server"
task :restart do
in_directory "#{deploy_to}/current" do
queue! %[bundle exec thin restart -C "#{thin_yml}"]
end
end
My problem is that when Mina hits the to :launch block, the current symlink has not yet been updated, so either it does not exist (if it is the 1st deployment for this project) or it's still pointing to the n-1 release (and thus, the server uses an outdated version of the project).
So I'd like to be able to invoke my :restart task once the new release has been moved to the release directory and the current symlink has been updated.
I think it's a bug of Mina. in_directory seems to not work properly when used inside a to context. A quick and dirty workaround would be adding #commands[:default] = commands(#to) at the end of the in_directory block.
desc "Manually restart Thin web server"
task :restart do
in_directory "#{deploy_to}/current" do
queue! %[bundle exec thin restart -C "#{thin_yml}"]
#commands[:default] = commands(#to)
end
end

Some Capistrano deployment hooks not working

I am using Capistrano v2.14.2 and trying to use the before and after hooks for deploy:create_symlink, but none of them seem to firing...
I was getting this Warning:
[Deprecation Warning] This API has changed, please hook 'deploy:create_symlink' instead of 'deploy:symlink'.
So I updated my code to use deploy:create_symlink instead of deploy:symlink
Here is a snipplet of my deploy.rb
namespace :foo do
task :start do
puts "starting foo..."
end
task :stop do
puts "stoping foo..."
end
end
before('deploy:create_symlink', "foo:stop")
after('deploy:create_symlink', "foo:start")
Here is a snipplet of the output:
* 2013-04-04 13:34:27 executing `deploy:symlink'
* executing "rm -f /web/example.com/current && ln -s /web/example.com/releases/20130404203425 /web/example.com/current"
servers: ["app1"]
[app1] executing command
command finished in 467ms
No hooks are called...
Hooks for deploy:finalize_update and deploy:update_code all seem to be working without any issue.
What has happened to being able to use before and after hooks for deploy:create_symlink ?
I'm running into a similar issue, using the same version of Capistrano. I'm also using capistrano-multistage, and I'm curious if that is causing the issue some how (haven't tested a plain Capistrano setup yet).
Basically, if you hook into a before/after trigger on deploy:symlink, it tells you to use deploy:create_symlink, but deploy:symlink is what actually runs. If I trigger on either of those, it doesn't fire.
I ran across this article, which got me thinking that i should trigger on "after deploy" instead, since symlink is the last step in deploy for me:
http://blog.rememberlenny.com/2013/03/04/deploying-wordpress-with-capistrano-symlink-issue-fix/
Here is how I resolved my deployment:
Moved my "before deploy:symlink" trigger to "after deploy:finalize_update" (since that was the previous task and it actually triggers)
Moved my "after deploy:symlink" trigger to "after deploy"
change
"after deploy:symlink"
to
"after deploy"

vlad tasks: after update, before symlink

We're using vlad the deployer to deploy our rails app.
Currently, we have some tasks that run after the vlad:update task. These tasks take a few minutes. During those few minutes, the site is broken.
I'd like to run those tasks in the middle of vlad:update -- after it has done everything except create the "current" symlink. How do I do that? the vlad:update task appears to be monolothic.
Found the answer. Define your task to run before the update_symlinks task rather than after the update task.
remote_task :finish_deployment, :roles => :app do
...
end
remote_task :update_symlinks => :finish_deployment

Asset Precompile on the development machine before capistrano deployment

I want the asset precompile to happen on my dev machine beofore the code is packed (tar ball'ed) by capistrano and have the precompiled assets already included in the final deployment package.
When I try the inbuilt capistrano recipe thats in
load 'deploy/assets' it runs
rake RAILS_GROUPS=assets assets:precompile on the server.
The reason I am looking for this because at the moment the precompile is taking too long on my EC2 micro-instance (and also at times just hangs),
It would great if asset compile could be done even before the deploy starts so that I can save the server from this heavy duty work load - until at least I have better configured servers available.
The workflow is still a little bumpy at the moment, but you may find some success using Guard-Rails-Assets. It's a little slow, especially if you are making a lot of asset changes, but it will compile assets when they are changed and you can just check them in to your repo to be deployed later.
I've just written a gem to solve this problem inside Rails, called turbo-sprockets-rails3. It speeds up your assets:precompile by only recompiling changed files, and only compiling once to generate all assets. It works out of the box for Capistrano, since your assets directory is shared between releases.
It would be really awesome if you could help me test out the turbo-sprockets-rails3 gem, and let me know if you have any problems.
Remove load 'deploy/assets' from Capfile or config/deploy.rb, and add the following lines to the config/deploy.rb:
set :assets_role, [ :web, :app ]
set :normalize_asset_timestamps, false
set :assets_tar_path, "#{release_name}-assets.tar.gz"
before "deploy:update" do
run_locally "rake assets:precompile"
run_locally "cd public; tar czf #{Dir.tmpdir}/#{assets_tar_path} assets"
end
before "deploy:finalize_update", :roles => assets_role, :except => { :no_release => true } do
upload "#{Dir.tmpdir}/#{assets_tar_path}", "#{shared_path}/#{assets_tar_path}"
run "cd #{shared_path}; /bin/tar xzf #{assets_tar_path}"
run "/bin/ln -s #{shared_path}/assets #{release_path}/public"
run "/bin/rm #{shared_path}/#{assets_tar_path}"
end
If you use turbo-sprockets-rails3, add this to the last block:
run "cd #{release_path}; #{rake} assets:clean_expired 2> /dev/null"

Resources