Когда нужно перенести какой-то сайт на новый сервер, очень выручает nginx.

Исходные данные

Есть два сервера:

  • novus.example.net - новый сервер, куда мы переносим сайт;
  • veteris.example.net - старый сервер, откуда мы переносим сайт.

Сайт проходит под именем www.example.net.

Проблема

Обновление DNS записей может занимать существенно время, на которое мы можем повлиять лишь отчасти. Даже если для какой-то A записи мы установим короткий TTL в пределах нескольких минут, нет никаких гарантий что все кеширующие DNS сервера будут этот TTL учитывать. Значит, даже при коротком TTL нам следует исходить из TTL порядка нескольких дней.

Алгоритм

Необходимо чтобы на запросы к нашему сайту старый сервер отвечал хотя бы несколько суток после переезда.

На новом сервере...

Если мы будем проксировать запросы от старого сервера на новый, то новый сервер увидит IP старого сервера, а не настоящие IP клиентов, зашедших на старый сервер. Это легко исправить одной лишь директивой.

tee /etc/nginx/conf.d/set_real_ip_from.conf <<DOC
set_real_ip_from $(dig +short veteris.example.net);
DOC

С такой директивой nginx будет знать что IP для запросов от старого сервера нужно заменить на IP, указанные в известном заголовке.

На старом сервере...

На старом сервере, откуда мы переезжаем, заменим блок server другим - проксирующим все запросы на новый сервер.

 server {
    server_name www.example.net;
    listen veteris.example.net:443 ssl;
    include ssl/example.net.conf;

    location / {
        proxy_pass https://novus.example.net;
    }
}

Для завершения настройки перезапустим nginx тут и там.

Так, пока идет обновление DNS, каждый посетитель будет обслужен независимо от того, по адресу какого сервера он обратится.

Переезд сайтов с сертификатами от Let's Encrypt

Прежде чем устраивать переезд, нужно получить SSL сертификаты от Let's Encrypt для домена и на новом сервере тоже.

Значит, нужно настроить переадресацию запросов на получение сертификатов со старого сервера на новый. Для этого в конфиге nginx для 80 порта дополнить блок location и добавить ещё один.

location /.well-known {
    root /var/www/html;
    try_files $uri @future;
}

location @future {
    proxy_pass http://novus.example.com;
}

Теперь можно получить сертификаты и на новом сервере, и на старом, без необходимости менять что-либо в DNS записях для домена.

certbot certonly -d $(hostname -d) -d www.$(hostname -d)

Переезжаете без https?

Нет проблем! Везде в конфиге замените https на http и 443 ssl на 80.

Ниже пример конфига для старого сервера, откуда переезжаем.

server {
    server_name www.example.net;
    listen veteris.example.net:80;

    location / {
        proxy_pass http://novus.example.net;
    }
}