За роки роботи я переносив сайти десятками: від візитівок на 40 МБ до магазинів із базою на 12 ГБ і живими замовленнями щохвилини. І майже завжди, коли перенос закінчувався кількагодинним простоєм, причина була не в хостингу. Причина була в порядку дій.

Найпоширеніший сценарій катастрофи виглядає так: людина у вівторок ввечері замовляє новий сервер, одразу змінює NS-сервери домену, а потім починає заливати файли. У результаті частина відвідувачів годинами бачить порожню заготовку або 404, форми не працюють, пошта частково падає в нікуди, а замовлення, які прийшли на старий сервер уже після «переїзду», просто губляться. Другий за популярністю сценарій — перенести все ідеально, але забути, що SSL-сертифікат на новому сервері ще не випущений, і зустріти клієнтів червоним екраном «Небезпечне з'єднання».

Хороша новина: перенос без простою — це не магія і не «залежить від щастя». Це послідовність, у якій зміна DNS стоїть наприкінці, а не на початку. Нижче — той самий план, за яким ми переносимо проєкти клієнтів, з командами, перевірками і планом відкату.

Чому взагалі виникає простій

Коли ви змінюєте DNS, світ не дізнається про це одночасно. Провайдери, браузери й публічні резолвери (8.8.8.8, 1.1.1.1) тримають закешовану відповідь стільки часу, скільки ви самі їм дозволили — це і є TTL. Тому після зміни A-запису частина користувачів іде на новий сервер, а частина ще годинами продовжує йти на старий.

Це не проблема сама собою. Проблема виникає тоді, коли обидві версії сайту живі й обидві приймають дані. Уявіть магазин: клієнт А потрапив на новий сервер і оформив замовлення, клієнт Б потрапив на старий і оформив своє. Через дві доби ви вимикаєте старий сервер — і замовлення клієнта Б зникає разом із ним. Формально простою не було, фактично ви втратили гроші й репутацію.

Тому правильна мета переносу звучить не «швидше перемкнути DNS», а так:

  • сайт має бути повністю робочим на новому сервері до зміни DNS;
  • період, коли обидва сервери можуть приймати дані, має бути мінімальним і контрольованим;
  • у будь-який момент має існувати спосіб повернутися назад за кілька хвилин.

Що таке TTL і чому він визначає ваш простій

TTL (Time To Live) — це вказівка «зберігай цю відповідь N секунд». Стандартне значення у більшості панелей — 3600 (година), інколи 14400 (чотири години) або навіть 86400 (доба). Це означає, що після зміни A-запису «хвіст» старого трафіку тягнеться рівно стільки ж.

Звідси перше й найважливіше правило всього переносу: TTL знижують не в день переносу, а щонайменше за добу до нього. Логіка проста: щоб світ швидко забув нову відповідь, він спершу має забути стару — а стару він тримає за старим, високим TTL.

Знизили TTL до 300 у понеділок — у вівторок вечором перемикання «розлітається» за 5–10 хвилин. Знизили TTL до 300 одночасно зі зміною IP — отримали ті самі 4 години хвоста, бо резолвери ще тримають попередній запис.

Перевірити поточний TTL можна однією командою:

dig +noall +answer uhost.online
dig +noall +answer @8.8.8.8 example.com A

Друге число у виводі — це залишок TTL у секундах. Якщо там 3600 — плануйте перенос не раніше ніж через добу після зниження.

Крок 0. Інвентаризація: що саме ви переносите

