{ bob.yexley.net }

software development, sports, the outdoors, faith, life...

Octopus Deploy - My New Favorite Toy

OctopusDeploy dashboard Every .NET developer I know has war stories about past horrors of deployments gone wrong. My theory is that’s because there’s not a good, universally accepted way to handle deployments of .NET apps on windows. Octopus steps in and offers a solution that, in my recent experience, dramatically simplifies the .NET deployment problem with a really elegant solution.

The Problem

I probably don’t really need to spend too much time here, do I? I mean, xcopy (with manual configuration, etc…yuck) is far too brittle and error-prone, MSDeploy/WebDeploy is just too much friction, third party installers and Wix are too much work (seriously, who has time for that?), and in enterprise/corporate environments, who really has the option of handling deployments through Visual Studio? What other options are there?

Well now, there’s Octopus.

A Cephalopod to the rescue

I first heard about Octopus on twitter, I think it must’ve been about six months ago. Ever since then I’ve been looking for an opportunity to try it out to see if it was as good as it appeared to be. I’m getting pretty close to wrapping up an initial release of a new product at work right now, so I thought this would be a perfect opportunity to try it out.

Getting up-and-running

Installation and configuration of a product is critically important, in my opinion. This is where customers/users get their true first impression of a product beyond just reading about it, seeing a few screenshots or watching a demo video. This is a users first actual use of the product. It was the first place that I found Octopus to truly shine. The installation and configuration was super easy, and I got through the entire thing without a single hiccup. I was really impressed with how easy it was.

There are two main components (well, actually three, sorta…but we’ll get to the third a little later) to setting up and using Octopus: the web portal, and the tentacles. The web portal is where you handle your environment configuration and deployments. From there, once you’ve established your environment configuration, and the portal is aware of your envirnonment, it interacts with tentacles when you actually execute a deployment. Tentacles, are like…”agents”, if you will…that run as background services on target servers, and execute the “installation” of deployment packages when instructed to do so by the web portal.

Here’s how it all works.

Making it happen

Octopus deploy process Don’t be intimidated by this diagram. It looks complicated, but it’s really not all that bad. Several of the components of the diagram are most likely already a part of your daily workflow and setup anyway. You do have source code right? If not, why are you even reading this? Also, if you’re reading this, you probably have target environments that you deploy to as well. If you don’t have a build server, that’s OK too, I can help with that (I’ll get to that in a minute) (I don’t have a functional build server at work either…yet). The NuGet repository? Well, that’s easier than you might think too…and again, I’ll get to that in a minute. With all of the pieces in place, with a little bit of simple configuration, Octopus just helps connect the pieces together, and makes it really easy to get things from one place to another, and makes it easy to get everything into the state it needs to be in once it gets there (things like handling different connection strings and configuration settings per environment…really simple).

Once you have all of the piece in place, there’s just a handful of easy steps to go from the raw source code on your desktop, to up-and-running live in a target environment.

When you want to deploy a package to a target environment with Octopus, you have to queue a deployment. Queuing a deployment involves:

  • Selecting the package you want to deploy. Octopus provides you with a dropdown list of package version numbers to choose from.
  • (Optionally) entering some release notes in a provided text area (accepts markdown).
  • Click the “queue deployment” button.

Yes, it really is that easy. Once a package has been queued for deployment with its associated release notes, it can then be deployed with a click of a button. Clicking the deploy button prompts you with a dialog to select which of your configured environments you wish to deploy it to. Click submit and your deployment is off-and-running to the target environment.

That being said, lets talk about how Octopus gets the deployment packages it makes available for deployment.

Feeding the Octopus

Octopus uses the NuGet package format for its deployment packages. You need to provide and configure Octopus with a NuGet package feed for each project you wish to automate deployment for. So to provide packages to Octopus for deployment, I had to do two things:

  1. Creating NuGet Packages

    I had to figure out a way to generate NuGet packages based on the compiled output of my web application. Eventually our goal is to get to the point where we have an automated build (continuous integration) server that generates our packages as part of its build, and serves up a NuGet package feed. We’ll soon be able to do just that with TeamCity. But…we’re not quite there yet, sooo… My immediate solution was to generate them myself. Last week I wrote about Pyke, a .NET build module that I wrote. As I was writing that module, I added functions for generating NuGet packages. As I mentioned in that post, we don’t currently have a functional build server in our organization (to reiterate the point…yet), so I currently run our build script locally, from my desktop. Our script currently has three main steps: 1) compile the app, 2) generate a NuGet package, and 3) copy that package out to a shared directory on our network, which also happens to be the source folder for the applications NuGet package feed…

  2. Creating and updating a NuGet Package feed

    The next step in figuring out how to deliver NuGet (deployment) packages to Octopus, was to create and source a NuGet package feed that I could provide to Octopus. This turned out to actually be a LOT easier than I expected it to be. The NuGet team has done a fantastic job all the way around that project, not only in implementation, but in documentation. I did some poking around in the NuGet docs, and found and followed these instructions on how to create your own remote (or internal) NuGet feed. They’ve created their own NuGet package that you add to an empty ASP.NET web application, deploy it to an IIS server, and boom…you’re done. That package is configured to look in a folder for packages to serve up in its feed. I followed their instructions, and shared up the package folder as a network share, and that’s where I copy my generated packages to from my build script, and the feed is automatically updated immediately. It literally took me about five minutes to get up-and-running with a functional NuGet package feed for Octopus to work with. It doesn’t get a whole lot easier than that.

Putting it all together

So, yeah…there’s a lot of words here, which probably makes it seem like a lot more work than it actually was. But ultimately, when all was said and done, this was all I had to do to get everything setup…

  1. Install the Octopus web portal. I had no issues with the installation at all, it took less than five minutes.
  2. Install the Tentacle on my target web server. That too went without issue, and took less than two minutes.
  3. Create a NuGet package feed hosted in IIS. As I just explained, it literally took about five minutes to put that together.
  4. Run my build script to generate a package so my feed had something to serve up.
  5. Configure my environment in the Octopus web portal. That was pretty straight-forward, and consisted of
    1. Pointing it to my NuGet feed (where it found a package waiting to be deployed)
    2. Pointing it to my target web server (where it discovered that there was a tentacle running, waiting for a package to install)
    3. Creating a project, to which I added the above configured target server and package feed.
    4. Done.

All total, if I had been able to perform all of those actions in sequence (I was putting all of this together in my “spare time” while doing my day-to-day development work), it would have taken me about an hour, tops, to get everything in place. The beauty of it is that, now that it is all in place, deploying new features and fixes to any of my environments takes a grand total of about two-and-a-half minutes.

THAT is a beautiful deployment process. If you haven’t yet, you really owe it to yourself to check out Octopus for handling your deployment if you’re doing .NET development. For a relatively low-friction setup and configuration, it will save you immeasurable time and hassle.

Comments