Skip to content
← กลับไปยังชุดเครื่องมือ

แอดออน Devcontainer

มอบ dev container ที่ทำซ้ำได้และแยกสภาพแวดล้อมให้กับ repository ซึ่งทั้งคน editor และ coding agent ใช้ร่วมกันได้ ใน DWP v7 (แพ็ก v7.9.0) แอดออนนี้ผสาน devcontainer-kit เข้ามา ซึ่งเป็นผลิตภัณฑ์ MIT ที่ทำงานได้แม้ไม่มี Deep Work Plan แอดออนนี้เป็นแบบเลือกใช้ repository หนึ่งสอดคล้องกับมาตรฐานได้อย่างสมบูรณ์แม้ไม่มีมัน

สิ่งที่ devcontainer-kit มอบให้

  • เทมเพลต ที่สร้างบนข้อกำหนด Dev Containers ซึ่ง dck init จะเรนเดอร์ลงใน repository ในโครงสร้างตายตัวแบบเดียว ได้แก่ .devcontainer/devcontainer.json, docker/local/<service>/Dockerfile, docker/local/docker-compose.yaml และ dev.sh หากรันอีกครั้งภายหลัง มันจะปรับให้สอดคล้องกันและไม่เขียนทับสิ่งที่คุณแก้ไขไว้เลย การเปลี่ยนแปลงใด ๆ ต่อไฟล์ที่มีอยู่จะแสดงให้เห็นก่อนและต้องได้รับความยินยอม
  • คอนเทนเนอร์ของ repository เอง Dockerfile เริ่มจาก image ทางการของ runtime ที่ตรึงด้วย digest ได้แก่ node-24, python-3.13 หรือ debian และคัดลอกขั้นตอน build ของชุดเครื่องมือไปไว้ที่ docker/local/<service>/dck/ โดยไม่มี base image ที่ใช้ร่วมกันเข้ามาเกี่ยวข้องเลย
  • dev.sh และ dck bash dev.sh up จะ build เริ่ม และเชื่อมต่อเข้าคอนเทนเนอร์จากเทอร์มินัลธรรมดา ส่วน shell, rebuild, doctor และคำสั่งอื่น ๆ ใช้งานได้ไม่ว่าจะมีหรือไม่มี VS Code หรือ Cursor ก็ตาม
  • Herdr สองทาง Herdr บนโฮสต์จะเชื่อมแต่ละคอนเทนเนอร์เข้ามาเป็นเครื่องหนึ่งผ่านเซิร์ฟเวอร์ SSH ที่รับเฉพาะ loopback และคอนเทนเนอร์จะเปิดขึ้นพร้อมแถบด้านข้างมาตรฐาน ได้แก่ App, Editor, Development และ Agents ทุก workspace และทุก pane รวมถึงที่เปิดภายหลัง จะเริ่มต้นที่พาธของแอป (ค่าเริ่มต้นคือ /app) ภายในคอนเทนเนอร์ herdr-peers ช่วยให้เอเจนต์ถามเอเจนต์ที่อยู่บนโฮสต์และในคอนเทนเนอร์อื่นได้
  • สกิล dck-dockerfile เอเจนต์สร้างหรือสร้างคอนเทนเนอร์ของ repository ใหม่ตามคำขอ และพิสูจน์ผลด้วยการ build จริง

การติดตั้ง

git clone --branch v1.1.1 https://github.com/DailybotHQ/devcontainer-kit && ./devcontainer-kit/install.sh
cd your-repo && dck init && bash dev.sh up

ข้อกำหนด: bash 3.2 ขึ้นไปและ python3 3.11 ขึ้นไปบนโฮสต์ Linux หรือ macOS รวมถึง Docker พร้อม Compose v2 สำหรับคำสั่งเกี่ยวกับคอนเทนเนอร์ ตรวจสอบรีลีสด้วย asset SHA256SUMS ของรีลีสนั้น ให้ตรึงไว้ที่ v1.1.1 เนื่องจาก v0.2.0 ไม่ได้รับการสนับสนุน