Перенос ламається не на файлах, а на дрібницях, про які ніхто не згадав. Перед тим як щось чіпати, випишіть у текстовий файл:

  1. Версії середовища: PHP (точна мінорна — 8.1 чи 8.3 це різні світи), MySQL/MariaDB, потрібні розширення (imagickintlsoapgdbcmathredis).
  2. Розмір даних: du -sh по каталогу сайту і розмір дампу БД. Це визначає, чи вкладеться фінальна синхронізація в п'ять хвилин або в дві години.
  3. Cron-задачі: вони не переїжджають самі. crontab -l на старому сервері — і збережіть вивід.
  4. Пошта: вона на цьому ж сервері чи на зовнішньому сервісі (Google Workspace, Mailgun, Zoho)? Це визначає, чи чіпаєте ви MX узагалі.
  5. Сторонні привʼязки до IP: платіжні шлюзи, API-партнери, банківські callback-и й вебхуки часто мають whitelist IP-адрес. Новий IP треба додати туди заздалегідь.
  6. Усі DNS-записи цілком: не лише A. TXT для верифікації Google Search Console, SPF, DKIM, DMARC, CNAME для піддоменів, записи для CDN. Зробіть повний скріншот або експорт зони.
  7. Де саме керується DNS: у реєстратора, у старого хостера, чи в Cloudflare? Від цього залежить, що ви взагалі будете перемикати — A-запис чи NS-сервери.

Останній пункт варто пояснити окремо, бо на ньому спотикаються найчастіше.

A-запис чи NS: різниця критична

  • Зміна A-запису — точкова операція. Ви змінюєте одне число, решта зони (MX, TXT, піддомени) залишається на місці. Розповсюджується за TTL. Це завжди безпечніший варіант для переносу без простою.
  • Зміна NS-серверів — це передача всієї зони новому провайдеру. Розповсюджується довше (до 24–48 годин, TTL у зоні реєстратора ви не контролюєте), і якщо ви не перенесли в нову зону усі записи — MX, SPF, DKIM, TXT-верифікації — вони просто зникнуть. Разом із поштою.

Порада проста: якщо у вас є вибір — переносьте через A-запис, а NS не чіпайте зовсім. Змінюйте NS лише тоді, коли ви справді хочете переїхати DNS-хостингом, і тоді робіть це окремою операцією в інший день, попередньо створивши всі записи в новій зоні й переконавшись, що вони віддаються правильно.

Плануєте переїзд і не хочете возитися самі? На тарифах NVMe-хостингу uHost ми переносимо сайт за вас — з тестовим запуском до зміни DNS і безкоштовно. Ви змінюєте одне число в DNS тоді, коли новий сервер уже перевірений.

Обрати хостинг

Крок 1. Знижуємо TTL (за 24–48 годин до переносу)

Заходите туди, де реально керується ваша зона, і знижуєте TTL для A-записів домену і www до 300 секунд. Якщо панель дозволяє 60 — ще краще.

Що важливо: MX-записи не чіпайте, якщо не переносите пошту. І не змінюйте самі IP на цьому кроці — тільки TTL.

Далі просто чекаєте. Це нудний крок, який економить години нервів.

Крок 2. Готуємо новий сервер і робимо чорновий перенос

На новому сервері створюєте сайт і базу, ставите потрібну версію PHP і розширення. А потім робите перший, чорновий перенос — не фінальний. Його мета не «переїхати», а виявити всі проблеми сумісності, поки старий сайт спокійно працює й ніхто нічого не помічає.

Файли найкраще тягнути через rsync — він докачує різницю, тому фінальна синхронізація потім займе секунди:

# з нового сервера тягнемо файли зі старого
rsync -avz --progress \
  -e "ssh -p 22" \
  user@old-server-ip:/var/www/example.com/ \
  /var/www/example.com/

Базу — дампом. Обов'язково з --single-transaction для InnoDB, щоб не блокувати таблиці живого сайту:

# на старому сервері
mysqldump --single-transaction --quick --routines --events \
  -u dbuser -p dbname | gzip > /tmp/dbname.sql.gz

# на новому сервері
gunzip < dbname.sql.gz | mysql -u newuser -p newdbname

Якщо доступу по SSH до старого хостингу немає (класика shared-хостингу), лишається FTP/SFTP і phpMyAdmin — тоді робіть архів на боці старого сервера через файловий менеджер панелі, а базу експортуйте частинами, якщо вона велика.

Після переносу правите конфіг підключення до БД: wp-config.php для WordPress, .env для Laravel, config/db.php для OpenCart тощо. І не забудьте виправити права на файли — після rsync від root вони часто ламаються:

chown -R www-data:www-data /var/www/example.com
find /var/www/example.com -type d -exec chmod 755 {} \;
find /var/www/example.com -type f -exec chmod 644 {} \;

