Easy Multi-device Local Development with xip.io

by: Derek Jones on: 8/21/2015

You are building a site locally and you’d like to quickly check your work on your iPad, iPhone, another computer, or maybe a client’s laptop. You could pay for a dynamic DNS service, setup a DNS server on your local network, or setup a proxy server perhaps. But there’s an easier way.

In my case I want to access my local feature branch of ExpressionEngine 3.0 on all my devices at home. The key is a “magic domain” service, xip.io.1

How to do it

I have my Apache VirtualHost and /etc/hosts file on my iMac configured to use http://ee3.dev/ for local development. I’ll add the special xip.io address as a ServerAlias, using the local IP address of my iMac (

ServerName ee3.dev
ServerAlias ee3.dev.
DocumentRoot /Users/derek/Sites/ExpressionEngine

I’m keeping the ee3.dev. prefix so I can use this naming system with all my projects and make it clear which VirtualHost I’m accessing. If you’re using MAMP Pro, just go to your Hosts tab and click the + button under the “Aliases” box to add the xip.io address as an alias.

Now to make sure asset paths and generated links go where they need to go, at the bottom of my config.php file in ExpressionEngine, I add the following:

if (preg_match('/.*\.xip\.io$/', $_SERVER['HTTP_HOST']))
    $base_url = "http://{$_SERVER['HTTP_HOST']}/";
    $config['site_url'] = $base_url;
    $config['cp_url'] = "{$base_url}admin.php";
    $config['theme_folder_url'] = "{$base_url}themes/";

This is the simplest example; many of you are using a dynamic config for multiple environments already so it may look familiar. You are telling ExpressionEngine to use the xip.io address as the foundation for all your URLs instead of the real one. My config file isn’t checked into source control, so my change doesn’t affect anyone else.

The key is validating the HTTP_HOST header2, as it is spoofable. We only want to change these settings if the URL ends in .xip.io. If you use HTTP_HOST without validation, you run the risk of a cache poisoning attack. That means an attacker could cause all generated links to point to their own servers for people who access your site after they do. If they copy your design, they have an effective phishing attack on your site’s visitors.3


Make sure to restart your web server after updating your VirtualHost, then anytime you want to pull up your local site on any device on your network, just key the xip.io address into the browser, in my case http://ee3.dev. Then I can work on my iMac and check it instantly on my phone, iPad, or Macbook Air, all which I keep on my desk.

There are many ways to do this; I found xip.io to be easy and seamless. What method do you use? Share your solution on the #eecms Twitter hashtag!

  1. When you access an xip.io domain, their DNS server extracts the IP address from the domain, and sends that back in the response. Think of it as a free zero-config public service that lets you give meaningful names to your local IP addresses. ↩︎

  2. Here’s a breakdown of the regex /.*\.xip\.io$/. The / at the beginning and end just define the boundary of the expression. Periods have special meaning in regex, so the ones we want to match in .xip.io are escaped as \.. Finally, we just want to make sure the domain ends in .xip.io, so we use .* in front of it, which means “any characters”, and $ is a special character that means the end of the string. There are dozens of ways to match the end of a string or a domain, this is but one. ↩︎

  3. Now would be a good opportunity to audit your preferred dynamic config solution. If it uses HTTP_HOST without validating that header or checking it against a whitelist, you have a security issue and should stop using that solution until you can address it. ↩︎

.(JavaScript must be enabled to view this email address) or share your feedback on this entry with @eecms on Twitter.

.(JavaScript must be enabled to view this email address)

ExpressionEngine News!

#eecms, #events, #releases