解決 Elastic Beanstalk 部署錯誤:Dockerrun.aws.json 被包錯層的血淚教訓

在 AWS Elastic Beanstalk 部署應用程式時,如果壓縮包的結構不正確,系統可能會誤判為缺少 Dockerfile 或 Dockerrun.aws.json,導致整個環境部署失敗。

解決 Elastic Beanstalk 部署錯誤:Dockerrun.aws.json 被包錯層的血淚教訓
Photo by Tomas Sobek / Unsplash

1. 問題背景

在 AWS Elastic Beanstalk 上部署 Metabase 時,升級版本後出現部署失敗的情況。起初錯誤訊息看起來像是 YAML 或 JSON 格式問題,但實際上問題出在壓縮包的層級結構。


2. 第一階段錯誤:YAML / JSON 解析失敗

錯誤訊息:

The configuration file __MACOSX/metabase-aws-eb/.ebextensions/._01_metabase.config ... contains invalid YAML or JSON ...

原因分析:
macOS Finder 在壓縮時會自動生成 __MACOSX/ 資料夾與以 ._ 開頭的隱藏檔案,導致 Elastic Beanstalk 在解析 .ebextensions 內設定時出現編碼錯誤。

解決方式:
使用終端機壓縮並排除隱藏檔案:

zip -r metabase-deploy.zip metabase-aws-eb/ -x "__MACOSX/*" -x "*/._*"

3. 第二階段錯誤:Dockerrun.aws.json 無法辨識

錯誤訊息:

Instance deployment: Both 'Dockerfile' and 'Dockerrun.aws.json' are missing in your source bundle.

原因分析:
Elastic Beanstalk 要求 Dockerrun.aws.json 必須位於壓縮檔的根目錄,但 Finder 壓縮時會自動多包一層資料夾,導致結構如下:

metabase-aws-eb/
  Dockerrun.aws.json
  .ebextensions/

部署後,EB 在根目錄找不到啟動檔,因此報錯。


4. 問題根本原因:壓縮層級錯誤

錯誤 zip 結構:

metabase-aws-eb/
  Dockerrun.aws.json
  .ebextensions/
  .platform/

正確 zip 結構:

Dockerrun.aws.json
.ebextensions/
.platform/

Elastic Beanstalk 解壓後必須能直接在根目錄看到 DockerfileDockerrun.aws.json 才能啟動應用。


5. 正確打包方式

在專案根目錄進入部署資料夾後壓縮:

cd project-root/metabase-aws-eb
zip -r ../metabase-deploy.zip * .ebextensions .platform

確認 zip 結構:

unzip -l ../metabase-deploy.zip

輸出結果應顯示:

Dockerrun.aws.json
.ebextensions/
.platform/

6. Elastic Beanstalk 的結構規則

  • Dockerrun.aws.jsonDockerfile 必須位於壓縮包根目錄
  • .ebextensions/.platform/ 需與之同層
  • 不可多包一層資料夾
  • 建議使用命令列打包以避免 macOS 自動產生的隱藏檔案

7. 結語

這次的部署錯誤看似複雜,實際上只是壓縮層級造成的低級錯誤。Elastic Beanstalk 的部署包結構相當嚴格,任何多餘的層級或隱藏檔案都可能導致環境建立失敗。部署前檢查 zip 結構、確認 Dockerrun.aws.json 位於根目錄,是避免浪費時間的關鍵。