在 Mac M1 上部署 Docker Container 至 Heroku 的方法,避免 Exec Format Error

前言

雖然 Heroku 推出了收費方案,但我仍然有一些服務是在上面執行,整體來說開發上也蠻方便的,所以新專案也會持續地使用它來建立專案。
然而,最近在嘗試使用 Docker 部署服務的時候遇到了 Exec Format Error 的錯誤,進一步查詢資料後發現這是 Mac M1 平台的問題,透過官方建議的流程所編譯出來的 Docker Image 不相容於 Heroku 的平台。

因此花了一些時間整理了一些步驟,讓部署流程更加順利。

問題

使用原本官方的指令進行部署

1
2
3
heroku container:login
heroku container:push web
heroku container:release web

但在瀏覽時出現了以下的錯誤:

1
2
3
4
2023-04-16T13:32:57.795520+00:00 heroku[web.1]: State changed from crashed to starting
2023-04-16T13:33:09.318876+00:00 heroku[web.1]: Starting process with command `npm start`
2023-04-16T13:33:10.245955+00:00 app[web.1]: Error: Exec format error
2023-04-16T13:33:10.369819+00:00 heroku[web.1]: Process exited with status 126

解決方式

具體來說,需要使用 Docker buildx 來強制設置正確的平台以與 Heroku 相容。
需要注意的是,不要直接使用 heroku:container push,因為目前不支援不同平台間的相容性問題

因此將指令做修改:

1
2
3
4
5
6
docker buildx build --platform linux/amd64 -t my-app .
docker tag my-app registry.heroku.com/my-app/web

docker push registry.heroku.com/my-app/web

heroku container:release web -a my-app

完成後確認網站結果

1
heroku open

References

https://devcenter.heroku.com/articles/container-registry-and-runtime
https://stackoverflow.com/questions/66982720/keep-running-into-the-same-deployment-error-exec-format-error-when-pushing-nod