Elastic Beanstalk 上的 Metabase 怎麼升級
EB 上的 Metabase 升級,其實只是把 Dockerrun.aws.json 裡的 image tag 改一行。這篇記錄我從 0.56.8 升到 0.63 的完整流程,含備份跟 rollback。
這篇是我 2026 年 9 月把 Metabase 從 0.56.8 升到 0.63.16.6 的紀錄。環境是 AWS Elastic Beanstalk(底下簡稱 EB),全部在 CloudShell 裡跑完,不用下載任何東西到自己電腦。
下次要升級,改一個版本號,從頭跑到尾就好。
先講結論:升級就是改一行字
EB 上的 Metabase 就是一個 Docker container。整包 source bundle 裡,真正決定「跑哪個版本」的只有 Dockerrun.aws.json 這個檔案裡的 image tag:
"Name": "metabase/metabase:v0.56.8" → "Name": "metabase/metabase:v0.63.16.6"
其他檔案都是你自己的環境設定,一個都不能少:
.ebextensions/:metabase-setup.sh、CloudWatch、Papertrail 這些.platform/:nginx.conf、nginx-ssl.conf、postdeploy hooks
所以正確做法不是去 Metabase 官網重抓一包空的 metabase-aws-eb.zip。而是把你現在正在跑的那包從 S3 拉下來,改一行,再上架回去。
順帶一提,Metabase 官方文件已經不建議用 EB 跑 production 了。所以這套流程要自己維護,這篇就是維護說明。
我的環境
你的值會不一樣,底下的指令把 <...> 換成自己的就好。
- 平台:Docker on 64bit Amazon Linux 2023
- 部署策略:AllAtOnce,MinSize 1 / MaxSize 2,前面掛 ALB
- Application DB:掛在 EB 環境上的 RDS PostgreSQL 16
- Region:ap-northeast-1
七個步驟
0. 設好變數
下次升級只要改 NEW 和 OLD,其他照抄。開 CloudShell(Console 左下角),貼這段:
# 下次升級只要改這兩行
NEW=0.63.16.6 # 要升到的版本
OLD=0.56.8-1 # 目前跑的 application version label
APP=<你的 EB application 名稱>
ENV=<你的 EB environment 名稱>
BUCKET=elasticbeanstalk-<region>-<account-id>
DB=<你的 RDS instance identifier>
SNAP=metabase-pre-$(date +%Y%m%d-%H%M)
export AWS_PAGER="" # 不然輸出會卡在 less 裡
先確認這個 tag 真的存在,免得部署一個不存在的 image:
curl -s -o /dev/null -w '%{http_code}\n' https://hub.docker.com/v2/repositories/metabase/metabase/tags/v$NEW
要回 200。
1. 備份 application database
Metabase 一啟動就會跑 schema migration,而且不會自動降版。整個流程只有這一步不能省。出事的時候,能救你的只有這顆快照。
aws rds create-db-snapshot \
--db-instance-identifier $DB \
--db-snapshot-identifier $SNAP
aws rds wait db-snapshot-available --db-snapshot-identifier $SNAP && echo READY
看到 READY 再往下。小資料庫大概 2 到 5 分鐘。快照本身不影響線上服務。
2. 找出目前的 source bundle 在哪
EB 把每一版部署包都存在 S3。用指令查目前這版的 key,不用去 Console 點:
aws elasticbeanstalk describe-application-versions \
--application-name $APP \
--query 'ApplicationVersions[].[VersionLabel,SourceBundle.S3Key]' \
--output text
# 輸出長這樣:
# 0.56.8-1 1759489403130-metabase-deploy.zip
# 0.56.8 1759487844154-metabase-deploy.zip
KEY=1759489403130-metabase-deploy.zip # 換成 $OLD 那一列的 key
3. 下載、改 image tag、重新打包
重點在最後那行 zip。一定要 cd 進解壓後的資料夾裡面再打包。如果把外層資料夾一起包進去,EB 會找不到 Dockerrun.aws.json。. 開頭的目錄也要包到。
cd ~ && rm -rf mb && mkdir -p mb/src && cd mb
aws s3 cp s3://$BUCKET/$KEY cur.zip
cd src && unzip -o ../cur.zip
# 只改 image tag,其他都不動
sed -i "s#metabase/metabase:v[0-9.]*#metabase/metabase:v$NEW#" Dockerrun.aws.json
cat Dockerrun.aws.json # 用眼睛確認一下
zip -r ../new.zip . -x '*.DS_Store'
cd .. && unzip -l new.zip # 應該看到 .ebextensions/ 跟 .platform/ 都在
4. 上傳並建立 application version
這步還不會部署,只是把新版本上架。做完可以去 Console 的 Application versions 看一眼有沒有出現。
aws s3 cp new.zip s3://$BUCKET/metabase-$NEW-deploy.zip
aws elasticbeanstalk create-application-version \
--application-name $APP \
--version-label $NEW \
--description "Metabase v$NEW" \
--source-bundle S3Bucket=$BUCKET,S3Key=metabase-$NEW-deploy.zip
回傳的 Status 是 UNPROCESSED 很正常。EB 只對 Java、PHP 這類 bundle 做預處理,Docker 的不會。
5. 部署
我的部署策略是 AllAtOnce:所有機器同時換,中間會斷線幾分鐘。好處是不會出現新舊版同時連同一顆 DB 的狀況,對 Metabase 的 migration 反而比較安全。挑離峰時間跑。
aws elasticbeanstalk update-environment \
--environment-name $ENV --version-label $NEW
aws elasticbeanstalk wait environment-updated --environment-name $ENV
aws elasticbeanstalk describe-environments --environment-names $ENV \
--query 'Environments[0].[Status,Health,VersionLabel]' --output text
# 期望:Ready Green 0.63.16.6
卡住或變紅的話,去環境的 Events 分頁看,或用 aws elasticbeanstalk retrieve-environment-info 拉 log。
6. 驗證真的換版了
EB 顯示的 version label 只是你自己取的名字,不代表 container 真的跑那版。要問 Metabase 自己:
URL=https://<你的 metabase 網址>
curl -s -o /dev/null -w 'health:%{http_code}\n' $URL/api/health
curl -s $URL/api/session/properties \
| python3 -c "import sys,json;print(json.load(sys.stdin)['version'])"
# {'date': '2026-09-04', 'tag': 'v0.63.16.6', 'hash': '05fdcf7'}
出事了怎麼退回去
Metabase 升級會改資料庫 schema,所以只把 image 換回舊版是起不來的。rollback 一定是兩件事一起做:
# 1. 應用退版
aws elasticbeanstalk update-environment --environment-name $ENV --version-label $OLD
# 2. 資料庫從升級前的快照還原(會建出一台新的 RDS instance)
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier metabase-restore-$(date +%Y%m%d) \
--db-snapshot-identifier $SNAP
快照不要急著刪。升完跑個幾天,確定沒問題再清。
幾個會踩到的坑
- 可以跳版。 0.40 以上可以直接跳到最新,不用一版一版升。只有 0.40 以下才要逐版爬。
- 打包位置。 要在解壓資料夾裡面 zip,而且一定要帶到
.ebextensions/跟.platform/。少了 nginx 設定或 metabase-setup.sh,環境會起來,但行為不對。 - DB 跟環境綁在一起。 如果你的 application DB 是掛在 EB 環境上的 RDS,原地部署沒問題。但哪天要「重建環境」,這台 RDS 會跟著環境一起被砍。那種情況要先把 DB 拆成獨立的 instance。
- 版本壽命很短。 非 LTS 版大概發布後兩個月就停止支援,LTS 是 14 個月。0.63 支援到 2026-11,0.58 是 LTS,支援到 2027-02。
- 舊環境的 Deprecated 警告。 如果 Console 一直跳平台已棄用的警告,先看是不是另一個沒在用的舊環境發出來的。確認沒人用再終止,而且要先確認它的 RDS 不是跟現役環境共用的。
升完之後:開啟 AI 功能
自架版的 Metabot 要自己帶 LLM API key。Metabase 自家的 AI Service 只給 Metabase Cloud 用。位置在 Admin settings → AI:選 provider(Anthropic、OpenAI、Amazon Bedrock、Azure、Mistral、OpenRouter、Z.AI),填 key,選 model,開 Metabot。
如果你本來就在 AWS 上,用 Amazon Bedrock 可以同帳號同區走 IAM,不用另外管一組 key。