Oli Warner About Contact Oli on Twitter Subscribe

ProTip: Change DNS without downtime

Thursday, 9 December 2010 dns

A few times I’ve found that I need to move a site to another server without any downtime but every time, DNS rears its ugly head and ruins my day.

I’m sure it’s a scenario that lots of other developers have been in. Sites occasionally need to be moved and when you maintain multiple websites for multiple clients, you can find you do a few of these each year.

As part of the migration you need to change the IP, www.example.com needs to point to the new server. Unfortunately because of the way DNS works, changes can take anywhere from a few minutes to a hundred hours. You can try to be clever by setting short TTLs on your domains well in advance of the move but the fact is you just can’t control how various users and their ISPs will cache the DNS data.

This might not bother some websites. Non-interactive websites don’t have anything to lose as long as they keep the old website server until all people are using the new version. But for interactive websites, it’s very important that all users are on the same version or you’ll lose data. Comments on the old version won’t show up on the new version (unless you manually port them across) and it just gets very sticky. One way or another you need to get all users using one version of the site.

One technique I’ve been using in the past is to use a temporary domain (eg: new.example.com) that points to the new server. I’ll install the site on that domain and then put redirect all traffic on the old server for the old domain to the new one. Then do the DNS move. All traffic ends up on the new server fairly unscathed. After a few days I’ll kill the redirect on the old server and redirect from new. to www. But this has a few problems:

But there’s an easier way. Proxy the traffic!

This epiphany came to me the other day in the middle of a server move. I was moving a client’s server to Linode from VPS.net (you can read my reasoning here). About 25 domains in total. I was pulling my hair out at the thought of having 25 temporary domains on the go when it came to me: why don’t I just install a proxy on the old server that reads the data from the new site?

Redirect all websites on a server

Install TinyProxy and open its config for editing:

sudo apt-get install tinyproxy
sudo nano /etc/tinyproxy.conf

Kill off nginx/apache/whatever. Probably a init script for you but I’ll leave this to you.

Then we need to fix your local DNS. From your server, run pingyourdomain.com. If you’re still seeing the old IP (that of this server), you’ll need to fix the DNS. You can do this quickly by running sudo nano /etc/hosts and adding a line like this (there should be examples in there):

new_server_ip    mydomain myseconddomain etc

And finally restart tinyproxy

sudo /etc/init.d/tinyproxy restart

Redirect just one site

If you only want to redirect a single site (and want to leave the other sites functioning as before) you obviously won’t want to kill your whole server.

If you’re using something like Apache, Nginx or Cherokee as your server, you can just edit your configuration. Apache has mod_proxy, Nginx and Cherokee have proxy modules and all will let you redirect the whole site to another server. Here’s Nginx:

location / {
proxy_pass http://yourdomain:80;
proxy_set_header X-Real-IP $remote_addr;
}

You should find that all the requests are handled (including posting). When the DNS has fully propagated and nobody is using TinyProxy, just shut off the old server and cancel your VPS.net account. Done. Magic.