node-gradle / gradle-node-plugin

Gradle plugin for integrating NodeJS in your build. :rocket:
Apache License 2.0
616 stars 120 forks source link

Support musl - npm install on alpine is failing #51

Open kappelmi opened 4 years ago

kappelmi commented 4 years ago

Hi i am using this plugin on 2 instances of linux. I have seen following error on 1 of the instance newly added to the system:

Task ':OlisWebGUI:npm_install' is not up-to-date because: Task has not declared any outputs despite executing actions. Starting process 'command '/home/jenkins/slave/workspace/test/workspace/OlisWeb/OlisWebGUI/.gradle/nodejs/node-v12.13.1-linux-x64/bin/npm''. Working directory: /home/jenkins/slave/workspace/test/workspace/OlisWeb/OlisWebGUI Command: /home/jenkins/slave/workspace/test/workspace/OlisWeb/OlisWebGUI/.gradle/nodejs/node-v12.13.1-linux-x64/bin/npm install Successfully started process 'command '/home/jenkins/slave/workspace/test/workspace/OlisWeb/OlisWebGUI/.gradle/nodejs/node-v12.13.1-linux-x64/bin/npm'' env: can't execute 'node': No such file or directory :OlisWebGUI:npm_install (Thread[Execution worker for ':' Thread 5,5,main]) completed. Took 0.066 secs.

FAILURE: Build failed with an exception.

What went wrong:
Execution failed for task ':OlisWebGUI:npm_install'.

Process 'command '/home/jenkins/slave/workspace/test/workspace/OlisWeb/OlisWebGUI/.gradle/nodejs/node-v12.13.1-linux-x64/bin/npm'' finished with non-zero exit value 127

after long debugging, i have found out, the linux i am using where this is failing is alpine, and it looks like, node original distro requires libc, but alpine uses musl

analyzing the official docker image from node:alpine it looks like, there is an unofficial distro for alpine linux.

would it be possible to fix the plugin, so it would detect alpine linux and download the proper distro from node/npm ?

pls also have a look in this file: https://github.com/nodejs/docker-node/blob/c6bc44e84afcdb81d9749b7b034c60e916a519ad/10/alpine3.10/Dockerfile

Thanks, kappelmi

deepy commented 4 years ago

I'll have to get back to you in regards to the unofficial node, but to work around this quickly you could download and install the unofficial node manually (make sure npm and node are in PATH) or base your image on the node alpine instead of alpine and configure the plugin to use the installed node instead of downloading it.

Secondly, Since I know you came from the original you might want to have a look at this section https://github.com/node-gradle/gradle-node-plugin/blob/master/docs/node.md#executing-npm-tasks npm_install is technically ok, but you should be using the npmInstall that the plugin creates for you instead :-)

kappelmi commented 4 years ago

Hi deepy, thanks for your quick answer, yes, i have copied this issue from the original plugin, and i also found the workaround, and using nginx:alpine image as base, and it works, if i set download = false still i think this is something which u could consider in a future version...

deepy commented 4 years ago

We do have ARM support so I guess it's not entirely out of the question to autodetect and handle it, though I don't know how we'd detect musl, I tried an alpine linux with musl openjdk but there's no java property and I can't find something other than the presence of /lib/libc.musl-x86_64.so.1.

I guess we could make the node artifact name configurable, but it's not in a great place in the code so that might have to wait until we port the plugin to kotlin.

kappelmi commented 4 years ago

how about this?

cat /etc/os-release NAME="Alpine Linux" ID=alpine

deepy commented 4 years ago

We'll go with checking for /lib/ld-musl-*.so.1, but I'm not sure when this will be worked on

deepy commented 4 years ago

You can work around this by adding an IvyRepo of your own with a different pattern, at least if I look at https://unofficial-builds.nodejs.org/download/release/v13.0.1/