Крок 3. Перевіряємо сайт на новому сервері до зміни DNS

Це той крок, який відрізняє спокійний перенос від героїчного. Ви можете відкрити сайт на новому сервері під справжнім доменом, поки для решти світу домен ще вказує на старий сервер. Робиться це через локальний файл hosts.

На macOS і Linux файл лежить у /etc/hosts, на Windows — у C:\Windows\System32\drivers\etc\hosts (відкривати блокнотом від імені адміністратора). Додаєте рядок з новим IP:

203.0.113.45  example.com www.example.com

Тепер ваш браузер іде на новий сервер, а всі інші — на старий. Що перевіряти:

  • головна, 5–10 внутрішніх сторінок, категорії, пагінація;
  • вхід в адмінку і збереження будь-якого матеріалу;
  • завантаження файлу/зображення — це перевірка прав і upload_max_filesize;
  • відправка форми зворотного звʼязку — перевірка того, що пошта з сервера взагалі йде;
  • для магазину — повний тестовий шлях: кошик, доставка, оформлення, тестова оплата;
  • консоль браузера на 404 і mixed content;
  • логи помилок на новому сервері: tail -f /var/log/nginx/error.log і лог PHP-FPM.

Знайшли проблему — виправляєте спокійно, бо клієнти цього не бачать. Саме тут виловлюються відсутній intl, зміна поведінки в новій версії PHP, жорстко прописані шляхи /home/olduser/... у конфігах і крони, які впали з іншим шляхом до бінарника PHP.

Крок 4. SSL — до перемикання, а не після

Дуже частий і дуже болючий прокол: DNS перемкнули, сайт відкрився — і одразу з попередженням про небезпечне з'єднання, бо сертифікату на новому сервері немає.

Тут є нюанс: стандартний випуск Let's Encrypt через HTTP-перевірку (--webroot) не спрацює до зміни DNS, бо валідатор піде за поточним A-записом, тобто на старий сервер. Виходів два:

  1. DNS-валідація — випустити сертифікат через TXT-запис _acme-challenge, не чіпаючи A-запис. Працює завжди й заздалегідь:
    certbot certonly --manual --preferred-challenges dns \
      -d example.com -d www.example.com
    Certbot покаже TXT-значення, ви додаєте його в DNS, чекаєте пару хвилин і підтверджуєте.
  2. Одразу після перемикання — тримати команду certbot --nginx -d example.com -d www.example.com набраною в терміналі й виконати її в першу ж хвилину. Ризиковано, але прийнятно для невеликих сайтів.

Якщо сайт стоїть за Cloudflare у режимі proxy (оранжева хмарка), задача спрощується: відвідувач бачить сертифікат Cloudflare, а на сервер ви можете поставити Origin-сертифікат Cloudflare із терміном на 15 років — і взагалі не залежати від валідацій під час переносу.

Потрібна повна свобода налаштувань? На VPS з Linux KVM ви самі керуєте версіями PHP, кешем, сертифікатами й фаєрволом — і переносите проєкти без чужих обмежень.

Подивитися VPS

Крок 5. Фінальна синхронізація і «тихий» режим

Тепер найтонший момент усього переносу. Між фінальним дампом бази й перемиканням DNS проходить якийсь час — і все, що клієнти зроблять на старому сайті в цей інтервал, буде втрачено. Тому інтервал треба або звести до хвилин, або зробити його безпечним.

Для звичайного сайту чи блогу з парою коментарів на день достатньо просто робити перенос у нічний час і не панікувати.

Для магазину або сервісу з живими даними правильна схема така:

  1. Вибираєте найтихішу годину за даними аналітики (зазвичай 3:00–5:00).
  2. На старому сайті вмикаєте режим обслуговування — не 500-у помилку, а нормальну сторінку з текстом «Технічні роботи, повернемось за 20 хвилин». Для WordPress це файл .maintenance, для решти — умова в index.php або return 503 у Nginx для всіх, крім вашого IP.
  3. Робите фінальний дамп бази й rsync — і те, й інше швидке, бо основне ви вже перенесли на кроці 2.
  4. Заливаєте дамп на новий сервер, ще раз швидко перевіряєте сайт через hosts.
  5. Перемикаєте DNS.
  6. Знімаєте режим обслуговування — на новому сервері. На старому залишаєте його увімкненим: так відвідувачі із закешованим DNS побачать чесне повідомлення, а не оформлять замовлення в нікуди.

