SSD Nodes Learn 🎉 VPS mulai $5.50/bln
Panduan Matt ConnorOleh Matt Connor

Cara Memindahkan Server ke VPS Baru

Pelajari cutover server ke VPS baru: inventaris, bangun ulang, sinkronkan data dua kali, turunkan TTL DNS lebih awal, verifikasi, lalu alihkan record.

Migrasikan server ke VPS baru melalui cutover yang dilatih

Untuk memigrasikan server ke VPS baru, perlakukan perpindahan ini sebagai cutover yang dilatih, bukan sekadar penyalinan. Bangun server baru dari awal, sinkronkan data dua kali, buktikan bahwa server baru berfungsi dengan alamat IP-nya sendiri sebelum menyentuh DNS, lalu ubah record dan biarkan server lama tetap berjalan sampai Anda benar-benar yakin. Menyalin byte adalah bagian yang mudah. Urutan operasi menentukan apakah perpindahan berlangsung tanpa masalah atau menimbulkan biaya besar.

Panduan ini membahas satu server Linux yang menjalankan aplikasi web, database, dan sertifikat TLS (transport layer security). Konfigurasi ini mencakup sebagian besar setup satu server. Ada dua host yang terlibat, sehingga setiap contoh menyebutkan dalam komentar host tempat perintah tersebut dijalankan. Alamatnya menggunakan rentang dokumentasi: 198.51.100.10 adalah server lama, 203.0.113.20 adalah server baru.

Baca seluruh runbook sebelum memulai. Langkah pertama, menurunkan TTL DNS, harus dilakukan beberapa hari sebelum langkah yang sebenarnya penting bagi Anda.

Catat inventaris sebelum membuat apa pun

Anda tidak dapat membangun ulang server yang belum dideskripsikan. Luangkan waktu satu jam untuk mencatat fungsi server lama, karena hal yang selalu rusak setelah migrasi adalah hal yang tidak diingat siapa pun: cron job, pengecualian firewall, atau file environment yang berada di luar direktori aplikasi.

Jalankan perintah berikut pada server lama dan simpan output-nya di lokasi yang dapat Anda baca dari server baru.

# old server: packages you asked for, not the dependencies they pulled in
apt-mark showmanual > ~/inv-packages.txt

# old server: what runs now, and what starts at boot
systemctl list-units --type=service --state=running --no-pager > ~/inv-services.txt
systemctl list-unit-files --state=enabled --no-pager >> ~/inv-services.txt
systemctl list-timers --all --no-pager > ~/inv-timers.txt

# old server: what is listening, on which address and port
sudo ss -tulpn > ~/inv-ports.txt

# old server: human accounts, skipping the system ones
awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $3, $6, $7}' /etc/passwd

apt-mark showmanual adalah daftar yang layak disimpan karena hanya mencantumkan hal-hal yang terpasang sebagai dependensi. dpkg --get-selections lengkap pada server yang telah digunakan selama lima tahun dapat menghasilkan dua ribu baris dan tidak memberi informasi tentang tujuan penggunaannya.

Pekerjaan terjadwal dapat tersembunyi di dua tempat, jadi periksa keduanya. Job yang hanya berjalan setiap bulan adalah job yang akan Anda temukan enam minggu setelah migrasi.

# old server: per-user crontabs, then the system drop-ins
for u in $(cut -d: -f1 /etc/passwd); do sudo crontab -lu "$u" 2>/dev/null | sed "s/^/$u: /"; done
sudo ls -la /etc/cron.d /etc/cron.daily /etc/cron.hourly

Selanjutnya, periksa komponen yang bukan file biasa: aturan firewall, sertifikat, database, dan jumlah data yang benar-benar akan dipindahkan.

# old server
sudo ufw status verbose        # or: sudo nft list ruleset
sudo certbot certificates
sudo -u postgres psql -c '\l'  # or: sudo mysql -e 'SHOW DATABASES;'
sudo du -xh --max-depth=1 / | sort -h

certbot certificates mencetak setiap nama sertifikat, domain yang dicakupnya, tanggal kedaluwarsa, dan path file di disk. Output tersebut menjadi daftar pemeriksaan TLS Anda. du -x tetap berada pada satu filesystem, sehingga tidak akan masuk ke volume backup yang di-mount dan melaporkan angka yang sepuluh kali lebih besar.

