Home > Blog

Attackmonkey Blog

Running Umbraco Over Reverse Proxy

Recently I had to get Umbraco working over a reverse proxy, and I thought I'd share how I did it, as there's actually a pretty painless way to get it working!

First up, what is a reverse proxy? A reverse proxy is like a virtual folder, except that the contents of the virtual folder resides on another server. Why would you need to do this? Well, usually, if you need to run Umbraco in a virtual folder in a .Net site, you could use a normal virtual folder. However, security considerations might prevent installing the Umbraco site on the same box as the main site, or the main site might be written in PHP and hosted on a *nix box for example.

Out of the box, platforms like Apache support reverse proxying natively through Mod Rewrite. In IIS, you have to use something called Application Request Routing (ARR), combined with URL Rewritiung to make it work. These are optional add ons for IIS. If you're interested, here's some information on how to do it with Mod Rewrite, and here's how to set up ARR in IIS.

One of the things that you often have to do with reverse proxied stuff is to rewrite the content as it's sent back to correct image paths and links etc. Normally you'd do this with outbound rewrite rules. It's not too painful for simple sites, but for something like Umbraco, which is a very complex system, it can be quite difficult to do without accidentally breaking stuff (you also need to heavily rewrite the contents of JS and CSS files, which can be quite slow, and each extra plugin increases the work usually).

So I figured out a much easier way of getting it all to work. Lets say you have www.mysite.com and you want to reverse proxy the URL www.mysite.com/blog/ to blog.mysite.com, which is an Umbraco site on another server. All you need to do is set up the Umbraco site on blog.mysite.com to run in a virtual folder that matches the name that you want to use for the reverse proxy, e.g. blog.mysite.com/blog/. As Virtual folder setups work pretty well out of the box, this means that you only need an outbound rule for the blog.mysite.com domain, everything else should just work out of the box, as it already thinks it's in the /blog/ folder!

Making Your Packages Work in a Virtual Directory

Just before Christmas I worked on a couple of projects where we needed to have Umbraco running in a virtual directory. Out of the box, Umbraco itself works very well in a virtual directory these days. The main issue that I ran into was packages that didn't work correctly when Umbrco was in a virtual folder.

From going through all the affected packages in the projects, I've compiled a list of things that you can do in your packages to help ensure that it will run correctly when your site is running in a virtual folder. So without further ado, here are the top five things to be aware of:

1. Paths in your package manifest

In your package manifest, ensure that your paths start with a ~. E.g. instead of referencing a script as "/app_plugins/my_plugin/script.js" use "~/app_plugins/my_plugin/script.js". Umbraco will then work out the correct path when it loads in all of the manifests.

2. Paths in your CSS

You often see people make their image paths in the CSS relative to the root of the site. This won't work in a virtual folder, so make sure all of your image paths are relative to the location of your CSS file. That way the paths will work, regardless of where the Umbraco site lives.

3. Paths in your JS

Again, it's common to see links to things in the JS file be rleative to the root, e.g. "/umbraco/surface/mysurface/get". Your JS will be executing from the /umbraco/ path, so code your paths accordingly. E.g. in the previous example, you could use "../umbraco/surface/mysurface/get".

4. Paths in your templates

As with paths in your JS, code the paths to images and other resources in your templates/views as if they're in the /umbraco/ folder. So instead of "/app_plugins/myplugin/images/", use "../app_plugins/myplugin/images/".

5. Paths inside your code

If you're mapping paths inside your code for things like Controllers and other compiled resources, don't forget the ~ at the start of the URL! this will then map the path to include the virtual folder as well.

And that's about it. If you follow those five guidelines, your package should work on an Umbrco site that's running in a virtual folder!


Upgrading to 7.3: Part 3 - Switching to Razor

In part 2 of this series, I talked about upgrading the site to 7.3. At this point we have a nice shiny site, but all of the additional functionality is currently in XSLT. The client this is for prefers their sites in Razor these days, so as an added thing to do, I now have to port the site over to Razor.