Останній пункт — недооцінений трюк. Він фактично прибирає проблему «двох живих сайтів»: старий сервер лишається доступним для DNS, але не приймає жодних даних.

Крок 6. Перемикаємо DNS

Змінюєте A-запис домену і www на новий IP. TTL залишаєте 300 — підвищите пізніше.

Перевірка того, що зміна пішла:

dig +short example.com @8.8.8.8
dig +short example.com @1.1.1.1
dig +short www.example.com @8.8.8.8

Різні резолвери оновлюються з різною швидкістю — це нормально. Якщо через 15 хвилин хоча б два публічні резолвери віддають новий IP, перемикання пройшло.

Важливо: тепер приберіть свій рядок із /etc/hosts. Інакше ви будете бачити «правильний» сайт незалежно від реального стану DNS і не помітите, якщо щось піде не так.

Крок 7. Пошта — окрема історія

Пошту руйнують частіше, ніж сайт, бо про неї згадують після. Три можливі ситуації:

  • Пошта на зовнішньому сервісі (Google Workspace, Microsoft 365, Mailgun). Найпростіший випадок: ви змінюєте лише A-запис, MX не чіпаєте — пошта нічого не помічає. Просто переконайтеся, що ви справді не чіпаєте MX і не змінюєте NS.
  • Пошта на старому хостингу і залишається там. Тоді MX має і далі вказувати на старий сервер. Але після зміни A-запису сайт почне надсилати листи з нового сервера — і треба оновити SPF, додавши новий IP, інакше Gmail почне позначати листи як спам:
    v=spf1 a mx ip4:203.0.113.45 include:_spf.google.com ~all
  • Пошта переїжджає разом із сайтом. Найважчий варіант. Створюєте всі скриньки на новому сервері до перемикання, переносите вміст через imapsync, і лише потім змінюєте MX. Обов'язково перевипускаєте DKIM на новому сервері й оновлюєте DKIM-запис у DNS. Старі скриньки не видаляйте щонайменше два тижні.

Крок 8. Перші 48 годин після перемикання

Перенос не закінчується зміною DNS. Що робити далі:

  1. Перевірити реальний трафік на старому сервері. tail -f по access-логу старого сервера покаже, скільки людей ще туди приходить. Коли потік вщухає до нуля-двох запитів на хвилину — «хвіст» закінчився.
  2. Перевірити крони. Найтихіша поломка переносу: сайт працює, а бекапи, розсилки й синхронізація з 1С мовчки не виконуються тиждень. Перенесіть crontab і переконайтеся, що завдання реально відпрацювало.
  3. Пройти сценарій оплати повністю, включно з callback від платіжного шлюзу. Саме тут вилазить незанесений у whitelist новий IP.
  4. Подивитися Search Console — розділ помилок сканування. Якщо після переносу зʼявилися 5xx, ви дізнаєтесь про це раніше, ніж просядуть позиції.
  5. Перевірити швидкість. Заміряйте TTFB до і після — це чесна відповідь на питання «а чи був сенс переїжджати».
  6. Перевірити, що бекапи на новому сервері вже налаштовані й реально створюються. Свіжий сервер — це сервер без жодного бекапу.

План відкату: те, чого зазвичай немає

Уся описана схема має вбудований аварійний вихід, і саме він робить перенос спокійним: поки старий сервер живий і його дані не змінювалися, відкат — це зміна одного A-запису назад. Із TTL 300 ви повернетесь на робочу версію за 5–10 хвилин.

Щоб цей вихід працював, дотримуйтесь двох правил:

  • Не видаляйте і не відключайте старий хостинг щонайменше 7–14 днів. Оплатити зайвий місяць дешевше за будь-який аварійний вечір. І тільки після цього періоду знімайте фінальний повний бекап старого сервера — файли плюс дамп БД — і зберігайте його окремо.
  • Розумійте точку невороття. Вона настає не при зміні DNS, а в момент, коли на новому сайті з'явилися нові дані — замовлення, реєстрації, коментарі. Після цього відкат уже означає втрату цих даних. Тому якщо щось пішло не так, вирішувати треба в перші хвилини, а не через дві доби.

