Skip to content

Instantly share code, notes, and snippets.

@peterdietz
Last active September 7, 2015 02:26
Show Gist options
  • Save peterdietz/8981396 to your computer and use it in GitHub Desktop.
Save peterdietz/8981396 to your computer and use it in GitHub Desktop.
Capistrano3 + Rails4 + NGINX + Passenger. After cap deploy restarts the app, we want to warm it up with a ping, so end user never waits

Most instructions for using Capistrano tell you how to make it restart Phusion Passenger by 'touch'ing the restart.txt file, but this doesn't immediately restart the app - instead the first person to try to use the application will cause it to be restarted, so they will see a delay of at least a few seconds.

This shows how to add a post-deploy task to 'ping' the server, to cause it to restart immediately.

Then add a deploy:ping task to config/deploy.rb and set it to run automatically after deploy:restart. Alternatively you could put it into the deploy:restart task directly.

TODO: Test the response HTTP header of the ping, that it is a 200, and not some other error response (404/500).

# config/deploy.rb
set :application, 'sampleapp'
#What is an accessible route to hit on the site?
#Note: I have nginx+passenger listening to :8080, our environment has a different web server entrypoint
#Also, our apps get deployed to a sub-uri, with the application_name as its URI
set :ping_url, "http://localhost:8080/#{fetch(:application)}"
# This is the standard Phusion Passenger restart code. You will probably already
# have something like this (if you have already got Capistrano set up).
namespace :deploy do
desc 'Restart application'
task :restart do
on roles(:app), in: :sequence, wait: 5 do
# Your restart mechanism here, for example:
execute "mkdir -p #{release_path.join('tmp')}"
execute :touch, release_path.join('tmp/restart.txt')
end
end
after :publishing, :restart
desc 'Warm up the application by pinging it, so enduser wont have to wait'
task :ping do
on roles(:app), in: :sequence, wait: 5 do
execute "curl -s -D - #{fetch(:ping_url)} -o /dev/null"
end
end
after :restart, :ping
after :restart, :clear_cache do
on roles(:web), in: :groups, limit: 3, wait: 10 do
# Here we can do anything such as:
# within release_path do
# execute :rake, 'cache:clear'
# end
end
end
end
# config/routes.rb
SampleApp::Application.routes.draw do
root to: 'application#index'
end
@peterdietz
Copy link
Author

Changes here from @davejamesmiller's version is that I DO NOT use a special /ping url, I want to test ACTUAL work being done, i.e. my homepage will probably crash if the DB isn't connecting, Elasticsearch doesn't connect, other needed configs...

Further fixes I'd like to do is to test the response of the curl. So, that if I get a 404, or a 500, then I kind of want my capistrano deploy to alert me with a failure? Otherwise, deploys typically work just fine, so I'm happy for now with the app being warmed up, hot&ready, like pizza to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment