skip to Main Content

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

2

Answers


  1. 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!

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

    ARG NODE_VERSION=18.16.0
    
    FROM node:${NODE_VERSION}-alpine AS node
    
    FROM alpine:3.17.2
    
    COPY --from=node /usr/lib /usr/lib
    COPY --from=node /usr/local/share /usr/local/share
    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

    Explanations

    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!

    Login or Signup to reply.
  2. Official node Dockerfiles are open source. You can start from one that is the closest to your requirements and tweak the minor versions for your needs.

    You need alpine:3.17.2 and NODE_VERSION 18.16.0 so this alpine-3.17.0 with node-18.16.0 is a good Dockerfile candidate to start with.

    Then adjust the versions and remove yarn if you don’t need it(luckily the node-18.16.0 is an exact match with what you need, so the only thing left is to bump the alpine starting version):

    # Original source: https://github.com/nodejs/docker-node/blob/4c95f887f7863eccc17d66729cd24ecc230209a2/18/alpine3.17/Dockerfile
    # Your requirements:
    # alpine:3.17.2
    # NODE_VERSION 18.16.0
    
    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="d093ef223708a6702db1dc591911f3b23481cb55a337df3adf80b6effaba90b2" 
              ;; 
            *) ;; 
          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 
        # 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 
        && 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 
      # smoke tests
      && node --version 
      && which node 
      && npm --version 
      && which npm
    
    # Replace the entrypoint you need after confirming that prerequisites are OK
    ENTRYPOINT ["sh"]
    
    

    Note the last 4 commands that print the node and npm versions.
    You may also run the container to do the same:

    On host:

    docker build -t alpine-node:3.17.2-18.16.0 .
    docker run -it alpine-node:3.17.2-18.16.0
    

    In container:

    node --version && which node && npm --version && which node
    

    Output:

    v18.16.0
    /usr/local/bin/node
    9.5.1
    /usr/local/bin/node
    / #
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search