Subdomain Baru, Migrasi Domain, Tanpa Rusak Login

Server saya di rumah tidak punya IP publik langsung, jadi semua domain yang saya kelola — termasuk pujamalca.my.id — masuk lewat sebuah reverse tunnel ke server di luar, baru diteruskan ke Nginx di mesin lokal. Enak untuk self-hosting, tapi setiap kali mau menambah subdomain baru, saya harus disiplin soal urutan langkahnya. Salah urutan sedikit saja, bisa bikin panik sendiri padahal sebenarnya semua normal.

Urutan yang saya pakai untuk subdomain baru

Waktu menyiapkan medcoder.pujamalca.my.id, urutannya begini: pastikan dulu DNS domain itu sudah menunjuk ke server saya, baru bikin konfigurasi Nginx untuk domain tersebut yang mengarah ke satu port tunnel lokal yang belum dipakai. Setelah itu tes konfigurasi dan reload Nginx, baru minta sertifikat HTTPS otomatis. Pendaftaran pemetaan port di sisi server tunnel saya taruh paling terakhir, bukan di awal.

Konsekuensinya, selama pemetaan tunnel belum didaftarkan, subdomain itu akan menampilkan error 502. Ini wajar dan memang diharapkan — bukan tanda ada yang rusak. HTTPS-nya sudah aktif, redirect http ke https juga sudah jalan, cuma trafiknya belum ada yang diteruskan sampai ke aplikasi karena container di belakangnya memang belum saya nyalakan. Begitu container aplikasi jalan dan pemetaan port didaftarkan, semuanya langsung normal tanpa perlu utak-atik konfigurasi lagi.

Root cause dari "port kosong" yang ternyata tidak kosong

Bagian yang lebih menjebak justru soal memilih port tunnel mana yang benar-benar kosong. Awalnya saya cuma melihat daftar pemetaan yang ada, lalu mengambil angka yang kelihatan belum dipakai. Ternyata itu tidak cukup — beberapa port yang kelihatannya longgar di catatan, diam-diam sudah diarahkan ke situs yang sama oleh konfigurasi proxy lain yang lupa saya bersihkan.

Baru ketahuan setelah saya curl konten homepage dari port tersebut dan membandingkannya dengan situs yang seharusnya. Sejak itu saya selalu melakukan dua pengecekan sebelum memutuskan sebuah port aman dipakai: cek listener yang benar-benar aktif di sisi server tunnel, dan grep semua konfigurasi proxy yang ada untuk memastikan tidak ada yang diam-diam sudah memakainya.

Jebakan kecil di perpanjangan sertifikat

Ada satu jebakan lain yang sempat bikin sertifikat gagal diperpanjang tanpa saya sadari, khusus untuk subdomain yang isinya cuma redirect. Alat perpanjangan sertifikat otomatis butuh menyisipkan sebuah path verifikasi khusus supaya bisa membuktikan saya pemilik domain. Masalahnya, kalau ada aturan "tangkap semua path" (catch-all) yang prioritasnya lebih tinggi di konfigurasi Nginx, path verifikasi itu ikut tertangkap dan tidak pernah sampai ke handler yang benar. Hasilnya perpanjangan sertifikat gagal diam-diam, tidak ada error mencolok, sampai suatu hari sertifikatnya kedaluwarsa. Solusinya sederhana: pastikan aturan untuk path verifikasi selalu dicek lebih dulu, sebelum aturan catch-all apa pun.

Pola tiga fase untuk migrasi domain aplikasi

Pelajaran yang lebih besar datang waktu saya memindahkan sebuah aplikasi dari domain lama ke domain baru. Saya belajar untuk tidak buru-buru redirect. Pola yang sekarang saya pakai selalu tiga fase:

  1. Siapkan domain baru dengan sertifikat HTTPS-nya sendiri, lalu sajikan aplikasi yang sama persis di kedua domain — lama dan baru — secara bersamaan.
  2. Baru ubah konfigurasi internal aplikasi itu sendiri: base URL, link kanonis, daftar origin yang diizinkan, lalu build ulang.
  3. Baru yang paling terakhir, domain lama di-redirect permanen ke domain baru.

Kalau urutan ini dimajukan — redirect dipasang duluan sebelum aplikasi benar-benar siap — akibatnya bisa parah. Redirect permanen otomatis mengubah request POST menjadi GET, dan sesi login biasanya terikat ke domain tertentu. Jadi kalau pengguna sedang login lewat form di domain lama yang sudah di-redirect, prosesnya bisa gagal total: request-nya berubah jadi GET di tengah jalan, sesinya juga tidak nyambung ke domain baru.

Takeaway

Intinya, setiap perubahan yang menyentuh routing publik — subdomain baru maupun migrasi domain — paling aman kalau bagian yang paling "mengunci" jalan keluar (pendaftaran port, redirect permanen) selalu jadi langkah paling terakhir, setelah semua yang lain terbukti jalan lebih dulu. Error yang muncul di tengah proses seperti itu (502, sertifikat gagal diperpanjang) tidak selalu berarti ada yang rusak — kadang itu justru tanda urutannya sedang benar.