Ada dua hal yang berada di luar server dan selalu terlupakan. Pertama, pihak ketiga mana pun yang memasukkan alamat IP server Anda ke dalam allowlist: payment gateway, database terkelola, relay SMTP, atau API mitra. Server baru memiliki alamat baru, jadi tambahkan IP baru ke allowlist tersebut sebelum cutover, bukan setelahnya. Kedua, periksa record DNS yang tidak Anda buat sendiri, seperti record MX atau record SPF yang menyebutkan IP lama dalam teks.

Mengapa Anda melakukan rebuild, bukan cloning root filesystem lama

Cloning seluruh root filesystem ke VPS baru terlihat lebih cepat, dan memang demikian, sampai ternyata tidak. Root filesystem yang telah digunakan di production selama bertahun-tahun biasanya berisi konfigurasi yang diedit manual tetapi tidak pernah didokumentasikan, paket dari repository yang sudah tidak ada, serta konfigurasi boot yang dibuat untuk perangkat keras virtual pada platform lama. Anda mengimpor semuanya, termasuk alasan Anda melakukan migrasi.

Rebuild lebih lambat pada hari pertama, tetapi lebih hemat setiap hari setelahnya. Anda menginstal release saat ini, menerapkan hardening dasar, lalu hanya menyalin data: direktori aplikasi, konfigurasi situs, dump database, sertifikat, dan upload pengguna. Apa pun yang tidak dapat Anda jelaskan tidak ikut dipindahkan. Mulai server baru seperti Anda memulai server mana pun, dengan sepuluh menit pertama pada VPS baru, lalu tambahkan service dari inventaris satu per satu dan pastikan setiap service berfungsi sebelum menambahkan service berikutnya.

Kapan pemulihan image atau snapshot merupakan pilihan yang tepat

Ada satu pengecualian yang masuk akal untuk pembangunan ulang. Jika server lama tidak dapat melakukan boot, atau aplikasi tersebut tidak lagi dapat dibangun dari source code, pemulihan image atau snapshot dari provider merupakan pilihan yang praktis. Metode ini memiliki batasan nyata: biasanya hanya berfungsi pada satu provider, dan sering kali hanya dalam satu keluarga plan, karena disk yang dipulihkan mengharapkan perangkat virtual dan penamaan jaringan dari platform tersebut.

Snapshot dari server yang sedang berjalan juga memiliki masalah konsistensi yang sama seperti salinan berbasis file lainnya dari database aktif. Perlakukan pemulihan image sebagai jalur pemulihan, bukan sebagai rencana migrasi, dan baca mengapa snapshot tidak sama dengan backup sebelum menjadikannya dasar rencana.

Cara file berpindah: rsync melalui SSH

Jalankan rsync dari server lama untuk mengirim data ke server baru. Pengiriman biasanya lebih sederhana karena server lama sudah memiliki data tersebut dan dapat membaca seluruhnya di bawah sudo.

# old server: dry run first, and read what it says it will do
sudo rsync -aHAX --dry-run --itemize-changes \
  -e 'ssh -i /root/.ssh/id_ed25519' \
  /srv/app/ deploy@203.0.113.20:/srv/app/

# old server: the real bulk pass
sudo rsync -aHAX --info=progress2 \
  -e 'ssh -i /root/.ssh/id_ed25519' \
  /srv/app/ deploy@203.0.113.20:/srv/app/

Flag tersebut penting. -a mempertahankan permission, timestamp, symbolic link, dan ownership. -H mempertahankan hard link sebagai hard link, bukan memperluasnya menjadi salinan terpisah. -A menyalin POSIX ACL (access control list), sedangkan -X menyalin extended attribute. Tanpa dua flag terakhir tersebut, file yang tampak identik dapat berperilaku berbeda karena label SELinux dan ACL disimpan dalam extended attribute, dan tidak ada mekanisme lain yang mencatatnya.

Dua detail paling sering menyebabkan kegagalan.

Slash di akhir menentukan lokasi data. /srv/app/ berarti isi direktori tersebut. /srv/app berarti direktori itu sendiri. Jika salah, Anda akan mendapatkan /srv/app/app di server baru. Aplikasi kemudian start, tetapi melaporkan file yang hilang karena path yang dikonfigurasikan kini satu tingkat terlalu dangkal.

