devkit English

Tình huống

Các tình huống thực tế, từ đầu đến cuối. Mỗi tình huống nói bạn đang có gì, cần làm gì trong app và trong terminal, sẽ thấy gì, và chỗ nào hay gặp trục trặc. Ví dụ dùng một dự án WebPress tên core-development, một shop tên shop, và các site được park trong ~/Project/sites; bạn thay bằng tên của mình.

1. Developer mới thiết lập core-development từ đầu

Tình huống

Hôm nay là ngày đầu tiên của bạn. Bạn có một máy Mac với Docker Desktop và Homebrew, quyền truy cập các git repository của team, và repository infra chứa file compose của team. Bạn chưa từng chạy dự án này.

Các bước

  1. Cài công cụ: brew install php@8.3 composer pnpm mkcert git (dùng bản PHP mà dự án cần).
  2. Cài devkit (tải về), chuyển vào Applications, chạy một lần xattr -dr com.apple.quarantine /Applications/devkit.app, rồi mở app.
  3. Clone repository infra và thêm nó làm stack. App: Stacks → Thêm stack…. CLI:
    git clone git@github.com:acme/local-infra.git ~/Project/infra/local-infra
    devkit stack add ~/Project/infra/local-infra
    devkit stack up local-infra
  4. Park thư mục sẽ chứa các site. App: Sites → Park thư mục…. CLI: mkdir -p ~/Project/sites && devkit park ~/Project/sites.
  5. Clone dự án và thiết lập đầy đủ. App: Clone từ git… cạnh thư mục đã park, nhập URL, chọn PHP 8.3 cho composer, tích Chạy site khi đã sẵn sàng. CLI:
    devkit site clone git@github.com:acme/core-development.git --php 8.3 --start --progress
  6. Kiểm tra: devkit doctor core-development, hoặc cột Doctor trong Sites.
  7. Chạy các lệnh lần đầu của chính dự án: devkit exec core-development -- php artisan migrate --seed.

Bạn sẽ thấy

Sheet clone lần lượt đánh dấu xong submodule, composer, pnpm và template .env, rồi báo core-development is up at http://localhost:8100. Dòng của site hiện main, PHP 8.3, database core_development và chữ OK màu xanh của doctor. Queue worker chạy trong Processes.

Lỗi thường gặp

  • Submodule riêng tư: lệnh clone dùng SSH agent của bạn. Nếu trong terminal ssh -T git@github.com hỏi passphrase hoặc thất bại, thì trong devkit cũng thất bại. Sửa key, rồi devkit site setup core-development chạy nốt các bước còn lại.
  • composer lỗi vì thiếu extension: lỗi ghi rõ bước nào. Cài extension cho bản PHP đó, rồi chạy lại site setup.
  • "PHP 8.3 not found": Homebrew đã cài nhưng devkit chưa quét lại; lệnh nào cũng quét lại, hoặc bấm Quét lại trong PHP.
  • App không tìm thấy composer hay pnpm trong khi terminal thì có: thoát và mở lại app để nó đọc lại PATH của shell.

2. Bug gấp khi feature đang làm dở

Tình huống

Bạn đang ở feat/loyalty-points trong core-development với 14 file chưa commit và một migration chỉ có trên branch của bạn. Production có bug ở checkout cần sửa trên main ngay hôm nay.

Các bước

  1. Để nguyên feature như hiện tại. Tạo một lane trên branch sửa lỗi từ main. App: … → Lane mới…, tên checkout-fix, Tạo feat/checkout-fix từ main, Fork kèm dữ liệu, bật chạy ngay. CLI:
    devkit git fetch core-development
    devkit lane new core-development checkout-fix --base origin/main --start
  2. Mở lane trong editor (⌘E trong menu … của lane, hoặc mở ~/Project/sites/core-development/.worktrees/checkout-fix), tái hiện bug ở URL của lane, rồi sửa.
  3. Chạy test trong lane: devkit exec core-development--checkout-fix -- php artisan test --filter Checkout.
  4. Commit trong thư mục lane, rồi push: nút Push trên thanh branch của lane, hoặc devkit git push core-development--checkout-fix. Mở pull request như thường lệ.
  5. Khi đã merge: Xoá lane… kèm Xoá luôn branch local, hoặc devkit lane rm core-development--checkout-fix --delete-branch.

