nodegit: Cannot be installed under Docker Alpine

I would like to use NodeGit under Docker with the Node alpine image but its doesn’t work. Do you know one of the ways to solve the problem?

I install NodeGit with yarn i get the following error message:

Error: Error loading shared library /home/node/node_modules/nodegit/build/Release/nodegit.node: Exec format error
at Object.Module._extensions..node (module.js:598:18)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3)
at Module.require (module.js:513:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/home/node/node_modules/nodegit/dist/nodegit.js:11:12)
at Module._compile (module.js:569:30)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3)
at Module.require (module.js:513:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/home/node/src/utils/versioning.js:11:17)
at Module._compile (module.js:569:30)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3)
at Module.require (module.js:513:17)
at require (internal/module.js:11:18)

I install NodeGit with npm i get the following error message:

> nodegit@0.20.1 install /home/node/node_modules/nodegit
> node lifecycleScripts/preinstall && node lifecycleScripts/install

[nodegit] Running pre-install script
[nodegit] Configuring libssh2.
{ Error: Command failed: /home/node/node_modules/nodegit/vendor/libssh2/configure --with-libssl-prefix=/home/node/node_modules/nodegit/vendor/openssl/openssl
/home/node/node_modules/nodegit/vendor/libssh2/missing: Unknown `--is-lightweight' option
Try `/home/node/node_modules/nodegit/vendor/libssh2/missing --help' for more information
configure: WARNING: 'missing' script is too old or missing
/home/node/node_modules/nodegit/vendor/libssh2/configure: ./configure.lineno: line 1: /usr/bin/file: not found
configure: error: No crypto library found!
Try --with-libssl-prefix=PATH
 or --with-libgcrypt-prefix=PATH
 or --with-wincng on Windows

    at ChildProcess.exithandler (child_process.js:252:12)
    at emitTwo (events.js:125:13)
    at ChildProcess.emit (events.js:213:7)
    at maybeClose (internal/child_process.js:887:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:208:5)
  killed: false,
  code: 1,
  signal: null,
  cmd: '/home/node/node_modules/nodegit/vendor/libssh2/configure --with-libssl-prefix=/home/node/node_modules/nodegit/vendor/openssl/openssl' }
/home/node/node_modules/nodegit/vendor/libssh2/missing: Unknown `--is-lightweight' option
Try `/home/node/node_modules/nodegit/vendor/libssh2/missing --help' for more information
configure: WARNING: 'missing' script is too old or missing
/home/node/node_modules/nodegit/vendor/libssh2/configure: ./configure.lineno: line 1: /usr/bin/file: not found
configure: error: No crypto library found!
Try --with-libssl-prefix=PATH
 or --with-libgcrypt-prefix=PATH
 or --with-wincng on Windows

[nodegit] ERROR - Could not finish preinstall
{ Error: Command failed: /home/node/node_modules/nodegit/vendor/libssh2/configure --with-libssl-prefix=/home/node/node_modules/nodegit/vendor/openssl/openssl
/home/node/node_modules/nodegit/vendor/libssh2/missing: Unknown `--is-lightweight' option
Try `/home/node/node_modules/nodegit/vendor/libssh2/missing --help' for more information
configure: WARNING: 'missing' script is too old or missing
/home/node/node_modules/nodegit/vendor/libssh2/configure: ./configure.lineno: line 1: /usr/bin/file: not found
configure: error: No crypto library found!
Try --with-libssl-prefix=PATH
 or --with-libgcrypt-prefix=PATH
 or --with-wincng on Windows

    at ChildProcess.exithandler (child_process.js:252:12)
    at emitTwo (events.js:125:13)
    at ChildProcess.emit (events.js:213:7)
    at maybeClose (internal/child_process.js:887:16)
    at Process.ChildProcess._handle.onexit (internal/child_process.js:208:5)
  killed: false,
  code: 1,
  signal: null,
  cmd: '/home/node/node_modules/nodegit/vendor/libssh2/configure --with-libssl-prefix=/home/node/node_modules/nodegit/vendor/openssl/openssl' }
npm info lifecycle nodegit@0.20.1~install: Failed to exec install script
npm WARN vao-api@1.0.0 No repository field.

npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! nodegit@0.20.1 install: `node lifecycleScripts/preinstall && node lifecycleScripts/install`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the nodegit@0.20.1 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2017-08-30T10_48_59_977Z-debug.log

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Comments: 30 (11 by maintainers)

Most upvoted comments

I now have a deeper understanding of this issue and have discovered a workaround.

To install the pre-built nodegit package on Alpine, the following packages are required:

apk --no-cache add gcc libc-dev libressl-dev

That allows you to install nodegit and use it to read and write local repositories. However, if you attempt to clone a remote repository, the process will segfault. The workaround for this problem is to rebuild nodegit at the time it is installed.

To rebuild nodegit at installation time, you first need to following additional packages:

apk --no-cache add make python curl-dev g++

Next, install nodegit with the BUILD_ONLY=true environment variable:

BUILD_ONLY=true npm install nodegit

or, with yarn:

BUILD_ONLY=true yarn add nodegit

The BUILD_ONLY=true environment variable can be used when installing any package which itself depends on nodegit. It just needs to be set at the time nodegit is being installed.

Compilation takes a long time, but I can confirm that it does solve the segfault problem. I tested this process using the node:8-alpine Docker image.

I think this is a duplicate of #1246.

There are two ways to solve the problem.

  1. Create the missing symlink that the precompiled binary is depending on.

     sudo ln -s /usr/lib64/libcurl.so.4 /usr/lib64/libcurl-gnutls.so.4
    
  2. Force nodegit to be recompiled at install time.

     BUILD_ONLY=true npm install nodegit
    

The second option slows down installation considerably.

Has anyone gotten this to work on node:12-alpine? The rebuild solution worked for me with alpine 3.8, but not 3.9.

FROM node:12-alpine

RUN apk --update --no-cache -q add libgit2-dev

ADD package.json index.js ./

RUN apk --no-cache --virtual .node-gyp-compilation-dependencies add \
		g++ \
		make \
		python \
		curl-dev \
	&& apk --no-cache add \
		bash \
		ca-certificates \
		krb5-dev \
		libgit2-dev

RUN BUILD_ONLY=true npm install

RUN apk del .node-gyp-compilation-dependencies

CMD ["node", "index.js"]
const nodegit = require('nodegit');
nodegit.Clone.clone('https://github.com/nodegit/nodegit/', 'test-test', {})
	.then(() => console.log('all good!'))
	.catch(e => console.log('error!', e));
{
  "name": "test",
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {
    "nodegit": "0.27.0"
  }
}
> docker build -t tester .
> docker run tester
Segmentation fault

In order to install on Alpine, you need the following packages:

apk --no-cache -q add build-base libgit2-dev

You also need this symlink:

ln -s /usr/lib/libcurl.so.4 /usr/lib/libcurl-gnutls.so.4

Then you can install and use nodegit on Alpine.

@rcjsuen I have installed the following package libgit2-dev and I think this has all dependencies for NodeGit. For example I add my dockerfile below

FROM node:8.1.0-alpine

COPY ./ /home/node

WORKDIR /home/node

# Git install
RUN mkdir /nodegit && \
    cd /nodegit && \
    apk update && \
    apk upgrade && \
    apk add git libgit2-dev && \
    apk add python tzdata pkgconfig build-base && \
    yarn add -E nodegit@0.20 && \
    apk del python tzdata pkgconfig build-base && \
    rm yarn.lock package.json && \
    rm -rf /tmp/* /var/cache/apk/* && \
    yarn cache clean && \

# Install Node modules
RUN rm -rf package-lock.json node_modules \
    && apk add --update --no-cache --virtual .build-deps \
    curl \
    g++ \
    gcc \
    gnupg \
    libgcc \
    make \
    alpine-sdk \
    python \
    && npm config set unsafe-perm true \
    && npm install \
    && npm prune --production \
    && apk del .build-deps \
    && rm -rf /usr/share/man /tmp/* /var/cache/apk/* \
    && ls -a /nodegit

EXPOSE 8000

USER node
CMD ["node", "index"]

@Perronef5 low-hanging solution for us was to use node:12-buster-slim as a base instead. Works out of the box with npm’s compiled nodegit. Just make sure to RUN apt-get update && apt-get install -y libgssapi-krb5-2 in the build.

@pheel Could you share the whole Dockerfile with the node:12-buster-slim approach? I can’t seem to make it work by just adding that line so probably I am missing something.

@prakasa-tkpd +1 same problem

@rcjsuen I have installed the following package libgit2-dev and I think this has all dependencies for NodeGit. For example I add my dockerfile below

FROM node:8.1.0-alpine

COPY ./ /home/node

WORKDIR /home/node

# Git install
RUN mkdir /nodegit && \
    cd /nodegit && \
    apk update && \
    apk upgrade && \
    apk add git libgit2-dev && \
    apk add python tzdata pkgconfig build-base && \
    yarn add -E nodegit@0.20 && \
    apk del python tzdata pkgconfig build-base && \
    rm yarn.lock package.json && \
    rm -rf /tmp/* /var/cache/apk/* && \
    yarn cache clean && \

# Install Node modules
RUN rm -rf package-lock.json node_modules \
    && apk add --update --no-cache --virtual .build-deps \
    curl \
    g++ \
    gcc \
    gnupg \
    libgcc \
    make \
    alpine-sdk \
    python \
    && npm config set unsafe-perm true \
    && npm install \
    && npm prune --production \
    && apk del .build-deps \
    && rm -rf /usr/share/man /tmp/* /var/cache/apk/* \
    && ls -a /nodegit

EXPOSE 8000

USER node
CMD ["node", "index"]

is this works ?

I have some error like this:

Error loading shared library libgssapi_krb5.so.2: No such file or directory

using multi stage dockerfile. Should I install krb5-libs or other libs in the last stage ?

I’ve distilled these steps in the following comment: https://gitlab.com/antora/docker-antora/issues/2#note_61275108