Migracja jest zmianą systemu, nie tylko hosta#

Serwer produkcyjny rzadko działa samodzielnie. Nawet prosta aplikacja może zależeć od DNS, SMTP, bazy danych, zewnętrznego API, certyfikatów, storage, harmonogramów, monitoringu i reguł sieciowych. Skopiowanie katalogu /opt/app nie odtwarza tych zależności.

Przed rozpoczęciem odpowiedz na trzy pytania:

  1. Co dokładnie ma zostać przeniesione?
  2. Jak udowodnimy, że nowa instancja działa poprawnie?
  3. Jak wrócimy, jeżeli kryteria nie zostaną spełnione?

Brak odpowiedzi na trzecie pytanie oznacza, że nie ma planu migracji — jest tylko plan wdrożenia.

Inwentaryzacja: stan faktyczny zamiast dokumentacji historycznej#

Dokumentacja bywa nieaktualna, dlatego inwentaryzacja powinna łączyć informacje deklarowane z obserwacją systemu. Zbierz:

  • system operacyjny, wersję kernela i architekturę,
  • jednostki systemd, kontenery i procesy uruchamiane ręcznie,
  • porty nasłuchujące i połączenia wychodzące,
  • reguły firewall, routing, NAT i dodatkowe ACL dostawcy,
  • wolumeny, mounty, katalogi danych i uprawnienia,
  • bazy danych, użytkowników, rozszerzenia i harmonogram backupu,
  • zadania cron oraz timery systemd,
  • konfigurację Nginx/Apache, domeny i certyfikaty,
  • sekrety, pliki .env i sposób ich rotacji,
  • integracje: SMTP, webhooki, API, monitoring i DNS.

Przykładowy zestaw poleceń kontrolnych:

bash
systemctl list-units --type=service --state=running
ss -lntup
findmnt
crontab -l
systemctl list-timers --all
docker compose ls
docker ps --format '{{.Names}}\t{{.Image}}\t{{.Ports}}'

Nie kopiuj wyników bez interpretacji. Proces może być pozostałością po starej wersji, a otwarty port może być nieużywany. Dla każdej pozycji określ właściciela, cel i krytyczność.

Zdefiniuj kryteria akceptacji przed budową nowego hosta#

Kryterium „strona się otwiera” jest niewystarczające. Dobra lista obejmuje ścieżki użytkownika i operacje techniczne:

ObszarPrzykładowe kryterium
HTTPwszystkie domeny zwracają właściwy kod i canonical redirect
TLSpoprawny łańcuch, hostname i automatyczne odnowienie
Aplikacjalogowanie, formularz, upload lub transakcja działają końcowo
Daneliczba rekordów i punkt kontrolny są zgodne
IntegracjeSMTP, płatności, webhooki i API przechodzą test
Operacjehealthcheck, backup, monitoring i logrotate są aktywne
Wydajnośćczas odpowiedzi oraz użycie zasobów nie pogorszyły się poza próg

Kryteria powinny być możliwe do wykonania przed i po przełączeniu. Dzięki temu porównujesz stary i nowy system tym samym testem.

Zbuduj nowy serwer jako powtarzalne środowisko#

Nowy host nie powinien być ręcznie odtwarzaną kopią starego. Warto uporządkować instalację:

  • aktualny wspierany system operacyjny,
  • minimalny zestaw pakietów,
  • osobny użytkownik wdrożeniowy,
  • SSH z kluczami i ograniczonym dostępem,
  • firewall tworzony przed wystawieniem usług,
  • Docker Compose lub jednoznaczne jednostki systemd,
  • Nginx jako reverse proxy,
  • automatyczne certyfikaty,
  • logowanie i rotacja,
  • monitoring liveness, readiness i TLS.

Jeżeli aplikacja jest konteneryzowana, obraz powinien być zbudowany z wersjonowanego źródła, a dane przechowywane poza warstwą kontenera. Nie traktuj docker commit jako procesu wydawniczego.

Zaplanuj migrację danych według poziomu spójności#

Dane statyczne można zwykle zsynchronizować wcześniej. Baza transakcyjna wymaga kontrolowanego punktu odcięcia. Wybierz strategię:

  • pełna przerwa zapisu — zatrzymanie aplikacji, finalny backup, restore i start,
  • replikacja — synchronizacja w tle i przełączenie po dogonieniu repliki,
  • dual write — rzadziej stosowane, bardziej ryzykowne bez przygotowania aplikacji,
  • eksport/import logiczny — dobry przy zmianie wersji lub selektywnej migracji,
  • snapshot blokowy — szybki, ale wymaga oceny spójności aplikacyjnej.

