I don’t have time to read and I want to jump immediately to the solution →.
The problem
From the day I started using DelayedJob in combination with God, I faced the problem to restart the god group every time I deployed a new application release.
In fact, when a rake task (God runs DelayedJob using the rake jobs:work task, here’s the config) is started, it loads the entire Rails environment and keeps it in memory as long as the process is running. When you deploy a new version, if you don’t restart the rake task, DelayedJob continues to run with the previous Rails version environment.
To restart a task/group in God:
$ god restart GROUP_NAME
Speaking about my servers, the problem is that God runs as root while Capistrano deploys new releases using a not-root not-sudo user, for security purposes. In practice, it means I can’t use the Capistrano sudo command because the deploy user is not in the sudoers list. Fortunately, the solution exists and is to run the command as su -c <command>.
The gotcha here is that when you use su you have to handle the remote server root password prompt. Thanks to Capistrano, this is as easy as pie.
Here’s the method I created to run the command.
The solution
# Runs +command+ as root invoking the command with su -c
# and handling the root password prompt.
#
# surun "/etc/init.d/apache reload"
# # Executes
# # su - -c '/etc/init.d/apache reload'
#
def surun(command)
password = fetch(:root_password, Capistrano::CLI.password_prompt("root password: "))
run("su - -c '#{command}'") do |channel, stream, output|
channel.send_data("#{password}n") if output
end
end
And here’s the final Capistrano/DelayedJob/Run code fragment.
namespace :god do
desc "Restart the god group 'GROUP_NAME'"
task :restart, :roles => :app do
surun "god restart GROUP_NAME"
end
end
after "deploy:restart", "delayed_job:restart"


Is there everything ok with surun? I got `surun’: undefined method `password_prompt’ for # (NoMethodError).
I`ve checked in the cli/ui.rb and Capistrano::CLI.password_prompt… without ‘ui’ works for me.
Unfortunately on Debian i get ‘su: must be run from a terminal’.
On my way to find the solution then.
You’re right kaczor1984, the method should be invoked on CLI.
I updated the example, thank you.
[...] release? I already discussed this problem in the past and the solution I adopted since today was to execute a command as root without using sudo. The problem with this solution, is that it requires you to type the root password each time you [...]
Minor edit to get working:
channel.send_data(“#{password}\n”) if output
This function outputs a command line something like below;
sh -c ‘su – -c ‘\\”#{command}’\\”’
But it doesn’t work properly. I need a command something like below;
sh -c ‘su – -c “#{command}”‘
Am I missing something…? Thanks in advance.
Hello Thank you for your useful information.
I needed add the following line
default_run_options[:pty] = true
def surun(command)
default_run_options[:pty] = true
password = fetch(:root_password, Capistrano::CLI.password_prompt(“root password: “))
run(“su – -c ‘#{command}’”) do |channel, stream, output|
channel.send_data(“#{password}\n”)
end
end