Dalam sudo, tilde adalah direktori home milik root. Menulis -e 'ssh -i ~/.ssh/id_ed25519' di dalam sudo rsync akan mencari key di /root/.ssh, bukan di direktori home Anda sendiri. Jika key tidak ada di sana, SSH menampilkan Permission denied (publickey), sedangkan rsync menampilkan rsync: connection unexpectedly closed lalu keluar dengan status non-zero. Tulis path key secara lengkap. Jika pesan autentikasi tersebut tetap muncul setelah path diperbaiki, kegagalan publickey memiliki daftar penyebab yang singkat, dan permission direktori di server baru adalah penyebab berikutnya yang perlu diperiksa.

Ownership memerlukan satu keputusan. Jika dijalankan sebagai root, secara default rsync memetakan owner dan group berdasarkan nama. Jadi, file yang dimiliki oleh www-data di server lama akan dimiliki oleh www-data di server baru, meskipun UID (user ID) numeriknya berbeda. Inilah yang Anda inginkan untuk pembangunan ulang. Tambahkan --numeric-ids hanya ketika menyalin filesystem yang account-nya tidak ada di target. Setelah itu, periksa hasilnya dengan ls -ln karena file yang dimiliki oleh UID tanpa account yang sesuai akan ditampilkan sebagai angka saja, dan setiap service yang membacanya akan ditolak aksesnya.

Jalankan penyalinan awal beberapa hari sebelumnya, saat server lama masih melayani trafik. Ulangi sesering yang diperlukan. rsync hanya mengirim perubahan, sehingga penyalinan kedua memerlukan waktu beberapa menit, bukan beberapa jam. Penyalinan terakhir, dalam window cutover, menambahkan --delete agar file yang dihapus dari server lama juga dihapus dari server baru.

# old server: final pass, inside the window, after the app has stopped writing
sudo rsync -aHAX --delete --info=progress2 \
  -e 'ssh -i /root/.ssh/id_ed25519' \
  /srv/app/ deploy@203.0.113.20:/srv/app/

--delete menghapus file di destination yang sudah tidak ada di source. Karena itu, path source yang salah ditambah --delete dapat mengosongkan direktori destination. Jalankan terlebih dahulu dengan --dry-run setiap kali. Transfer yang lama juga dapat terputus ketika sesi SSH di laptop Anda terputus. Karena itu, jalankan transfer di dalam tmux atau screen pada server lama. Tambahkan --bwlimit=20M jika penyalinan memenuhi kapasitas link saat server lama masih melayani pengguna.

Perpindahan database: dump native

Database bukan direktori berisi file, meskipun tampak seperti itu. Database terdiri atas file, status dalam memori, dan write-ahead log. Data hanya konsisten pada waktu yang ditentukan oleh database itu sendiri. Gunakan tool bawaannya.

PostgreSQL memerlukan dua dump karena role berlaku di seluruh cluster dan pg_dump tidak menyertakannya:

# old server
sudo -u postgres pg_dumpall --globals-only -f /var/backups/globals.sql
sudo -u postgres pg_dump -Fc -f /var/backups/appdb.dump appdb
# new server: restore in this order
sudo -u postgres psql -f /var/backups/globals.sql
sudo -u postgres createdb -O appuser appdb
sudo -u postgres pg_restore -d appdb --no-owner /var/backups/appdb.dump

Jika globals.sql dilewati, semua tabel akan dipulihkan, tetapi tidak ada application role yang dapat membacanya. Penyebabnya, pernyataan GRANT merujuk ke user yang tidak ada. -Fc menulis format custom archive. Format ini hanya dapat dibaca oleh pg_restore dan memungkinkan Anda memulihkan tabel tertentu nanti. Pulihkan ke major version yang sama atau yang lebih baru. Pemulihan ke versi sebelumnya, misalnya dari 17 ke 16, tidak didukung. pg_restore akan menolak archive dengan error unsupported-version pada file header sebelum menulis apa pun.

MySQL dan MariaDB menggunakan satu perintah dengan empat opsi yang tidak aktif secara default:

# old server
sudo mysqldump --single-transaction --routines --triggers --events \
  --databases appdb > /var/backups/appdb.sql
# new server
sudo mysql < /var/backups/appdb.sql

--single-transaction mengambil snapshot yang konsisten tanpa memblokir writer, tetapi hanya untuk tabel InnoDB. Tabel MyISAM dalam database yang sama disalin tanpa jaminan tersebut. Karena itu, periksa storage engine sebelum mempercayai dump. --routines, --triggers, dan --events tidak aktif secara default. Artinya, plain dump memulihkan data, tetapi diam-diam tidak menyertakan stored procedure dan scheduled event. User database dan grant-nya berada di system database mysql. Database ini tidak pernah diproses oleh dump --databases appdb. Karena itu, buat ulang user dan grant tersebut di server baru dengan CREATE USER dan GRANT. MariaDB 11 merilis tool yang sama dengan nama mariadb-dump dan mempertahankan mysqldump sebagai symbolic link. Jadi, kedua nama tersebut dapat digunakan per August 2026.

SQLite adalah satu file. Menyalin file tersebut saat aplikasi sedang menulis dapat menghasilkan file yang tidak utuh. SQLite memiliki cara aman sendiri:

# old server
sqlite3 /var/lib/app/app.db ".backup '/var/backups/app.db'"

Apa pun engine yang digunakan, periksa dump sebelum mempercayainya. Dump yang berhenti lebih awal karena disk penuh tetap dapat dipulihkan tanpa error, hingga proses pemulihan mencapai bagian tempat dump tersebut terpotong.

# old server: a complete mysqldump ends with a line reading "-- Dump completed on ..."
tail -n 3 /var/backups/appdb.sql

# new server: after restore, count rows in a table whose size you know
sudo mysql -e 'SELECT COUNT(*) FROM appdb.orders;'

Mengapa Anda tidak dapat menggunakan rsync untuk database yang sedang berjalan

rsync menyalin file satu per satu. Database yang sedang berjalan menulis ke beberapa file secara bersamaan. Saat rsync mencapai file terakhir, file pertama sudah tidak lagi mutakhir. Salinan tersebut berisi halaman dari waktu yang berbeda, sehingga mencerminkan keadaan yang tidak pernah dimiliki database. Akibatnya, server dapat menolak untuk start. Dalam kasus yang lebih buruk, server dapat start dan memberikan jawaban yang benar selama seminggu, lalu gagal ketika sebuah query akhirnya mengakses halaman yang rusak. Tidak ada peringatan sebelum kegagalan tersebut.

Ada dua cara yang aman untuk memindahkan file itu sendiri. Hentikan database, salin file, lalu start kembali. Cara ini benar dan sederhana, tetapi downtime berlangsung selama proses penyalinan. Cara lainnya adalah menggunakan tool yang dibuat untuk menyalin server yang sedang berjalan secara fisik. Untuk PostgreSQL, tool tersebut adalah pg_basebackup. Tool ini berkoordinasi dengan server agar salinan tetap konsisten:

# new server: pull a physical copy from the old one
pg_basebackup -h 198.51.100.10 -U replicator -D /var/lib/postgresql/16/main -X stream -P

Cara ini memerlukan role dengan atribut REPLICATION dan entri pg_hba.conf yang sesuai pada server lama. Karena itu, konfigurasinya lebih rumit daripada dump. Cara ini layak digunakan jika ukuran database cukup besar sehingga proses dump dan restore tidak dapat diselesaikan dalam window yang tersedia. Untuk migrasi single-server biasa, dump merupakan pilihan yang lebih baik.

Bangun ulang sertifikat sebelum cutover, bukan setelahnya

Sertifikat TLS terikat pada nama domain, bukan alamat IP, sehingga file sertifikat dapat dipindahkan tanpa masalah. Namun, proses perpanjangan tidak dapat dipindahkan dengan mudah. Tantangan HTTP-01 default Certbot meminta certificate authority mengambil file melalui port 80 pada nama yang sedang disertifikasi. Sebelum DNS mengarah ke server baru, permintaan tersebut akan sampai ke server lama dan proses perpanjangan pada server baru gagal.