In the back office, all of the old templates were still listed, but as I hadn't copied the master pages across from the old site (as we're switching to MVC), they'rer all empty. It was fairly trivial to then just re-save each of those (which created the physical view pages in my project), and then adding a Layout file with the outer page. I copied all the HTML from the old templates, with a few minor changes. I was able to remove a couple of templates, and combine a couple of others!

The old site is nearly 5 years old, so pretty much everything is XSLT/Macros. Razor allows you to move everything into partials and controllers, so looking at the code, it's possible to do away with all of the Macros bar the one that allows you to embed a special corporate video into the Richtext editor.

I went through the site and converted all the old macro based functionality into Razor. Some of it could just be inlined in the templates, as it was template specific, the rest was turned into plain old partials.

A few parts of the code made sense to be surface controllers (the search, and a user profile page, as well as the login stuff). THese were pretty easy to port over.

With the XSLT, al ot of the code could just be ported over and rewritten. Quite a few macros were no longer needed, or could be combined. By the time I was done, I only had a handful of Partials, compare to the 20+ Macros on the old version of the site.

Once I'd tested everything to make sure it still worked compared to the old version of the site, it was time to tidy up. All of the old Macros and XSLT files were deleted from Umbraco.

At this point, we have a fully upgraded site, now running on the latest version of Umbraco! As an added bonus, between starting this and finishing, Umbraco crept up to 7.3.4, but a quick "Update-Package UmbracoCms" in Nuget in VS sorted that out very quickly and efficiently!

The site and database can now be deployed, replacing the old site, and we're good to go!

All in all, the process has been significantly less hassle than I expected, and I'm really imprressed with how straightforward it all was. I'd be much less hesitant to recommend upgrading a fairly straighforward Umbraco site than I might have been previously. I'd love to hear if anyone else has tried this, and whether your experiences were as painless as mine!

Upgrading to 7.3: Part 2 - The Upgrade

In part 1 of this series, I talked about preparing for the site upgrade. In this part I'm going to talk about how I did the actual Upgrade.

Before we start, I pulled down the site files and a backup of the Database from the live site. I set both up to run on my local machine, and did some house keeping first. On this particualr site, we were removing a section and some of the DocTypes, so I did that on the old copy first, to make things easier later on. I then took another backup of the database once I was done (in case anything wet wrong and I needed to start again).

Next, I set up a new VS.Net project, and installed Umbraco 7.3 using NuGet, along with some essential stuff, like the core property value converters (also installed from NuGet). Once those were installed, I opened the web.config file for the newly installed copy of Umbraco and set the connection string to point to my old database. I decided against merging in my config values etc at this point, as I wanted there to be as few errors as possible.

With baited breath, I ran the website from VS.Net. I got the Umbraco installer screen, and it flagged that I was running an upgrade rather than a fresh install, hapy days! I clicked the next button, aaaaand got a big fat SQL error. The error message that I got was a bit misleading, as it lists all of the tables etc that aren't in the core install, and I though that was the problem, however, after much digging through the log files, it turned out to be a SQL server permissions issue on the database. I sorted that out and ran the site again. This time, after a couple of minutes, I saw the success screen, and it redirected me to the back office.

I had a click around and everything seemed OK. The two DataTypes that weren't v7 compatible were showing as labels, but everything was working. At this point, I backed everything up again, and then merged in my config files, master templates, scripts, CSS and images etc. If you're updating from a Web Forms site, don't forget to change the default rendering engine to Web Forms from MVC in the umbracoSettings site.

At this point I ran into a couple of issues. the first was that older versions of Umbraco let you have a - in the alias of DocTypes, and the newer versions don't. This particular site had a couple of DocTypes that had - in them, so I had to re-save the DocTypes and restart the App Pool to get rid of the error that was being generated. Next was that the EXSLT extensions were removed in 7, so some of my XSLT broke. Not to worry though, you can get a package for that from the mighty Lee Kelleher. In this particular instance, I don't care about fixing the XSLT, as I'm going to replace all the XSLT with Razor.

