แนะนำ CodingBooth

ลองใช้กับโปรเจกต์ของคุณ แล้วค่อยมาขอบใจกันทีหลัง

เครื่อง host ที่รกอยู่ทางซ้าย เทียบกับ container CodingBooth ที่สะอาดและแยกออกมาทางขวา
Host ของคุณ กับ booth — โปรเจกต์เดียวกัน แต่ขอบเขตของผลกระทบต่างกันลิบ

ปัญหา

นักพัฒนาที่สลับไปมาระหว่างหลายโปรเจกต์ มักทิ้งร่องรอยต่าง ๆ ไว้บนเครื่องของตัวเอง — runtime เวอร์ชันหนึ่งตรงนี้ CLI แบบ global อีกตัวตรงนั้น หรือ shell hook ที่ใครสักคนทิ้งไว้ตอนทำสคริปต์ onboarding ผ่านไปสักพัก ร่องรอยเหล่านี้ก็เริ่มขัดแย้งกันเองในรูปแบบที่คาดเดาได้ยาก

มีรูปแบบสามอย่างที่กัดกินเวลาของทีมอยู่เรื่อย ๆ:

  1. เศษซากจากโปรเจกต์ ทุกโปรเจกต์จะติดตั้ง อะไรบางอย่าง เสมอ — JDK เวอร์ชันหนึ่ง, ชุดเครื่องมือ Go, database client, หรือ SDK สักตัว ผ่านไปไม่กี่เดือนเครื่อง host ก็กลายเป็นสุสานของ toolchain ที่เซ็ตค้างไว้ครึ่ง ๆ กลาง ๆ และโปรเจกต์สองตัวที่ควรเป็นอิสระต่อกัน กลับลงเอยด้วยการแชร์ค่า global ตัวเดียวกัน
  2. โปรเจกต์เก่าทรมานคนเซ็ต ยิ่งโปรเจกต์ใหญ่และเก่ามากเท่าไหร่ ก็ยิ่งเซ็ตยาก — และยิ่งยากขึ้นไปอีกที่จะเซ็ตให้ เหมือนกัน กับคนอื่นในทีม เอกสาร onboarding มักจะเก่าจนใช้ไม่ได้ สคริปต์ setup เคยรันได้บนแล็ปท็อปของใครสักคนเมื่อปี 2019 และเวอร์ชันของ build tool ที่ “ใช้ได้” ก็ไม่ได้ถูก publish ไว้ที่ไหนชัด ๆ อีกแล้ว
  3. AI ทำให้สภาพแวดล้อมไหลโดยไม่รู้ตัว ผู้ช่วยเขียนโค้ดด้วย AI นั้นมีประโยชน์มาก แต่มันจะแนะนำให้รัน brew install this หรือ go install that@latest อย่างใจดีในระหว่างที่กำลังแก้ปัญหาเล็ก ๆ อยู่ — และถ้าไม่มีใครคอยสังเกตใกล้ ๆ เครื่องมือพวกนั้นก็จะตกค้างอยู่บน host อย่างถาวร คูณด้วยหนึ่งปีของการทำงานคู่กับผู้ช่วย AI สภาพแวดล้อมก็เปลี่ยนแปลงเงียบ ๆ ในแบบที่ไม่มีใครเขียนเอกสารไว้

ทั้งสามข้อนี้รวมแล้วก็คือเรื่องเดียวกัน: การพัฒนา ทำซ้ำได้ยากขึ้นเรื่อย ๆ ส่วนที่แย่ที่สุดคือความไม่เข้ากันเหล่านี้มักจะแอบซ่อนอยู่อย่างเงียบ ๆ — minor version ที่ต่างกันนิดเดียว, native lib ที่หายไป, หรือค่า PATH ที่ตกค้าง — ทำให้มองไม่เห็นจนกว่าจะนานทีหลัง ส่วนใหญ่ตอนที่คนอื่นพยายามรันโค้ดเดียวกัน

Production ถูกใส่ไว้ใน container แล้ว CI ก็ถูกใส่ไว้ใน container แล้ว แต่ลูปของการพัฒนา — ส่วนที่นักพัฒนาใช้เวลาทั้งวันอยู่จริง ๆ — กลับยังไม่ได้ถูกใส่ใน container CodingBooth คือชิ้นส่วนที่ขาดหายไป

รู้จัก CodingBooth

CodingBooth มอบสภาพแวดล้อมการพัฒนาที่แยกออกจากกันและทำซ้ำได้ให้กับทุกโปรเจกต์ — ประกาศไว้ในตัว repo เรียกใช้ด้วยคำสั่งเดียว และล้างทิ้งได้โดยไม่ทิ้งร่องรอยใด ๆ บนเครื่อง host