รายการ ค่า
ผลิตภัณฑ์ DailybotHQ/devcontainer-kit แท็ก v1.1.1 อินเทอร์เฟซ 2
คีย์ใน registry devcontainer ใน .dwp/config.json
config ต่อ repository .devcontainer/dck.toml
การตรวจจับ dck doctor --json

เสถียรตั้งแต่ v1.0.0 อินเทอร์เฟซสาธารณะเป็นไปตาม semantic versioning และจะเปลี่ยนแปลงแบบไม่เข้ากันกับของเดิมเฉพาะในเวอร์ชันหลักใหม่เท่านั้น (และสำหรับไฟล์ จะมาพร้อมหมายเลขอินเทอร์เฟซใหม่) ได้แก่ คำสั่งย่อยของ dck พร้อมแฟล็กและรหัสออกที่มีเอกสารกำกับ (0 สำเร็จ, 1 ล้มเหลว, 2 การใช้งานผิด, 3 การกำหนดค่า, 4 สภาพแวดล้อม, 5 ถูกปฏิเสธ) สคีมาของ dck.toml, โปรไฟล์โฮสต์ และ dck doctor --json (อินเทอร์เฟซ 2) และสัญญาการเรนเดอร์ ซึ่งได้แก่ ไฟล์ที่ dck init เขียนและเป็นเจ้าของ มาร์กเกอร์ dck:managed และบล็อกของผู้ใช้ที่มันคงไว้ รวมถึงสภาพแวดล้อมที่ entrypoint อ่าน การย้ายจาก v0.3.7 ไม่ทำให้สิ่งใดเสียหาย ให้รัน dck init และ dck rebuild เพื่อให้อิมเมจมีเวอร์ชันที่ตรึงไว้ชุดใหม่ (herdr-peers v1.1.0, coding-agents-kit v1.1.0 และ DeepWorkPlan Vim v1.0.1)

เลเยอร์

ทุกคอนเทนเนอร์มีเครื่องมือพัฒนา ได้แก่ git, gh, ripgrep, เซิร์ฟเวอร์ SSH, Herdr และ herdr-peers โดยไม่มีความลับใด ๆ เว้นแต่คุณจะเลือกเปิดใช้บัญชีโฮสต์ ส่วนที่เหลือเป็นเลเยอร์ที่คุณเลือกใน dck.toml:

เลเยอร์ ค่าเริ่มต้น สิ่งที่เพิ่มเข้ามา
agents ปิด coding-agents-kit จากรีลีสที่ผ่านการตรวจสอบ และ CLI ที่คุณระบุ โดยแต่ละตัวมีโวลุมถาวรของตัวเอง พร้อม preset classic (claudex, codexx, …) และ providers (claude-glm, codex-azure, …) เอเจนต์ทำงานแบบอัตโนมัติโดยค่าเริ่มต้น เพราะคอนเทนเนอร์คือ sandbox การเลือกไม่ใช้: ตั้ง AGENTKIT_PERMISSIONS=ask ใน .env ของ service
editor เปิด Neovim พร้อม DeepWorkPlan Vim ที่ตรึงไว้ด้วยแท็ก หากปิดจะได้ editor แบบธรรมดา
dailybot ปิด Dailybot CLI สำหรับแอดออน dailybot

การล็อกอิน gh การตั้งค่า Herdr และตัวตน git ยังคงอยู่หลัง bash dev.sh rebuild เมื่อใช้เลเยอร์ agents image ยังมีสกิลสามตัวของ coding-agents-kit (agentkit, agentkit-setup, agentkit-orchestrate) ซึ่งจะถูกลิงก์เข้าไดเรกทอรีสกิลของทุกเอเจนต์ทุกครั้งที่เริ่ม ดังนั้นคอนเทนเนอร์ที่สร้างขึ้นใหม่ก็ยังคงมีสกิลเหล่านี้