Крок 9. Прибирання

  • Через 2–3 доби після переносу підніміть TTL назад до 3600 — інакше ви даремно навантажуєте резолвери і трохи додаєте затримки кожному відвідувачу.
  • Приберіть режим обслуговування зі старого сервера і краще зупиніть на ньому веб-сервер зовсім.
  • Перевірте, що автопродовження Let's Encrypt на новому сервері працює: certbot renew --dry-run.
  • Зніміть фінальний бекап старого сервера й тільки тоді закривайте послугу.

Типові помилки, які я бачу найчастіше

  1. Зміна NS замість A-запису «щоб надійніше». Наслідок — зникла пошта і збита верифікація домену в Google, бо TXT і MX не перенесли в нову зону.
  2. Зниження TTL одночасно зі зміною IP. Класика. Хвіст старого трафіку залишається таким самим довгим, як був.
  3. Перенос без тесту через hosts. Усі проблеми сумісності виявляються під час живого трафіку.
  4. Забуті крони. Виявляється за тиждень, коли клієнт питає, чому не прийшла місячна розсилка.
  5. Старий сервер вимкнули «наступного ранку». Частина відвідувачів із добовим TTL отримала повністю мертвий сайт.
  6. Дамп бази без --single-transaction. На магазині це блокування таблиць і кілька хвилин лежачого сайту саме тоді, коли ви цього не чекали.
  7. Різні версії PHP. Особливо болісно при стрибку через дві мінорні версії: старі теми й модулі падають на змінах у типізації.
  8. Забутий новий IP у whitelist платіжного шлюзу. Сайт працює, оплати проходять, а статуси замовлень не оновлюються, бо callback не доходить.

Чек-лист переносу

За 1–2 дні:

  • виписані версії PHP/MySQL, розширення, розміри даних;
  • зроблений експорт або скріншот усієї DNS-зони;
  • новий IP додано у whitelist платіжок і API-партнерів;
  • TTL для A-записів знижено до 300;
  • сайт і база чорново перенесені на новий сервер;
  • сайт перевірений через hosts: адмінка, форми, завантаження, оплата;
  • SSL-сертифікат випущений через DNS-валідацію;
  • крони перенесені (поки що вимкнені);
  • вирішено, що робимо з поштою.

У день переносу:

  • увімкнено режим обслуговування на старому сайті;
  • зроблена фінальна синхронізація файлів і бази;
  • швидка перевірка через hosts;
  • змінено A-запис;
  • рядок із hosts прибрано;
  • режим обслуговування знято на новому, залишено на старому;
  • крони увімкнені;
  • перевірено dig по 8.8.8.8 і 1.1.1.1.

Протягом тижня:

  • трафік на старому сервері дійшов до нуля;
  • крони відпрацювали хоча б раз;
  • тестова оплата з callback пройшла;
  • Search Console без нових 5xx;
  • бекапи на новому сервері створюються;
  • TTL повернено до 3600;
  • фінальний бекап старого сервера збережений окремо.

Висновок

Перенос без простою — це не швидкість рук, а правильний порядок: спершу знизити TTL, потім перенести й перевірити все на новому сервері під справжнім доменом через hosts, випустити SSL до перемикання, зробити фінальну синхронізацію у «тихому» режимі — і лише потім змінити одне число в DNS. Старий сервер при цьому живе ще два тижні як безкоштовна страховка.

Якщо ви пройшли цим списком і жодна перевірка не червона — переїзд пройде так, що ваші відвідувачі його просто не помітять. А це і є єдиний критерій успішного переносу.

Переносимо ваш сайт безкоштовно. Наша команда виконує весь план вище — від зниження TTL до фінальної перевірки — на NVMe-хостингу, VPS або виділеному сервері uHost. Ви лише підтверджуєте час перемикання.

Хостинг на NVMe Виділені сервери