ในระดับภาพรวม โมเดลก็เรียบง่าย:

  • วางโฟลเดอร์ .booth/ ไว้ในโปรเจกต์ของคุณ ประกาศสภาพแวดล้อมไว้ในนั้น (Boothfile หรือ Dockerfile บวกกับ config.toml เล็ก ๆ)
  • รัน ./booth booth จะสตาร์ต container ที่ผู้ใช้ภายในถูกแมปกับ UID/GID ของ host เมานต์โปรเจกต์ของคุณเข้าไป และเปิดหน้าบ้านตามตัวที่คุณเลือก
  • แก้โค้ด build รัน test ภายใน booth ไฟล์ที่คุณสร้างจะเป็นของ คุณเอง บน host — ไม่ต้องเต้นรำกับ chown ไม่มีไฟล์ที่ root เป็นเจ้าของหลงเหลือ
./booth

เพราะสภาพแวดล้อมถูกประกาศไว้ใน repo booth ที่เพื่อนร่วมทีมรันจึงเป็น booth เดียวกับที่คุณรัน อยู่บน image เดียวกัน ด้วยเครื่องมือเวอร์ชันเดียวกัน host ยังสะอาด โปรเจกต์ยังพกพาได้ การเซ็ตยังทำซ้ำได้

รูปแบบที่ง่ายที่สุดของการประกาศนั้นคือ Boothfile — รูปแบบ declarative ระดับสูงที่ถูก compile ลงไปเป็น Dockerfile ด้านล่างคือ Boothfile ตัวจริงที่สร้าง booth ที่ใช้พัฒนาบล็อกนี้:

# .booth/Boothfile
# syntax=codingbooth/boothfile:1
# Configured by: booth config --no-tui --overwrite --variant codeserver --port 13579 --expose 5173 --select firebase+credential/claude-code+auto-accept+credential+settings-cache

setup claude-code
setup firebase

บรรทัด setup สองบรรทัดก็เพียงพอที่จะประกาศสภาพแวดล้อมการพัฒนาสำหรับบล็อก Svelte + Firebase ทั้งหมด setup แต่ละบรรทัดจะแมปไปยังสคริปต์ติดตั้งที่ดูแลแล้ว ซึ่งจะเชื่อมเครื่องมือเข้ากับ PATH และตั้งค่า default ที่เหมาะสม — ไม่มีบรรทัด FROM ไม่มีพิธีรีตอง ARG ไม่ต้องชุลมุนกับ shell ถ้าอยากใช้ Docker ดิบ ๆ ก็แค่วาง Dockerfile ไว้ใน .booth/ แล้ว CodingBooth จะใช้ไฟล์นั้นโดยตรง

คอมเมนต์ # Configured by: คือคำสั่ง booth config ที่ใช้สร้างไฟล์นี้ขึ้นมาจริง ๆ — copy-paste ลงใน shell แล้วคุณจะได้ Boothfile และ config.toml ตัวเดียวกันออกมาตั้งแต่ศูนย์

การติดตั้ง CodingBooth เองก็ใช้คำสั่งเดียว:

curl -fsSL https://codingbooth.io/install.sh | bash

Variants — ไม่ใช่แค่ Terminal

ก่อนจะไปต่อ: booth ไม่จำเป็นต้องเป็นเซสชันแบบ text-only เสมอไป ความเข้าใจแรกมักจะเป็นแบบนั้น ละมันก็ทำให้เครื่องมือดูด้อยกว่าความเป็นจริง แต่จริงๆแล้ว CodingBooth มาพร้อมหลาย variants — หน้าบ้านต่างชนิดที่ใช้สภาพแวดล้อมเบื้องหลังเดียวกันทั้งหมด:

  • base — terminal ในเบราว์เซอร์แบบเบาผ่าน ttyd
  • terminal — เซสชัน shell ตรง ๆ ใน terminal ของเครื่อง host
  • notebook — Jupyter Lab พร้อม kernel หลายภาษา
  • codeserver — VS Code เต็มรูปแบบในเบราว์เซอร์ ครบทั้ง extension
  • desktop-xfce / desktop-kde — เดสก์ท็อป Linux เต็มรูปแบบในเบราว์เซอร์ ครบทั้งแอป GUI, file manager, เบราว์เซอร์ และทุกอย่างที่ต้องมี

booth เดียวกัน UI ต่างกัน วันนี้คุณเปิดโปรเจกต์ใน VS Code บนเบราว์เซอร์ พรุ่งนี้เปิดใหม่เป็น notebook เพื่อพล็อตกราฟ แล้วสลับไป desktop variant เต็มรูปแบบเมื่อต้องรันเครื่องมือ GUI — ทำได้ทั้งหมดโดยไม่ต้องเปลี่ยน toolchain เบื้องล่าง

