WordPress Network Domain Mapping with Symlinks

First a warning: this post is about to get as deep into tech talk as I ever like to get. If you’re looking for anything even remotely resembling the kind of conversation you’d typically have with me over coffee, you’ll be thoroughly disappointed! But if you’re a fan of WordPress with geekward leanings, this might be of interest. Ok, so now onto the post.

I’ve just finished setting up a test installation for running a WordPress network (aka multisite) in a shared web hosting environment, and thought I’d share some tips for anyone else who is trying to do the same. Getting the basics done by following the instructions on how to create a WordPress network is straightforward enough, but it’s the nuances in various configurations, particularly with sub-domains, DNS management and admin tools from hosting companies, that will likely throw people for a bit of a loop.

The End Goal: WordPress Network, with Sub-Domains, in a Shared Hosting Environment

This is what I wanted to get set up:

(1) A WP Network, installed in a sub-domain: e.g. wpnetwork.mydomain.com*

(2) The WP Network configured to support sub-domains for sites (rather than sub-folders): e.g. site1.wpnetwork.mydomain.com

(3) Domain mapping (enabled with the WPMU Domain Mapping Plugin) to allow each site within the network to map a domain of their choosing to the site within the network: e.g. Allow site1.com to resolve to site1.wpnetwork.mydomain.com (so that when someone visits http://site1.com, they see http://site1.com as the domain, but the files and content are actually stored at http://site1.wpnetwork.mydomain.com)

(4) Run all of this in a shared web hosting environment**

  • *Note 1: I’ve opted to install WP in the sub-domain so that I can keep the root of my primary domain completely independent of any other sites or apps. Why? In my experience, I’ve always found that installing multiple apps or software in sub-folders eventually gets messy, particularly when you get into anything like version control, mod_rewrite, htaccess rules, and other libraries or frameworks. This is basically just a way to hedge your bets in case things grow in the future.
  • **Note 2: There are pros and cons (or more like benefits and risks) with running a WordPress network in a shared hosting environment, but I won’t get into those here. Suffice it to say that there are times when you will want to run the network in a shared environment…like maybe you’re just trying to get a proof of concept up or MVP up and running and need to keep start-up costs low.

How to Create a WordPress Network with Sub-Domains

Just about all the steps to achieve this setup is covered quite well in the documentation on how to create a WordPress network, as well as the installation instructions for the WPMU Domain Mapping plugin, plus an additional set of instructions for clarity.

I followed all those steps and everything worked fine:

  • install and set up a WordPress network: check
  • support sub-domains for new sites in the network: check
  • install domain mapping plugin: check
  • create a CNAME in the DNS for the new site and site maps to the new domain: check
  • view new site at the new domain: DOH! This is where things fell apart.

Instead of seeing the content that is running in the WP network, all I would see is a 404 or page not found error. The new domain resolved properly, but the content didn’t appear.

After some digging around and some emails back and forth with my different web hosts, the picture became a little more clear. Where things fall apart in this set up is in the way that the server and DNS all operates in a shared hosting environment.

Shared Hosting = Layers of Abstraction

In a shared hosting environment, there are typically multiple customers all sharing space on the same machine or set of machines. Various techniques are used to then point a domain record to the location where the actual files for the website reside. Because multiple sites are sharing the same machine, there are all sorts of layers of abstraction that can make it a little trickier to figure out where exactly something might be going wrong with mapping a domain to the actual web files.

So to bring it back to the example, what was happening was that the domain server for site1.com knew to look for the site at site1.wpnetwork.mydomain.com, but the web host where the WP network was installed (wpnetwork.mydomain.com) didn’t know how to then find the data associated with site1.wpnetwork.mydomain.com. Instead of pointing to the root of the WP network, it was looking elsewhere.

How to Map Sub-Domains in a WordPress Network Using Symlinks

What was needed, it turns out, is something called a “symlink“. In this scenario, the symlink is basically being used to point the domain to the directory on the shared web hosting environment where the files for the site actually reside. It’s probably more complicated than that, but that’s the basic concept.

There are different ways to create a symlink, the most common way you’ll likely read about is to create the symlink via SSH using a command line tool (like Terminal if you’re on a Mac). There are different ways to do this depending on who you’re hosted with, so it would be best to contact your hosting provider and ask how to create a symlink. Here’s an example of how to create a symlink with MediaTemple.

In general terms, what you need to do is first create a domain entry for the new domain with the web host where you have your WordPress network installed. This will likely be creating a set of new folders in the file storage which you actually don’t need or want. So you will then need to delete these folders, and then create the symlink.

To do this via SSH, you would open up your SSH client (again, like Terminal if you’re on Mac), connect to your account on the web host, navigate to the directory where domains are stored, remove any folders that are associated with that domain, and then create the symlink for that domain. The command is quite simple:

ln -s wpnetwork.mydomain.com site1.com

This all translates roughly into:

[make link] [type=symlink] [location where files/content reside] [alternate domain]

But Command Line and SSH Really Scare Me

Ok, so using the command line and tunneling into your site with SSH can be a little intimidating. And also, all of this will only work if your web host provides you with shell (SSH) access. But many web hosts won’t provide shell access to customers in a shared hosting environment. Also, if you plan on creating more than a handful of sites in the network, or you plan on creating a more distributed workflow for your WordPress network where individual site creators can manage their own domain mapping, creating each new symlink through SSH will add a ton of overhead to your administrative processes as someone (with enough confidence and technical skill) will have to create the symlink for each and every new site in the network.

There is a work-around, though: create the symlink with a PHP script. Now this may not be supported on all web hosts, but it’s quite simple to do. Here’s a quick overview of how to create a symlink with PHP.

WordPressMU Domain Mapping with Automagic Symlink Creation?

Creating the symlink with PHP brings this all back almost full circle to the domain mapping plugin. It would be great if the WordPress MU Domain Mapping plugin also included the capability to have the symlink automagically created when the new domain is added through the backend domain mapping interface. E.g. add a PHP script to create the symlink and run the script when the new domain mapping setting is created. This opens up another set of considerations around roles and permissions, but it would sure be a handy addition.

Is this something you’d be interested in or interested in helping with? Let me know. Also, right now it’s just an idea. If you’re an advanced programmer familiar with server configurations and domain mapping, and you know of a good reason why this is a really bad idea (permissions and security come to mind), it would be great to hear from you.

So there you have it: a WordPress Network, with sub-domains, and custom domain mapping, in a shared hosting environment – enabled with symlinks!