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:
-
People can see the change in domain. Perhaps not the biggest problem but depending on the scenario, it might not look professional.
-
Search engines see the change. Most will behave and treat the redirect sensible… But some might drop you from their index or penalise your rankings. Search traffic accounts for a huge portion of my traffic and this applies to most of my clients. Traffic means money.
-
And from a maintenance point of view, people might make links to the temporary domain while you’re in the transition. This means you have to keep the temporary domain and redirect it to your proper domain indefinitely or lose/break an inbound link.
-
It’s relatively heavy on time. Making all these changes requires multiple trips to change the DNS, multiple configurations for two servers. It’s a pain in the arse.
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
- Change
User
andGroup
toroot
. Security hole, I know but this needs to be done so that it can run on Port 80. If it’s any consolation, you can move all sensitive data off the server before you do this. - Change
Port
to80
. - Comment out
Allow 127.0.0.1
so all users can see it.
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.