variant codeserver (VS Code ในเบราว์เซอร์) ที่รันอยู่ภายใน booth
codeserver — VS Code ในเบราว์เซอร์
variant notebook (Jupyter Lab) ที่รันอยู่ภายใน booth
notebook — Jupyter Lab พร้อม kernel หลายภาษา
variant desktop-xfce (เดสก์ท็อป Linux เต็มรูปแบบ) ที่รันอยู่ภายใน booth ผ่าน noVNC
desktop-xfce — เดสก์ท็อป Linux เต็มรูปแบบในเบราว์เซอร์

เรื่องที่เกี่ยวกับ runtime — จะใช้ variant ไหน การแมป port การเมานต์ volume — จะอยู่ในไฟล์ config.toml ขนาดเล็กข้าง ๆ Boothfile อีกครั้ง ด้านล่างคือ config.toml ตัวจริงของบล็อกนี้:

# .booth/config.toml
# Configured by: booth config --no-tui --overwrite --variant codeserver --port 13579 --expose 5173 --select firebase+credential/claude-code+auto-accept+credential+settings-cache

variant = "codeserver"
port    = "13579"

run-args = [
    "-v", "~/.config/configstore/firebase-tools.json:/etc/cb-home-seed/.config/configstore/firebase-tools.json:ro",
    "-v", "~/.claude.json:/etc/cb-home-seed/.claude.json:ro",
    "-v", "~/.claude/.credentials.json:/etc/cb-home/.claude/.credentials.json:ro",
    "--publish", "5173:5173"
]

การ mount เหล่านี้ส่ง credential ของ Firebase CLI และ Claude Code จาก host เข้าไปใน booth แบบ read-only — ดังนั้นการ deploy และผู้ช่วย AI ก็ทำงานได้เลยภายใน container โดยไม่ต้อง login ใหม่ --publish 5173:5173 ส่งต่อ dev server ของ Vite กลับมาที่ host

ถ้า booth เป็นแค่ terminal ที่แต่งหน้าตามาให้ดูดีหน่อย มันคงไม่น่าสนใจสักเท่าไหร่ ประเด็นจริง ๆ คือ สภาพแวดล้อม นั่นแหละคือหน่วยของการทำซ้ำได้ ส่วน UI ก็เป็นแค่เลนส์ที่มองเข้าไปเท่านั้น

Config TUI — ตั้งค่าโดยไม่ต้องเขียน TOML เอง

การประกาศสภาพแวดล้อมด้วยมือเองนั้นพอใช้ได้สำหรับโปรเจกต์เล็ก ๆ แต่จะหมดสนุกทันที เมื่อคุณอยากได้ Python + IDE ตัวที่ชอบ + ผู้ช่วย AI + การเมานต์ credential + database client CodingBooth มาพร้อม Config TUI แบบ interactive สำหรับเรื่องนี้โดยเฉพาะ

booth config

TUI เป็นอินเทอร์เฟซแบบ terminal ที่มีหลายแท็บ ให้คุณดู เทมเพลตกว่า 130 ตัว ในหลายหมวด — โปรแกรมภาษา, IDE, ผู้ช่วยเขียนโค้ดด้วย AI, ฐานข้อมูล, เบราว์เซอร์, เดสก์ท็อป, ชุดสำหรับการศึกษา และเครื่องมือสำหรับนักพัฒนา — เปิด/ปิด extension ตามต้องการ และพรีวิวผลลัพธ์ของโฟลเดอร์ .booth/ ก่อนที่จะเขียนออกไปจริง ถ้าโฟลเดอร์ .booth/ มีอยู่แล้ว TUI จะ pre-populate ด้วยตัวเลือกปัจจุบันของคุณ ดังนั้นการเปิดโปรเจกต์ขึ้นมาใหม่จะรู้สึกเหมือนแก้ไข ไม่ใช่เริ่มต้นใหม่ทั้งหมด

ถ้าอยากใช้แบบสคริปต์ ตัวเลือกเดียวกันก็ใช้ได้แบบ non-interactive:

booth config --no-tui \
    --select java+maven \
    --select claude-code+credential

ไม่ว่าจะทางไหน สุดท้ายคุณจะได้โฟลเดอร์ .booth/ ที่คนอื่น — หรือตัวคุณเองในอนาคต — สามารถ clone แล้วรันได้ด้วยคำสั่งเดียว

ลองเล่นแบบเร็ว ๆ

วิธีที่เร็วที่สุดในการสัมผัสว่า booth ทำอะไรได้คือการลองตัวอย่างที่สร้างไว้ให้แล้ว แคตตาล็อกมีมาให้หลายสิบตัวอย่าง — รวมถึงตัวอย่างที่ใช้ toolchain ที่คุณแทบจะไม่มีบนเครื่อง host แน่ ๆ:

