Deploying multiple projects to a single Azure Webapp


I’m currently evaluating Octopus Deploy and have a few questions the best way to get one of our apps deployed.

We have a web-based admin dashboard for our backend APIs which is a collection of around 40 independent single-page webapps (HTML/JS, all static content). Each one is independently versioned and deployed to its own subdirectory of the site (i.e. /ProductManager, /UserManager, /CatalogManager, etc).

We have 5 environments for our backend APIs (dev, integration, rc, sandbox, and prod). Each environment has its own matching instance of the admin dashboards.

The hosting environment is an Azure webapp. Each instance of the dashboard is hosted on its own Azure webapp. – i.e.,,, etc. (The prod instance is also deployed to two different webapps in different Azure regions so it is highly available)

The current deploy process consists of some rake (ruby) scripts invoked from TeamCity. When a single dashboard (for example, UserManager) is deployed, the scripts:

  1. Use msdeploy.exe to sync the contents of the production slot to the staging slot.
  2. Run config transforms (setting API endpoints, etc)
  3. Deploy the package to the app’s subdirectory (i.e. to /UserManager/) on the staging slot.
  4. Swap the staging and production slots.

All of the apps are versioned and deployed independently. For example, the UserManager dashboard might be on v1.0 in Prod and v1.1 in Dev, while the developer maintaining the CatalogManager dashboard may have published CatalogManager v1.5 to all environments already.

The swap process is in place to prevent an end user from opening the webpage mid-deploy and getting a mix of old code and new. We sync the slots at the beginning of the deploy, so that an old version of a different dashboard is not swapped back into production. In TeamCity, we use the “Shared Resources” feature to prevent two deployments targeting the same environment from running in parallel (which would have unpredictable results, if it happened – and with >40 dashboards it has! :)).

Now that the infodump is over: I’m having some trouble conceptualizing how to model all of this using Octopus. Some ideas include:

  • Creating a single “API Dashboard” project which deploys ~40 packages.
    Since different teams control when their dashboard updates are deployed to each environment, this won’t work. Team A might want to publish a new version of the UserManager dashboard to Prod to coincide with an API update, while Team B might be waiting for QA to finish testing the CatalogManager dashboard before it goes anywhere past integration.
  • Creating ~40 different projects, one for each dashboard.
    This seems like the nicest approach to me because it models how things work already, but a deployment requires an exclusive “lock” on the environment (because of the sync/swap process) and I’m not sure how to do this in Octopus.

What are your thoughts? Is there anything I might be missing here?

Hi Brant,

Thank you for getting in touch.

The single project for 40 steps actually sounds like the best solution. That way you don’t need to rely on the current state of the system to get a good deployment, and can start from a blank slate each time. You can use Channels and branches (or tags) to manage which versions of code gets deployed where.

Octopus will stop releases being created with the wrong packages based on the channel rules. The auto detection of packages in the create release process also respects channel rules, so you can set your build server up to just create a release and it will pick up the latest ~40 packages for applicable for that channel.

For example if you setup up a channel rule saying that the production channel releases cannot contain pre-release packages, the ProductManager.1.2.3-rc package will be blocked from being included in that release. Alternatively you could also define the max version allowed of each package in each channel.

If you did want to go the 40 separate projects route, other clients have setup a lock file on a shared drive that is checked and written at the start of the deployment and then cleared at the end (or on failure). You can choose to either delay or cancel the deployment if you encounter a lock file.

Hope that helps,

Robert W