I'm doing a Capistrano deployment of a Rails app. It's been a lot of fun for the most part.
After the deployment is complete (in deploy:restart
), I would like to start the Rails server, watch the output for a while, and then hit Ctrl-C
to send an interrupt, thereby stopping the output, and proceeding the deploy:cleanup
task. At one point it seemed like this was working, except that it appeared to be considering the interrupt to be an exception and so was saying it "Cannot Start the Rails Server" even though it was actually started and running. I wanted to rescue the interrupt, and so wrote the following, based in part on another thread here:
namespace :deploy do
task :restart, :roles => :app, :except => { :no_release => true } do
begin
logger.info 'Attempting to Start the Rails Server'
run "cd #{release_path} && script/rails s"
rescue SystemExit, Interrupt
logger.info %q[Au revoir! And don't worry. The server will continue running just fine without you hanging around looking over it's shoulder.]
rescue Exception => error
logger.important 'Cannot Start the Rails Server. This may be a problem.'
logger.info "#{error}"
end
end
end
However, this doesn't work. Before I hit Ctrl-C, while the server is still running, as I would expect, I'm getting this sort of thing:
** [out :: server.example.com] Started GET "/assets/bootstrap.js?body=1" for 178.120.25.53 at 2012-07-09 19:10:53 +0000
** [out :: server.example.com] Served asset /bootstrap.js - 200 OK (11ms)
And then after I send the interrupt, I'm getting this:
** Au revoir! And don't worry. The server will continue running just fine without you hanging around looking over it's shoulder.
triggering after callbacks for `deploy:restart'
* executing `deploy:cleanup'
* executing "ls -xt /srv/www/my_project/releases"
servers: ["server.example.com"]
[server.example.com] executing command
command finished in 774ms
** keeping 1 of 2 deployed releases
* executing "rm -rf /srv/www/my_project/releases/20120709190209"
servers: ["server.example.com"]
[server.example.com] executing command
command finished in 811ms
Which looks right...but as it turns out, Rails is not, in fact, still running, as a grep of the processes before and after reveals.
Before Ctrl-C
, I see both the Capistrano command (19358), and the Rails server it started (19507):
user@server.example.com:~$ ps ax | grep rails | grep -v grep
19358 pts/1 Ss+ 0:01 bash -c cd /srv/www/my_project/releases/20120709190521 && script/rails s
19507 pts/1 Sl+ 0:41 ruby script/rails s
After Ctrl-C
, the Rails server is still there, or it appears to be:
user@server.example.com:~$ ps ax | grep rails | grep -v grep
19507 ? Sl 0:41 ruby script/rails s
But after I attempt to hit the site in a web browser, it disappears! Weird eh?
user@server.example.com:~$ ps ax | grep rails | grep -v grep
user@server.example.com:~$ [no output; returned to prompt]
So, my question is: How do I do this thing? How do sever the communication between the running Rails process and Capistrano, allow Capistrano to move on to it's remaining tasks, and then give me back my terminal prompt, without stopping the Rails server? Any help would be appreciated.