Opsi pertama adalah menyalin sertifikat yang ada beserta status perpanjangannya. Sertifikat tetap valid hingga tanggal kedaluwarsanya, di server mana pun sertifikat tersebut disimpan.

# old server
sudo rsync -aHAX -e 'ssh -i /root/.ssh/id_ed25519' \
  /etc/letsencrypt/ root@203.0.113.20:/etc/letsencrypt/

Setiap file di bawah /etc/letsencrypt/renewal/ mencantumkan plugin authenticator yang menerbitkan sertifikat tersebut. Karena itu, instal plugin yang sama pada server baru (misalnya python3-certbot-nginx), atau perpanjangan pertama akan gagal dengan pesan tentang authenticator yang tidak dikenal. Pastikan proses perpanjangan berhasil sebelum mengandalkannya:

# new server, after DNS has moved
sudo certbot renew --dry-run

Opsi kedua adalah menerbitkan sertifikat baru pada server baru menggunakan tantangan DNS-01. Tantangan ini membuktikan kendali melalui record TXT dan tidak pernah menggunakan port 80. Cara ini dapat dilakukan sebelum migrasi, saat nama tersebut masih mengarah ke server lama. Karena itu, opsi ini lebih bersih jika Anda dapat mengotomatiskan penyedia DNS. Menerbitkan sertifikat dengan tantangan DNS-01 membahas konfigurasi plugin dan kredensial.

Apa pun pilihannya, periksa sertifikat yang benar-benar disajikan server baru tanpa mengubah DNS:

# your laptop
echo | openssl s_client -connect 203.0.113.20:443 -servername example.com 2>/dev/null \
  | openssl x509 -noout -subject -dates -issuer

-servername mengirimkan SNI (server name indication), yang membuat web server memilih virtual host yang tepat. Jika opsi ini dihilangkan, Anda akan menerima sertifikat default untuk IP tersebut dan terjadi ketidakcocokan yang terlihat seperti masalah nyata, padahal bukan.

Turunkan hari TTL DNS sebelum pengalihan

DNS sering menjadi bagian yang gagal dalam migrasi yang sudah direncanakan dengan baik, karena penundaan sudah melekat dan tidak dapat dipersingkat pada hari pengalihan. Resolver yang telah menyimpan record A Anda dalam cache akan terus menyajikannya selama TTL (time to live) yang diterimanya. Menurunkan TTL sekarang tidak berdampak pada resolver yang menyimpan record tersebut dalam cache sepuluh menit lalu dengan nilai lama: resolver itu mempertahankan nilai lama selama sisa TTL lama, lalu baru mempelajari nilai baru yang lebih singkat. Jadi, turunkan TTL setidaknya satu periode TTL lama penuh sebelum pengalihan. Melakukannya satu hari sebelumnya merupakan pilihan yang lebih aman. Jika komponen-komponen ini masih baru bagi Anda, panduan record, resolver, dan caching menjelaskan dasar-dasarnya.

Angka-angka di bawah ini merupakan perhitungan dari TTL itu sendiri, bukan hasil pengukuran.

ChartHow long a stale IP can survive, by record TTL
The data behind this chart
[
  {
    "label": "TTL 3600 s (common default)",
    "ttl_seconds": 3600,
    "worst_case_stale_minutes": 60
  },
  {
    "label": "TTL 900 s",
    "ttl_seconds": 900,
    "worst_case_stale_minutes": 15
  },
  {
    "label": "TTL 300 s (lowered for cutover)",
    "ttl_seconds": 300,
    "worst_case_stale_minutes": 5
  },
  {
    "label": "TTL 60 s (short window)",
    "ttl_seconds": 60,
    "worst_case_stale_minutes": 1
  }
]

Record yang dipublikasikan dengan TTL sebesar 3600 detik dapat terus mengarahkan pengguna ke IP lama selama 60 menit setelah Anda mengubahnya. Turunkan nilainya menjadi 300 detik, dan kondisi terburuk tersebut berkurang menjadi 5 menit. Anggap angka-angka tersebut sebagai batas minimum, bukan jaminan. Beberapa resolver menerapkan TTL minimum sendiri dan mengabaikan nilai yang lebih singkat. Beberapa runtime aplikasi juga menyimpan alamat yang telah di-resolve dalam cache selama proses berjalan. Akibatnya, client yang dimulai sebelum perubahan Anda mungkin tidak melakukan pencarian ulang sampai proses tersebut dimulai ulang.

