#Migration

ย้ายเว็บ .aspx เก่าทั้งเว็บ ทำเป็น catalog JSON แล้วคัดรูปขยะออกเอง
เจ้าของเว็บ .aspx เก่าขอให้ทำเว็บใหม่ แต่เนื้อหาสิบกว่าปีอยู่ในฐานข้อมูลที่เข้าไม่ถึงแล้ว ผมเลยไล่เก็บหน้าเว็บของเขาเองมาทำเป็น catalog JSON ที่คง legacy_id ไว้ทั้งหมด แล้วเขียนตัวคัดรูปสามชั้นกันไม่ให้ QR ของแถมกลายเป็นรูปปกบทความ

time-series เป็น JSON โตวันละ 50 MB ย้ายลงคอลัมน์โดยไม่แก้ dashboard
เก็บค่าที่อ่านจากอุปกรณ์ทั้งเฟรมเป็น JSON array วินาทีละแถว ผ่านไปสองสัปดาห์ตารางโต 183 MB ที่ปลายทางและ 625 MB บนเซิร์ฟเวอร์ พร้อมกับ JSON_EXTRACT ที่ทำ index ไม่ได้ — วิธีย้ายไปเก็บเป็นคอลัมน์ int แล้วให้ API ประกอบ array คืนแบบ sparse เพื่อไม่ให้ dashboard รู้ตัวสักบรรทัด

โค้ดชุดเดียวสองบทบาท เว็บอยู่โฮสต์ worker อยู่เครื่องที่บ้าน
ระบบทั้งตัวเคยวิ่งอยู่บนเครื่องเดียวหลังเน็ตบ้าน เครื่องดับทีเดียวทีมใช้อะไรไม่ได้เลย ผมเลยแยกเป็นสองบทบาทด้วยโค้ดชุดเดิม — เว็บอยู่โฮสต์ที่เปิดตลอด งานหนักอยู่เครื่องที่บ้านแล้ววิ่งมาดึงงานเอง พร้อมตาราง claim แบบ atomic และแผนสลับ 18 ขั้นที่มีทางถอย

มี backup ครบทุกไฟล์ แต่สร้างเครื่องใหม่ไม่ได้
dump ฐานข้อมูลครบ tar โค้ดครบ ไฟล์ความลับครบ แต่พอเอาไปวางบนเครื่องเปล่าแล้วเว็บไม่ขึ้น เพราะของที่ทำให้เครื่องทำงานได้จริงไม่เคยอยู่ในไฟล์ backup เลย บทความนี้คือรายการของที่หายไปกับเครื่อง และลำดับกู้ที่ผมเขียนไว้ให้ตัวเองในอนาคต

charset ไม่ตรง ทำ index ตายเงียบ ตอน JOIN ข้ามฐาน — mirror utf8mb4
ฐานเก่าเป็น tis620 ฐานใหม่เป็น utf8mb4 พอ JOIN ข้าม database ปุ๊บ index ทุกตัวกลายเป็นของประดับทันทีโดยไม่มี error สักบรรทัด — วิธีพิสูจน์ด้วย EXPLAIN และวิธีทำ mirror แปลง tis620 เป็น utf8mb4 ตอน dump พร้อมกับดัก sed ที่ทำตารางพังเงียบ ๆ

ย้ายบอร์ด vBulletin 4.2.5 ไป Flarum: บทเรียนจากสองแสนโพสต์
ย้ายฟอรัมเก่า vBulletin 4.2.5 ที่มีสมาชิกเจ็ดพันกว่า กระทู้สองหมื่นกว่า และโพสต์สองแสนกว่า ไปอยู่บน Flarum — บันทึกกับดักที่เสียเวลาจริง ตั้งแต่ guest userid 0 ที่ทำ FK พังทั้งชุด, md5 ซ้อน md5 ของรหัสผ่านเก่า, การแปลง BBCode เป็น s9e XML, attachment ที่อยู่บนดิสก์ไม่ใช่ใน DB ไปจนถึงเหตุผลที่ต้อง scp สคริปต์แทน heredoc

นำเข้า/ย้ายข้อมูลไทยให้ไม่พัง: กับดัก VARCHAR, idempotency, สระ OCR
บทเรียนจริงจากงานนำเข้า/ย้ายข้อมูลไทยหลายแสนแถว — VARCHAR สั้นไปตัด synthetic key จนชนกันเงียบๆ, idempotency ที่ต้อง DELETE ก่อน INSERT ไม่งั้นยอดพุ่ง 200%, collation ที่มอง su001 กับ SU001 เท่ากันแต่เก็บทั้งคู่, และสระไทยเพี้ยนจาก OCR ที่ต้องมี normalization map ก่อน insert

แคปหน้าจอเว็บทีละหลายโดเมน + บังคับให้ชนเซิร์ฟเวอร์ต้นทาง ข้าม Cloudflare
ต้องแคปหน้าจอเว็บทีละหลายสิบโดเมนเพื่อตรวจ หรืออยากยืนยันว่าเซิร์ฟเวอร์ต้นทาง (ไม่ใช่ CDN cache) render ถูก — แต่ flag screenshot ของ Chrome พังตั้งแต่รุ่น 132 และแก้ hosts ก็โดน AV คืนค่า บทความนี้ใช้ Playwright override DNS ระดับโปรเซส จบทั้งสองปัญหา