Dla każdej metody określ maksymalną utratę danych (RPO) i akceptowalny czas niedostępności (RTO). Jeżeli formularz kontaktowy przyjmuje dane podczas kopiowania bazy, musisz wiedzieć, gdzie trafią wiadomości wysłane pomiędzy pierwszym i finalnym sync.

Przed cutover wykonaj próbny restore. Backup, którego nigdy nie odtworzono, jest tylko założeniem.

DNS, certyfikaty i ruch przychodzący#

Kilka dni przed zmianą obniż TTL rekordów, ale zachowaj świadomość, że cache nie zniknie wszędzie natychmiast. Nowy serwer powinien obsługiwać domenę jeszcze przed publicznym przełączeniem. Do testów można użyć wpisu w lokalnym hosts lub żądania z nadpisanym nagłówkiem Host i właściwym adresem.

Certyfikat można wystawić przez HTTP-01, DNS-01 albo przenieść istniejący materiał zgodnie z polityką. Najbezpieczniej jest przygotować automatyczne odnawianie na nowym hoście i wykonać certbot renew --dry-run.

Podczas okresu propagacji oba serwery mogą otrzymywać ruch. Jeżeli aplikacja przyjmuje zapisy, trzeba zapewnić wspólne dane albo jasno wyznaczyć moment, po którym stary host przestaje obsługiwać zapisy.

Cutover powinien być krótką, opisaną sekwencją#

Przykładowa runbook:

  1. Ogłoś rozpoczęcie okna i zamroź zmiany konfiguracji.
  2. Uruchom tryb maintenance lub zatrzymaj zapis.
  3. Wykonaj finalną synchronizację danych.
  4. Potwierdź checksumy, wersję schematu i liczbę rekordów.
  5. Uruchom aplikację na nowym serwerze.
  6. Wykonaj lokalny smoke test po adresie nowego hosta.
  7. Przełącz DNS, floating IP, load balancer albo routing.
  8. Wykonaj publiczny smoke test.
  9. Obserwuj logi, metryki, kolejki i integracje.
  10. Zakończ maintenance dopiero po spełnieniu kryteriów.

Każdy krok powinien mieć właściciela, oczekiwany wynik i limit czasu. Jeżeli krok przekracza limit, uruchamiasz zdefiniowaną decyzję: kontynuacja, pauza albo rollback.

Rollback: powrót obejmuje również dane#

Najprostszy rollback ruchu to przywrócenie poprzedniego DNS lub adresu. To nie wystarczy, jeśli nowy system przyjął zapisy. Trzeba zdecydować, czy:

  • nowe dane zostaną przeniesione z powrotem,
  • okno zapisu zostanie zamknięte do czasu decyzji,
  • utrata danych jest akceptowana i udokumentowana,
  • stary system może odczytać schemat zmieniony przez nową wersję.

Migracja połączona z upgrade bazy lub aplikacji komplikuje rollback. Rozdzielenie zmiany hosta od zmiany wersji zmniejsza liczbę zmiennych. Jeśli to możliwe, najpierw uruchom tę samą wersję na nowej infrastrukturze, a dopiero po stabilizacji wykonaj upgrade.

Stabilizacja po migracji#

Po sukcesie nie usuwaj od razu starego hosta. Przez uzgodniony okres monitoruj:

  • błędy HTTP i aplikacji,
  • opóźnienia oraz wykorzystanie CPU, RAM i dysku,
  • stan bazy, replikacji i kolejek,
  • powodzenie backupu,
  • formularze, e-mail i webhooki,
  • wygasanie certyfikatu,
  • nieoczekiwany ruch kierowany nadal na stary adres.

Wykonaj również restart kontrolowany nowego hosta. System, który działa tylko do pierwszego rebootu, nie jest gotowy produkcyjnie. Sprawdź kolejność usług, automatyczny start kontenerów, mounty oraz odblokowanie sekretów.

Checklista zakończenia#

  • Wszystkie kryteria akceptacji przeszły po publicznym przełączeniu.
  • Monitoring zewnętrzny widzi nowy system.
  • Backup po migracji został wykonany i zweryfikowany.
  • Certyfikat ma aktywne automatyczne odnowienie.
  • Logi nie pokazują starych adresów, błędów integracji ani rosnących kolejek.
  • Dokumentacja, diagram i dane dostępowe zostały zaktualizowane.
  • Stary host jest odłączony od ruchu, ale zachowany zgodnie z planem rollback.
  • Termin ostatecznego usunięcia starej infrastruktury jest zapisany.

Bezpieczna migracja jest nudna w dobrym znaczeniu tego słowa: każdy krok jest oczekiwany, wynik mierzalny, a decyzja o powrocie przygotowana zanim pojawi się presja.