The only other issue that I had was that there appears to be a bug in one of the database Migrations that scrambles the order of some of your DocType properties. But that was easily fixed by re-ordering the properties on the affected DocTypes and re-saving them.

Finally, in the Data Types section, I swapped the MNTP pickers from uComponents (which were now labels) ot the new built in one, and as they were set to store CSV, that just worked. The other DataType (Embedded Content) was removed and replaced with Nested Content. This required a bit of set up, and re-entering the data, but it only took about an hour.

At this point, I have a (mostly) functional site, upgraded from 4.7.2 to 7.3. It was much less hassle than I was expecting, and it seems to have worked very well for me. Your mileage may vary, I suspect that for a much more complex site, you'll have a lot more issues, especially if you are using quite a few custom DataTypes.

In part 3, I'm going to cover switching the site over from XSLT and Master Pages to Views, and tidying everything up, ready to go up to the live site again.

Upgrading to 7.3: Part 1 - Preparation

In my previous article, I talked about how impressed I was with the Umbraco upgrade process in 7.3. I'm now much further through the full upgrade, so I'm going to blog about it, in the hope that it helps others considering doing the same.

In this part, I'm going to talk about the planning for the upgrade.

I have a client who has an old 4.7.1 site, and they'd like to use some functionality that's only present in v7. Previously I was looking at a full rebuild and re-importing content, but due to the volume of content (10,000+ pages), I wasn't too keen on this, as copying content between installs is notoriously fiddly.

So, when Neils announced that the new version would upgrade the database and it actually worked, I decided to give it a go, as it could potentially save me a LOT of time.

So, the existing site:

  • Runs on 4.7.1
  • Has 10,000+ pages
  • Uses XSLT Macros and MasterPages
  • Uses a handful of packages, mostly event based stuff (CustomMenus, AutoFolders etc)
  • Uses two custom DataTypes (Embedded Content and uComponents MultiNode tree picker)

First up, what do we want to achieve with the upgrade?

  • Upgrade to 7.3
  • Swap out all of the XSLT/MasterPages for Views/Razor
  • Remove some unused sections of the site

So, what issues are you likely to hit? Firstly, not all of the packages may have been updated for v7. In this case, we were using the MultiNode tree picker from uComponents, which isn't available in v7. This one is pretty straightforward. Make sure the DataType is set to store as CSV (if it isn't already), and republish all the pages with the DataType on. That way we can just swap DataType to the built in v7 Multiple Content Picker after the upgrade, and we won't lose any data.

Embedded content can be replaced with either Archetype, or Nested Content. HOWEVER, the data cannot be just swapped over. When you upgrade Umbraco to v7, any DataTypes that are non-core are turned into labels, and the values preserved, and the DataTypes are set to a non-editable control. You could write some custom code to reformat the data for your new DataType using the API once you've done the upgrade, but in this case, the DataType was only being used to display some widget boxes on the home page, and nowhere else, so re-adding the 8 boxes after we've upgraded is probably quicker than messing aroud trying to reformat the data.

So, now that we've covered the basic issues we're likely to hit, what next? I decided to take the following approach to the upgrade:

  • Take a copy of the database
  • Remove all the stuff that we don't need on the old version of the CMS
  • Backup the database (in case it goes horribly wrong)
  • Create a new Visual Studio project and install Umbraco 7.3 and packages through NuGet
  • Run the Upgrade
  • Merge in the stuff I needed and then start changing view/macros etc
  • Test thoroughly
  • Deploy
  • Retire to somewhere hot and drink cocktails with tiny hats

So, having done a bit of prep work, we're ready to rock. Watch out for part 2, where I'll talk about the initial upgrade process.