Keep running into the same deployment error (Exec Format Error) when pushing Node.js Docker from local (Apple M1) to Heroku

Error I get when releasing image

2021-04-07T06:30:58.443089+00:00 heroku[web.1]: Starting process with command `node index.js`
2021-04-07T06:31:01.899268+00:00 app[web.1]: Error: Exec format error

I went back to the most simple node.js code that only requires Express. Can not get my head around it what could be wrong.

Setup is as following:

  • running Docker Desktop on Mac (Apple M1)
  • installed latest Heroku, latest NPM, latest Node
  • working with VS Code
  • dockerfile setup:
WORKDIR /app
COPY package.json .
RUN npm install
COPY index.js .
CMD ["node", "index.js"]
  • package.json
{
  "name": "SigningV2",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1"
  }
}
  • Procfile
web: npm start
  • added two variables online
- PORT: 3000
- USE_NPM_INSTALL: TRUE  (also tried without, same result)

ps: when running heroku local web, it works


Solution 1:

Ok, found a working solution. It's Apple M1 that is breaking this standard setup (again) :(

We need to force the correct platform to be compatible by Heroku. To do this, we are going to use Docker buildx. Note, do not use Heroku:container push because as far as I know, that does not support the forcing of different platforms.

What worked for me is the following sequence:

# replace signingv2 with your own tag
docker buildx build --platform linux/amd64 -t signingv2 .

# make sure to use the name of your Heroku app
docker tag signingv2 registry.heroku.com/signingv2/web

# use docker push to push it to the Heroku registry
docker push registry.heroku.com/signingv2/web

# then use heroku release to activate
heroku container:release web -a signingv2

Hope that Docker for Apple M1 is supported on several platforms soon.