Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Installing specific version of NodeJS and NPM on Alpine docker image

I need to use a standard Alpine docker image and install a specific version of Node and NPM. Heres is my attempt so far:

FROM alpine:3.17.2

RUN apk update
RUN apk upgrade
RUN apk add bash git helm openssh yq github-cli

RUN apk add \
    curl \
    docker \
    openrc

# nvm environment variables
ENV NVM_DIR /usr/local/nvm
ENV NVM_VERSION 0.39.3
ENV NODE_VERSION 18.16.0

# install nvm
# https://github.com/creationix/nvm#install-script
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v$NVM_VERSION/install.sh | bash

# install node and npm
RUN source $NVM_DIR/nvm.sh \
    && nvm install $NODE_VERSION \
    && nvm alias default $NODE_VERSION \
    && nvm use default

# add node and npm to path so the commands are available
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH

RUN ls -asl $NVM_DIR/versions/node/v$NODE_VERSION/bin
RUN ls -asl $NVM_DIR/versions/node/v$NODE_VERSION/lib/node_modules/npm/bin

RUN $NVM_DIR/versions/node/v$NODE_VERSION/bin/node -v

RUN $NVM_DIR/versions/node/v$NODE_VERSION/bin/npm install --global yarn

# Start docker on boot
RUN rc-update add docker boot

# Default commands to bash
ENTRYPOINT ["bash"]

I am getting this:

#7 [ 4/10] RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.39.3/install.sh | bash
#7 sha256:76a5a08c3c01075cd22585bc1f3df8f47fe258b116742db843cea6fa553a09c6
#7 0.181   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
#7 0.182                                  Dload  Upload   Total   Spent    Left  Speed
100 15916  100 15916    0     0  57463      0 --:--:-- --:--:-- --:--:-- 60287
#7 0.478 => Downloading nvm from git to '/usr/local/nvm'
=> Cloning into '/usr/local/nvm'...
#7 3.239 * (HEAD detached at FETCH_HEAD)
#7 3.240   master
#7 3.268 => Compressing and cleaning up git repository
#7 3.307
#7 3.338 => Profile not found. Tried ~/.bashrc, ~/.bash_profile, ~/.zprofile, ~/.zshrc, and ~/.profile.
#7 3.338 => Create one of them and run this script again
#7 3.338    OR
#7 3.338 => Append the following lines to the correct file yourself:
#7 3.338
#7 3.338 export NVM_DIR="/usr/local/nvm"
#7 3.338 [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
#7 3.338
#7 3.440 => Installing Node.js version 18.16.0
#7 4.948 Downloading and installing node v18.16.0...
#7 5.646 Downloading https://nodejs.org/dist/v18.16.0/node-v18.16.0-linux-x64.tar.gz...
######################################################################## 100.0%
#7 8.333 Computing checksum with sha256sum
#7 8.832 Checksums matched!
#7 11.93 Now using node v18.16.0 (npm v)
#7 12.41 Creating default alias: default -> 18.16.0 (-> v18.16.0 *)
#7 12.63 Failed to install Node.js 18.16.0
#7 12.63 => Close and reopen your terminal to start using nvm or run the following to use it now:
#7 12.63
#7 12.63 export NVM_DIR="/usr/local/nvm"
#7 12.63 [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
#7 DONE 12.7s

I am not sure about the "Failed to install Node.js 18.16.0" message, as you will see in my tests with "ls" it seems to be installed?

First I "ls" the bin directory where I expect node to be installed:

RUN ls -asl /usr/local/nvm/versions/node/v18.16.0/bin
#9 sha256:42ba843ab812861bf82e0e493e211095cc749408940b5ec21ce94fabe3997538
#9 0.138 total 88820
#9 0.141      4 drwxr-xr-x    2 1000     1000          4096 Apr 27 07:35 .
#9 0.141      4 drwxr-xr-x    6 root     root          4096 Apr 27 07:35 ..
#9 0.141      0 lrwxrwxrwx    1 root     root            45 Apr 27 07:35 corepack -> ../lib/node_modules/corepack/dist/corepack.js
#9 0.141  88812 -rwxr-xr-x    1 1000     1000      90940576 Apr 12 05:31 node
#9 0.141      0 lrwxrwxrwx    1 root     root            38 Apr 27 07:35 npm -> ../lib/node_modules/npm/bin/npm-cli.js
#9 0.141      0 lrwxrwxrwx    1 root     root            38 Apr 27 07:35 npx -> ../lib/node_modules/npm/bin/npx-cli.js
#9 DONE 0.1s

