html
When moving web servers to new infrastructure, the traditional DNS update approach creates a synchronization gap where some users hit the old server while others reach the new one. This becomes problematic when maintaining stateful applications or database consistency. The HTTP 301/302 redirect solution solves this by creating a unified traffic funnel.
For Apache servers, modify the virtual host configuration on your OLD server:
<VirtualHost *:80> ServerName yourdomain.com Redirect permanent / http://new-server-ip/ ProxyPreserveHost On RequestHeader set Host "yourdomain.com" </VirtualHost>
For Nginx configurations on the old server:
server { listen 80; server_name yourdomain.com; return 301 http://$server_name$request_uri; proxy_set_header Host $host; proxy_pass http://new-server-ip; }
The critical component is maintaining the original Host header through the redirect chain. This example shows a Node.js middleware approach for seamless transition:
const express = require('express'); const app = express(); app.use((req, res, next) => { req.headers['x-forwarded-host'] = req.headers.host; next(); }); app.get('*', (req, res) => { res.redirect(301, http://${newServerIP}${req.url}); });
After implementing redirects, update your DNS TTL values 48 hours pre-migration:
; Reduce TTL for smoother transition $TTL 300 @ IN A new-server-ip
Verify the redirect chain maintains host headers using curl:
curl -vIL -H "Host: yourdomain.com" http://old-server-ip/path
Check for these critical response elements:
HTTP/1.1 301 Moved Permanently Location: http://yourdomain.com/new-path Host: yourdomain.com
For MySQL/MariaDB environments, implement master-master replication during migration:
CHANGE MASTER TO MASTER_HOST='old-server-ip', MASTER_USER='replica_user', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=123456;
When migrating servers with different IP addresses, DNS propagation delays create a synchronization nightmare. Users hitting old DNS records will reach your original server, while others see the new one - causing database consistency issues.
A naive 301 redirect from old-server to new-IP creates these problems:
# Bad example - loses host header
RewriteEngine On
RewriteRule ^(.*)$ http://203.0.113.45/$1 [R=301,L]
This makes browsers display the raw IP address, breaking SSL certificates and confusing users.
Instead of redirects, configure your old server as a reverse proxy:
# Apache config
<VirtualHost *:80>
ServerName example.com
ProxyPreserveHost On
ProxyPass / http://203.0.113.45/
ProxyPassReverse / http://203.0.113.45/
</VirtualHost>
# Nginx config
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://203.0.113.45;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
During migration window:
- Configure master-slave replication from old to new server
- Set read-only mode on old server during final cutover
- Use this MySQL command to verify sync status:
SHOW SLAVE STATUS\G
When proxies are active:
# Reduce TTL 24h before migration
$ dig +short example.com IN SOA
# Expected output shows TTL value
Update DNS records only after confirming proxy works perfectly.
For HTTPS traffic:
# Apache SSL proxy config
SSLProxyEngine On
SSLProxyCheckPeerCN off
SSLProxyCheckPeerName off
Ensure your new server has valid certificates for all domains.