Saat memeriksa apakah TTL yang lebih singkat sudah aktif, baca jawaban authoritative, bukan cache Anda sendiri:

# your laptop: ask the zone's own nameserver, so no cache is involved
dig +short NS example.com
dig +noall +answer @$(dig +short NS example.com | head -n1) example.com A

Field kedua pada baris jawaban tersebut adalah TTL dalam detik. Selanjutnya, periksa record yang sering terlupakan: record AAAA jika server lama menggunakan IPv6, nama www jika merupakan record A terpisah, bukan CNAME, record MX apa pun yang mengarah ke server itu sendiri, record SPF yang mencantumkan IP lama, serta reverse DNS (record PTR) pada alamat baru. Atur PTR melalui control panel provider Anda sebelum pengalihan jika server mengirim email, karena mail server penerima memeriksa record tersebut. PTR yang tidak ada dapat menyebabkan email ditolak beberapa jam setelah bagian lain tampak berjalan normal.

Verifikasi server baru menggunakan alamat IP-nya sebelum mengubah DNS

Anda dapat menguji seluruh aplikasi pada server baru saat DNS masih mengarah ke server lama. Timpa pencarian nama untuk satu permintaan:

# your laptop: force one name to the new IP, for this request only
curl -sS --resolve example.com:443:203.0.113.20 \
  -o /dev/null -w '%{http_code} %{ssl_verify_result}\n' https://example.com/

--resolve hanya mengubah tujuan koneksi. Sertifikat TLS tetap diverifikasi terhadap nama sebenarnya. Dengan demikian, pengujian ini membuktikan sertifikat dan service. %{ssl_verify_result} menampilkan 0 jika rantai sertifikat berhasil diverifikasi.

Untuk menelusuri situs melalui browser, timpa nama tersebut untuk seluruh komputer dengan menambahkan satu baris ke /etc/hosts pada laptop Anda, atau ke C:\Windows\System32\drivers\etc\hosts pada Windows:

203.0.113.20 example.com www.example.com

Kemudian gunakan aplikasi seperti pengguna biasa. Login. Muat halaman yang membaca data dari database. Kirim formulir yang menulis data ke database. Upload file dan pastikan file tersebut tersimpan di disk. Jalankan fitur yang mengirim email, lalu pastikan email tersebut diterima, karena SMTP keluar dari IP baru sering menimbulkan masalah yang tidak terduga. Hapus baris hosts segera setelah selesai. Jika baris tersebut dibiarkan, Anda dapat menghabiskan waktu satu jam untuk men-debug situs yang sebenarnya dapat dilihat dengan baik oleh semua pengguna lain.

Pemindahan, langkah demi langkah

  1. Beberapa hari sebelumnya: turunkan TTL, jalankan rsync massal, siapkan server baru, lalu uji server tersebut menggunakan penggantian hosts.
  2. Pada hari pelaksanaan, sebelum periode pemindahan: tambahkan IP baru ke setiap allowlist pihak ketiga, lalu pastikan job backup server baru sudah dikonfigurasi dan diarahkan ke repository Anda.
  3. Saat periode pemindahan dimulai: aktifkan maintenance mode pada aplikasi di server lama agar aplikasi berhenti menerima penulisan.
  4. Buat dump database terakhir, lalu jalankan tahap rsync terakhir dengan --delete.
  5. Pulihkan dump pada server baru, lalu start service.
  6. Uji kembali melalui --resolve dan penggantian hosts, termasuk melakukan satu penulisan nyata.
  7. Ubah record A dan AAAA ke IP baru.
  8. Pantau kedua server. Access log server lama menunjukkan siapa yang masih mengaksesnya, dan jumlahnya seharusnya turun menuju nol selama TTL berlaku.
  9. Nonaktifkan halaman pemeliharaan.
  10. Biarkan server lama tetap berjalan tanpa diubah selama setidaknya satu minggu.

Langkah maintenance mode adalah langkah yang sering dilewati. Padahal, langkah inilah yang melindungi Anda. Setelah database baru menerima penulisan, rollback berarti kehilangan penulisan tersebut atau membuat dump database baru lalu memuatnya kembali ke database lama. Periode read-only selama beberapa menit tidak mahal. Dua database yang sama-sama menerima penulisan dapat memerlukan rekonsiliasi manual selama berhari-hari.

