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:
@@ -4,60 +4,11 @@ set -e
|
||||
echo "=== CFDivePlatform 容器初始化開始 ==="
|
||||
|
||||
# 確保目錄與權限(php-fpm 啟動前必須完成)
|
||||
# storage-app-public 具名 volume 掛載時會覆蓋 image 內建的權限,每次啟動都需要重新確保
|
||||
[ ! -d "/var/www/storage" ] && mkdir -p /var/www/storage
|
||||
[ ! -d "/var/www/bootstrap/cache" ] && mkdir -p /var/www/bootstrap/cache
|
||||
chown -R www-data:www-data /var/www
|
||||
chmod -R 775 /var/www/storage /var/www/bootstrap/cache
|
||||
|
||||
# 確保 .env 存在
|
||||
if [ ! -f .env ]; then
|
||||
cp .env.example .env
|
||||
php artisan key:generate
|
||||
fi
|
||||
|
||||
# 強制 DB_HOST=db(Docker service name,不能用 localhost)
|
||||
php -r "
|
||||
\$env = file_get_contents('/var/www/.env');
|
||||
\$env = preg_replace('/^DB_HOST=.*$/m', 'DB_HOST=db', \$env);
|
||||
file_put_contents('/var/www/.env', \$env);
|
||||
"
|
||||
|
||||
# Composer 依賴(vendor 不存在或 lock 內容變更時才裝)
|
||||
# 用內容比對而非 mtime:git checkout/pull 會更新 composer.json 的 mtime,
|
||||
# mtime 比對會讓每次分支操作後的開機都重跑 autoload 生成(bind mount 上耗時數分鐘、期間全站 502)
|
||||
if [ -f "composer.lock" ] && { [ ! -d "vendor" ] || ! cmp -s composer.lock vendor/.composer.lock.installed; }; then
|
||||
composer install --no-scripts --optimize-autoloader
|
||||
cp composer.lock vendor/.composer.lock.installed
|
||||
fi
|
||||
|
||||
# 背景執行:等 MySQL → migration → cache clear → storage link → swagger
|
||||
# php-fpm 不等這些完成就先啟動,避免重啟時 CORS 502
|
||||
(
|
||||
echo "⏳ [背景] 等待 MySQL..."
|
||||
COUNT=0
|
||||
until mysqladmin ping -h"db" -u"${DB_USERNAME:-cfdiveuser}" -p"${DB_PASSWORD}" --silent 2>/dev/null || [ $COUNT -ge 30 ]; do
|
||||
sleep 2
|
||||
COUNT=$((COUNT+1))
|
||||
done
|
||||
|
||||
echo "🗄️ [背景] 執行 migration..."
|
||||
php artisan migrate --force || echo "⚠️ migration 失敗"
|
||||
|
||||
echo "🧹 [背景] 清除 Laravel 緩存..."
|
||||
php artisan config:clear || true
|
||||
php artisan cache:clear || true
|
||||
php artisan route:clear || true
|
||||
php artisan view:clear || true
|
||||
|
||||
echo "🔗 [背景] storage:link..."
|
||||
php artisan storage:link --force || true
|
||||
|
||||
if php -r "echo class_exists('L5Swagger\\L5SwaggerServiceProvider') ? 'yes' : 'no';" 2>/dev/null | grep -q 'yes'; then
|
||||
php artisan l5-swagger:generate || true
|
||||
fi
|
||||
|
||||
echo "✅ [背景] 初始化完成"
|
||||
) &
|
||||
|
||||
echo "🚀 啟動 php-fpm..."
|
||||
exec "$@"
|
||||
|
||||
Reference in New Issue
Block a user