Rollbacks
In the majority of failed deployment situations, it probably makes more sense to revert the bad code and redeploy, rather than running deploy:rollback. Capistrano provides basic rollback support, but as each application and system handles rollbacks differently, it is up to the individual to test and validate that rollback behaves correctly for their use case. For example, capistrano-rails will run special tasks on rollback to fix the assets, but does nothing special with database migrations.
Correctly rolling back a release is a complex process that depends on the specifics of your application and the Capistrano plugins you’ve assembled. Be proactive and test your rollback procedure before trying it for the first time in a time of crisis.
When a deployment is run, Capistrano executes one task at a time on all servers and waits for that task to be done before moving on to the next one. If a task fails on a server, Capistrano exits without waiting for further tasks. In a multiple server situation, when a task fails on one server by exiting with a non-0 exit code, Capistrano closes the SSH connections to any still in-progress servers and their tasks exit.
If the error occurs during a deployment task which is prior to the final cutover, for example during creation of symlinks, the process will simply stop and the previously deployed application will continue to run. However if the failing deployment task is after deploy:symlink:release
, during which the current
symlink is moved to the newly deployed code, this may result in an inconsistent state which may be solved by executing cap [stage] deploy:rollback
. Rollback can also be a solution for issues with failed deployments due to buggy code or other reasons.
Per https://capistranorb.com/documentation/getting-started/flow/, the standard deployment and rollback processes are nearly identical. The difference is that in a deploy, the deploy:updating
and deploy:updated
tasks are executed, while in a rollback, the deploy:reverting
and deploy:reverted
(a hook task) tasks are run. Also, instead of deploy:finishing
, deploy:finishing_rollback
is run, as cleanup can sometimes be different.
deploy:reverting
This starts by setting the release_path to the last known good release path. It does this by obtaining a list of folders in the releases folder and if there are at least two, sets the second to last release as the release_path. It also sets the rollback_timestamp
to this same release which it uses for the log entry.
Once this has been set, the remaining standard deployment tasks flip the symlink accordingly.
deploy:finishing_rollback
To finish the rollback, Capistrano creates a tarball of the failed release in the deploy path, and then deletes the release folder.
deploy:failed
In a situation where cap [stage] deploy
fails, the deploy:failed
hook is invoked. You can add custom rollback tasks to this hook:
after 'deploy:failed', :send_for_help do
#
end
This is different from a specifically invoked rollback, and is application specific. For reasons stated above, it can be dangerous to use this hook without careful testing.
deploy:rollback ROLLBACK_RELEASE=release
Rollback to a specific release using the ROLLBACK_RELEASE
environment variable.
e.g. cap staging deploy:rollback ROLLBACK_RELEASE=20160614133327