My company just did this with several largish Web sites. The basic procedure we followed was:
- Lower the domain's TTL as much as possible. Do this in advance by at least as much time as the current TTL.
- Set up the Web site on the new server exactly how you want the "final product" to be
- Add an aliased name to the site on the new server, such as www2.domain.com or www-new.domain.com. With Apache, you would use the ServerAlias directive. If the site has any dynamic code at all (PHP, mod_perl, RubyOnRails, etc.), make certain that the site will behave and respond correctly with this new name.
- At cutover time, set up a redirect on the old server pointing to the new server
- Change DNS for www to go to the new IP.
For Apache, you should probably use mod_rewrite for the redirect so you can preserve the URIs requested by the client. A simple implementation would be:
# old server
<VirtualHost 1.1.1.1:80>
ServerName www.domain.com
RewriteEngine on
RewriteRule ^(.*)$ http://www-new.domain.com$1 [L]
</VirtualHost>
# new server
<VirtualHost 1.1.1.2:80>
ServerName www.domain.com
ServerAlias www-new.domain.com
</VirtualHost>
This will do a 302 temporary redirect for www.domain.com/anything to www-new.domain.com/anything. You want it to be temporary because you probably want search engines to only index www.domain.com, not www-new.domain.com.
Once the DNS change for www.domain.com has propagated to your satisfaction, you can either dump www-new altogether, or gently ease anyone using it back over to www with another redirect. It's almost the same process as above; set up the old server to handle www-new, change DNS for www-new to point to the old server, and set up a redirect on the old server sending www-new traffic to www:
# old server
<VirtualHost 1.1.1.1:80>
ServerName www-new.domain.com
RewriteEngine on
RewriteRule ^(.*)$ http://www.domain.com$1 [R=301,L]
</VirtualHost>
# new server
<VirtualHost 1.1.1.2:80>
ServerName www.domain.com
# ServerAlias removed, no longer needed
</VirtualHost>
This time you want to do a permanent 301 redirect, again to clue in search engine crawlers that www.domain.com is the site you want them to index.