ข้ามไปยังเนื้อหา

กลับเข้าหน้าผู้ดูแล

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

ทางกลับทั้งสองแบบตั้งได้ที่เมนู “ความปลอดภัย” ในหน้าแอดมิน

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

หน้าเข้าสู่ระบบของแอดมินมีลิงก์ “กู้คืนการเข้าถึง” ไปที่ /recovery หรือจะเปิดเองก็ได้ เช่น https://cms.example.com/recovery หน้านี้อยู่ที่ที่อยู่นี้เสมอ ไม่ว่าคุณจะตั้ง path ของแอดมินไว้เป็นอะไร และแสดงเป็นภาษาเริ่มต้นของเว็บ

  1. ในส่วน “ใช้รหัสกู้คืน” กรอกรหัสที่ยังไม่ได้ใช้หนึ่งรหัสลงในช่อง “รหัสกู้คืน” แล้วกด “ดำเนินการต่ออย่างปลอดภัย”
  2. เบราว์เซอร์จะให้อุปกรณ์สร้าง passkey ใหม่ ให้สร้างในหน้าต่างเบราว์เซอร์ปกติ เหมือนตอนใช้ตัวช่วยตั้งค่า
  3. เมื่อบันทึก passkey แล้ว หน้าแอดมินจะเปิดขึ้นมาโดยคุณเข้าสู่ระบบอยู่แล้ว

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

ถ้ารหัสผิดหรือถูกใช้ไปแล้ว หน้าจะแจ้งว่า “เริ่มการกู้คืนไม่สำเร็จ ตรวจสอบรหัสแล้วลองอีกครั้ง” ลองได้ห้าครั้งภายใน 30 นาทีต่อหนึ่ง IP หลังจากนั้นต้องรอสักพัก

passkey ใหม่จะบันทึกในชื่อ “Recovery passkey” และเมื่อบันทึกแล้ว passkey เก่าทุกตัวจะถูกลบออก รวมถึงตัวสำรองด้วย เมื่อกลับเข้ามาได้แล้ว ให้เพิ่ม passkey สำรองใหม่ที่เมนู “ความปลอดภัย” และสร้างรหัสชุดใหม่ถ้าเหลืออยู่ไม่กี่รหัส

ถ้าไม่มีทั้ง passkey สำรองและรหัสกู้คืน ให้สร้างลิงก์กู้คืนบนเซิร์ฟเวอร์ โดยรันคำสั่งในโฟลเดอร์โค้ด คำสั่งนี้ต้องใช้แพ็กเกจในโฟลเดอร์โค้ด ถ้ายังไม่เคยรัน npm ci ไว้ตอนสำรองข้อมูล ให้รันหนึ่งครั้งก่อน

Terminal window
npm run admin:recover

แบบแรกนี้ไม่เปลี่ยนอะไรเลย แค่พิมพ์ชื่อเว็บ ที่อยู่ของเว็บ และอีเมลของเจ้าของ ตามด้วย Inspection only. Re-run with --execute to create a one-time recovery link. ตรวจให้แน่ใจว่าเป็นเว็บที่ตั้งใจไว้ แล้วจึงรัน

Terminal window
npm run admin:recover -- --execute

คำสั่งนี้ต้องรันในเทอร์มินัลที่โต้ตอบได้ และจะให้พิมพ์ RECOVER ตามด้วย origin ของเว็บ เช่น RECOVER https://cms.example.com เมื่อพิมพ์บรรทัดนี้ ทุกอุปกรณ์ที่เจ้าของเว็บเข้าสู่ระบบค้างไว้จะหลุดออกจากระบบทันที ถ้าพิมพ์อย่างอื่น คำสั่งจะหยุดพร้อมข้อความ Confirmation did not match. No changes were made. ถ้าพิมพ์ตรง คำสั่งจะพิมพ์ลิงก์ที่ใช้ได้ครั้งเดียวและหมดอายุในอีกสิบนาที

One-time recovery link (expires 2026-09-25T09:10:00.000Z):
https://cms.example.com/recovery?context=...

เวลาที่แสดงเป็น UTC ให้เปิดลิงก์บนอุปกรณ์ที่จะเก็บ passkey ตัวใหม่ แล้วกด “สร้าง passkey สำหรับกู้คืน” ในส่วน “สร้าง passkey ทดแทน” จากนั้นขั้นตอนจะเหมือนกับตอนใช้รหัสกู้คืน และ passkey ตัวใหม่จะมาแทน passkey เก่าทุกตัว ส่วนรหัสกู้คืนที่เก็บไว้ยังใช้ได้เหมือนเดิม

