Uncle Labs CNC · สมาชิก / License / Config / Deploy
ชื่อเว็บไซต์ Uncle Labs CNC สำหรับ unclelabs-cnc.com โค้ดพร้อมตั้งค่าบนเซิร์ฟเวอร์ แต่ยังไม่ได้ชี้ DNS, ออก certificate, เชื่อม SMTP หรือใช้ Google OAuth credentials ของเจ้าของโดเมน
เส้นทางหลัก
| URL | ใช้ทำอะไร |
|---|---|
/ | หน้าแนะนำเว็บไซต์ |
/accounts/signup/ | อีเมล รหัสผ่าน ชื่อ และเบอร์โทร; บริษัท/หมายเหตุไม่บังคับ |
/accounts/login/ | ล็อกอินอีเมล หรือ Google เมื่อเชื่อมต่อแล้ว |
/accounts/password/reset/ | ขออีเมลตั้งรหัสผ่านใหม่ |
/member/ | วันหมดอายุ งานส่วนตัว ไฟล์ส่งออก และ Desktop keys |
/cam/ | CAM ตามสิทธิ์ที่ตั้งใน Config |
/admin/members/accesspolicy/ | Config: เลือก operations และสิทธิ์ต่อชุด |
/admin/members/license/ | เปลี่ยนวันหมดอายุ ระงับสมาชิก เลือก operations เฉพาะราย |
/admin/members/licenseevent/ | ประวัติการเปลี่ยน license พร้อมผู้แก้ไข |
กติกาสมาชิก
- สมัครแล้วล็อกอินและเข้า CAM ทันที ไม่รออนุมัติหรือยืนยันอีเมลก่อนใช้ Trial เริ่มต้นเปิดครบทุกฟีเจอร์ 30 วัน แอดมินยังปรับ Trial Config ได้
- บังคับชื่อและเบอร์โทรทั้งการสมัครอีเมลและ Google บริษัท/หมายเหตุไม่บังคับ แอดมินอ่านได้ที่ /admin/members/memberprofile/ หมายเหตุขอเวลาทดลองเพิ่มไม่ต่ออายุเอง
- Google จะถามข้อมูลติดต่อเฉพาะตอนสร้างบัญชีครั้งแรก การกลับมา login ใช้บัญชีเดิมตามปกติ
- ทดลอง 30 × 24 ชั่วโมงนับจากเวลาสร้างบัญชีในเซิร์ฟเวอร์ ล็อกอินใหม่ เปลี่ยนรหัสผ่าน หรือเชื่อม Google ไม่ต่อเวลาทดลอง
- เวลาเก็บแบบ timezone-aware และแสดง Asia/Bangkok สิทธิ์หมดทันทีเมื่อเวลาปัจจุบันถึง expires_at
- บัญชีที่ยืนยันด้วยอีเมลอยู่แล้วจะไม่ถูกเชื่อมกับ Google ให้อัตโนมัติเพียงเพราะอีเมลตรงกัน ให้ล็อกอินบัญชีเดิมแล้วใช้เมนูเชื่อมต่อ Google
- ไม่มีระบบรับชำระเงิน / recurring subscription / invoice ในรุ่นนี้ แอดมินจัดการ license เอง
Config: เลือก Operation ที่เปิดให้ใช้
เข้า Admin → Access policies มี 3 ชุด: trial, licensed, expired ไม่ต้องเขียนโค้ดเพื่อเปลี่ยนรายการ
1. ติ๊ก operations ที่ต้องการ เช่น Face, Drill, Pocket, Engrave; Imported หมายถึงทางเดิน NC ที่นำเข้า
2. เปิดสิทธิ์ สร้าง/แก้ไขและจำลองงาน, ส่งออก NC, สร้าง PDF, นำเข้า NC และ Desktop API ตามต้องการ
3. กด Save ใช้กับคำขอถัดไปทันที สมาชิกที่เปิดหน้า CAM ค้างไว้อาจยังเห็นเมนูเก่าจนรีเฟรช แต่เซิร์ฟเวอร์ตรวจสิทธิ์ใหม่แล้ว
เริ่มต้น Trial และ Licensed เปิดทั้งหมด ส่วน Expired ปิดงานใหม่ทั้งหมดแต่ยังอ่านโปรเจกต์และดาวน์โหลดไฟล์ที่มีอยู่ในหน้าสมาชิกได้ ถ้าต้องการให้หลังหมดอายุยังใช้ Face/Drill ให้เปิด สร้าง/แก้ไขและจำลองงาน ในชุด Expired แล้วเลือกเฉพาะ 2 operations นี้ สิทธิ์ส่งออกและ PDF ตั้งแยกได้ งานใหม่ทุกประเภทต้องเปิดสร้าง/แก้ไขด้วย
ใน License รายคน เลือก ใช้รายการ operations จาก Config เพื่อรับชุดส่วนกลาง หรือเอาเครื่องหมายออกแล้วเลือกเฉพาะราย รายการว่างหมายถึงไม่อนุญาต operations ใดเลย ไม่ได้แปลว่าเปิดทั้งหมด รายการเฉพาะรายใช้ขณะ license ยังไม่หมดอายุ เมื่อหมดอายุใช้ชุด Expired หากระงับสมาชิกจะปิดงานใหม่ทั้งหมดเสมอ
ตัวเลือก operations ควบคุมงานที่เปิดใช้อยู่ในโปรเจกต์ สามารถเก็บ operation ที่ปิดไว้ใน JSON ได้ แต่เปิดและคำนวณไม่ได้หากไม่มีสิทธิ์ เมื่อปิดสิทธิ์ Export API preview จะไม่ส่งข้อความ NC ให้ และปุ่มส่งออก/คัดลอกจะถูกปิด สิ่งนี้เป็นระบบสิทธิ์บริการ ไม่ใช่ DRM ป้องกันการอนุมาน NC จาก geometry
License และแอดมิน
สร้างแอดมินคนแรกบนเครื่องเซิร์ฟเวอร์ด้วยคำสั่งด้านล่าง ไม่มี username/password แอดมินสำเร็จรูปในโค้ด เลือกรหัสผ่านที่แข็งแรง เก็บสิทธิ์ Superuser ให้เฉพาะผู้ดูแลหลัก Staff คนอื่นต้องได้รับ permissions ของ License / Access policy จากผู้ดูแล
.venv/Scripts/python.exe manage.py createsuperuserใน License เปลี่ยน plan เป็น licensed และตั้ง expires_at เพื่ออนุญาตสมาชิกระยะเวลาที่ต้องการ ค่า suspended ใช้หยุดสิทธิ์ทันที ใช้ Admin note บันทึกเหตุผล การแก้ผ่าน Admin ถูกบันทึกใน License events และ Django admin log ควรสำรองฐานข้อมูลก่อนแก้จำนวนมาก
การทดลองบน Windows เครื่องนี้
รัน Start Workshop.bat ตามปกติ ค่าเริ่มต้นเปิดระบบสมาชิก SQLite ใช้พัฒนาในเครื่อง ส่วนหน้า CAM อยู่ /cam/ หลัง login
อีเมลในโหมดพัฒนาจะเขียนลง tmp/emails/ แทนส่งจริง เปิดไฟล์ล่าสุดเพื่อใช้ลิงก์ยืนยันหรือ reset เฉพาะการทดสอบในเครื่อง ไฟล์เหล่านี้มี token ส่วนตัว ห้ามเผยแพร่โฟลเดอร์นี้
ถ้าต้องใช้โหมดเครื่อง CNC เดิมที่ไม่สมัครสมาชิก ให้ตั้ง WORKSHOP_MODE=local ก่อนเปิดโปรแกรม โหมดนี้จำกัดหน้าแก้ไขไว้ที่ loopback เหมือนเดิม production settings บังคับ cloud และไม่รับ global Desktop key เดิม
ย้ายโปรเจกต์เก่าเข้าบัญชีเจ้าของ
ข้อมูลก่อนมีระบบสมาชิกถูกเก็บเป็นรายการไม่มี owner และไม่แสดงให้สมาชิกใหม่ ระบบไม่มอบงานเก่าให้คนแรกที่สมัคร สำรอง SQLite ไว้แล้วใน tmp/backups/before-members.sqlite3 จากรอบเพิ่มระบบนี้
หลังสร้างและตรวจอีเมลเจ้าของงาน ใช้คำสั่ง preview ก่อน แล้วใช้ --apply เมื่อรายการและบัญชีถูกต้อง คำสั่งไม่ลบข้อมูลและไม่เปลี่ยนเจ้าของงานที่มีเจ้าของแล้ว
.venv/Scripts/python.exe manage.py claim_local_data owner@example.com.venv/Scripts/python.exe manage.py claim_local_data owner@example.com --applyGoogle Login
ใช้ Google OAuth Web application ใน Google Cloud Console ภายใต้บัญชีของคุณ ตั้งชื่อแอป Uncle Labs CNC ตั้ง consent screen และอีเมลติดต่อ แล้วเพิ่ม redirect URI ตรงทุกตัวอักษร:
https://unclelabs-cnc.com/accounts/google/login/callback/http://127.0.0.1:8000/accounts/google/login/callback/URI localhost ใช้เฉพาะพัฒนา Authorized JavaScript origin สำหรับเว็บคือ https://unclelabs-cnc.com ทดสอบด้วย test users ของ Google ก่อนเปลี่ยน OAuth publishing status เป็น Production กรอกโดเมนและลิงก์ข้อมูลความเป็นส่วนตัวของธุรกิจตามที่ Google กำหนด ไม่เปิด Gmail API; ใช้เพียงข้อมูลบัญชี email/profile เพื่อเข้าสู่ระบบ
ใส่ GOOGLE_CLIENT_ID และ GOOGLE_CLIENT_SECRET ในไฟล์ private JSON ที่ขั้นตอน deploy สร้างให้ หรือ environment ของเซิร์ฟเวอร์ แล้ว reload Apache ไม่ใส่ใน JavaScript หรือ source control ไม่ต้องสร้าง SocialApp ซ้ำใน Django Admin เพราะระบบอ่านจาก environment
ปุ่ม Google จะไม่ทำงานจนใส่ credentials ครบ การทดสอบในโปรเจกต์ตรวจ state/PKCE และ callback ที่ไม่ถูกต้องแล้ว แต่การล็อกอิน Google จริงต้องทดสอบกับ OAuth app ของเจ้าของโดเมนหลังตั้งค่านี้
SMTP / อีเมลยืนยัน
ตั้งค่า EMAIL_HOST, EMAIL_PORT, EMAIL_HOST_USER, EMAIL_HOST_PASSWORD, EMAIL_USE_TLS และ DEFAULT_FROM_EMAIL กับผู้ให้บริการ SMTP ที่คุณเลือก ยืนยัน sender domain unclelabs-cnc.com และตั้ง SPF/DKIM/DMARC ตามผู้ให้บริการ ใช้บัญชีส่งอีเมลธุรกรรมโดยเฉพาะ
ทดสอบ verification และ reset กับอีเมลของเจ้าของระบบก่อนเปิดสมาชิกจริง SMTP ต้องส่งถึงผู้รับได้ ไม่ใช่แค่เปิด TCP ได้ ใน production ไม่มีการ fallback เขียนอีเมลลงไฟล์
Deploy ด้วยชุด Apache เดิมใน deploy/
ใช้สคริปต์ 01–05 เดิมของโปรเจกต์: Apache + mod_wsgi + Certbot + SQLite3 โดยปรับค่าของเว็บนี้ใน deploy/deploy.env แล้ว โค้ดเดิมก่อนปรับเก็บไว้ใน tmp/backups/deploy-before-members/ การเปลี่ยนรอบนี้ตรวจด้วยซอฟต์แวร์ในเครื่อง ยังไม่ได้รันติดตั้งบน VPS จริง
ค่าปัจจุบันคือ APP_NAME unclelabs-cnc, WSGI_DIR workshop, DOMAIN unclelabs-cnc.com, STATIC_DIR staticfiles และ venv แยกชื่อ venv-unclelabs-cnc ใช้ Ubuntu ที่มี Python >=3.11 และ mod_wsgi ตรงกับ Python ของระบบ เช่น Ubuntu 24.04 ไม่ใช้ venv ที่คัดลอกมาจาก Windows
1. ตรวจ deploy.env โดยเฉพาะ APP_USER, DOMAIN, USE_WWW และอีเมล Certbot ชี้ DNS A/AAAA ของโดเมนและ www ให้ตรง VPS หากไม่ได้ใช้งาน IPv6 อย่าเพิ่ม AAAA
2. บนเซิร์ฟเวอร์ใหม่ รัน sudo bash 01_server_init.sh จากโฟลเดอร์ deploy ตามกระบวนการเดิม ถ้าเซิร์ฟเวอร์เตรียมไว้แล้ว ให้ตรวจองค์ประกอบที่มีอยู่ก่อนรันสคริปต์ตั้งค่าเครื่องซ้ำ
3. เข้าด้วย APP_USER แล้วอัปโหลดโค้ดให้ manage.py อยู่ /home/unclelabsadmin/unclelabs-cnc/manage.py รวม cam/static/vendor และโฟลเดอร์ deploy ให้ครบ อัปโหลดชุดสคริปต์ล่าสุดที่ ~/deploy ด้วย ไม่อัปโหลด .venv, node_modules, tmp หรือฐานข้อมูลทดสอบทับข้อมูลจริง
4. รัน bash 02_app_setup.sh จาก ~/deploy สคริปต์เตรียม venv, ติดตั้ง packages และถามค่า SMTP / Google ครั้งแรก จากนั้นสำรองฐานข้อมูลเดิมถ้ามี, migrate, สร้างตาราง cache, เปิด WAL และ collectstatic
5. สร้างแอดมิน แล้วรันสคริปต์ Apache และ HTTPS ตามลำดับด้านล่าง หน้าเข้าสู่ระบบต้องใช้ HTTPS จึงทดสอบหลังขั้นตอน 04 เสร็จ
cd ~/deploybash 02_app_setup.shsource /home/unclelabsadmin/venv-unclelabs-cnc/bin/activatecd /home/unclelabsadmin/unclelabs-cncpython manage.py createsuperuserpython manage.py check --deploycd ~/deploysudo bash 03_apache_site.shsudo bash 04_ssl.shไฟล์ค่าลับอยู่ /home/unclelabsadmin/unclelabs-cnc.private.json นอกโฟลเดอร์ที่อัปโหลดเว็บ สคริปต์สร้าง SECRET_KEY แบบสุ่มให้ และไม่เขียนทับไฟล์เดิม ค่า SMTP ใช้ STARTTLS พอร์ต 587 ตามค่าเริ่มต้น Google เว้นว่างได้ก่อน เมื่อแก้ไฟล์แล้วให้ reload Apache คำสั่ง manage.py และ WSGI อ่านไฟล์นี้อัตโนมัติและเลือก production settings โดยใช้ค่า environment ที่ตั้งไว้ก่อนเป็นลำดับแรก
อย่าเปลี่ยน SECRET_KEY ทุกครั้งที่อัปเดต และเก็บสำรองไฟล์ค่าลับแยกอย่างปลอดภัย ไม่อัปโหลดไปยัง static/media หรือเผยแพร่พร้อม source code ถ้าเปลี่ยน APP_USER ให้แทน path ในตัวอย่างด้วยค่าจริง
Production ปิด DEBUG, บังคับ HTTPS และ secure cookies ใช้ SQLite ทั้งข้อมูลแอปและตาราง rate-limit cache Apache รัน WSGI 1 process / 2 threads และไม่เชื่อ proxy headers ที่ผู้ใช้ส่งมาเอง หากเพิ่ม CDN หรือ reverse proxy ภายหลังต้องปรับการตรวจ HTTPS/IP ให้ตรงการติดตั้งนั้น
SQLite3 และ Backup
ฐานข้อมูลอยู่ APP_DIR/db.sqlite3 เปิด WAL และตั้ง busy timeout 30 วินาที เก็บบนดิสก์ภายในเซิร์ฟเวอร์เดียว ไม่แชร์ไฟล์ฐานข้อมูลข้ามหลายเซิร์ฟเวอร์ ฐานข้อมูลเก็บสมาชิก license โปรเจกต์ NC ต้นฉบับ และไฟล์ส่งออก จึงควรติดตามพื้นที่ดิสก์และมีสำรองนอกเซิร์ฟเวอร์
สำรองด้วย SQLite online backup API ซึ่งรวมข้อมูลที่ยังอยู่ใน WAL และปฏิเสธการเขียนทับชื่อเดิม:
source /home/unclelabsadmin/venv-unclelabs-cnc/bin/activatecd /home/unclelabsadmin/unclelabs-cncpython manage.py sqlite_backup /home/unclelabsadmin/backups/unclelabs-2026-09-10.sqlite3เมื่อย้ายเครื่องหรือกู้คืน ให้หยุดแอปที่เขียนฐานข้อมูลก่อน เก็บฐานข้อมูลปัจจุบันพร้อม sidecar ไว้แยก แล้วนำไฟล์ backup ที่ตรวจแล้วมาเป็น db.sqlite3 ตั้งเจ้าของและสิทธิ์ตามขั้นตอน 02 ก่อนเริ่มแอป ทดสอบการกู้คืนในเครื่องแยกก่อนใช้กับข้อมูลจริง
อัปเดตและตรวจหลังติดตั้ง
อัปโหลดโค้ดและสคริปต์ใหม่โดยไม่ทับ db.sqlite3 หรือไฟล์ค่าลับ แล้วรัน bash 05_update.sh จาก ~/deploy สคริปต์จะสำรอง SQLite ไป APP_HOME/backups/ ก่อน migrate, เตรียม cache/WAL/static, ตรวจ deployment settings และ reload Apache
หลังติดตั้งให้ตรวจสมัครสมาชิกแล้วเข้า CAM ทันที reset รหัสผ่าน Google login อายุทดลอง Config สิทธิ์ operations และ API ด้วยบัญชีทดสอบ ตรวจว่าบัญชีอื่นเข้าถึงงานและไฟล์ของเจ้าของไม่ได้ การส่งอีเมลและ Google จริงต้องทดสอบกับบริการที่ตั้งไว้บนโดเมนนี้
ก่อนเปิดบริการให้เตรียมราคา เงื่อนไขบริการ นโยบายความเป็นส่วนตัวและช่องทางติดต่อของธุรกิจ พร้อมกำหนดระยะเก็บไฟล์และแผนสำรองข้อมูล
Desktop และ Windows XP
โหมด Cloud สมาชิกสร้าง API key จาก /member/ ได้แยกแต่ละเครื่อง เก็บเฉพาะ hash ในฐานข้อมูล Key ฉบับเต็มแสดงครั้งเดียว เพิกถอนเองได้ ใช้ header X-API-Key และตรวจ license/operations ฝั่งเซิร์ฟเวอร์ด้วย
Windows XP/Python รุ่นเก่าอาจไม่รองรับ TLS ของเว็บไซต์สมัยใหม่ ใช้เครื่อง Windows/Linux สมัยใหม่เป็นตัวกลางใน LAN สำหรับเชื่อม HTTPS ไป Cloud แล้วรับส่งกับ XP ใน LAN ที่ควบคุมได้ ไม่ลด TLS หรือเปิด HTTP ของระบบสมาชิกสาธารณะเพื่อรองรับ XP โหมด local เดิมยังมีไว้สำหรับการเชื่อมตรงในโรงงาน
แหล่งอ้างอิง
- django-allauth Google provider