โวลุมสถานะ (SSH host key, ~/.ssh, การล็อกอิน gh, สถานะไคลเอนต์ของ Herdr และประวัติ) มีชื่อว่า state เมื่อหลายเซอร์วิสใช้ compose project เดียวกัน ให้ตั้งชื่อเฉพาะให้แต่ละเซอร์วิสด้วย [compose] state_volume ใน dck.toml (หรือ dck init --state-volume NAME) มิฉะนั้นทุกเซอร์วิสจะเมานต์โวลุมเดียวกัน และ dck doctor จะแจ้งเรื่องนี้

เอเจนต์ข้ามเครื่อง

ตั้งแต่ v0.2.3 บน Docker Desktop คำสั่ง dck up จะเชื่อม mesh แบบสองทิศทางให้โดยไม่ต้องทำขั้นตอนใดด้วยมือ

  • คอนเทนเนอร์และโฮสต์ เอเจนต์ภายในคอนเทนเนอร์เข้าถึงเอเจนต์ Herdr บนโฮสต์ ในคอนเทนเนอร์ dck อื่นทุกตัว และในคอนเทนเนอร์ loopback อื่นที่ Herdr บนโฮสต์ของคุณจัดการอยู่แล้ว และเอเจนต์เหล่านั้นก็เข้าถึงกลับได้ peer ทุกตัวมี host key ที่ถูกตรึงไว้ ไม่มีสิ่งใดได้รับความไว้วางใจตั้งแต่การใช้งานครั้งแรก
  • listener บนโฮสต์ที่เลือกใช้ได้ dck setup จะเสนอเพียงครั้งเดียวให้ติดตั้งเซิร์ฟเวอร์ SSH ระดับผู้ใช้บน 127.0.0.1 ที่รับเฉพาะ key ของ dck และ launchd คอยรันไว้ตลอด (macOS) หากคุณรัน listener แบบ loopback อยู่แล้ว ให้ชี้โปรไฟล์โฮสต์ไปที่ตัวนั้นแทน dck host listener disable จะลบมันออก
  • คงอยู่หลังการ rebuild แค็ตตาล็อกเครื่องของ Herdr ในคอนเทนเนอร์อยู่บนโวลุม ดังนั้น bash dev.sh rebuild จะเก็บทุกเครื่องที่ลงทะเบียนไว้ภายในไว้ ตั้งแต่ v0.3.2 คำสั่ง rebuild, start และ restart จะทำขั้นตอนเดียวกับ up คือลงทะเบียนคอนเทนเนอร์กับ Herdr บนโฮสต์อีกครั้ง ตรึง host key ใหม่ และ push mesh อีกครั้ง ดังนั้นคอนเทนเนอร์ที่ build ใหม่ตั้งแต่ต้นจะเข้าถึงโฮสต์และ peer ของมันได้ทันที
  • pane ของ Codex ภายในคอนเทนเนอร์ เอเจนต์ Codex ต้องมี HERDR_PEERS_SELF ซึ่งก็คือ machine id ของคอนเทนเนอร์ตามที่บันทึกไว้บนโฮสต์ จึงจะถาม peer บนเครื่องอื่นได้ ตั้งแต่ v0.3.3 ชุดเครื่องมือจะบันทึก id นี้ทุกครั้งที่ลงทะเบียน และ login shell ของคอนเทนเนอร์จะ export ค่านี้ให้ จึงไม่มีเอเจนต์ใดต้องตั้งค่าเองด้วยมือ และ dck doctor จะแจ้งเตือนเมื่อค่าไม่ตรงกัน ตั้งแต่ v0.3.4 คอนฟิก Codex ของคอนเทนเนอร์เองจะข้ามการตรวจหาอัปเดตตอนเริ่มทำงานของ Codex และ daemon เบื้องหลังของมัน (ชุดเครื่องมือตรึงเวอร์ชันของ CLI ทุกตัวไว้แล้ว) โดยไม่แตะต้อง home ของ Codex บนโฮสต์ของคุณหรือโปรไฟล์ที่แชร์เลย
  • ตอบกลับจากโฮสต์ได้ด้วย dck setup ติดตั้ง herdr-peers ที่ผ่านการตรวจสอบแล้วบนโฮสต์ ทำให้ dck agents และ dck ask ใช้งานบนโฮสต์ได้ และเอเจนต์บนโฮสต์ตอบกลับด้วย herdr-peers reply
  • คอนเทนเนอร์ที่ชุดเครื่องมือไม่ได้สร้าง ระบุ public key ที่คอนเทนเนอร์เหล่านั้นใช้ล็อกอินไว้ใต้ [ssh] authorized_extra ในโปรไฟล์โฮสต์ของคุณ แล้วคอนเทนเนอร์เหล่านั้นก็จะเข้าถึงคอนเทนเนอร์ dck ได้เช่นกัน

