ข้ามไปยังเนื้อหา
บทความทั้งหมด

เผยแพร่เมื่อ อ่าน 4 นาที

ทำไมเว็บนี้ถึงมี CMS ของตัวเอง (และมันแลกมาด้วยอะไร)

พอร์ตโฟลิโอจะเป็นหน้า static เฉย ๆ ก็ได้ แต่ของผมเป็น CMS เล็ก ๆ บน Next.js กับ PostgreSQL นี่คือสิ่งที่ได้มา และสองบทเรียนที่จ่ายไป

  • Next.js
  • Prisma
  • Railway
  • Cloudflare
  • Behind the scenes

เว็บส่วนตัวเป็นโปรเจกต์เดียวที่ไม่มีใครมาบอกว่าต้องสร้างอะไร และอิสระนั้นเองที่ทำให้เว็บส่วนตัวส่วนใหญ่กลายเป็นหน้า static ที่ไม่เคยเปลี่ยน: ทันทีที่การอัปเดตหมายถึงต้องแตะโค้ด มันก็หยุดถูกอัปเดต ผมอยากได้ตรงกันข้าม คือเว็บที่ผมจะแก้ไปเรื่อย ๆ จึงสร้างเป็น CMS เล็ก ๆ แทน

"CMS ของตัวเอง" ที่นี่แปลว่าอะไร

มีแอป Next.js ตัวเดียว ผู้เยี่ยมชมได้หน้า public แบบมี motion สองภาษาที่ render ไว้ล่วงหน้าและรีเฟรชตามคำสั่ง ส่วนผมได้แอดมิน Ant Design ที่แก้เนื้อหาทุกชิ้น ทั้งโปรไฟล์ ประสบการณ์ โปรเจกต์ และตอนนี้ก็บทความ ได้ในที่เดียว ภาษาอังกฤษกับไทยเคียงกัน

การตัดสินใจสามอย่างกำหนดทุกอย่างที่เหลือ:

เนื้อหามีวงจรชีวิต ไม่มีอะไรขึ้นเว็บเพราะผมกดบันทึกฟอร์ม การแก้สิ่งที่เผยแพร่แล้วจะกลายเป็น "การเปลี่ยนแปลงที่ยังไม่เผยแพร่" หน้า public ยังแสดงของเดิมจนกว่าผมจะกด Publish changes และทุกการเผยแพร่ถูกเก็บเป็นเวอร์ชันที่ย้อนกลับได้ ฟังดูเป็นพิธีรีตองสำหรับเว็บของคนคนเดียว แต่นี่แหละที่ทำให้แก้เว็บบนมือถือตอนเที่ยงคืนได้อย่างปลอดภัย

ไฟล์คือไลบรารี ไม่ใช่ช่องกรอก URL อัปโหลดตรงไป Cloudflare R2 ผ่าน presigned URL อ้างอิงด้วย checksum และรู้ว่าตัวเองถูกใช้ที่ไหน อัปโหลดรูปเดิมซ้ำจะได้ object เดิม และไลบรารีจะไม่ยอมลบไฟล์ที่หน้าไหนยังใช้อยู่ alt text เขียนครั้งเดียวต่อภาษาแล้วติดไปกับไฟล์ทุกที่

เจ้าของล็อกอินด้วย passkey รหัสผ่านมีไว้แค่ลงทะเบียน passkey ตัวแรก เปลี่ยนรหัสผ่านแล้วอุปกรณ์อื่นทั้งหมดจะถูกตัดออก ซึ่งก็คือเรื่องราวการกู้คืนทั้งหมดของเว็บที่มีเจ้าของคนเดียว

แลกมาด้วยอะไร

งานหน้าเว็บคือส่วนที่สนุก บทเรียนราคาแพงอยู่ที่ operations และทั้งสองเรื่องมาจากจุดเดียวกัน: เว็บนี้ถูก render ตอน build จากฐานข้อมูล

เรื่องแรก: build ที่อ่านฐานข้อมูลจะพังทันทีที่ migration เพิ่มตารางที่ build ต้องใช้ เพราะ migration ถูกกำหนดให้รัน หลัง build มันพังสามครั้งก่อนผมจะอ่าน error ดี ๆ วิธีแก้ไม่ได้ฉลาดอะไร: ตอนนี้ CI apply migration ก่อน และแพลตฟอร์มรอ CI ก่อนจะ build กับดักที่ตกได้สองครั้งสมควรมีรั้ว ไม่ใช่แค่โน้ตเตือน

เรื่องที่สอง: backup ที่ไม่เคยถูก restore เป็นแค่สมมติฐาน dump รายคืนถูกเข้ารหัสด้วยกุญแจที่ CI ไม่มี ซึ่งอุ่นใจดีจนถึงวันที่ต้องใช้จริง การ restore จึงเป็นสคริปต์ที่ซ้อมกับฐานข้อมูลชั่วคราว และถูกรันจริงมาแล้ว ฟอร์มติดต่อก็เช่นกัน ข้อความถูกบันทึกก่อนแล้วค่อยส่งอีเมล เพราะสักวันผู้ให้บริการเมลก็ต้องมีวันแย่ ๆ

คุ้มไหม

ถ้าคิดแค่ตัวเว็บ อาจจะไม่ แต่ในฐานะที่ซ้อมเรื่องน่าเบื่อ ทั้ง migration ภายใต้ความกดดัน backup ที่เชื่อถือได้ และการตรวจในเบราว์เซอร์จริงก่อนปล่อย มันคืนทุนมาหลายรอบแล้ว และตัวแก้ธีมที่ขยายสี 4 สีเป็น token แปดสิบกว่าตัวพร้อมพรีวิวสด เป็นของประเภทที่จะสร้างก็ต่อเมื่อเว็บเป็นของคุณเอง

สิ่งถัดไปในรายการคือ site settings (ชื่อหน้านี้จะได้ไม่ต้องเป็นค่าคงที่ในโค้ด) และหน้าอ่าน audit log ที่ดีกว่านี้ โพสต์นี้เป็นโพสต์แรกที่เขียนผ่านตัวแก้ไขที่มันเล่าถึง