คำสั่งนี้อ่านค่าตั้งค่าจากไฟล์ที่ TOME_CMS_ENV_FILE ระบุ ถ้าไม่ได้ระบุจะอ่าน .env.local ในโฟลเดอร์โค้ด และถ้าไม่มีจึงอ่าน /etc/tome-cms/tome-cms.env ถ้าอ่านไม่ได้สักไฟล์ คำสั่งจะหยุดพร้อมข้อความ No readable TomeCMS environment file found. Set TOME_CMS_ENV_FILE or create .env.local.

ถ้าเปิดปลั๊กอิน Cloudflare Turnstile ไว้ ฟอร์มเข้าสู่ระบบจะมี challenge ให้ผ่านก่อน ถ้า challenge ไม่ขึ้นในเบราว์เซอร์ของคุณ ให้ปิดปลั๊กอินจากโฟลเดอร์โค้ด

Terminal window
npm run plugin:disable turnstile

คำสั่งนี้ปิดปลั๊กอินแต่ยังเก็บการตั้งค่าไว้ ถ้าจะล้างการตั้งค่าไปด้วย ให้รัน npm run plugin:disable turnstile -- --forget ตัว challenge ตรวจแค่ตอนเข้าสู่ระบบ ไม่ได้ตรวจตอนสร้าง passkey หน้า /recovery จึงใช้ได้เสมอ ไม่ว่าปลั๊กอินจะเปิดอยู่หรือไม่

การรีเซ็ตจะพาเว็บกลับไปที่ตัวช่วยตั้งค่าครั้งแรก โดยลบเนื้อหาและการตั้งค่าของเว็บ ไฟล์ทุกไฟล์ใน bucket และบัญชีของเจ้าของเว็บพร้อม passkey, session และรหัสกู้คืนทั้งหมด สิ่งที่ยังอยู่คือตารางในฐานข้อมูลกับบันทึกว่ารัน migration ไหนไปแล้ว และ .env.local ซึ่งมี installation token อยู่ข้างใน

เว็บที่รีเซ็ตไปแล้วจะกลับมาได้จากชุดสำรองเท่านั้น ถ้ามีอะไรในเว็บที่อาจต้องใช้ภายหลัง ให้สำรองข้อมูลไว้ก่อน

  1. รัน npm ci ในโฟลเดอร์โค้ดหนึ่งครั้ง ถ้ายังไม่เคยรัน

  2. หยุดแอป

    Terminal window
    docker compose -f compose.yaml --env-file .env.local stop app
  3. ดูก่อนว่าการรีเซ็ตจะลบอะไรบ้าง

    Terminal window
    npm run admin:reset-installation

    คำสั่งจะพิมพ์ origin ของเว็บ ชื่อฐานข้อมูล ชื่อ bucket และชื่อเว็บ ตามด้วยจำนวนแถวแต่ละประเภทในฐานข้อมูล จำนวน object ที่ TomeCMS รู้จัก และจำนวน object ที่อยู่ใน bucket แล้วจบด้วย Dry run complete. No changes were made.

  4. รีเซ็ตจริง

    Terminal window
    npm run admin:reset-installation -- --execute

    คำสั่งนี้ต้องรันในเทอร์มินัลที่โต้ตอบได้ หลังแสดงรายการเดิมอีกรอบ คำสั่งจะพิมพ์บรรทัดหนึ่งให้คุณพิมพ์ตาม คือ RESET ตามด้วย origin ชื่อฐานข้อมูล และชื่อ bucket เช่น RESET https://cms.example.com tomecms tomecms-media ถ้ากด Enter เฉย ๆ จะเป็นการยกเลิก และถ้าพิมพ์ไม่ตรงก็ไม่มีอะไรเปลี่ยน

  5. คำสั่งจะลบ object ทุกตัวใน bucket ล้างตาราง แล้วตรวจว่าทั้งสองที่ว่างจริง จากนั้นจบด้วย Reset complete. Restart TomeCMS and open /install. ให้เปิดแอปอีกครั้ง

    Terminal window
    docker compose -f compose.yaml --env-file .env.local start app
  6. เปิด /install แล้วทำตามตัวช่วยตั้งค่าใหม่ด้วย installation token เดิม

มีสองกรณีที่การรีเซ็ตจะไม่ยอมทำงานและไม่เปลี่ยนอะไรเลย กรณีแรก ถ้ายังมีการอัปโหลดที่เพิ่งได้ลายเซ็นไปไม่กี่นาทีและอาจยังส่งไฟล์เข้ามาได้ คำสั่งจะแจ้งว่า Recent signed uploads are still valid. Stop TomeCMS, wait five minutes, and run reset again. กรณีที่สอง ถ้าใน bucket มี object ที่ไม่มีตารางไหนรู้จัก คำสั่งจะแจ้งว่า The media bucket contains objects not tracked by TomeCMS; no changes were made. Use a dedicated clean bucket. ควรให้เว็บมี bucket เป็นของตัวเอง เพราะการรีเซ็ตจะล้าง bucket ทั้งใบ

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

