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
- Cài công cụ:
brew install php@8.3 composer pnpm mkcert git(dùng bản PHP mà dự án cần). - 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. - 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 - 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. - 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 - Kiểm tra:
devkit doctor core-development, hoặc cột Doctor trong Sites. - 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.comhỏi passphrase hoặc thất bại, thì trong devkit cũng thất bại. Sửa key, rồidevkit site setup core-developmentchạ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
composerhaypnpmtrong khi terminal thì có: thoát và mở lại app để nó đọc lạiPATHcủ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
- Để 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êncheckout-fix, Tạofeat/checkout-fixtừ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 - 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. - Chạy test trong lane:
devkit exec core-development--checkout-fix -- php artisan test --filter Checkout. - 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ệ. - 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
migratetrong lane, hoặc rollback migration đó trong lane. --basenhận mọi git ref; hãy fetch trước (như trên) đểorigin/mainlà bản mới nhất. Dùng--branchnế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 rmtừ 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
- 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 - Tạo một lane cho mỗi agent, để mỗi agent có thư mục, branch, database và port riêng:
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."devkit lane new core-development agent-export --start devkit lane new core-development agent-search --start - 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ằngexeccủa devkit trên lane của mình. - Theo dõi chúng làm gì: MCP → Audit log, hoặc
devkit mcp audit --limit 30. - Review từng branch, merge, rồi xoá các lane. Khi agent gọi
lane_rm, nó nhậnCONFIRM_REQUIREDkè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
phptừ shell riêng có thể dùng bản PHP khác và sai.env. Dặn chúng dùngexec. - 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
- Dừng những gì đang ghi vào database để snapshot nhất quán:
devkit proc stop shop(queue, scheduler). - Tạo snapshot. App:
…→ Tạo snapshot database, tênbefore_orders_rewrite. CLI:devkit db snapshot shop before_orders_rewrite. - Chạy migration:
devkit exec shop -- php artisan migrate. - Kiểm tra:
devkit db query shop "SELECT status, COUNT(*) FROM orders GROUP BY status", và bấm thử qua site. - 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. - 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
migrationsvề 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
- 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). - 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 *) - 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.
- 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 - Chạy test:
devkit exec shop -- php artisan test, và dùng thử site. - 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
peclhay Homebrew cài cho 8.2 không có trên 8.4.devkit php info 8.4liệ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 checklà 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
- Đả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). - Bật lên. App:
…→ Xdebug… → debug → Áp dụng và chạy lại. CLI:devkit xdebug on shop. - 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).
- Đặt breakpoint trong code giỏ hàng, bật trigger trên trình duyệt (Xdebug Helper, hoặc thêm
?XDEBUG_TRIGGER=1vào URL) rồi tải trang. - Debug lệnh CLI cũng vậy:
XDEBUG_TRIGGER=1 devkit exec shop --xdebug -- php artisan cart:recalculate 42. - 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_hostvề máy của bạn (host.docker.internal; trên Linux thêmextra_hosts: ["host.docker.internal:host-gateway"]). - Chạy
docker compose up -dcho 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
- 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. - Đả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. - Đổ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 - Đăng ký
https://shop.localhost/auth/google/callbacklàm redirect URL trong console của Google. VìAPP_URLlấy từ{{site.url}}, Laravel đã tự tạo đúng URL. - 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: imagecaddy:2chỉ mở admin API bên trong container, trừ khi đặtCADDY_ADMIN: 0.0.0.0:2019và publish port đó trên127.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ànhhttps://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ùngdevkit settings set --domain-suffix testvà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
- Xem tình trạng mọi thứ:
devkit modules core-development --fetch, hoặc tab Modules sau khi bấm Fetch. - 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. - Tạo branch trong mọi module. App: tab Modules, gõ
feat/cms-blocksvà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 - 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.
- 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. - Sau này, để theo việc của đồng đội: Pull tất cả /
devkit modules pull core-development, rồidevkit 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 checkoutkhô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
- Dừng site để không có gì ghi vào trong lúc import:
devkit site down shop. - Tìm database:
devkit stack listhiệ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:
Thaycd ~/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'mysqlbằng tên service database của bạn; với MariaDB, client làmariadbvà 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. - Chạy site và các migration còn chờ:
devkit site up shop && devkit exec shop -- php artisan migrate. - Giữ bản sạch:
devkit db snapshot shop prod_clean(tab Database → Tạo snapshot database…). - Thoải mái thử nghiệm. Muốn làm lại từ đầu:
devkit db restore shop prod_clean --yes. - Đư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ữ
.envriêng render từ template, nênAPP_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_HOSTvàMAIL_PORTtớ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_cleancũng khôi phục bảngmigrationscủa nó; chạy lạimigratesau đó 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
- Xem devkit đã nhận ra những gì:
devkit proc list core-development(queue, schedule, vite, vite:admin, vite:core…). - Chạy những gì hôm nay cần. App: tab Processes → chạy
schedulevàvite:admin. CLI:devkit proc start core-development schedule vite:admin - 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 - 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. - Sau khi sửa một class job:
devkit proc restart core-development queue(worker giữ code cũ trong bộ nhớ). - 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
--strictPorttrên port devkit cấp;vite.configcủ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 bbị từ chối. Dùngsh -c 'php artisan a && php artisan b'. - Sau lần
proc add,sethayrmđầu tiên, danh sách được lưu lại, nên một filevite.config.x.jsmới sẽ không được nhận cho tới khi chạydevkit 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
- Liệt kê những gì đang có:
devkit lane list,devkit db snapshots <site>cho từng site,devkit site list --all. - 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:
Lệnh này xoá luôn database của lane và các snapshot của nó.devkit lane rm core-development--old-spike --dry-run devkit lane rm core-development--old-spike - 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. - 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 - 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 deletekhông có--drop-dbsẽ 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 upsẽ chạy các service của stack mà site cần.- Port đang bị dùng
statusbáoPORT_IN_USE: port 8100 of shop is held by another process, gợi ýlsof -nP -iTCP:8100 -sTCP:LISTEN. Thường đó là mộtphp artisan servebạ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ằngdevkit site set shop --php 8.3.- Thiếu Xdebug
site.xdebuglỗi vớiXDEBUG_MISSINGcho 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.composerliệt kê những gìcomposer check-platform-reqsbá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
PATHcủ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
- 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. - PHP: Ubuntu có sẵn một bản (
sudo apt install php8.3-clicù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*. - 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 & - 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.
- 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_UNAVAILABLEdù Docker đang chạy: user không truy cập được socket. Thêm họ vào groupdockerrồ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.internaltrê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 exportDEVKIT_EDITOR. Tin cậy và đồng bộ hosts dùng$TERMINALnế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
- 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ọilane_newvớischema_only: true. - Dặn agent: "Work only in
.worktrees/agent-tests. Run tests with devkit'sexeconcore-development--agent-tests, shortcutphpunit. Read failures withlogs. Never call tools oncore-developmentitself." - 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}} - 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. - 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.xmlhoặc.env.testing. Nếu ở đó ghi một database cố định, hai lane chạy test sẽ dùng chung nó; nên dùngsqlitein-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
execgiới hạn 64 KiB: hãy yêu cầu--stop-on-failurehoặ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.