ใช้ร่วมกับ coding-agents-kit ทั้งบนโฮสต์และในคอนเทนเนอร์ แล้ว ak ตัวเดียวกันจะเปิดเอเจนต์ได้ทั้งสองฝั่ง

บัญชีโฮสต์ภายในคอนเทนเนอร์

คอนเทนเนอร์ใช้บัญชีที่คุณมีอยู่แล้วบนโฮสต์ได้ เช่นเดียวกับที่ git ทำงานผ่าน SSH agent ของโฮสต์อยู่แล้ว โดยไม่ต้องล็อกอินภายในคอนเทนเนอร์ ความสามารถนี้ต้องเลือกเปิดใช้เอง และตั้งค่าไว้ใน โปรไฟล์โฮสต์ ของคุณ ไม่ใช่ใน dck.toml ของ repository:

[agents]
host_profiles = true          # ค่าเริ่มต้น false
host_env_keys = ["ZAI_CODING_API_KEY"]   # allow-list ของชื่อ env ที่จะแชร์

เมื่อเปิด host_profiles คำสั่ง dck up จะแชร์เฉพาะโปรไฟล์ของ CLI ที่ repository ติดตั้ง:

  • Claude Code ผ่านโทเคนอายุยาวหนึ่งตัวต่อโปรไฟล์ ได้แก่ CLAUDE_CODE_OAUTH_TOKEN สำหรับ @default และ CLAUDE_CODE_OAUTH_TOKEN_<SUFFIX> สำหรับ @name (suffix เป็นตัวพิมพ์ใหญ่ และอักขระใดที่อยู่นอก A-Z, 0-9 และ _ จะถูกแปลงเป็น _)
  • Codex ผ่านไฟล์ auth ของมัน สำหรับ @default และสำหรับแต่ละโปรไฟล์
  • ไฟล์ env ของชุดเครื่องมือ แบบอ่านอย่างเดียว และคัดเหลือเฉพาะชื่อที่อยู่ใน host_env_keys

home ของ agentkit ทั้งหมดจะไม่ถูกเมานต์เลย และโปรไฟล์ที่เก็บ path แบบ absolute ของโฮสต์จะถูกข้ามไป การล็อกอิน Codex ที่แชร์แบบอ่าน-เขียนอาจถูกรีเฟรชโดยผู้เขียนสองรายพร้อมกัน จึงควรมีเอเจนต์ที่ทำงานอยู่เพียงตัวเดียวต่อหนึ่งบัญชี Codex [agents] default_profile ในโปรไฟล์โฮสต์ (เช่น { claude = "@work3" }) ทำให้คำสั่ง ak claude แบบไม่ระบุโปรไฟล์ภายในคอนเทนเนอร์ใช้บัญชีที่แชร์นั้น (coding-agents-kit ≥ v0.5.2) ส่วนการล็อกอิน Claude แบบ @default บน macOS เก็บอยู่ใน Keychain จึงแชร์ไม่ได้ ตั้งแต่ v0.3.4 shell ของคอนเทนเนอร์ยังชี้คำสั่ง claude หรือ codex แบบไม่ระบุโปรไฟล์ไปที่บัญชีนั้นด้วย ทำให้ pane ที่ Herdr กู้คืนเปิดขึ้นบนบัญชีนั้นแทนที่จะเป็นหน้าจอล็อกอิน ภายในคอนเทนเนอร์ คำสั่ง ak <kind> @<profile> เดียวกันจะรันบนบัญชีเดียวกับบนโฮสต์ ซึ่งทำให้ lead ส่งบัญชีที่ ak pick เลือกไว้ให้ lane ในคอนเทนเนอร์ได้ ดู การรันเอเจนต์หลายตัว