Rencana rollback

Rollback adalah satu tindakan: kembalikan record DNS ke 198.51.100.10. Tindakan ini hanya dapat dilakukan karena empat hal yang Anda kerjakan sebelumnya.

  • Server lama masih berjalan dengan service aktif dan data tetap utuh. Anda menghentikan penulisan data di sana, bukan menonaktifkan server tersebut.
  • TTL masih rendah, sehingga jalur kembali sama cepatnya dengan proses perpindahan sebelumnya.
  • Anda menambahkan IP baru ke allowlist pihak ketiga, bukan mengganti IP lama. Jika alamat lama dihapus, jalur rollback akan gagal pada payment gateway.
  • Server baru tidak menerima penulisan data yang tidak dapat Anda identifikasi, karena sejauh ini satu-satunya penulisan data berasal dari transaksi pengujian Anda sendiri.

Tentukan sebelum periode pemeliharaan dimulai kondisi yang memicu rollback. Dua pemicu sudah cukup: error apa pun yang tidak dapat Anda diagnosis dalam jumlah menit yang telah ditetapkan, dan kehilangan data sekecil apa pun. Menuliskannya terlebih dahulu akan mencegah waktu terbuang untuk menebak-nebak, yang dapat mengubah gangguan selama sepuluh menit menjadi gangguan yang panjang.

Buktikan bahwa migrasi berhasil

Migrasi belum selesai saat situs dapat dimuat. Periksa hal-hal yang baru gagal kemudian.

# new server
systemctl --failed
journalctl -p err -b --no-pager | tail -n 40
sudo certbot certificates
sudo systemctl list-timers --all --no-pager

systemctl --failed pelaporan 0 loaded units listed adalah hasil yang Anda inginkan. certbot certificates harus menampilkan tanggal kedaluwarsa yang diharapkan, dan list-timers harus menampilkan setiap job terjadwal dari inventaris Anda dengan waktu eksekusi berikutnya yang valid, bukan kolom kosong.

Selanjutnya, reboot server baru sekali dengan sengaja sambil memantaunya. Service yang dijalankan seseorang secara manual tetapi tidak pernah diaktifkan akan berfungsi sempurna sampai reboot pertama yang tidak direncanakan pada pukul tiga pagi.

# new server
sudo reboot

# your laptop, once it comes back
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com/

Jika aplikasi berjalan dalam container, jebakan yang sama memiliki bentuk berbeda, karena stack compose memerlukan kebijakan restart eksplisit agar dapat berjalan kembali setelah reboot.

Pemeriksaan terakhir adalah yang paling mudah ditunda dan paling penting: job backup. Migrasi yang berakhir dengan server tanpa backup hanya mengganti satu risiko dengan risiko lain. Jalankan backup secara manual pada server baru, lalu restore satu file dari backup tersebut ke direktori sementara. Repository restic dengan restore yang benar-benar telah diuji adalah bentuk yang membantu saat Anda membutuhkannya. Jika server lama dan baru dijalankan berdampingan selama seminggu, cara yang konsisten untuk mengakses dan mengonfigurasi setiap host mencegah keduanya menyimpang saat masih aktif.

Setelah cutover: server lama dan langkah terakhir

Pertahankan server lama selama satu hingga dua minggu. Biayanya hanya satu bulan paket yang memang akan Anda batalkan, dan server tersebut adalah satu-satunya opsi rollback yang Anda miliki. Setelah itu, selesaikan langkah-langkah lainnya.

  • Menggunakan kembali hostname yang sama dalam ~/.ssh/config untuk server baru akan menyebabkan WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! pada koneksi pertama, karena hostname tersebut kini merespons dengan host key yang berbeda. Hapus entri lama dengan ssh-keygen -R example.com setelah Anda memastikan alasan perubahannya, bukan secara refleks, karena peringatan yang sama juga dapat menunjukkan serangan intersepsi. Migrasi juga merupakan waktu yang tepat untuk meninjau key mana yang dapat mengakses apa. Hal inilah yang dibahas dalam manajemen SSH key pada fleet kecil.
  • Buat satu snapshot atau backup terakhir server lama, lalu simpan di lokasi yang bukan milik provider lama.
  • Hapus IP lama dari pemeriksaan monitoring, record SPF, dan allowlist pihak ketiga, dalam urutan tersebut dan sebagai langkah terakhir.
  • Batalkan paket lama hanya setelah salinan terakhir tersebut dipastikan dapat dibaca di lokasi lain.

