Membangkitkan WordPress Lama di Docker Tanpa Jebakan Redirect 301
Container nyala, malah dilempar ke domain produksi. Tiga mekanisme first-run Docker dilewati volume lama, dan wp_options simpan kejutan lain.
Ringkasan
Nyalain WordPress lama di Docker, eh malah diarahkan ke domain produksi karena URL lama masih nempel di wp_options. Ternyata skrip init database dan salin file inti cuma jalan di instalasi baru, jadi kalau pakai volume lama harus restore manual dulu. Warning di log biasanya cuma noise, cukup pantau log database sampai import selesai.
Sudah lama nggak megang situs WordPress produksi lawas, dan tugas saya cuma satu: hidupkan lagi secara lokal di Docker. Container menyala, semua kelihatan sehat. Begitu saya buka di browser, malah dilempar ke domain produksi asli lewat redirect 301. Tebakan pertama saya, pasti cache DNS atau compose saya yang salah. Ternyata dua-duanya nggak bersalah: URL lama itu memang masih tertanam di tabel wp_options, dan tiga mekanisme "pertama kali" di Docker diam-diam nggak pernah jalan karena saya menempelkan volume data lama.
Tiga mekanisme pertama kali yang dilewati diam-diam
Container itu dirancang untuk instalasi bersih, bukan untuk mayat situs yang dibangkitkan. Skrip inisialisasi di docker-entrypoint-initdb.d pada MariaDB cuma jalan saat direktori data benar-benar baru, tepatnya di jalur pembuatan instalasi baru pada entrypoint resminya [10]. Begitu volume database lama ku-pasang, proses import dump SQL itu nggak akan pernah terjadi otomatis. Restorasi harus jalan sendiri, di sisi container database.
Di sisi aplikasi ceritanya mirip. Image WordPress resmi menyalin berkas inti dari /usr/src/wordpress ke /var/www/html saat startup pertama [12], dan itu pun cuma kalau index.php plus wp-includes/version.php belum ada di tujuan [13]. Volume wp-content lama yang sudah berisi plugin hasil restore? Dilewati, biar nggak ditimpa versi bawaan image.
Satu lagi yang sering disalahpahami: WORDPRESS_DB_NAME harus sudah ada di server database; container WordPress nggak mau membuatkannya [12]. Jadi urutannya bukan compose up lalu berdoa, tapi restore database dulu, baru nyalakan WordPress. Untuk WORDPRESS_DB_HOST, nilainya nama service compose plus port, misalnya db:3306, bukan alamat loopback. Dengan data lama, dua mekanisme pertama tadi melewati saya tanpa pesan error, dan hasilnya konfigurasi setengah jalan yang kelihatan "hampir jalan".
Balik ke browser yang dilempar ke domain produksi, bagian yang paling bikin kesal. Cara tercepat: edit baris siteurl dan home di tabel wp_options, atau tambahkan WP_HOME dan WP_SITEURL di wp-config.php [8]. Tapi ada tangkapannya: konstanta WP_HOME itu menimpa nilai home di wp_options tanpa mengubah isi databasenya [9]. Baris lama tetap di sana, nunggu dikoreksi kalau suatu saat konstantanya dilepas. Hard-coding juga menghilangkan editor pengaturan umum di dashboard. Saya pilih koreksi langsung di wp_options untuk kasus restore, dan simpan konstanta buat kasus yang memang mau dikunci permanen.
Di log Apache, jangan panik duluan sama peringatan soal .htaccess bawaan hosting lama, misalnya direktif lsapi_module khas cPanel. File itu memang cuma konfigurasi per-direktori yang dibaca tanpa menyentuh konfigurasi utama server [11]. Apache modern biasanya mengabaikan direktif yang nggak dikenal itu dan cukup mencatat peringatan. Noise, bukan kebakaran.
Supaya import dump nggak jadi boomerang saat container di-recreate, skrip init saya sekarang selalu cek dulu jumlah tabel: kalau skema sudah terisi, import dilewati. Pola idempotent sederhana ini yang bikin restart aman, karena docker-entrypoint-initdb.d sendiri nggak punya konsep "sudah pernah".
Peringatan MariaDB yang kelihatan menakutkan
Terakhir, di log MariaDB ada pesan io_uring_queue_init() failed with errno 1 yang pertama kali saya baca sebagai kerusakan disk. Bukan. Kalau io_uring dinonaktifkan di lingkungan, MariaDB otomatis fallback ke libaio yang lebih tua [14]. Statusnya terlacak resmi di JIRA MariaDB, sifatnya informatif, dan bukan error fatal untuk beban biasa.
Pelajaran kecil dari migrasi ini: hormati mekanisme first-run-nya, jangan lawan. Kalau datanya lama, jalankan restorasi secara eksplisit, koreksi URL di database atau kunci lewat konstanta, dan baca log sampai selesai sebelum memutuskan ada yang rusak. Hampir semua "error" tadi ternyata cuma container yang setia menjalankan aturan instalasi bersihnya.
Satu kebiasaan lagi yang sekarang jadi ritual: setelah compose naik, saya buka log database, bukan halaman situs. Kalau import dump besar berjalan, log itu yang kasih tahu progres; halaman situs justru bisa sempat dilempar ke domain lama dan bikin panik palsu. Dua kali saya nyaris menghapus volume yang ternyata masih sibuk mengimpor. Dari situ saya belajar menahan klik sampai log benar-benar selesai.
Kalau dump-nya besar, proses import bisa berjalan beberapa menit dalam diam. Kebiasaan saya sekarang: biarkan container database tetap hidup, pantau lewat lognya, dan jangan berani memutuskan gagal sebelum log benar-benar berhenti bergerak. Dua kali saya nyaris menghapus volume yang ternyata masih sibuk mengimpor.