หลาย repository ใน compose stack เดียว

ตั้งแต่ v0.3.3 repository ที่ service ของตนเป็นส่วนหนึ่งของโปรเจกต์ compose ที่ใหญ่กว่า (API, เว็บแอป, worker และฐานข้อมูลที่ใช้โปรเจกต์เดียวกัน) เข้าร่วมโปรเจกต์นั้นได้โดยไม่ต้องแก้ไขสิ่งที่ dck เรนเดอร์ด้วยมือ ทุกอย่างเป็นแบบเพิ่มเติม repository ที่ไม่ได้ตั้งค่าคีย์เหล่านี้เลยจะเรนเดอร์ออกมาเหมือนเดิมทุกประการ

  • หนึ่งโปรเจกต์ หนึ่งโวลุมสถานะต่อ service [compose] project ระบุชื่อโปรเจกต์ที่ใช้ร่วมกันในทุก repository ส่วน state_volume, [compose] networks และ [compose] volumes แยกสถานะของแต่ละ service รวมถึงโวลุมข้อมูลและเครือข่ายของ stack ออกจากกัน
  • บล็อกของผู้ใช้ บรรทัดที่อยู่ระหว่าง # >>> user:<service> >>> และ # <<< user:<service> <<< ภายใน service ของ dck จะถูกเก็บไว้ตามเดิมทุกตัวอักษร ใช้คีย์ธรรมดาสำหรับสิ่งที่ dck ไม่ได้เรนเดอร์ (depends_on, healthcheck) และใช้ x-dck-merge: สำหรับคีย์ที่ dck เรนเดอร์ ไฟล์ที่มี marker ของ dck เพียงบางส่วนจะถูกปฏิเสธพร้อมวิธีแก้ แทนที่จะถูกเขียนทับ
  • สตริงพอร์ต ssh_port และ ports รับนิพจน์ของ compose เช่น "${API_PORT:-8000}:8000" และจะอยู่บน 127.0.0.1 เว้นแต่สตริงจะระบุ IP ของโฮสต์
  • build ที่ใช้ร่วมกันและ launcher ของคุณเอง [build] context และ [build] dockerfile รองรับ Dockerfile ที่หลาย service ใช้ร่วมกัน ส่วน dev_sh = false จะคง dev.sh ของ repository เองไว้
  • อินสแตนซ์ satellite ของ workspace ตั้งแต่ v0.3.5 อินสแตนซ์ที่สองของ service ในโปรเจกต์ compose ของตัวเองจะเริ่มและหยุดผ่าน dck (dck --project P --compose-file F --service S up หรือ down) จึงได้ host key บัญชี ตัวตน git และเครื่อง Herdr เดียวกับอินสแตนซ์หลัก ส่วน up --seed-state-from VOLUME จะคัดลอกเฉพาะการล็อกอินลงในโวลุมสถานะที่ยังว่างอยู่ของอินสแตนซ์นั้น ในไฟล์ overlay extends ต้องระบุไฟล์ที่ตนขยาย
  • Node สำหรับเอเจนต์ Node ของเอเจนต์เองอยู่ใต้ /opt/dck/node และไม่เคยแทนที่ Node ของ image ส่วน [agents] node_first = true จะวาง Node นี้ไว้ลำดับแรกใน PATH เมื่อเครื่องมือของ repository ต้องการ

