API Node TypeScript com TensorflowJS erro node-pre-gyp info This Node instance does not support builds for N-API version 7

Fala pessoal, tudo bem? Estou tentando fazer deploy de uma API NodeJS, escrita em TypeScript que tem como dependência o TensorflowJS (@tensorflow/tfjs-node). Porém, ao executar o script npm install (ao reiniciar o container), recebo os seguintes logs de erro:

Jan 22 05:18:07   npm ERR! /usr/src/app/.npm/_logs/2021-01-22T08_18_07_758Z-debug.log
Jan 22 05:18:07   npm ERR! A complete log of this run can be found in:
Jan 22 05:18:07  
Jan 22 05:18:07   npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
Jan 22 05:18:07   npm ERR! Failed at the nome-do-projeto@1.0.0 start script.
Jan 22 05:18:07   npm ERR!
Jan 22 05:18:07   npm ERR! Exit status 132
Jan 22 05:18:07   npm ERR! nome-do-projeto@1.0.0 start: `npm run build && cd dist && node index.js`
Jan 22 05:18:07   npm ERR! errno 132
Jan 22 05:18:07   npm ERR! code ELIFECYCLE
Jan 22 05:18:07   Illegal instruction (core dumped)
Jan 22 05:18:07   node-pre-gyp info This Node instance does not support builds for N-API version 7
Jan 22 05:18:07   node-pre-gyp info This Node instance does not support builds for N-API version 6
Jan 22 05:18:07   node-pre-gyp info This Node instance does not support builds for N-API version 7
Jan 22 05:18:07   node-pre-gyp info This Node instance does not support builds for N-API version 6
Jan 22 05:18:00  
Jan 22 05:18:00   > tsc
Jan 22 05:18:00   > nome-do-projeto@1.0.0 build /usr/src/app

Meu package.json

{
    "name": "nome-do-projeto",
    "version": "1.0.0",
    "description": "Rest API",
    "main": "./dist/index.js",
    "scripts": {
      "dev": "npm run build && ts-node-dev --transpile-only index.ts",
      "start": "npm run build && cd dist && node index.js",
      "build": "tsc"
    },
    "devDependencies": {
      "@types/chance": "^1.1.1",
      "@types/cors": "^2.8.9",
      "@types/express": "^4.17.9",
      "@types/multer": "^1.4.5",
      "@types/mysql": "^2.15.17",
      "@types/node": "^14.14.22",
      "@types/sharp": "^0.26.1"
    },
    "dependencies": {
      "@lighthouseapps/utils": "^1.4.0",
      "@tensorflow/tfjs-automl": "^1.0.0",
      "@tensorflow/tfjs-node": "^2.8.3",
      "axios": "^0.21.1",
      "bcryptjs": "^2.4.3",
      "chance": "^1.1.7",
      "cors": "^2.8.5",
      "dotenv": "^8.2.0",
      "express": "^4.17.1",
      "jsonwebtoken": "^8.5.1",
      "module-alias": "^2.2.2",
      "moment": "^2.29.1",
      "multer": "^1.4.2",
      "mysql2": "^2.2.5",
      "sharp": "^0.27.0",
      "ts-node-dev": "^1.0.0",
      "typescript": "^4.1.2"
    }
  }
  

Notas:

  1. Executando localmente, com o Node na versão v12.18.3, tudo ocorre bem…
  2. Realizando o deploy no Heroku, tudo funciona também :grimacing:

Alguém tem alguma ideia de solução? Estou perdido :scream:

1 Curtida

Olá @GustavoKuze, bem vindo a comunidade Umbler!

Bem, minha primeira pergunta é que versão do node está definida na página da sua aplicação da umbler? Você pode visualizar isso na página de gerenciamento principal do site. No canto superior direto terá o símbolo do nodejs e uma combo box para escolher a versão. Se não tiver como 12, troca para 12 e tenta novamente.

Uma sugestão sobre os scripts do package.json, defina um script de postinstall onde você vai fazer essa parte do build da aplicação quando você fizer o commit. E no start deixa somento o node dist/index.js. Assim evita ter que fazer um build toda a vez que reiniciar o serviço :slight_smile:

2 Curtidas

Opa, obrigado pela sua resposta! A versão do Node do container da Umbler é a v12.16.2. Até perguntei para o suporte se seria possível atualizar para a mesma versão que estou rodando localmente, e no momento não existe essa possibilidade :pensive:

Sobre o build ser executado no start, na realidade essa foi uma alteração feita justamente durante os testes pra testar rodar o container :sweat_smile:

Vou tentar realizar o postinstall e em seguida posto aqui os logs de saída.

1 Curtida
  1. Fazendo as alterações que vc mencionou no package.json, a sessão de script ficou assim:
