feat(docker): 移除 bind mount,程式碼與 vendor 烘進 image
Run Tests / test (pull_request) Successful in 32s

Dockerfile 改 multi-stage(app + web),app/scheduler/queue-worker/
reverb/nginx 五個服務都不再依賴 ./:/var/www bind mount 取得程式碼;
nginx 改本地 build 從 app 階段 COPY --from 取得 public/,public/storage
symlink 在兩階段各自於 build 時建立。docker-compose.yml 新增具名 volume
storage-app-public 讓上傳檔案跨 image 重建保留;env_file: 取代原本
bind mount 帶入 .env 的方式,只給四個 Laravel runtime 服務。
compose.override.yml 補上開發用 bind mount 維持改 code 立即生效;
docker-entrypoint.sh 收斂到只剩目錄權限設定,migration/cache/swagger
移到 deploy.yml 統一負責,避免職責重疊。

實作驗證時發現並修復三個規劃階段沒預見的問題:app 服務的 build: 缺
target: app 導致預設建到最後一個 stage(image 實際變成 nginx);
.dockerignore 需排除本機既有的 public/storage 符號連結(Windows 上
會讓 build context 打包失敗);env_file: 讓 .env 全部變數變成真實
環境變數、蓋掉 phpunit.xml 的測試隔離設定,已擴大 tests/bootstrap.php
的強制覆蓋清單修復(239 tests 全綠)。

本機 dev 模式與 production 模式(無 override)皆完整驗證:healthcheck、
migration/cache/swagger、上傳檔案持久性、nginx 獨立於 app 服務靜態檔
與 storage 檔案、.env 熱更新、nginx 無 .env 存取權。

openspec change: bake-image-remove-bind-mount

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0142LC1kQb8EyV59TjHDkhWS
This commit is contained in:
2026-08-04 16:59:18 +08:00
parent 3b0cdf96d8
commit 6a7d98b0fe
12 changed files with 226 additions and 168 deletions
@@ -21,7 +21,7 @@
## Impact
- **受影響檔案**`Dockerfile`(改為 multi-stage`app` + `web`)、`.dockerignore`(新增)、`docker-compose.yml``.gitea/workflows/deploy.yml``docker/php/docker-entrypoint.sh`
- **受影響檔案**`Dockerfile`(改為 multi-stage`app` + `web`)、`.dockerignore`(新增,含 `public/storage` 排除本機既有符號連結)、`docker-compose.yml``app` 服務需明確 `target: app`,否則預設建到最後一個 stage)、`.gitea/workflows/deploy.yml``docker/php/docker-entrypoint.sh``compose.override.yml`;另因 `env_file:``.env` 全部變數成為真實環境變數而牽動 `tests/bootstrap.php``phpunit.xml`(擴大既有測試環境隔離的強制覆蓋範圍,非新增機制,詳見 design.md 實作驗證後追加)
- **受影響服務**app、nginx(改為本地 build 而非拉取 `nginx:alpine`)、scheduler、queue-worker、reverb(全部五個掛 bind mount 的服務)
- **受影響流程**VPS 部署流程(Gitea Actions self-hosted runner)、本機開發流程(開發者需改用 `docker compose build` 才能讓程式碼變動生效,或另外規劃開發環境仍用 bind mount 的 override 方案)
- **不受影響**`file-storage-s3`(本次不強制切換到 S3,上傳檔案改走具名 volume 過渡)、`compose-cloud-baseline`healthcheck/開發工具隔離邏輯不變)