FAQ

Berapa lama waktu yang diperlukan untuk memigrasikan server ke VPS baru?

Gangguan yang terlihat oleh pengguna biasanya hanya mencakup dump database terakhir, proses rsync terakhir, dan saat service dijalankan. Untuk aplikasi kecil, proses ini biasanya memerlukan sepuluh hingga tiga puluh menit. Waktu kalendernya lebih lama karena TTL DNS harus diturunkan setidaknya satu periode TTL lama sebelum perpindahan. Menurunkannya sehari sebelumnya lebih aman. Jadwalkan juga penyalinan data utama beberapa hari lebih awal. Proses ini berjalan pada server yang aktif. Jika diulangi nanti, hanya data yang berubah sejak proses sebelumnya yang ditransfer.

Apakah saya dapat menjalankan rsync pada database MySQL atau PostgreSQL yang sedang berjalan, tanpa membuat dump?

Tidak. rsync menyalin file satu per satu ketika database menulis ke beberapa file secara bersamaan. Akibatnya, salinan dapat berisi halaman dari waktu yang berbeda dan merepresentasikan keadaan yang tidak pernah dimiliki database. Database mungkin menolak untuk berjalan, atau berhasil berjalan lalu gagal ketika query mengakses halaman yang rusak. Gunakan pg_dump dengan pg_dumpall --globals-only, atau mysqldump --single-transaction. Alternatifnya, hentikan database terlebih dahulu, lalu salin file-nya. Untuk cluster PostgreSQL berukuran besar, pg_basebackup membuat salinan fisik yang konsisten dari server yang sedang berjalan.

Bagaimana cara menguji VPS baru sebelum mengubah DNS?

Ubah hasil pencarian nama pada komputer Anda sendiri. Untuk satu request, curl --resolve example.com:443:203.0.113.20 https://example.com/ mengarahkan koneksi ke IP baru, tetapi tetap memeriksa sertifikat berdasarkan nama sebenarnya. Untuk pengujian melalui browser, tambahkan 203.0.113.20 example.com ke /etc/hosts pada laptop Anda. Lakukan login, pembacaan database, pengiriman formulir, dan upload file. Setelah itu, hapus baris tersebut. Untuk memeriksa sertifikat saja, jalankan openssl s_client -connect 203.0.113.20:443 -servername example.com.

TTL apa yang harus saya gunakan, dan kapan harus menurunkannya?

Turunkan record A dan AAAA menjadi 300 detik. Lakukan ini setidaknya satu periode TTL lama penuh sebelum perpindahan. Resolver yang menyimpan record sebelum perubahan Anda akan mempertahankan nilai lama selama sisa TTL lama. Jadi, menurunkannya satu jam sebelumnya tidak berpengaruh jika TTL lama adalah 86400. Kembalikan nilainya ke nilai normal beberapa hari setelah migrasi, setelah access log server lama tidak lagi mencatat aktivitas.

Apakah saya harus menyalin sertifikat TLS atau menerbitkan yang baru di server baru?

Keduanya dapat digunakan. Menyalin /etc/letsencrypt/ membuat sertifikat tetap valid hingga tanggal kedaluwarsa yang sudah ditetapkan. Namun, Anda harus memasang plugin authenticator certbot yang sama di server baru. Jika tidak, pembaruan pertama akan gagal. Jalankan certbot renew --dry-run setelah perpindahan DNS untuk memastikan semuanya berfungsi. Menerbitkan sertifikat baru lebih bersih jika Anda dapat menggunakan challenge DNS-01 karena metode ini membuktikan kendali melalui record TXT dan dapat digunakan sebelum DNS mengarah ke server baru. Challenge HTTP-01 tidak dapat digunakan pada server baru sebelum DNS dipindahkan karena request validasi akan mencapai server lama.