แอปเก่าพังหลังย้ายเซิร์ฟเวอร์ — error 1364/1366 กับ MariaDB strict mode
ย้ายเว็บจากเซิร์ฟเวอร์เก่ามาเครื่องใหม่แล้วฟอร์มสมัครสมาชิกพังทั้งที่โค้ดไม่เปลี่ยน — ต้นเหตุคือ STRICT_TRANS_TABLES ใน sql_mode ของ MariaDB รุ่นใหม่ พร้อมวิธีแก้ 3 ระดับ ตั้งแต่ conf.d จนถึง SET SESSION รายแอป

โดเมน .com โดนยึด — ย้ายทั้งเว็บไป .net บน DirectAdmin แบบข้อมูลไม่หาย
โดเมน .com หมดอายุหลุดไปอยู่กับ domain squatter — เล่าวิธีย้ายทั้งเว็บ (ไฟล์/เมล/DNS/SSL) ไปโดเมน .net ใหม่บน DirectAdmin ด้วย CMD_CHANGE_DOMAIN คำสั่งเดียว พร้อมงานหลังบ้าน 4 อย่างที่ไม่ตามมาอัตโนมัติ

ใช้ Claude อัป Proxmox 8 ขึ้น 9 แล้วสร้าง Windows VM ใหม่ทั้งคลัสเตอร์
เคสจริง ใช้ VS Code + Claude อัป Proxmox 8 ขึ้น 9 ทั้ง cluster แล้วล้างสร้าง Windows VM ใหม่ทั้งหมดแบบ VDI โดยไม่ได้ ssh เข้าเครื่องเองเลยสักครั้ง ถอดคำสั่งและสคริปต์ที่ Claude สร้างระหว่างทำงานจริงออกมาเป็นขั้นตอน ให้คนหรือ AI อ่านแล้วเอาไปสั่งทำซ้ำได้จริง

qcow2 หรือ ZFS — ทำไมผมเพิ่งย้าย หลังใช้เครื่องเดิมมา 12 ปี
บันทึกเหตุผลเบื้องหลังการเลือก storage layer ของเครื่อง Proxmox ที่รันมา 12 ปีไม่เคย reinstall — ทำไมปี 2014 เลือก qcow2 ทำไมเพิ่งย้าย ZFS ปี 2026 และอะไรคือสิ่งที่เปลี่ยน calculus จริง ๆ

ย้าย DirectAdmin จาก CentOS 7 ไป Debian 12 บน Proxmox (สารบัญซีรีส์)
บันทึกการย้าย DirectAdmin shared host จาก CentOS 7 (EOL) ไป Debian 12 บน Proxmox ลูกค้า 80+ ราย แตกเป็น 5 ตอน พร้อมภาพรวมขั้นตอนและลิงก์ทุกตอน

ย้าย DA ตอนจบ — security fixes + hardening หลังเครื่องนิ่ง
ปิดท้ายซีรีส์ย้าย DirectAdmin ข้ามดิสโทร ด้วยงาน security ที่ทำหลังเครื่องนิ่งแล้ว — sudoers wildcard CVE, OpenSSL SECLEVEL, ModSec exclusion ก่อน CRS, csfpost drop-in และ 5 ชั้นรอด DA update

ย้าย DA จาก CentOS 7 ไป Debian 12 ตอนที่ 4 — Cutover จริง กับ 17 ปัญหาหลังสลับเครื่อง
เล่า cutover จริงที่แผน downtime ใกล้ 0 พังเพราะ DA Legacy license และ qcow2 อ่านช้า สุดท้าย downtime 1 ชม. แล้วเจอ 17 ปัญหารัวๆ หลังสลับเครื่อง — critical web stack ดับ, medium subset ใช้ไม่ได้, minor debugging notes ครบ

ย้าย DA ตอนที่ 3 — ลง DirectAdmin + CustomBuild บน Debian 12
ลง DirectAdmin ผ่าน setup.sh แล้วประกอบ stack ทั้ง PHP หลายเวอร์ชัน MariaDB ModSecurity และ rspamd ด้วย CustomBuild บน staging VM ที่อยู่หลัง NAT พร้อมกับดักที่ผมเจอมาแล้วจริง

ย้าย DA สู่ Debian 12 ตอนที่ 2 — เปลี่ยน storage เป็น ZFS mirror
เปลี่ยน storage layer จาก mdadm RAID1 + ext4 + qcow2 สามชั้น มาเป็น ZFS mirror + raw zvol ชั้นเดียว โดยทำได้ขณะ VM เก่ายัง online ผ่านเทคนิค degrade RAID เหลือ disk ใบเดียว

ย้าย DA CentOS 7 → Debian 12 บน Proxmox ตอนที่ 1 — NAT pre-stage
เทคนิคเตรียม VM ใหม่บน internal bridge แบบ NAT ขณะที่ VM เก่ายังให้บริการลูกค้าปกติ ลด downtime ตอนย้าย DirectAdmin จาก CentOS 7 ไป Debian 12 บน Proxmox