ส่วนนี้สำหรับการติดตั้งแบบ managed ตั้งแต่ 1.0.0 ขึ้นไป การติดตั้งแบบ build จากซอร์สโค้ดเก็บการตั้งค่าไว้ใน .env.local และไม่มีตัวอัปเดต

ถ้าตัวติดตั้งแบบ managed ล้มเหลวหลังจากเขียนไฟล์ตั้งค่าเสร็จแล้ว ตัวติดตั้งจะเก็บทุกอย่างไว้ ทั้งไฟล์ตั้งค่า ค่าลับ image, volume และ log แล้วพิมพ์บอกว่าบันทึกข้อมูลวินิจฉัยไว้ที่ /var/log/tome-cms/install-<id>.json ไฟล์นี้อ่านได้เฉพาะ root และรหัสผ่าน token ค่าลับ กุญแจ และที่อยู่ฐานข้อมูลถูกตัดออกจากไฟล์แล้ว อ่านได้ด้วย sudo less ถ้าล้มเหลวก่อนถึงจุดนั้น ตัวติดตั้งจะลบเฉพาะสิ่งที่การรันครั้งนั้นเพิ่งสร้างขึ้น

อย่าแตะ volume และค่าลับ ห้ามรัน down --volumes และห้ามสร้างค่าลับชุดใหม่เพื่อลองติดตั้งอีกรอบ ให้อ่าน log ก่อน

Terminal window
sudo docker compose -p tomecms -f /opt/tome-cms/compose.managed.yaml \
--env-file /etc/tome-cms/tome-cms.env \
--env-file /var/lib/tome-cms/updater/image.env logs --tail 100
sudo journalctl -u tomecms-updater -n 100 --no-pager

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

Terminal window
sudo docker compose -p tomecms -f /opt/tome-cms/compose.managed.yaml \
--env-file /etc/tome-cms/tome-cms.env \
--env-file /var/lib/tome-cms/updater/image.env run --rm --no-deps --pull never app npm run db:migrate
sudo docker compose -p tomecms -f /opt/tome-cms/compose.managed.yaml \
--env-file /etc/tome-cms/tome-cms.env \
--env-file /var/lib/tome-cms/updater/image.env up -d --wait --no-deps --pull never app
curl --fail http://127.0.0.1:4321/health/ready
sudo systemctl daemon-reload
sudo systemctl enable --now tomecms-updater
sudo curl --unix-socket /run/tome-cms/updater.sock http://localhost/v1/status

การอัปเดตผ่านเว็บที่ล้มเหลวและกลับไปใช้แอปตัวเดิมอย่างปลอดภัยไม่ได้ จะจบที่สถานะ failed_manual_recovery ชุดสำรองของการอัปเดตครั้งนั้นจะถูกเก็บไว้ และหน้าแอดมินจะเริ่มอัปเดตครั้งใหม่ไม่ได้จนกว่าผู้ดูแลเซิร์ฟเวอร์จะจัดการเสร็จ อย่าลบ /var/lib/tome-cms/updater/job.json เพื่อให้ปุ่มกลับมา

ถ้าการอัปเดตหยุดก่อนสำรองข้อมูล สถานะของตัวอัปเดตจะมี "backupCreatedAt" เป็น null และยังไม่มีอะไรเปลี่ยน กรณีนี้ให้รัน sudo npm run updater:clear-failed จากโค้ดที่ checkout ไว้ที่ 1.0.3 ขึ้นไป คำสั่งนี้จะแยกเก็บการอัปเดตนั้นไว้ ตามที่หน้าแก้ปัญหาแสดงไว้ และจะไม่ยอมทำกับการอัปเดตแบบอื่น

ถ้าไม่ใช่กรณีนั้น ให้หยุดตัวอัปเดตและแอป แล้วคัดลอกชุดสำรองซึ่งอยู่ใต้ /var/backups/tome-cms/ ออกไปเก็บนอกเซิร์ฟเวอร์ ตรวจชุดสำรองด้วย npm run restore:check ก่อนจะเปลี่ยนอะไร ส่วนการกู้ฐานข้อมูลและไฟล์คืนต้องทำเอง ถ้า manifest.json ของชุดสำรองมี "scope": "database" แปลว่าเป็นชุดที่สำรองแค่ฐานข้อมูลก่อนการอัปเดตที่ไม่มี migration ให้ปล่อย bucket ไว้อย่างเดิม หรือกู้ไฟล์จากชุดสำรองเต็มที่เก่ากว่า