"scripts": {
    "dev": "npm run build && ts-node-dev --transpile-only index.ts",
    "start": "node ./dist/index.js",
    "build": "tsc",
    "postinstall": "npm run build"
  },
  1. A saída do console ao realizar o deploy via git-remote foi a seguinte:
Jan 22 09:08:25   npm ERR! /usr/src/app/.npm/_logs/2021-01-22T12_08_25_845Z-debug.log
Jan 22 09:08:25   npm ERR! A complete log of this run can be found in:
Jan 22 09:08:25  
Jan 22 09:08:25   npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
Jan 22 09:08:25   npm ERR! Failed at the nome-da-api@1.0.0 start script.
Jan 22 09:08:25   npm ERR!
Jan 22 09:08:25   npm ERR! Exit status 1
Jan 22 09:08:25   npm ERR! nome-da-api@1.0.0 start: `node ./dist/index.js`
Jan 22 09:08:25   npm ERR! errno 1
Jan 22 09:08:25   npm ERR! code ELIFECYCLE
Jan 22 09:08:25   at Object.Module._extensions..js (internal/modules/cjs/loader.js:1176:10)
Jan 22 09:08:25   at Module._compile (internal/modules/cjs/loader.js:1156:30)
Jan 22 09:08:25   at Object.<anonymous> (/usr/src/app/dist/app/controllers/classificationController.js:16:12)
Jan 22 09:08:25   at require (internal/modules/cjs/helpers.js:77:18)
Jan 22 09:08:25   at Module.require (internal/modules/cjs/loader.js:1042:19)
Jan 22 09:08:25   at Function.Module._load (internal/modules/cjs/loader.js:899:14)
Jan 22 09:08:25   at Module.load (internal/modules/cjs/loader.js:1000:32)
Jan 22 09:08:25   at Object.Module._extensions..js (internal/modules/cjs/loader.js:1176:10)
Jan 22 09:08:25   at Module._compile (internal/modules/cjs/loader.js:1156:30)
Jan 22 09:08:25   at Object.<anonymous> (/usr/src/app/node_modules/@tensorflow/tfjs-node/dist/index.js:49:11)
Jan 22 09:08:25   If you have problem with building the addon module, please check https://github.com/tensorflow/tfjs/blob/master/tfjs-node/WINDOWS_TROUBLESHOOTING.md or file an issue.
Jan 22 09:08:25   Please run command 'npm rebuild @tensorflow/tfjs-node build-addon-from-source' to rebuild the native addon module.
Jan 22 09:08:25   Error: The Node.js native addon module (tfjs_binding.node) can not be found at path: /usr/src/app/node_modules/@tensorflow/tfjs-node/lib/napi-v5/tfjs_binding.node.
Jan 22 09:08:25  
Jan 22 09:08:25   ^
Jan 22 09:08:25   throw new Error("The Node.js native addon module (tfjs_binding.node) can not " +
Jan 22 09:08:25   /usr/src/app/node_modules/@tensorflow/tfjs-node/dist/index.js:49
Jan 22 09:08:25   node-pre-gyp info This Node instance does not support builds for N-API version 7
Jan 22 09:08:25   node-pre-gyp info This Node instance does not support builds for N-API version 6
Jan 22 09:08:25   node-pre-gyp info This Node instance does not support builds for N-API version 7
Jan 22 09:08:25   node-pre-gyp info This Node instance does not support builds for N-API version 6
Jan 22 09:08:24  
Jan 22 09:08:24   > node ./dist/index.js
Jan 22 09:08:24   >nome-da-api@1.0.0 start /usr/src/app
  1. Executando o comando indicado para realizar o rebuild do Tensorflow, via SSH, o resultado foi esse:
~$ npm rebuild @tensorflow/tfjs-node build-addon-from-source

> @tensorflow/tfjs-node@2.8.5 install /usr/src/app/node_modules/@tensorflow/tfjs-node
> node scripts/install.js

CPU-linux-2.8.5.tar.gz
* Building TensorFlow Node.js bindings
@tensorflow/tfjs-node@2.8.5 /usr/src/app/node_modules/@tensorflow/tfjs-node
ssh-user@ed1cb66b89d1:~$

  1. Ao reiniciar o container o primeiro erro persiste :anguished:
Jan 22 09:17:26   npm ERR! /usr/src/app/.npm/_logs/2021-01-22T12_17_26_078Z-debug.log
Jan 22 09:17:26   npm ERR! A complete log of this run can be found in:
Jan 22 09:17:26  
Jan 22 09:17:26   npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
Jan 22 09:17:26   npm ERR! Failed at the nome-da-api@1.0.0 start script.
Jan 22 09:17:26   npm ERR!
Jan 22 09:17:26   npm ERR! Exit status 132
Jan 22 09:17:26   npm ERR! nome-da-api@1.0.0 start: `node ./dist/index.js`
Jan 22 09:17:26   npm ERR! errno 132
Jan 22 09:17:26   npm ERR! code ELIFECYCLE
Jan 22 09:17:26   Illegal instruction (core dumped)
Jan 22 09:17:25   node-pre-gyp info This Node instance does not support builds for N-API version 7
Jan 22 09:17:25   node-pre-gyp info This Node instance does not support builds for N-API version 6
Jan 22 09:17:25   node-pre-gyp info This Node instance does not support builds for N-API version 7
Jan 22 09:17:25   node-pre-gyp info This Node instance does not support builds for N-API version 6
Jan 22 09:17:24  
Jan 22 09:17:24   > node ./dist/index.js
Jan 22 09:17:24   > nome-da-api@1.0.0 start /usr/src/app
1 Curtida

Faz todo o sentido o problema persistir, a sugestão era sobre a quantidade de builds mesmo.

Mas vamos lá, dei uma pesquisada aqui e me lembrei que já passei por esse problema. No geral o tensorflow tem uma restrições bem específicas de compatibilidade de versão tanto no JS quanto no normal. No seu caso a versão do node dá suporte a n-api 6 ou 7 e a versão que você está instalando não dá suporte a essa versão. Sugiro fazer o downgrade para versão 1.7.0, é a que uso nos meus projetos e funciona. Infelizmente não achei a matriz de compatibilidade de versão. Então sugiro ir testando as versões que funcionam ou pesquisar melhor a versão correta.

1 Curtida

Show! Vou testar suas sugestões. :+1:

1 Curtida

Bom, realizei o downgrade para a versão que vc sugeriu e ela não possui as funcionalidades que preciso para carregar o modelo do AutoML. Testei também a versão 2.7.0 (de 3 meses atrás) e 2.4.0 (de 4 meses atrás), o erro persistiu.

Criei então uma VM Ubuntu 20.10, com o node na mesma versão do container do site (v12.16.2) para testar.

Bastou instalar as seguintes dependências no Ubuntu:

sudo apt-get install g++
sudo apt-get install -y build-essential python

e o node-pre-gyp globalmente:

npm install node-pre-gyp -g

e funcionou corretamente (na VM), ou seja, a versão do Node v12.16.2 parece ser sim compatível com a versão 2.8.3 que estou utilizando do @tensorflow/tfjs-node.

A questão que fica é: Como posso instalar essas dependências na máquina da Umbler?

Ah, engraçado. Também tive esse mesmo problema no heroku fazendo o deploy direto da aplicação, o meu erro foi outro, mas o problema é o mesmo.

No fim não consegui usar usar no heroku devido a falta dessas dependências e acredito que você também não consiga fazer aqui também pelo mesmo motivo. Até onde já conversei com o suporte o container que roda nossas aplicações é bem enxuto e por isso acredito que não tenha os compiladores.

@Mario_Alves, com relação aos containers node, temos disponível o g++ e python? A node recomenda ter os dois disponíveis para poder fazer as compilações dos pacotes que precisam compilar algo. Outra coisa, qual a base do container node? É alpine?

Se for alpine também não vai funcionar @GustavoKuze. Passei por esse problema esses dias, o alpine não usa glibc, usa musl e o tfjs precisa da lib, se não dá um erro de ld ao rodar a aplicação.

Minha sugestão seria contratar um servidor que aceite imagens docker e você montar o serviço nele usando ubuntu:20.04.

Voce falou no primeiro post que consegue fazer o deploy no heroku, como você está usando o serviço lá? Está fazendo o deploy com docker?

Voce falou no primeiro post que consegue fazer o deploy no heroku, como você está usando o serviço lá? Está fazendo o deploy com docker?

Na realidade não, no Heroku estou fazendo o deploy via integração com o Github

Minha sugestão seria contratar um servidor que aceite imagens docker e você montar o serviço nele usando ubuntu:20.04

Sim, já estou avaliando outros caminhos. Acredito que esse método não irá suprir as necessidades do projeto mesmo :confused:

Se for alpine também não vai funcionar @GustavoKuze. Passei por esse problema esses dias, o alpine não usa glibc , usa musl e o tfjs precisa da lib, se não dá um erro de ld ao rodar a aplicação.

Boa! Agradeço as informações :+1:

1 Curtida

O Heroku aceita deploy por container caso você precise de alguma ferramenta a mais. Recomendo a solução de deploy usando o heroku.yml que é mais simple de fazer integração continua. As instruções inicias estão aqui https://devcenter.heroku.com/articles/build-docker-images-heroku-yml.

As limitações no plano free dessa solução são:

  1. Memória RAM de 512mb
  2. A imagem docker deve ter menos de 40 layers.

Um ponto interessante é que não tem limitação de tamanho da imagem.

Outro ponto também é que o Heroku usa ubuntu como base das imagens node como se pode verificar nos dockerfile em: https://github.com/heroku/stack-images.

1 Curtida