Bạn sẽ thấy

Hai dòng: core-development trên feat/loyalty-points với chấm cam, và bên dưới là checkout-fix trên feat/checkout-fix với port riêng (ví dụ http://localhost:8107) và database core_development_l1. Cả hai chạy cùng lúc được.

Lỗi thường gặp

  • Database của lane là bản sao database của site, nên có cả migration của feature. Nếu cần test bản sửa mà không có nó, chọn Chỉ schema rồi chạy migrate trong lane, hoặc rollback migration đó trong lane.
  • --base nhận mọi git ref; hãy fetch trước (như trên) để origin/main là bản mới nhất. Dùng --branch nếu muốn tên branch khác, ví dụ hotfix/checkout.
  • Nếu template không có prefix {{lane.suffix}}, queue worker của lane có thể lấy job từ queue của site. Hãy thêm prefix (xem cảnh báo về Redis).
  • lane rm từ chối khi bản sửa chưa được push. Đó là chủ ý; hãy push trước.

3. Hai AI agent chạy song song, mỗi agent một lane

Tình huống

Bạn muốn Claude Code làm tính năng xuất CSV trong khi Codex CLI refactor phần tìm kiếm, cả hai trong core-development, mà không giẫm chân nhau hay đụng vào việc của bạn.

Các bước

  1. Kết nối cả hai agent một lần (xem thiết lập). App: MCP → chọn agent → Sao chép hoặc Ghi vào dự án…. CLI:
    cd ~/Project/sites/core-development
    devkit mcp config claude-code --write
    devkit mcp config codex --write
  2. Tạo một lane cho mỗi agent, để mỗi agent có thư mục, branch, database và port riêng:
    devkit lane new core-development agent-export --start
    devkit lane new core-development agent-search --start
    Hoặc để từng agent tự làm: "Create a lane named agent-export of core-development with lane_new (start: true) and work only in its folder."
  3. Khởi động mỗi agent trong thư mục lane của nó (.worktrees/agent-export, .worktrees/agent-search) và dặn nó chạy test bằng exec của devkit trên lane của mình.
  4. Theo dõi chúng làm gì: MCP → Audit log, hoặc devkit mcp audit --limit 30.
  5. Review từng branch, merge, rồi xoá các lane. Khi agent gọi lane_rm, nó nhận CONFIRM_REQUIRED kèm danh sách những gì sẽ mất; agent nên cho bạn xem và hỏi lại.

Bạn sẽ thấy

Menu bar hiện 2 AI agent đang kết nối. Sites liệt kê cả hai lane dưới core-development với branch feat/agent-export và feat/agent-search. Audit log ghi từng lệnh gọi kèm tên agent, tool và tham số.

Lỗi thường gặp

  • Agent khởi động trong thư mục của chính site sẽ sửa working tree của bạn. Hãy khởi động nó trong thư mục lane.
  • Agent chạy php từ shell riêng có thể dùng bản PHP khác và sai .env. Dặn chúng dùng exec.
  • Chạy hai bộ test cùng lúc trên laptop yếu sẽ chậm; mỗi lane là một bản sao đầy đủ của app.
  • Đặt prefix Redis trong template trước khi bắt đầu, nếu không hai lane và site sẽ dùng chung cache và queue.

4. Thử một migration rủi ro một cách an toàn

Tình huống

Một migration viết lại bảng orders của shop. Bạn muốn chạy nó trên dữ liệu thật, kiểm tra kết quả, và quay lại đúng trạng thái trước đó nếu có sự cố.

Các bước

  1. Dừng những gì đang ghi vào database để snapshot nhất quán: devkit proc stop shop (queue, scheduler).
  2. Tạo snapshot. App: … → Tạo snapshot database, tên before_orders_rewrite. CLI: devkit db snapshot shop before_orders_rewrite.
  3. Chạy migration: devkit exec shop -- php artisan migrate.
  4. Kiểm tra: devkit db query shop "SELECT status, COUNT(*) FROM orders GROUP BY status", và bấm thử qua site.
  5. Nếu sai: App: tab Database → Khôi phục… trên before_orders_rewrite, giữ bật Tạo snapshot database hiện tại trước. CLI: devkit db restore shop before_orders_rewrite --yes.
  6. Sửa migration và lặp lại từ bước 3. Xong việc thì xoá các snapshot không còn cần (Xoá…, hoặc devkit db snapshot rm shop before_orders_rewrite --yes).

Bạn sẽ thấy

Sheet khôi phục liệt kê Những gì sẽ diễn ra: dừng server và các process PHP của site, chép snapshot vào một database tạm rồi tráo vào, sau đó chạy lại chúng. Sau đó tab Database có hai snapshot: của bạn và pre_restore_20261026_153012, tức trạng thái hỏng, phòng khi bạn cần so sánh.

Lỗi thường gặp

  • Khôi phục cũng đưa bảng migrations về như cũ, nên lần sau Laravel sẽ chạy lại migration. Ở đây đó đúng là điều bạn muốn.
  • View, trigger và stored procedure không nằm trong snapshot. Nếu migration thay đổi chúng, hãy tạo lại sau khi khôi phục.
  • Snapshot nằm trên cùng database server và chiếm dung lượng đĩa bằng chính database. Xoá chúng khi xong việc.
  • An toàn hơn nữa: làm trong một lane (devkit lane new shop orders-rewrite) và không bao giờ đụng tới dữ liệu của site.

5. Thử nâng lên bản PHP mới

Tình huống

shop chạy trên PHP 8.2. Bạn muốn biết nó có chạy được trên 8.4 không, và quay lại chỉ với một cú bấm nếu không.

Các bước

  1. Cài 8.4 nếu chưa có: brew install php@8.4 (Linux: package của distro; mục PHP hiện đúng lệnh trên thẻ chưa cài).
  2. Hỏi composer trước khi chuyển. App: PHP → chọn 8.4 → Kiểm tra site khác → shop, có ghi (nếu chuyển sang). CLI:
    devkit php check 8.4 shop
    shop with PHP 8.4: fails
      ext-imagick n/a missing (spatie/image requires *)
  3. Sửa những gì nó báo (cài extension cho 8.4, hoặc cập nhật package), rồi kiểm tra lại cho tới khi nó báo ok.
  4. Chuyển. App: thẻ PHP trong chi tiết site → 8.4, rồi Chạy lại ngay trên banner. CLI:
    devkit site set shop --php 8.4
    devkit site up shop
  5. Chạy test: devkit exec shop -- php artisan test, và dùng thử site.
  6. Chưa ổn? Bấm Hoàn tác trên banner, hoặc devkit site set shop --php 8.2 && devkit site up shop.

Bạn sẽ thấy

Banner ghi Đã chuyển sang PHP 8.4, kèm lưu ý rằng serve và các process PHP vẫn dùng 8.2 cho tới khi site chạy lại, rằng lane đi theo site, và các phát hiện của doctor cho bản mới (nếu có). Sau Chạy lại ngay, dòng của site ghi PHP 8.4.

Lỗi thường gặp

  • Chuyển bản không tự chạy lại site đang chạy; cho tới khi chạy lại, binary cũ vẫn phục vụ. Cẩn thận với cảm giác "vẫn chạy tốt" mà thực ra vẫn là 8.2.
  • Lane luôn chạy bản PHP của site, nên cũng chuyển theo.
  • Extension đi theo từng bản PHP: extension pecl hay Homebrew cài cho 8.2 không có trên 8.4. devkit php info 8.4 liệt kê những gì đã được nạp.
  • Lane không thể tự thử bản PHP khác, vì luôn chạy bản của site. php check là cách hỏi mà không phải chuyển gì cả.

6. Debug từng bước một request bằng Xdebug

Tình huống

Một mã giảm giá bị áp hai lần trên trang giỏ hàng của shop và bạn muốn đi từng bước qua request trong PhpStorm hoặc VS Code.

Các bước

  1. Đảm bảo Xdebug đã được cài cho bản PHP của site: devkit xdebug status shop. Nếu chưa, nó in lệnh cài (ví dụ pecl install xdebug).
  2. Bật lên. App: … → Xdebug… → debug → Áp dụng và chạy lại. CLI: devkit xdebug on shop.
  3. Trong IDE, lắng nghe ở port 9003: Start Listening for PHP Debug Connections của PhpStorm, hoặc cấu hình Listen for Xdebug của VS Code (xem Kết nối IDE).
  4. Đặt breakpoint trong code giỏ hàng, bật trigger trên trình duyệt (Xdebug Helper, hoặc thêm ?XDEBUG_TRIGGER=1 vào URL) rồi tải trang.
  5. Debug lệnh CLI cũng vậy: XDEBUG_TRIGGER=1 devkit exec shop --xdebug -- php artisan cart:recalculate 42.
  6. Xong việc thì tắt đi (off trong sheet, hoặc devkit xdebug off shop): Xdebug làm chậm mọi request.

Bạn sẽ thấy

Sheet Xdebug với debug hiện Bắt đầu phiên: Khi có trigger, Client host: 127.0.0.1, Port: 9003 và Ánh xạ đường dẫn: Không cần. IDE dừng ở breakpoint.

Lỗi thường gặp

  • Không có gì xảy ra: thiếu trigger. Thiết lập của devkit chỉ debug những request có trigger.
  • Với engine caddy, Xdebug là của container PHP, nên bật lên sẽ ảnh hưởng mọi site trên container đó; sheet có liệt kê. File compose phải truyền XDEBUG_MODE: ${XDEBUG_MODE:-off}, và image phải trỏ xdebug.client_host về máy của bạn (host.docker.internal; trên Linux thêm extra_hosts: ["host.docker.internal:host-gateway"]).
  • Chạy docker compose up -d cho stack bên ngoài devkit sẽ tạo lại container với Xdebug tắt.
  • Queue worker chạy job trong một process khác. Để debug một job, bật trigger cho process đó bằng XDEBUG_TRIGGER=1 devkit exec shop --xdebug -- php artisan queue:work --once.

7. Khi bạn cần HTTPS

Tình huống

shop đăng nhập bằng Google, mà OAuth client của Google chỉ nhận redirect URL https://; session cookie của nó là Secure; và PWA của nó đăng ký service worker. Không cái nào chạy được trên http://localhost:8100.

Các bước

  1. Cài mkcert và tin cậy CA của nó một lần. App: Cài đặt → Chứng chỉ → Tin cậy…, mở một terminal có thể hỏi mật khẩu; sau đó bấm Kiểm tra lại. CLI: brew install mkcert && devkit trust.
  2. Đảm bảo một stack của bạn có service Caddy và PHP-FPM đúng bản PHP của site, mount các site ở cùng đường dẫn (có sẵn file compose mẫu trong HTTPS với engine caddy), rồi thêm stack: devkit stack add ~/Project/infra/web-stack.
  3. Đổi engine. App: … → Đổi engine… → caddy; sheet liệt kê Những gì thay đổi và Yêu cầu. CLI:
    devkit site set shop --engine caddy --php 8.3
    devkit site up shop          # https://shop.localhost
  4. Đăng ký https://shop.localhost/auth/google/callback làm redirect URL trong console của Google. Vì APP_URL lấy từ {{site.url}}, Laravel đã tự tạo đúng URL.
  5. Chạy devkit doctor shop: nó kiểm tra mkcert, admin API của Caddy, các mount và chứng chỉ.

Bạn sẽ thấy

Cột URL hiện https://shop.localhost với chứng chỉ hợp lệ (trình duyệt không cảnh báo). Processes hiện caddy route → php-fpm cho serve. Các lane của site có https://<lane>.shop.localhost.

Lỗi thường gặp

  • SITE_NOT_MOUNTED: container Caddy hoặc PHP không thấy site ở cùng đường dẫn tuyệt đối. Sửa volume, ví dụ ${HOME}/Project:${HOME}/Project.
  • CADDY_UNREACHABLE: image caddy:2 chỉ mở admin API bên trong container, trừ khi đặt CADDY_ADMIN: 0.0.0.0:2019 và publish port đó trên 127.0.0.1.
  • Docker Desktop không bật privileged port mapping thì không publish được 443: publish 8443:443, và URL sẽ thành https://shop.localhost:8443.
  • Sau khi chạy lại container Caddy, site hiện là đã dừng: chạy lại site up để đưa route của nó trở lại.
  • Nếu nhà cung cấp nào từ chối tên miền .localhost, dùng devkit settings set --domain-suffix test và devkit hosts sync (nó hỏi mật khẩu).

8. Làm việc trên nhiều module và submodule

Tình huống

Một tính năng CMS động tới chính core-development và bốn module trong modules/. Mọi repository đều cần branch feat/cms-blocks, và tất cả phải được push cùng nhau.

Các bước

  1. Xem tình trạng mọi thứ: devkit modules core-development --fetch, hoặc tab Modules sau khi bấm Fetch.
  2. Tạo branch trong site: thanh branch → Branch mới… → feat/cms-blocks → Tạo và checkout. CLI: devkit git checkout core-development feat/cms-blocks --create.
  3. Tạo branch trong mọi module. App: tab Modules, gõ feat/cms-blocks vào Branch, tích Tạo nếu chưa có, bấm Checkout trong mọi module. CLI (tất cả, hoặc chỉ một số):
    devkit modules checkout core-development feat/cms-blocks --create
    devkit modules checkout core-development feat/cms-blocks --create --only common,framework,media,page-builder
  4. Làm việc và commit trong từng thư mục module như bình thường (nút Terminal của mỗi dòng mở terminal ở đó). Sau đó commit các submodule pointer mới trong site.
  5. Push tất cả: Push trên thanh branch với Gồm cả submodule được bật, hoặc devkit git push core-development: các module đi trước được push trước, rồi tới site, tự đặt upstream ở lần push đầu.
  6. Sau này, để theo việc của đồng đội: Pull tất cả / devkit modules pull core-development, rồi devkit git pull core-development.

Bạn sẽ thấy

Lệnh checkout báo một dòng cho mỗi module: done, unchanged (đã ở đó rồi), hoặc skipped kèm MODULE_DIRTY. Các dòng Modules hiện feat/cms-blocks với chấm xanh dương (không phải branch mà .gitmodules theo dõi) và Push ↑1 cho tới khi push.

Lỗi thường gặp

  • Module có thay đổi chưa commit sẽ bị bỏ qua, không bao giờ bị đụng tới. Commit hoặc stash nó, rồi chạy lại checkout; lệnh chỉ làm ở những chỗ cần.
  • Nếu push một module thất bại, site sẽ không được push, để site không bao giờ trỏ tới commit mà người khác không có. Sửa module đó rồi push lại.
  • Checkout sang branch khác của site sẽ đưa các submodule về commit mà branch đó ghi lại. Hãy commit phần việc trong module trước khi đổi branch của site.
  • modules checkout không bao giờ fetch: khi branch chỉ có trên remote, hãy fetch trước.

9. Nạp bản sao dữ liệu production, rồi giữ một snapshot sạch

Tình huống

Bạn nhận được một bản dump đã làm sạch shop-prod.sql.gz và muốn shop chạy trên nó, kèm một bản sạch để quay về mỗi khi các thử nghiệm làm rối dữ liệu.

Các bước

  1. Dừng site để không có gì ghi vào trong lúc import: devkit site down shop.
  2. Tìm database: devkit stack list hiện service MySQL và port đã publish; mật khẩu root nằm trong file compose của stack. devkit không có lệnh import; hãy dùng client của chính stack:
    cd ~/Project/infra/local-infra
    gunzip -c ~/Downloads/shop-prod.sql.gz | docker compose exec -T mysql sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD" shop'
    Thay mysql bằng tên service database của bạn; với MariaDB, client là mariadb và biến là MARIADB_ROOT_PASSWORD. Client trên máy bạn cũng được: mysql -h 127.0.0.1 -P <port> -uroot -p shop.
  3. Chạy site và các migration còn chờ: devkit site up shop && devkit exec shop -- php artisan migrate.
  4. Giữ bản sạch: devkit db snapshot shop prod_clean (tab Database → Tạo snapshot database…).
  5. Thoải mái thử nghiệm. Muốn làm lại từ đầu: devkit db restore shop prod_clean --yes.
  6. Đưa dữ liệu mới vào các lane đang có: Đặt lại database từ shop… trên từng lane, hoặc devkit db reset shop--feature-x --yes.

Bạn sẽ thấy

devkit db snapshots shop liệt kê prod_clean kèm dung lượng. Các lane mới tạo bằng lane new tự fork dữ liệu đã import.

Lỗi thường gặp

  • Site giữ .env riêng render từ template, nên APP_URL, cấu hình mail và key thanh toán của production không bao giờ lọt vào qua bản dump. Nhưng các thiết lập lưu trong database (URL, API key trong bảng settings) thì có: hãy kiểm tra và làm sạch chúng.
  • Dữ liệu chứa địa chỉ e-mail thật của khách hàng. Template được tạo sẵn sẽ trỏ MAIL_HOST và MAIL_PORT tới Mailpit hoặc MailHog của stack nếu stack có, để mail rơi vào Hộp thư của nó; hãy kiểm tra template của bạn có làm vậy trước khi chạy các job trong queue.
  • Mỗi snapshot và mỗi lần fork lane là một bản sao đầy đủ trên cùng server: database 5 GB cộng hai lane và ba snapshot là 30 GB đĩa của Docker.
  • Khôi phục prod_clean cũng khôi phục bảng migrations của nó; chạy lại migrate sau đó nếu branch của bạn có migration mới hơn.

10. Chạy queue worker, scheduler và Vite cùng lúc

Tình huống

core-development có queue, các tác vụ định kỳ, Laravel Reverb cho websocket, và nhiều cấu hình Vite (vite.config.js, vite.config.core.js, vite.config.admin.js). Bạn muốn tất cả cùng chạy khi làm phần admin, và những ngày khác chỉ cần queue.

Các bước

  1. Xem devkit đã nhận ra những gì: devkit proc list core-development (queue, schedule, vite, vite:admin, vite:core…).
  2. Chạy những gì hôm nay cần. App: tab Processes → chạy schedule và vite:admin. CLI:
    devkit proc start core-development schedule vite:admin
  3. Thêm Reverb với port riêng, chạy cùng site:
    devkit proc add core-development reverb --command "php artisan reverb:start --port={port}" --port --autostart
  4. Cho scheduler chạy cùng site luôn: công tắc Tự chạy, hoặc devkit proc set core-development schedule --autostart=true.
  5. Sau khi sửa một class job: devkit proc restart core-development queue (worker giữ code cũ trong bộ nhớ).
  6. Có gì đó dừng? devkit proc logs core-development vite:admin --lines 50, hoặc khung log dưới bảng.

Bạn sẽ thấy

Mỗi process Vite có port riêng trong cột Port (ví dụ 8101, 8102), được cấp một lần và giữ nguyên, nên một lane có thể chạy cùng cấu hình Vite ở port khác cùng lúc. Process bị crash hiện đã thoát kèm các dòng log cuối.

Lỗi thường gặp

  • Vite chạy với --strictPort trên port devkit cấp; vite.config của bạn không nên hard-code port khác.
  • Lệnh chạy không qua shell: php artisan a && php artisan b bị từ chối. Dùng sh -c 'php artisan a && php artisan b'.
  • Sau lần proc add, set hay rm đầu tiên, danh sách được lưu lại, nên một file vite.config.x.js mới sẽ không được nhận cho tới khi chạy devkit proc reset core-development (lệnh này cũng bỏ các thay đổi của bạn).
  • devkit không tự chạy lại process bị crash. Queue worker chết vì lỗi fatal sẽ ở trạng thái đã thoát cho tới khi bạn chạy nó.

11. Dọn dung lượng đĩa

Tình huống

Docker báo đĩa sắp đầy. Qua nhiều tháng bạn đã tạo những lane, snapshot và site thử nghiệm không còn cần đến.

Các bước

  1. Liệt kê những gì đang có: devkit lane list, devkit db snapshots <site> cho từng site, devkit site list --all.
  2. Xoá các lane đã xong. Kiểm tra trước những gì sẽ mất, rồi xoá. App: Xoá lane… hiện ra điều đó. CLI:
    devkit lane rm core-development--old-spike --dry-run
    devkit lane rm core-development--old-spike
    Lệnh này xoá luôn database của lane và các snapshot của nó.
  3. Xoá snapshot cũ: tab Database → Xoá…, hoặc devkit db snapshot rm shop pre_restore_20260901_101500 --yes. Snapshot an toàn (pre_restore_…) chồng chất sau nhiều lần khôi phục.
  4. Xoá các site đã xong, kèm database, thư mục chuyển vào Thùng rác. App: Xoá site…, gõ tên, tích Xoá database. CLI:
    devkit site delete old-landing --trash --drop-db --yes
  5. Dọn Thùng rác khi bạn đã chắc chắn.

Bạn sẽ thấy

lane rm in removed … và dropped core_development_l3, …. site delete in thư mục đã đi đâu và database nào đã bị xoá.

Lỗi thường gặp

  • DIRTY_WORKTREE: có phần việc chỉ tồn tại trên máy bạn (chưa commit, chưa push, một stash). Push nó, hoặc chấp nhận mất và truyền --force (app: Vẫn xoá và bỏ phần việc này).
  • site delete không có --drop-db sẽ giữ database trên server, mà xoá database mới là việc giải phóng nhiều đĩa Docker nhất.
  • Với --trash, Thùng rác phải nằm cùng ổ đĩa với site; site trên ổ ngoài không thể vào Thùng rác trong home của bạn, và devkit báo điều đó trước khi làm gì.
  • Chưa chắc? Ẩn site thay vì xoá: không có gì bị xoá, nhưng site dừng và biến khỏi danh sách.

12. Xử lý sự cố với doctor

Tình huống

Sáng thứ Hai, Chạy tất cả để lại vài site màu đỏ. Thay vì đoán, hãy hỏi doctor.

Các bước

devkit doctor            # cả máy và mọi site đang hiện
devkit doctor shop       # chi tiết một site
devkit status            # những gì đang chạy, và các vấn đề như PORT_IN_USE

Trong app: badge Doctor trên mỗi dòng, Chạy doctor trong menu, hoặc Cài đặt → Doctor; Sao chép báo cáo chép báo cáo để gửi đồng đội hoặc bộ phận hỗ trợ.

Các phát hiện thường gặp

Docker không chạy
fail docker … cannot connect to the Docker daemon, gợi ý install or start Docker (Docker Desktop, OrbStack or Colima). Bật Docker, rồi Chạy tất cả lần nữa; site up sẽ chạy các service của stack mà site cần.
Port đang bị dùng
status báo PORT_IN_USE: port 8100 of shop is held by another process, gợi ý lsof -nP -iTCP:8100 -sTCP:LISTEN. Thường đó là một php artisan serve bạn tự chạy, hoặc site của một công cụ khác. Dừng nó; site giữ port của mình và phục vụ ở đó lần chạy sau.
Thiếu một bản PHP
fail site.php shop … PHP 8.1 not found on this machine, gợi ý brew install php@8.1 (hoặc package của distro). Cài nó, hoặc chuyển site sang một bản đã cài bằng devkit site set shop --php 8.3.
Thiếu Xdebug
site.xdebug lỗi với XDEBUG_MISSING cho site đang bật Xdebug, gợi ý …/pecl install xdebug. Cài nó cho bản PHP đó, hoặc tắt Xdebug cho site.
Template không render được
fail site.template … unresolved template variables: s3.endpoint: template dùng một service mà stack không có. Bỏ dòng đó hoặc thêm service.
Yêu cầu nền tảng
site.composer liệt kê những gì composer check-platform-reqs báo cho bản PHP của site (thiếu extension, bản quá mới).

Lỗi thường gặp

  • App tìm thấy ít hơn terminal: app đọc PATH của login shell lúc khởi động. Sửa shell profile, rồi thoát và mở lại app.
  • Site đã ẩn không được kiểm tra, trừ khi bạn chỉ định tên.
  • doctor không bao giờ thay đổi gì; các gợi ý của nó là lệnh để bạn tự chạy.

13. Thành viên trong team dùng Linux

Tình huống

Một đồng nghiệp mới dùng Ubuntu 24.04 và muốn thiết lập giống những người dùng Mac.

Các bước

  1. Cài những thứ cơ bản: Docker Engine (và thêm user vào group docker), git, composer, và những gì app cần: sudo apt install python3-gi gir1.2-gtk-4.0 librsvg2-common.
  2. PHP: Ubuntu có sẵn một bản (sudo apt install php8.3-cli cùng các extension như php8.3-mysql php8.3-redis php8.3-intl php8.3-gd); các bản khác lấy từ repository ondrej/php. devkit tìm thấy chúng trong /usr/bin/php*.
  3. Cài devkit:
    tar -xzf devkit_v1.0.0_linux_amd64_app.tar.gz
    ./devkit_v1.0.0_linux_amd64_app/install.sh
    devkit-gtk &
  4. Từ đây mọi thứ giống trên macOS: thêm stack, park thư mục site, clone hoặc chạy site, lane, MCP.
  5. Cho HTTPS: sudo apt install mkcert libnss3-tools, rồi Cài đặt → Chứng chỉ → Tin cậy…, mở một terminal để nhập mật khẩu.

Bạn sẽ thấy

Biểu tượng devkit trên tray (GNOME của Ubuntu có extension AppIndicator), với menu giống menu bar trên Mac, và cùng cửa sổ quản lý, sáng hoặc tối theo desktop.

Lỗi thường gặp

  • Không có biểu tượng tray trên GNOME thuần: cài extension AppIndicator, hoặc chạy devkit-gtk --no-tray để có cửa sổ panel.
  • DOCKER_UNAVAILABLE dù Docker đang chạy: user không truy cập được socket. Thêm họ vào group docker rồi đăng nhập lại.
  • Trên ext4 (không có copy-on-write), lane chép toàn bộ vendor/ và node_modules/. Tạo lane sẽ lâu hơn và tốn đĩa hơn so với trên Mac.
  • Xdebug trong container PHP không với tới host.docker.internal trên Docker native, trừ khi service có extra_hosts: ["host.docker.internal:host-gateway"].
  • Mở trong editor chạy code; đặt lệnh khác trong Cài đặt → App này → Editor hoặc export DEVKIT_EDITOR. Tin cậy và đồng bộ hosts dùng $TERMINAL nếu biến này được đặt.

14. Cho agent chạy test mà không đụng tới site chính

Tình huống

Bạn muốn agent sửa một bộ test đang lỗi. Test của nó chạy migration và truncate bảng, và bạn không muốn chuyện đó xảy ra gần database bạn đang dùng.

Các bước

  1. Tạo cho nó một lane với schema trống: App: Lane mới… → Chỉ schema. CLI: devkit lane new core-development agent-tests --schema-only --start. Hoặc bảo agent gọi lane_new với schema_only: true.
  2. Dặn agent: "Work only in .worktrees/agent-tests. Run tests with devkit's exec on core-development--agent-tests, shortcut phpunit. Read failures with logs. Never call tools on core-development itself."
  3. Các lệnh gọi của agent trông như thế này:
    {"tool":"exec","arguments":{"site":"core-development--agent-tests","shortcut":"phpunit","command":["--filter","InvoiceTest"]}}
    {"tool":"exec","arguments":{"site":"core-development--agent-tests","command":["php","artisan","test"],"timeout_seconds":1200}}
  4. Với một lỗi khó, nó có thể chạy riêng một test với xdebug: true; việc đó không bật Xdebug cho bất cứ thứ gì khác.
  5. Kiểm tra việc nó làm trong audit log và trên branch của lane, rồi xoá lane.

Bạn sẽ thấy

Kết quả exec trả về dạng JSON với exitCode và 64 KiB output cuối; một lượt test thất bại là ok: true với exitCode khác 0, nhờ vậy agent đọc được lỗi. Database và process của site bạn không bị đụng tới; audit log chỉ hiện …--agent-tests là đích.

Lỗi thường gặp

  • Test Laravel thường dùng database riêng từ phpunit.xml hoặc .env.testing. Nếu ở đó ghi một database cố định, hai lane chạy test sẽ dùng chung nó; nên dùng sqlite in-memory, hoặc tên có chứa lane.
  • Bộ test dài: tăng timeout_seconds (mặc định 600). Lệnh quá thời gian sẽ bị dừng, kể cả trong container PHP.
  • Output của exec giới hạn 64 KiB: hãy yêu cầu --stop-on-failure hoặc một filter, đừng lấy output của cả bộ test.
  • Agent có shell riêng có thể đi vòng qua devkit. Dùng thiết lập quyền của agent để giữ nó trong thư mục lane.