booth example list
booth example try snake-zig my-snake
cd my-snake
booth

ตัวอย่าง snake build ด้วย Zig ภายใน booth คุณแก้โค้ดและคอมไพล์ได้ ไบนารีที่ได้จะอยู่ฝั่ง host พร้อมรันได้เลย ไม่มี Zig ที่ถูกติดตั้งบนเครื่องของคุณ ไม่มีอะไรต้องเก็บกวาดทีหลัง — นี่คือสรุปทุกอย่างในรูปแบบย่อ

ใครได้ประโยชน์

ถ้าข้อใดข้อหนึ่งด้านล่างนี้ตรงกับชีวิตประจำสัปดาห์ของคุณ booth ก็น่าจะคุ้มค่าที่จะมีไว้:

  • นักพัฒนาที่ใช้หลายภาษา (polyglot) ที่ต้องสลับไปมาระหว่างภาษาต่าง ๆ booth หนึ่งตัวต่อหนึ่งโปรเจกต์ หมายถึงไม่ต้องเล่นกล sdkman / gvm / nvm และไม่ต้องกลัวเวอร์ชัน global ซ้อนทับกัน
  • ทีมที่กำลังรับสมาชิกใหม่ clone repo รัน ./booth แล้วคุณก็พร้อมเทียบเท่ากับคนอื่นในทีมตั้งแต่วันแรก — เวอร์ชันเดียวกัน CLI เดียวกัน ค่า default เดียวกัน
  • ผู้ดูแลระบบใหญ่หรือระบบ legacy ปักหมุด toolchain ไว้ที่เวอร์ชันที่ยังใช้งานได้จริง ๆ ใน repo และเลิกพึ่งวิกิ setup ที่ไม่มีใครอัปเดต
  • อาจารย์และคนจัด workshop แจก repository ตัวเดียว แล้วทุกคนได้สภาพแวดล้อมเหมือนกัน โดยไม่ต้องเสียทั้งวันไป debug ปัญหาเฉพาะของแต่ละแพลตฟอร์ม
  • นักวิจัยที่กลับมาทำงานเก่าต่อ เปิดโปรเจกต์ที่หลับใหลมาหลายปี และเรียก toolchain ดั้งเดิมขึ้นมาได้ โดยไม่ต้องขุดหาบนเครื่องปัจจุบัน
  • งานที่ใช้ AI หนัก ๆ ใส่ setup claude-code ลงใน Boothfile แล้วผู้ช่วยจะรันอยู่ภายใน booth พร้อมเอกสารแนะนำสำหรับ agent ที่ /opt/codingbooth/AGENT.md และ extension เสริมสำหรับ credential ที่เมานต์ login ของ host แบบ read-only ปล่อยให้ผู้ช่วยติดตั้งอะไรก็ได้ที่มันอยากติด — host ไม่ถูกแตะต้อง และถ้ามันแนะนำพลาด การรีสตาร์ท booth ครั้งเดียวก็ย้อนกลับได้
  • นักพัฒนาเดี่ยวที่ชอบเครื่องสะอาด ไม่ต้องมีสุสาน runtime ที่เซ็ตค้างไว้บน แล็ปท็อปอีกแล้ว เพียงเพราะคุณเคยลองเล่น tutorial สักครั้ง

ปิดท้าย

แม้แต่บล็อกตัวนี้เอง — Svelte 5, SvelteKit, Firebase Hosting — ก็พัฒนาอยู่ภายใน CodingBooth Boothfile สองบรรทัด ไฟล์ config.toml หนึ่งไฟล์ และคำสั่ง ./booth ครั้งเดียว ก็ยกสภาพแวดล้อมทั้งหมดขึ้นมาได้

“Works on my machine” กลายเป็น meme เพราะมันเกิดขึ้นซ้ำแล้วซ้ำเล่า CodingBooth ทำให้ลูปของการพัฒนา — ส่วนที่นักพัฒนาใช้เวลาส่วนใหญ่อยู่จริง ๆ — ทำซ้ำได้พอ ๆ กับ container ของ production ที่อยู่ข้าง ๆ booth หนึ่งตัวต่อโปรเจกต์หนึ่งตัว เครื่อง host ที่สะอาด repo ที่พกพาสภาพแวดล้อมของตัวเองมาด้วย

ขอให้สนุกกับการเขียนโค้ดครับ!
Nawa Man


อ่านเพิ่มเติม

เว็บไซต์

https://codingbooth.io

เจาะลึก

https://codingbooth.io/more.html

GitHub

https://github.com/NawaMan/CodingBooth

Comments

Thank you for keeping the comment section positive, constructive and respectful. I appreciate constructive criticism & respectful disagreement!

0 / 5000