This guide will walk through rolling back a Java application deployed to a Tomcat web server. We will be using the PetClinic Spring Boot example. The PetClinic application consists of two components:
- Database
- Website
Rolling back the database is out of scope for this guide. This article describes reasons and scenarios in which rolling back a database could result in data loss or incorrect data. This guide assumes that there are no database changes or the changes are backward compatible.
Parallel deployments in Apache Tomcat
In Tomcat v7, Apache included the ability to do parallel deployments which allows you to deploy multiple versions of the same application to a Tomcat server. If a version number is provided during deployment, Tomcat will combine it with the context path to rename the .war
to <contextpath>##<version>.war
. Once the new version is in a running state, Tomcat will redirect new sessions to the new version of the application. Existing sessions will continue against the old version until they expire. This functionality is ideally suited for supporting rollback scenarios when deploying to Tomcat.
The rollback strategy described in this guide will not work if the undeployOldVersions feature is enabled on Tomcat.
Existing deployment process
For this guide, we’ll start with an existing deployment process for deploying the PetClinic application:
- Create Database If Not Exists
- Deploy Database Changes
- Deploy PetClinic Web App
- Verify Deployment
- Notify Stakeholders
View the deployment process on our samples instance. Please login as a guest.
Zero-configuration rollback
The easiest way to rollback to a previous version is to:
- Find the release you want to roll back.
- Click the REDEPLOY button next to the environment you want to roll back.
That redeployment will work because a snapshot is taken when you create a release. The snapshot includes:
- Deployment Process
- Project Variables
- Referenced Variables Sets
- Package Versions
Re-deploying the previous release will re-run the deployment process as it existed when that release was created. By default, the deploy package steps (such as deploy to IIS or deploy a Windows Service) will extract to a new folder each time a deployment is run, perform the configuration transforms, and run any scripts embedded in the package.
Zero Configuration Rollbacks should work for most our customers. However, your deployment process might need a bit more fine tuning. The rest of this guide is focused on disabling specific steps during a rollback process.
Simple rollback process
While doing a rollback can be an operational exercise, the most typical reason for a rollback is something is wrong with the release, and you need to back out the changes. A bad release should also be prevented from moving forward.
The updated deployment process for a simple rollback would look like this:
- Calculate Deployment Mode
- Create Database If Not Exists (skip during rollback)
- Deploy Database Changes (skip during rollback)
- Deploy PetClinic Web App
- Verify Deployment
- Notify Stakeholders
- Block Release Progression
View the deployment process on our samples instance. Please login as a guest.
Calculate deployment mode
Calculate Deployment Mode is a community step template created by Octopus Deploy. It compares the release number being deployed with the current release number for the environment. When the release number is greater than the current release number, it is a deployment. When it is less, then it is a rollback. The step templates sets a number of output variables, including ones you can use in variable run conditions.
Skipping database steps
The two database steps, Create Database If Not Exists
and Deploy Database Changes
should be skipped for a rollback scenario. Rolling back database changes could result in data loss or interrupt testing operations. To skip these steps, we’ll use one of the Variable Run Condition output variables from Calculate Deployment Mode step:
#{Octopus.Action[Calculate Deployment Mode].Output.RunOnDeploy}
When looking at the deployment process from the Process tab, there isn’t a quick way to determine under which conditions a step will be executed. Using the Notes
field for a step is an easy way to provide users information at a glance.
Block release progression
Blocking Release Progression is an optional step to add to your rollback process. The Block Release Progression step template uses the API to prevent the rolled back release from progressing.
This step includes the following parameters:
- Octopus Url: #{Octopus.Web.BaseUrl} (default value)
- Octopus API Key: API Key with permissions to block releases
- Release Id to Block: #{Octopus.Release.CurrentForEnvironment.Id} (default value)
- Reason: This can be pulled from a manual intervention step or set to
Rolling back to #{Octopus.Release.Number}
This step will only run on a rollback; set the run condition for this step to:
#{Octopus.Action[Calculate Deployment Mode].Output.RunOnRollback}
To unblock that release, go to the release page and click the UNBLOCK button.
Complex rollback process
In the simple rollback scenario, the .war
file is redeployed, extracted, variable replacement is executed, the .war
is repackaged before finally being sent to the Tomcat server webapps location. In cases where the .war
is very large, the extraction and repackaging of the .war
could take quite some time, making the rollback process lengthy. This is where the parallel deployments feature of Tomcat can benefit us as all the processes have already occurred during the initial deployment of that release.
The new deployment process would look like this:
- Calculate Deployment Mode
- Rollback reason (only during rollback)
- Create Database If Not Exists (skip during rollback)
- Deploy Database Changes (only during deploy or redeploy)
- Stop App in Tomcat (only when the previous release exists)
- Deploy PetClinic Web App
- Start App in Tomcat (only during rollback)
- Verify the deployment
- Notify Stakeholders
- Block Release Progression (only during rollback)
View the deployment process on our samples instance. Please login as a guest.
Next, we’ll go through the newly added and altered steps:
Rollback reason
The Rollback Reason is a Manual Intervention step that prompts the user for the reason they are rolling back. The text entered is stored in an output variable which will be used in the Block Release Progression step further down the process.
Stop app in Tomcat
Before we deploy a new version of our application, we first must stop the existing one. The Advanced Options section of the Start/Stop App in Tomcat
step is where we specify which version of the application we’re going to stop. For this guide, the version is identified as the previous release number, which is represented by the following variable.
#{Octopus.Release.CurrentForEnvironment.Number}
We also need to choose the option to Stop the application.
This step will fail if there isn’t a previous release to stop, so we’ll need to add a run condition only to run when a previous release exists. That can be represented by using the following run condition:
#{if Octopus.Release.CurrentForEnvironment.Number}True#{/if}
Deploy PetClinic Web App
To configure our deployment to work with the parallel deployment feature, we need to set the deployment version of our application. This is done in the Advanced Options section of the **Deploy to Tomcat Via Manager*8 step. In the following screenshot, you will see the Octopus variable of #{Octopus.Release.Number}
being used for the version number.
The radio button at the bottom gives you the option to have this deployment be in a Running
state or a Stopped
state; the default is Running
.
For this guide, we only want the Deploy step to occur on a Deployment or a Redeployment. The Calculate Deployment Mode step provides us with an output variable called RunOnDeployOrRedeploy
that contains the correct statement for a variable run condition for this step. Add the following as the value for the Variable Run Condition on this step.
#{Octopus.Action[Calculate Deployment Mode].Output.RunOnDeployOrRedeploy}
Start app in Tomcat
When executing the rollback, we’ll need to start the previous version.
This step is only required during a rollback scenario, so you’ll need to add the following to the Variable Run Condition.
#{Octopus.Action[Calculate Deployment Mode].Output.RunOnRollback}
Block release progression
The Rollback Reason
step captures the reason for the rollback. We can pass the text entered in this step to the Reason
field of this step by using the following output variable.
#{Octopus.Action[Rollback reason].Output.Manual.Notes}
The retention policy of Octopus Deploy will clean up any old versions of the applications in folders controlled by Octopus. However, the <contextpath>##<version>.war
files are not controlled by Octopus and will not be cleaned up with a retention policy. To assist in Tomcat maintenance, the Octopus team developed the Undeploy Tomcat Application via Manager step template. This template will remove the application using the specified context path and optional version number.
Choosing a rollback strategy
It is our recommendation that you start with the simple rollback strategy, moving to the complex if you determine that the simple method doesn’t suit your needs.
Help us continuously improve
Please let us know if you have any feedback about this page.
Page updated on Wednesday, October 4, 2023