This seem ok to me, is it not?

My other "ls" gives this:

RUN ls -asl /usr/local/nvm/versions/node/v18.16.0/lib/node_modules/npm/bin
#10 sha256:c2872332dbb58f191400fa23211a691db9a5f5dc07425bc9d3c83bf1cafb31f8
#10 0.141 total 36
#10 0.144      4 drwxr-xr-x    3 1000     1000          4096 Apr 27 07:35 .
#10 0.144      4 drwxr-xr-x    7 1000     1000          4096 Apr 27 07:35 ..
#10 0.144      4 drwxr-xr-x    2 1000     1000          4096 Apr 27 07:35 node-gyp-bin
#10 0.144      4 -rwxr-xr-x    1 1000     1000          1365 Oct 11  2022 npm
#10 0.144      4 -rwxr-xr-x    1 1000     1000            54 Oct 11  2022 npm-cli.js
#10 0.144      4 -rwxr-xr-x    1 1000     1000           483 Oct 11  2022 npm.cmd
#10 0.144      4 -rwxr-xr-x    1 1000     1000          1567 Oct 11  2022 npx
#10 0.144      4 -rwxr-xr-x    1 1000     1000          2922 Dec  7 06:00 npx-cli.js
#10 0.144      4 -rwxr-xr-x    1 1000     1000           539 Oct 11  2022 npx.cmd
#10 DONE 0.2s

So npm is here also, looking good?

In my initial post here, I was giving the wrong error message, I am sorry. The error message was from my local machine, which is a Mac with the M2 CPU, and I believe this caused that error, but that is for another day. I need it to run on the build servers, where we are running linux on amd64 so there I have a different error, the following error:

Step 14/17 : RUN $NVM_DIR/versions/node/v$NODE_VERSION/bin/node -v
 ---> Running in d63ec3b287d9
/bin/sh: /usr/local/nvm/versions/node/v18.16.0/bin/node: not found
The command '/bin/sh -c $NVM_DIR/versions/node/v$NODE_VERSION/bin/node -v' returned a non-zero code: 127

Error: Process completed with exit code 127.

So my "ls" say node is there but when I try and run it, it is not?

Best regards
Søren

like image 264
Neigaard Avatar asked Sep 06 '25 21:09

Neigaard


2 Answers

Use official versions

I don't know why you are using NVM.

According to your words. It doesn't matter how but you have to install a specific version of node on a specific version of alpine!

Just change NODE_VERSION and ALPINE_VERSION to what you need.

Here's my way using an alpine image not a node one:

ARG NODE_VERSION=18.16.0
ARG ALPINE_VERSION=3.17.2

FROM node:${NODE_VERSION}-alpine AS node

FROM alpine:${ALPINE_VERSION}

COPY --from=node /usr/lib /usr/lib
COPY --from=node /usr/local/lib /usr/local/lib
COPY --from=node /usr/local/include /usr/local/include
COPY --from=node /usr/local/bin /usr/local/bin

RUN node -v

RUN npm install -g yarn --force

RUN yarn -v

CMD ["node", "path/to/your/script.js"]

I removed your unnecessary package installations but you can add them if you need them!

e.g.: RUN apk add bash git helm openssh yq github-cli

e.g.: RUN rc-update add docker boot

Explanation

Add NODE_VERSION as ARG so you can use it in everywhere!

Copy binary files from official build of node:<version>-alpine to your version of alpine!

Simply install yarn using --force flag to avoid errors and DONE!!!!