กุญแจ SSH ของโฮสต์ภายในคอนเทนเนอร์

เครื่องมือบางตัวอ่านเฉพาะไฟล์ key และไม่สนใจ agent ที่ถูก forward มา เช่น gh auth login จะเสนอให้สร้าง key ใหม่ ตั้งแต่ v0.3.2 คุณเลือกเปิดใช้ได้ โดยตั้งค่าได้เฉพาะในโปรไฟล์โฮสต์ของคุณเท่านั้น (dck.toml ของ repository ตั้งค่านี้ไม่ได้ และ dck setup จะถามเพียงครั้งเดียว โดยค่าเริ่มต้นคือไม่เปิดใช้):

[ssh]
copy_keys = true              # default false

ขณะที่เปิดใช้อยู่ dck up จะ bind ~/.ssh ของโฮสต์แบบอ่านอย่างเดียวไว้ที่ ~/.ssh_host และทุกครั้งที่เริ่มจะคัดลอก key id_* ในนั้นไปยัง ~/.ssh ของคอนเทนเนอร์ (private key เป็น 0600) ให้ตรงกับโฮสต์อยู่เสมอ การ forward agent ยังเหมือนเดิม และเมื่อปิดใช้ สำเนาจะถูกลบออกในการเริ่มครั้งถัดไป ข้อแลกเปลี่ยนคือ ~/.ssh ทั้งหมดของโฮสต์อ่านได้จากภายในคอนเทนเนอร์ และ private key จะถูกเก็บไว้ในโวลุมสถานะ

ค่าเริ่มต้นด้านความปลอดภัย

  • ทุกพอร์ตที่เผยแพร่จะ bind กับ 127.0.0.1 เว้นแต่ dck.toml จะตั้งค่า bind
  • git ผ่าน SSH จะใช้ SSH agent ของโฮสต์ผ่าน socket ของมัน ไม่ใช้ไฟล์ key และไม่เมานต์ ~/.ssh หรือ ~/.gitconfig เลย เว้นแต่คุณเปิดใช้ copy_keys ในโปรไฟล์โฮสต์ของคุณ ตัวตน git มาจากค่า DCK_GIT_* ที่ dck setup กรอกให้
  • SSH host key ถูกสร้างขึ้นขณะรันลงในโวลุมเฉพาะของแต่ละโปรเจกต์ ไม่ถูกฝังไว้ใน image เลย เซิร์ฟเวอร์รับเฉพาะ public key ไม่อนุญาตให้ล็อกอินเป็น root และไม่ใช้รหัสผ่าน
  • เทมเพลตไม่เพิ่ม cap_add ไม่ใช้โหมด privileged และไม่เมานต์ Docker socket
  • การดาวน์โหลดทุกครั้งถูกตรึงด้วยเวอร์ชันและตรวจสอบด้วย checksum ส่วน base image ถูกตรึงด้วย digest
  • mesh ของ Herdr ที่ทำให้เอเจนต์ในคอนเทนเนอร์หนึ่งเข้าถึงคอนเทนเนอร์อื่นได้เปิดอยู่โดยค่าเริ่มต้น และมีเอกสารวิธีปิดไว้ใน threat model ของชุดเครื่องมือ listener บนโฮสต์ทำให้โค้ดในคอนเทนเนอร์ที่กำลังรันอยู่เปิด shell บนโฮสต์ในนามของคุณได้ จึงต้องเลือกเปิดใช้เอง ใช้ได้เฉพาะ loopback รับเฉพาะ key ของ dck และลบออกได้ด้วย dck host listener disable

หมายเหตุ

เป็นแบบเลือกใช้และไม่บังคับเสมอ repo หนึ่งสอดคล้องกับมาตรฐานได้อย่างสมบูรณ์แม้ไม่มีแอดออนแบบเลือกใช้ใดเลย รองรับโฮสต์ Linux และ macOS ส่วน mesh ระหว่างคอนเทนเนอร์ต้องใช้ Docker Desktop