CMD path/to/your/script.js is enough to run your long running JS. Don't use additional tools!

Compile the official versions

You can use the code provided by node it self from here. Just change the versions in the first two lines!

FROM alpine:3.17.2

ENV NODE_VERSION 18.16.0

RUN addgroup -g 1000 node \
    && adduser -u 1000 -G node -s /bin/sh -D node \
    && apk add --no-cache \
        libstdc++ \
    && apk add --no-cache --virtual .build-deps \
        curl \
    && ARCH= && alpineArch="$(apk --print-arch)" \
      && case "${alpineArch##*-}" in \
        x86_64) \
          ARCH='x64' \
          CHECKSUM="f3ad9443e8d9d53bfc00ec875181e9dc2ccf86205a50fce119e0610cdba8ccf1" \
          ;; \
        *) ;; \
      esac \
  && if [ -n "${CHECKSUM}" ]; then \
    set -eu; \
    curl -fsSLO --compressed "https://unofficial-builds.nodejs.org/download/release/v$NODE_VERSION/node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz"; \
    echo "$CHECKSUM  node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz" | sha256sum -c - \
      && tar -xJf "node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \
      && ln -s /usr/local/bin/node /usr/local/bin/nodejs; \
  else \
    echo "Building from source" \
    # backup build
    && apk add --no-cache --virtual .build-deps-full \
        binutils-gold \
        g++ \
        gcc \
        gnupg \
        libgcc \
        linux-headers \
        make \
        python3 \
    # use pre-existing gpg directory, see https://github.com/nodejs/docker-node/pull/1895#issuecomment-1550389150
    && export GNUPGHOME="$(mktemp -d)" \
    # gpg keys listed at https://github.com/nodejs/node#release-keys
    && for key in \
      4ED778F539E3634C779C87C6D7062848A1AB005C \
      141F07595B7B3FFE74309A937405533BE57C7D57 \
      74F12602B6F1C4E913FAA37AD3A89613643B6201 \
      DD792F5973C6DE52C432CBDAC77ABFA00DDBF2B7 \
      61FC681DFB92A079F1685E77973F295594EC4689 \
      8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \
      C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \
      890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4 \
      C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C \
      108F52B48DB57BB0CC439B2997B01419BD92F80A \
    ; do \
      gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$key" || \
      gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key" ; \
    done \
    && curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION.tar.xz" \
    && curl -fsSLO --compressed "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc" \
    && gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
    && gpgconf --kill all \
    && rm -rf "$GNUPGHOME" \
    && grep " node-v$NODE_VERSION.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
    && tar -xf "node-v$NODE_VERSION.tar.xz" \
    && cd "node-v$NODE_VERSION" \
    && ./configure \
    && make -j$(getconf _NPROCESSORS_ONLN) V= \
    && make install \
    && apk del .build-deps-full \
    && cd .. \
    && rm -Rf "node-v$NODE_VERSION" \
    && rm "node-v$NODE_VERSION.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt; \
  fi \
  && rm -f "node-v$NODE_VERSION-linux-$ARCH-musl.tar.xz" \
  && apk del .build-deps \
  # Run some smoke tests
  && node --version \
  && npm --version

ENV YARN_VERSION 1.22.19

RUN apk add --no-cache --virtual .build-deps-yarn curl gnupg tar \
  # use pre-existing gpg directory, see https://github.com/nodejs/docker-node/pull/1895#issuecomment-1550389150
  && export GNUPGHOME="$(mktemp -d)" \
  && for key in \
    6A010C5166006599AA17F08146C2130DFD2497F5 \
  ; do \
    gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$key" || \
    gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key" ; \
  done \
  && curl -fsSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" \
  && curl -fsSLO --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz.asc" \
  && gpg --batch --verify yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \
  && gpgconf --kill all \
  && rm -rf "$GNUPGHOME" \
  && mkdir -p /opt \
  && tar -xzf yarn-v$YARN_VERSION.tar.gz -C /opt/ \
  && ln -s /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn \
  && ln -s /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg \
  && rm yarn-v$YARN_VERSION.tar.gz.asc yarn-v$YARN_VERSION.tar.gz \
  && apk del .build-deps-yarn \
  # smoke test
  && yarn --version

COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]

CMD [ "node" ]
like image 87
Alijvhr Avatar answered Sep 09 '25 23:09

Alijvhr


Here is my solution which is using unofficial node builds from https://nodejs.org/en/download

  1. Create Dockerfile, with desired alpine, node and npm versions In the example:
  • alpine v3.17.2
  • nodejs v18.16.0
  • npm v9.6.6
FROM alpine:3.17.2
ENV NODE_PACKAGE_URL  https://unofficial-builds.nodejs.org/download/release/v18.16.0/node-v18.16.0-linux-x64-musl.tar.gz

RUN apk add libstdc++
WORKDIR /opt
RUN wget $NODE_PACKAGE_URL
RUN mkdir -p /opt/nodejs
RUN tar -zxvf *.tar.gz --directory /opt/nodejs --strip-components=1
RUN rm *.tar.gz
RUN ln -s /opt/nodejs/bin/node /usr/local/bin/node
RUN ln -s /opt/nodejs/bin/npm /usr/local/bin/npm

# npm version coming with node is 9.5.1
# To install specific npm version, run the following command, or remove it to use the default npm version:
RUN npm install -g [email protected]

  1. Build a docker image
docker build -t node-18.16.0-npm-9.6.6-alpine-3.17.2 .
[+] Building 24.4s (15/15) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                                                                           0.0s
 => => transferring dockerfile: 753B                                                                                                                                                                           0.0s
 => [internal] load .dockerignore                                                                                                                                                                              0.0s
 => => transferring context: 2B                                                                                                                                                                                0.0s
 => [internal] load metadata for docker.io/library/alpine:3.17.2                                                                                                                                               0.7s
 => [ 1/11] FROM docker.io/library/alpine:3.17.2@sha256:ff6bdca1701f3a8a67e328815ff2346b0e4067d32ec36b7992c1fdc001dc8517                                                                                       0.0s
 => CACHED [ 2/11] RUN apk add libstdc++                                                                                                                                                                       0.0s
 => CACHED [ 3/11] WORKDIR /opt                                                                                                                                                                                0.0s
 => CACHED [ 4/11] RUN wget https://unofficial-builds.nodejs.org/download/release/v18.16.0/node-v18.16.0-linux-x64-musl.tar.gz                                                                                 0.0s
 => CACHED [ 5/11] RUN mkdir -p /opt/nodejs                                                                                                                                                                    0.0s
 => [ 6/11] RUN tar -zxvf *.tar.gz --directory /opt/nodejs --strip-components=1                                                                                                                                4.2s
 => [ 7/11] RUN rm *.tar.gz                                                                                                                                                                                    0.3s
 => [ 8/11] RUN ls -l /opt/nodejs                                                                                                                                                                              0.6s
 => [ 9/11] RUN ln -s /opt/nodejs/bin/node /usr/local/bin/node                                                                                                                                                 0.2s
 => [10/11] RUN ln -s /opt/nodejs/bin/npm /usr/local/bin/npm                                                                                                                                                   0.2s
 => [11/11] RUN npm install -g [email protected]                                                                                                                                                                      17.1s
 => exporting to image                                                                                                                                                                                         1.0s
 => => exporting layers                                                                                                                                                                                        0.9s
 => => writing image sha256:e133d992089c2efd071b423fa093f81bf4a732ac06c1ec7dd6cb09cec894a9b3                                                                                                                   0.0s
 => => naming to docker.io/library/node-18.16.0-npm-9.6.6-alpine-3.17.2
  1. Run the container and check the installed versions
docker run -it node-18.16.0-npm-9.6.6-alpine-3.17.2 node --version
v18.16.0
docker run -it node-18.16.0-npm-9.6.6-alpine-3.17.2 npm --version
9.6.6
like image 34
Borislav Gizdov Avatar answered Sep 09 '25 23:09

Borislav Gizdov