How to install Node.js with yarn package manager in Dockerfile - node.js

I would like to install Node.js with yarn.pkg in my Dockerfile.
The Dockerfile is for a Laravel8/PHP8 project.
This is my actual try:
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash -
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
&& echo "deb https://dl.yarnpkg.com/debian/ stable main" > /etc/apt/sources.list.d/yarn.list
RUN apt-get update -y \
&& apt-get install -y --no-install-recommends \
nodejs \
yarn \
mysql-client
If I try it this way, I got this output on my shell:
=> CACHED [ 8/20] RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - 0.0s
=> ERROR [ 9/20] RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - 0.4s
------
> [ 9/20] RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -:
#12 0.331 Warning: apt-key output should not be parsed (stdout is not a terminal)
#12 0.384 gpg: Segmentation fault
#12 0.384 no valid OpenPGP data found.
------
failed to solve: rpc error: code = Unknown desc = executor failed running [/bin/sh -c curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -]: exit code: 2
Is there a way to solve this problem?
If you need more information about it, please let me know.
Regards,
Manny

Top-Master, thank's a lot for your input. It has helped me a lot to find my solution.
Here it is...
I have used the Dockerfile you posted above and made some small changes:
ENV NODE_VERSION=16.5
ENV NVM_DIR=/root/.nvm
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
RUN . "$NVM_DIR/nvm.sh" \
&& nvm install ${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" \
&& nvm use v${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" \
&& nvm alias default v${NODE_VERSION}
ENV PATH="/root/.nvm/versions/node/v${NODE_VERSION}/bin/:${PATH}"
RUN npm install -g yarn
The problem was, the RUN npm install -g yarn command run into an error and the build fails. After some googling around I've found this webpage https://docs.npmjs.com/downloading-and-installing-node-js-and-npm.
They recommend, that npm should be installed separately because of the directory structure and user rights. They are not the same if you install npm with Node.js together.
So I've done this:
ENV NODE_VERSION=16.5
ENV NVM_DIR=/root/.nvm
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
RUN . "$NVM_DIR/nvm.sh" \
&& nvm install ${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" \
&& nvm use v${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" \
&& nvm alias default v${NODE_VERSION}
ENV PATH="/root/.nvm/versions/node/v${NODE_VERSION}/bin/:${PATH}"
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
npm
RUN npm install -g yarn
For me (and I hope for many other people too) it works now :)
Thank's again!
Have a nice time!

Hmm... NPM (Node package manager) is installed along with Node.js, and Yarn is just a module that is installed like npm install -g yarn
Simply edit and use what another post mentions like:
ENV NODE_VERSION=12.6.0
RUN apt install -y curl
ENV NVM_DIR=/root/.nvm
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.34.0/install.sh | bash
RUN . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm use v${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm alias default v${NODE_VERSION}
ENV PATH="/root/.nvm/versions/node/v${NODE_VERSION}/bin/:${PATH}"
RUN node --version
RUN npm --version
RUN npm install -g yarn
Note that this is the best way I know to manage Node's version.

Related

Docker: npm not found

I have the following Dockerfile:
FROM ubuntu
USER root
RUN apt-get update && apt-get install curl -y
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -
RUN apt-get update && apt-get upgrade -y && apt-get install nodejs -y
RUN mkdir /opt/public
RUN mkdir /opt/bin
ADD public /opt/public
ADD bin /opt/bin
RUN ls -lah /opt/bin
RUN ls -lah /opt/public
ADD run.sh /bin/run.sh
RUN chmod +x /bin/run.sh
RUN cd /opt/bin && npm install
CMD ["/bin/run.sh"]
When I build the Container, I get this eror:
/bin/sh: 1: npm: not found
What is the problem? Could you please help me?
Try installing npm separately while building the image:
RUN apt-get update && apt-get upgrade -y && \
apt-get install -y nodejs \
npm # note this one
Node also packages npm, so no need to install npm like mentioned by Yury. It's in general a bad idea to do it like that, because you don't have control over the nodejs and npm version
For me the answer was quite simple. I had the following code:
# install nodejs
RUN curl --silent --location https://deb.nodesource.com/setup_12.x | bash -
RUN apt-get install -y \
nodejs
RUN echo "Node: " && node -v
RUN echo "NPM: " && npm -v
but I for got to install curl, so it failed. So before this, you need to install curl:
RUN apt-get update && apt-get install -y curl
You perhaps have already installed node and npm here. May be you need to run npm/node related script in a new interactive shell, after installing node packages through curl. So, in the last line, you may try:
CMD cat /bin/run.sh | bash -ic
Or
CMD bash -i /bin/run.sh
Or
CMD ["/bin/bash","-i","/bin/run.sh"]
Interactive bash for npm/node worked in my case and is invoked with bash -i
Try adding these two lines in Docker file before running any npm command.
RUN apt-get install --no-install-recommends apt-utils --yes \
&& apt-get install --no-install-recommends npm --yes
I was getting following error while building docker container:
> [runtime 1/11] RUN curl -sL https://deb.nodesource.com/setup_16.x | -E bash; apt-get install -y nodejs; npm i -g npm#8:
#11 0.360 /bin/sh: 1: -E: not found
#11 1.687 Reading package lists...
#11 1.696 Building dependency tree...
#11 1.698 Reading state information...
#11 1.703 E: Unable to locate package nodejs
#11 1.703 /bin/sh: 1: npm: not found
err: appname
/bin/sh: 1: npm: not found
In dockerfile i changed:
RUN curl -sL https://deb.nodesource.com/setup_16.x | bash - \
&& apt-get install -y nodejs \
&& npm i -g npm#8
to this
RUN apt-get update && apt-get upgrade -y && \
apt-get install -y nodejs \
npm
and container build succeeded
In case anyone continues to run across this problem, it's likely due to the package manager on the image's underlying OS specifying a version of node that's so old that it doesn't include npm. Here's a modified version of the linked answer for a Dockerfile:
# This is needed to update the OS' package manager so that
# the current version of node will be installed:
RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash -
RUN apt-get -yq update \
&& apt-get -yq upgrade \
&& apt-get install -yq nodejs \
&& npm --version

Dockerfile ubuntu only installs node version 4.2

This dockerfile installs nodejs version 4.2 and I cant understand why. could someone please help me install node 9.2. i've tried taking out the -- no install-recommends command to no avail.
adding more text her because stack would not let me post this even though it is a very simple question that I've looked on the web for quite some time about to no avail.adding more text her because stack would not let me post this even though it is a very simple question that I've looked on the web for quite some time about to no avail.
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y --no-install-recommends curl sudo
RUN curl -sL https://deb.nodesource.com/setup_9.x | sudo -E bash -
RUN apt-get install -y nodejs && \
apt-get install --yes build-essential
RUN apt-get install --yes npm
#VOLUME "/usr/local/app"
# Set up C++ dev env
RUN apt-get update && \
apt-get dist-upgrade -y && \
apt-get install gcc-multilib g++-multilib cmake wget -y && \
apt-get clean autoclean && \
apt-get autoremove -y
#wget -O /tmp/conan.deb -L https://github.com/conan-io/conan/releases/download/0.25.1/conan-ubuntu-64_0_25_1.deb && \
#dpkg -i /tmp/conan.deb
#ADD ./scripts/cmake-build.sh /build.sh
#RUN chmod +x /build.sh
#RUN /build.sh
RUN mkdir -p /usr/local/app
WORKDIR /usr/local/app
COPY package.json /usr/local/app
RUN ["npm", "install"]
COPY . .
RUN echo "/usr/local/app/dm" > /etc/ld.so.conf.d/mythrift.conf
RUN echo "/usr/lib/x86_64-linux-gnu" >> /etc/ld.so.conf.d/mythrift.conf
RUN echo "/usr/local/lib64" >> /etc/ld.so.conf.d/mythrift.conf
RUN ldconfig
RUN chmod +x dm/dm3
RUN ldd dm/dm3
RUN ["chmod", "+x", "dm/dm3"]
RUN ["chmod", "777", "policy"]
RUN ls -al .
RUN ["nodejs", "-v"]
CMD ["nodejs", "-v"]
EDIT
Apparently it's important for the OP to run exactly this version of ubuntu. Here's a sample that builds on top of FROM ubuntu:16.04:
FROM ubuntu:16.04
RUN apt-get update && apt-get install -y --reinstall ca-certificates curl build-essential \
&& curl -s https://nodejs.org/dist/v9.9.0/node-v9.9.0-linux-x64.tar.xz \
-o node-v9.9.0-linux-x64.tar.xz && tar xf node-v9.9.0-linux-x64.tar.xz \
&& cd node-v9.9.0-linux-x64 && cp -r bin include lib share /usr/local \
&& rm -rf /node-v9.9.0-linux-x64.tar.xz /node-v9.9.0-linux-x64
CMD ["node", "-v"]
Build
docker build -t testing .
Test
docker run testing
v9.9.0
Note that this only takes care of the node related things and don't take into account all the other dependencies.
The reason you are getting node 4 is because apt-get only installs the default version of a package which will never be the cutting edge latest.
Whilst this issue is present in a Docker container, it is not specific to Docker as it will happen on any Ubuntu installation, both inside or outside of Docker.
To get the latest version you have 2 options.
(1) Install using a PPA:
cd ~
curl -sL https://deb.nodesource.com/setup_9.x -o nodesource_setup.sh
sudo bash nodesource_setup.sh
sudo apt-get install nodejs
nodejs -v
(2) Install using Node Version Manager (nvm)
The latter is great because it lets you install multiple versions of Node and jump between them very quickly.
Here's a link to an amazing Digital Ocean article on this very topic:
https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-16-04
Here's a link to NVM ... https://github.com/creationix/nvm

Dockerfile build /bin/sh -c returned a non-zero code: 1

my dockerfile conf:
FROM ubuntu:16.04
MAINTAINER S.K.
RUN apt-get update
RUN apt-get install curl -y
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash
RUN export NVM_DIR="$HOME/.nvm"
RUN [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
RUN nvm install node
RUN nvm use 6.9.1
RUN npm i express -g
RUN npm i nunjucks -g
RUN npm i nodemon -g
RUN mkdir -p PROJECT
VOLUME /PROJECT/
EXPOSE 1520
In the step RUN [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" Im get error:
The command '/bin/sh -c [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"' returned a non-zero code: 1
Everybody knows how I can fix it ?
I solved my problem ! Thanks for all, who tried to help me !
After each command (RUN, CMD and else) Docker makes container, save changes on docker image and delete container before next command.Docker also compress directories and files each command iteration. You should know it before do anything, if you don't want to get an exception or error..
This is working code :
FROM ubuntu:16.04
MAINTAINER S.K.
RUN apt-get update
RUN apt-get install curl -y
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash \
&& export NVM_DIR="$HOME/.nvm" && [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" \
&& nvm install 6.9.1 \
&& npm i express -g \
&& npm i nunjucks -g \
&& npm i nodemon -g \
&& npm i gulp -g \
RUN mkdir -p ./PROJECT
EXPOSE 1520
For me solution was:
npm i -g --unsafe-perm nodemon
https://serverfault.com/questions/875909/npm-postinstall-not-running-in-docker/891399#891399

Install node in Dockerfile?

I am user of AWS elastic beanstalk, and I have a little problem. I want to build my CSS files with less+node. But I don`t know how to install node in my dockerfile, when building with jenkins.
Here is installation packages what I am using in my docker. I will be glad for any suggestions.
FROM php:5.6-apache
# Install PHP5 and modules along with composer binary
RUN apt-get update
RUN apt-get -y install \
curl \
default-jdk \
git \
libcurl4-openssl-dev \
libpq-dev \
libmcrypt-dev \
libpq5 \
npm \
node \
zlib1g-dev \
libfreetype6-dev \
libjpeg62-turbo-dev \
libpng12-dev
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
RUN docker-php-ext-install curl json mbstring opcache pdo_mysql zip gd exif sockets mcrypt
# Install pecl
RUN pecl install -o -f memcache-beta \
&& rm -rf /tmp/pear \
&& echo 'extension=memcache.so' > /usr/local/etc/php/conf.d/memcache.ini
After this I am runing my entrypoint.sh with code
#!/usr/bin/env sh
composer run-script post-install-cmd --no-interaction
chmod 0777 -R /var/app/app/cache
chmod 0777 -R /var/app/app/logs
exec apache2-foreground
But then I`ve got this error
Error Output: [2016-04-04 11:23:44] assetic.ERROR: The template ":tmp:module.html.twig" contains an error: A template that extends another one cannot have a body in ":tmp:module.ht
ml.twig" at line 7.
But when I install inside the Docker container node this way
apt-get install git-core curl build-essential openssl libssl-dev
git clone https://github.com/nodejs/node.git
cd node
./configure
make
sudo make install
node -v
I can build my CSS. So question is..how this installation above make install inside my Dockerfile when I am building it with Jenkins?
I think this works slightly better.
ENV NODE_VERSION=16.13.0
RUN apt install -y curl
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
ENV NVM_DIR=/root/.nvm
RUN . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm use v${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm alias default v${NODE_VERSION}
ENV PATH="/root/.nvm/versions/node/v${NODE_VERSION}/bin/:${PATH}"
RUN node --version
RUN npm --version
Note that nvm is a version manager for node.js, designed to be installed per-user, and invoked per-shell. nvm works on any POSIX-compliant shell (sh, dash, ksh, zsh, bash), in particular on these platforms: unix, macOS, and windows WSL.
Running apt-get install node does not install Node.js, because that's not the package you're asking for.
If you run apt-cache info node you can see that what you are installing is a "Amateur Packet Radio Node program (transitional package)"
You should follow the Node.js install instructions to install via package manager.
Or if you like building from git, you can just do that inside Docker:
RUN apt-get install -y git-core curl build-essential openssl libssl-dev \
&& git clone https://github.com/nodejs/node.git \
&& cd node \
&& ./configure \
&& make \
&& sudo make install
According to the following answer, I would suggest using npm via the n package, that lets you choose the nodejs version, or use the latest tag or the lts tag. For example for latest:
RUN apt-get update && apt-get install -y \
software-properties-common \
npm
RUN npm install npm#latest -g && \
npm install n -g && \
n latest
Just 2 lines
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt-get install -y nodejs
Get the node image and put it at the top of your dockerfile:
FROM node:[tag_name] AS [alias_name]
Verify the version by adding following code:
RUN echo "NODE Version:" && node --version
RUN echo "NPM Version:" && npm --version
Then add the following code every time you need to use nodejs in a container:
COPY --from=[alias_name] . .
From the codes above, replace the following with:
[tag_name] - the tag value of the node image you want to use. Visit https://hub.docker.com/_/node?tab=tags for the list of available tags.
[alias_name] - your preferred image name to use in your dockerfile.
Example:
FROM node:latest AS node_base
RUN echo "NODE Version:" && node --version
RUN echo "NPM Version:" && npm --version
FROM php:5.6-apache
COPY --from=node_base . .
### OTHER CODE GOES HERE
Binary download without any compilation
FROM ubuntu
RUN apt-get update && apt-get install -y \
ca-certificates \
curl
ARG NODE_VERSION=14.16.0
ARG NODE_PACKAGE=node-v$NODE_VERSION-linux-x64
ARG NODE_HOME=/opt/$NODE_PACKAGE
ENV NODE_PATH $NODE_HOME/lib/node_modules
ENV PATH $NODE_HOME/bin:$PATH
RUN curl https://nodejs.org/dist/v$NODE_VERSION/$NODE_PACKAGE.tar.gz | tar -xzC /opt/
# comes with npm
# RUN npm install -g typescript
I am using following Dockerfile to setup node version 8.10.0.
Here I have used NVM (Node Version Manager ), so we can choose which node version should be installed on that container. Please use absolute path of npm when installing node modules (eg: /root/.nvm/versions/node/v${NODE_VERSION}/bin/npm install leasot#latest -g)
FROM ubuntu:18.04
ENV NODE_VERSION=8.10.0
RUN apt-get update && \
apt-get install wget curl ca-certificates rsync -y
RUN wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash
ENV NVM_DIR=/root/.nvm
RUN . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm use v${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm alias default v${NODE_VERSION}
RUN cp /root/.nvm/versions/node/v${NODE_VERSION}/bin/node /usr/bin/
RUN cp /root/.nvm/versions/node/v${NODE_VERSION}/bin/npm /usr/bin/
RUN /root/.nvm/versions/node/v${NODE_VERSION}/bin/npm install leasot#latest -g
Note: This is a cropped Dockerfile.
The short answer, for example, install v14.17.1
ENV PATH="/opt/node-v14.17.1-linux-x64/bin:${PATH}"
RUN curl https://nodejs.org/dist/v14.17.1/node-v14.17.1-linux-x64.tar.gz |tar xzf - -C /opt/
list of all available versions can be found here -> https://nodejs.org/dist/
Directly into /usr/local so it's already in your $PATH
ARG NODE_VERSION=8.10.0
RUN curl https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.gz | tar -xz -C /usr/local --strip-components 1
The accepted answer gives the link to the installation instructions for all systems, but it won't run out of the box since you often (e.g. for ubuntu) don't have all required dependencies installed (namely curl and sudo).
So here's for example how you'd do it for ubuntu:
FROM ubuntu
# Core dependencies
RUN apt-get update && apt-get install -y curl sudo
# Node
# Uncomment your target version
# RUN curl -fsSL https://deb.nodesource.com/setup_10.x | sudo -E bash -
# RUN curl -fsSL https://deb.nodesource.com/setup_12.x | sudo -E bash -
# RUN curl -fsSL https://deb.nodesource.com/setup_14.x | sudo -E bash -
# RUN curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -
RUN sudo apt-get install -y nodejs
RUN echo "NODE Version:" && node --version
RUN echo "NPM Version:" && npm --version
then build with
docker build . --progress=plain
to see the output of the echo statements. Of course you could also leave away the echo statements and run it regularly with docker build ., after you've made sure everything is working as intended.
You can also leave away the installation of sudo, but then you'll have to get rid of the sudo occurrences in the script.
FROM ubuntu:20.04
# all necessaries for next RUN
RUN set -e; \
apt-get update && \
apt-get install -qqy --no-install-recommends \
curl wget nano gnupg2 software-properties-common && \
rm -rf /var/lib/apt/lists;
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
# uncomment for checking versions
# Step 4/10 : RUN apt-cache show nodejs | grep Version;return 1;
# ---> Running in xxxxxxxxx
# Version: 14.18.2-deb-1nodesource1
# Version: 10.19.0~dfsg-3ubuntu1
#RUN apt-cache show nodejs | grep Version;return 1;
RUN set -e; \
apt-get update && \
apt-get install -qqy \
nodejs && \
rm -rf /var/lib/apt/lists;
# uncomment for check
# RUN node -v

How to install nvm in docker?

I am in the process of building a new Docker image and I'm looking to get NVM installed so I can manage nodejs.
Reading the docs on how to install NVM they mention that you need to source your .bashrc file in order to start using NVM.
I've tried to set this up in a Dockerfile, but so far building fails with the error:
"bash: nvm: command not found"
Here are the relevant lines from my Dockerfile:
ADD files/nvm_install.sh /root/
RUN chmod a+x /root/nvm_install.sh
RUN bash -c "/root/nvm_install.sh"
RUN bash -l -c "source /root/.bashrc"
RUN cd /root
RUN bash -l -c "nvm install 0.10.31"
Here is the output from trying to build:
docker build -t nginx_dock .
Step 0 : FROM ubuntu
---> 826544226fdc
Step 1 : MAINTAINER dficociello
---> Using cache
---> da3bc340fbb3
Step 2 : RUN apt-get update
---> Using cache
---> 6b6b611feb4f
Step 3 : RUN apt-get install nginx curl -y
---> Using cache
---> 159eb0b16d23
Step 4 : RUN touch /root/.bashrc
---> Using cache
---> 5e9e8216191b
Step 5 : ADD files/nginx.conf /etc/nginx/
---> Using cache
---> c4a4a11296a2
Step 6 : ADD files/nvm_install.sh /root/
---> Using cache
---> b37cba2a18ca
Step 7 : RUN chmod a+x /root/nvm_install.sh
---> Using cache
---> bb13e2a2893d
Step 8 : RUN bash -c "/root/nvm_install.sh"
---> Using cache
---> 149b49a8fc71
Step 9 : RUN bash -l -c "source /root/.bashrc"
---> Running in 75f353ed0d53
---> 0eae8eae7874
Removing intermediate container 75f353ed0d53
Step 10 : RUN cd /root
---> Running in feacbd998dd0
---> 284293ef46b0
Removing intermediate container feacbd998dd0
Step 11 : RUN bash -l -c "nvm install 0.10.31"
---> Running in 388514d11067
bash: nvm: command not found
2014/09/17 13:15:11 The command [/bin/sh -c bash -l -c "nvm install 0.10.31"] returned a non-zero code: 127
I'm pretty new to Docker so I may be missing something fundamental to writing Dockerfiles, but so far all the reading I've done hasn't shown me a good solution.
When you RUN bash... each time that runs in a separate process, anything set in the environment is not maintained. Here's how I install nvm:
# Replace shell with bash so we can source files
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
# Set debconf to run non-interactively
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
# Install base dependencies
RUN apt-get update && apt-get install -y -q --no-install-recommends \
apt-transport-https \
build-essential \
ca-certificates \
curl \
git \
libssl-dev \
wget \
&& rm -rf /var/lib/apt/lists/*
ENV NVM_DIR /usr/local/nvm # or ~/.nvm , depending
ENV NODE_VERSION 0.10.33
# Install nvm with node and npm
RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.20.0/install.sh | bash \
&& . $NVM_DIR/nvm.sh \
&& nvm install $NODE_VERSION \
&& nvm alias default $NODE_VERSION \
&& nvm use default
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/v$NODE_VERSION/bin:$PATH
Update 20/02/2020: This solution works if you're using a debian base image. If you're using ubuntu, see this answer.
Here is the cleanest way to install nvm that I have found:
SHELL ["/bin/bash", "--login", "-c"]
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
RUN nvm install 10.15.3
Explanation
The first line sets the Dockerfile's default shell to a bash login shell. Note: this means that every subsequent RUN, CMD, and ENTRYPOINT will be run under the current user (usually root), and source the ~/.bashrc file if run in the shell form.
The second line installs nvm with bash. When the script is run with bash, it appends to the ~/.bashrc file.
The third line installs a particular version of nodejs and uses it. The nvm, npm, and node commands are available because they are run via a bash login shell (see line 1).
To help everyone that are looking for a way to install the Node.js with NVM on Ubuntu (last version), I made the dockerfile below. I'm using the last version of Docker, Ubuntu, Node.js and the NVM is working properly (the $PATH was fixed). I'm using this in a production environment.
$ docker info \
Server Version: 1.9.1
Kernel Version: 4.1.13-boot2docker
Operating System: Boot2Docker 1.9.1 (TCL 6.4.1); master : cef800b - Fri Nov 20 19:33:59 UTC 2015
Node.js Version: stable 4.2.4 LTS
Ubuntu Version: 14.04.3
dockerfile:
FROM ubuntu:14.04.3
# Replace shell with bash so we can source files
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
# make sure apt is up to date
RUN apt-get update --fix-missing
RUN apt-get install -y curl
RUN apt-get install -y build-essential libssl-dev
ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION 4.2.4
# Install nvm with node and npm
RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.30.1/install.sh | bash \
&& source $NVM_DIR/nvm.sh \
&& nvm install $NODE_VERSION \
&& nvm alias default $NODE_VERSION \
&& nvm use default
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
RUN mkdir /usr/app
RUN mkdir /usr/app/log
WORKDIR /usr/app
# log dir
VOLUME /usr/app/log
# Bundle app source
COPY . /usr/app
# Install app dependencies
RUN npm install
EXPOSE 3000
CMD ["node", "server.js"]
Nvm paths have changed since the accepted answer, so if you want to use a more up-to-date nvm version, you need to make a few changes. Also, it is not necessary to remap sh to make it work:
ENV NVM_DIR /usr/local/nvm
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash
ENV NODE_VERSION v7.9.0
RUN /bin/bash -c "source $NVM_DIR/nvm.sh && nvm install $NODE_VERSION && nvm use --delete-prefix $NODE_VERSION"
ENV NODE_PATH $NVM_DIR/versions/node/$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/$NODE_VERSION/bin:$PATH
Not sure if you will need the --delete-prefix option on the nvm use - I did, but that may be something strange about my base image.
Took me an hour or two to figure out the cleanest way to do it. --login doesn't seem to execute .bashrc so you have to supply -i to launch it in interactive mode. This causes Docker to yell at you for a bit so I only launch this way for the installation, then reset to my standard shell.
# Installing Node
SHELL ["/bin/bash", "--login", "-i", "-c"]
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.2/install.sh | bash
RUN source /root/.bashrc && nvm install 12.14.1
SHELL ["/bin/bash", "--login", "-c"]
Each RUN in a Dockerfile is executed in a different container. So if you source a file in a container, its content will not be available in the next one.
That is why when you install an application and you need to do several steps, you must do it in the same container.
With your example:
ADD files/nvm_install.sh /root/
RUN chmod a+x /root/nvm_install.sh && \
/root/nvm_install.sh && \
source /root/.bashrc && \
cd /root && \
nvm install 0.10.31
This is based on the top answer and works in 2018:
# Replace shell with bash so we can source files
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
# Install base dependencies
RUN apt-get update && apt-get install -y -q --no-install-recommends \
apt-transport-https \
build-essential \
ca-certificates \
curl \
git \
libssl-dev \
wget
ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION 8.11.3
WORKDIR $NVM_DIR
RUN curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash \
&& . $NVM_DIR/nvm.sh \
&& nvm install $NODE_VERSION \
&& nvm alias default $NODE_VERSION \
&& nvm use default
ENV NODE_PATH $NVM_DIR/versions/node/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
Note that nvm is not a bash command, it is an alias. This can screw you up if you're relying on $PATH.
Updated 2022
Just one answer put the curl installation but did not work the entire Dockerfile
Here my Dockerfile ready to copy/paste in which I install latest nvm 2022 version with latest Ubuntu
FROM ubuntu
# nvm requirements
RUN apt-get update
RUN echo "y" | apt-get install curl
# nvm env vars
RUN mkdir -p /usr/local/nvm
ENV NVM_DIR /usr/local/nvm
# IMPORTANT: set the exact version
ENV NODE_VERSION v16.17.0
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
RUN /bin/bash -c "source $NVM_DIR/nvm.sh && nvm install $NODE_VERSION && nvm use --delete-prefix $NODE_VERSION"
# add node and npm to the PATH
ENV NODE_PATH $NVM_DIR/versions/node/$NODE_VERSION/bin
ENV PATH $NODE_PATH:$PATH
RUN npm -v
RUN node -v
Log
Notes
Set the exact version of nodejs is mandatory because if you set nvm use v16, 16.17.0 will be downloaded and then there is no way to get the 16.17.0 from v16 to be set in the PATH
nvm force us to search last and specific version raw.githubusercontent../nvm/v0.39.1/install.sh of the script its readme https://github.com/nvm-sh/nvm#install--update-script instead to have something like this: raw.githubusercontent../nvm/latest/install.sh
If your nodejsapp is classic and standard, don't use nvm. Instead use FROM node:16 directly
You could use this nvm snippet in another projects in which the base image is not a node:16. For example, I have a python docker image and nodejs was required.
Here is my working version
FROM ubuntu:14.04
# Declare constants
ENV NVM_VERSION v0.29.0
ENV NODE_VERSION v5.0.0
# Replace shell with bash so we can source files
RUN rm /bin/sh && ln -s /bin/bash /bin/sh
# Install pre-reqs
RUN apt-get update
RUN apt-get -y install curl build-essential
# Install NVM
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/${NVM_VERSION}/install.sh | bash
# Install NODE
RUN source ~/.nvm/nvm.sh; \
nvm install $NODE_VERSION; \
nvm use --delete-prefix $NODE_VERSION;
Took help from #abdulljibali and #shamisis answers.
Based upon the suggestion in #Kuhess answer, I replaced the source command with the following in my Dockerfile
RUN cat ~/.nvm/nvm.sh >> installnode.sh
RUN echo "nvm install 0.10.35" >> installnode.sh
RUN sh installnode.sh
25-Feb-2021
The main problem is with use of the 'source' directive, which is bash shell specific.
What worked for me was replacing 'source' with '.' for a Ubuntu 18 install.
My Dockerfile:
FROM ubuntu:bionic
RUN \
apt update && \
apt upgrade -y && \
apt install -y curl
ENV NVM_DIR /root/.nvm
ENV NODE_VERSION 14.16
# Install nvm with node and npm
RUN curl -sL https://raw.githubusercontent.com/creationix/nvm/v0.35.3/install.sh | bash \
&& . $NVM_DIR/nvm.sh \
&& nvm install $NODE_VERSION
I must begin with the fact that I searched all over to get a working example of nvm inside docker and I found none. Even the answers in this thread did not work.
So, I spent quite some time and came up with one that works:
# install dependencies
RUN apt-get update && apt-get install -y \
curl \
npm \
nodejs \
git;
# compatibility fix for node on ubuntu
RUN ln -s /usr/bin/nodejs /usr/bin/node;
# install nvm
RUN curl https://raw.githubusercontent.com/creationix/nvm/v0.24.1/install.sh | sh;
# invoke nvm to install node
RUN cp -f ~/.nvm/nvm.sh ~/.nvm/nvm-tmp.sh; \
echo "nvm install 0.12.2; nvm alias default 0.12.2" >> ~/.nvm/nvm-tmp.sh; \
sh ~/.nvm/nvm-tmp.sh; \
rm ~/.nvm/nvm-tmp.sh;
Notice how I have installed nodejs via apt-get as well. I found that some packages don't get installed inside docker unless this is done.
A key difference between the attempt to get the nvm command in the question:
RUN bash -l -c "source /root/.bashrc"
which doesn't work and the attempt to do the same in the accepted answer:
source $NVM_DIR/nvm.sh
Is that the second version sources the nvm.sh script directly, whereas the original tries to do it via the .bashrc file.
The .bashrc file has a line in it early on which exits if it's being run in a non interactive shell:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esac
So it never gets to the bit where it would have sourced nvm.sh which actually puts the nvm command in your shell.
I wouldn't be surprised if docker is running this stuff in a non interactive shell. This hadn't been explicitly pointed out, so I thought I would mention it as it's what caught me out when I was doing something similar with vagrant.
None of these worked for me, for my python3-onbuild container I had to force-create symbolic links to the nvm installation.
# Install npm and nodejs
RUN apt-get install -y build-essential libssl-dev
RUN mkdir /root/.nvm
ENV NVM_DIR /root/.nvm
ENV NODE_VERSION 8.9.4
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.9/install.sh | bash
RUN chmod +x $HOME/.nvm/nvm.sh
RUN . $HOME/.nvm/nvm.sh && nvm install $NODE_VERSION && nvm alias default $NODE_VERSION && nvm use default && npm install -g npm
RUN ln -sf /root/.nvm/versions/node/v$NODE_VERSION/bin/node /usr/bin/nodejs
RUN ln -sf /root/.nvm/versions/node/v$NODE_VERSION/bin/node /usr/bin/node
RUN ln -sf /root/.nvm/versions/node/v$NODE_VERSION/bin/npm /usr/bin/npm
This is what worked for me (I'm using debian buster):
RUN apt-get update
RUN apt-get install -y build-essential checkinstall libssl-dev
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.35.1/install.sh | bash
SHELL ["/bin/bash", "--login", "-c"]
You should now be able to do nvm install <version>.
This installs the lts-version of nodejs when extending image "php:7.4.15" (debian:buster-slim):
# Install nvm to install npm and node.js
ENV NVM_DIR /root/.nvm
ENV NODE_VERSION lts/*
RUN mkdir $HOME/.nvm && \
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash && \
chmod +x $HOME/.nvm/nvm.sh && \
. $HOME/.nvm/nvm.sh && \
nvm install --latest-npm "$NODE_VERSION" && \
nvm alias default "$NODE_VERSION" && \
nvm use default && \
DEFAULT_NODE_VERSION=$(nvm version default) && \
ln -sf /root/.nvm/versions/node/$DEFAULT_NODE_VERSION/bin/node /usr/bin/nodejs && \
ln -sf /root/.nvm/versions/node/$DEFAULT_NODE_VERSION/bin/node /usr/bin/node && \
ln -sf /root/.nvm/versions/node/$DEFAULT_NODE_VERSION/bin/npm /usr/bin/npm
nvm not found can result from it being installed for a different user than the one who is executing the container. You may need to prefix the installation with the custom user who is executing the container. The last USER statement defines the container user.
USER $USERNAME
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
Reason
Diving into a nvm install script, e. g. v0.39.1, one can see that is installed into $HOME of the current user. If you have not changed it, the default user of a ubuntu image is root. When starting the container with a different user however, nvm won't be found; hence make sure user of installation and execution align.
nvm_default_install_dir() {
[ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm"
}
2022 update:
based off https://stackoverflow.com/a/60137919/2047472 I came up with:
FROM python:3.10
RUN touch .profile
SHELL ["/bin/bash", "--login", "-i", "-c"]
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
SHELL ["/bin/bash", "--login", "-c"]
RUN nvm install
RUN node -v
RUN npm -v
if you use .nvmrc and use source to init nvm, beware of a bug in nvm.sh causing it to exit with return code 3 when .nvmrc is present in current or parent directory
I had to touch .profile as it didn't exist, otherwise nvm is not activated in subsequent RUN commands
touch .bashrc didn't work
After testing most information here as well as other posts, turned out in my case it was related to permission issues, that lead to weird bugs, like failing to install a npm project unless run as root user, my setup was to run VueJs along a PHP CMS, the final portion that worked was:
ENV NVM_DIR $TMP_STORE/nvm
ENV NODE_VERSION 16.15.0
RUN chown -R www-data:www-data /var/www/
USER www-data
RUN export XDG_CONFIG_HOME=$TMP_STORE \
&& curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
#RUN chown -R www-data:www-data $NVM_DIR
RUN source $NVM_DIR/nvm.sh \
&& nvm install $NODE_VERSION \
&& nvm alias default $NODE_VERSION \
&& nvm use default
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
RUN npm install -g #vue/cli \
&& npm install -g vue
USER root
The whole docker configuration can be found here
Also had an oddly hard time for my docker file extending the CircleCI runner image - this worked for me:
FROM circleci/runner:launch-agent
SHELL ["/bin/bash", "--login", "-c"]
USER $USERNAME
RUN wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | bash;
ENV NODE_VERSION 18.12.1
ENV NVM_DIR $HOME/.nvm
RUN \
. ~/.nvm/nvm.sh \
&& nvm install $NODE_VERSION \
&& nvm alias default $NODE_VERSION \
&& nvm use default;
ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
RUN npm -v
RUN node -v
I had a really hard time getting NVM working properly on an alpine-based image. I ultimately just copied over a bunch of the shared directories from an official Node alpine image. Seems to be working quite well so far.
# Dockerfile
###############################################################################
# https://docs.docker.com/develop/develop-images/multistage-build/
# Builder Image
# This image is intended to build the app source code, not to run it.
###############################################################################
FROM node:16-alpine as builder
WORKDIR /build-tmp
COPY ./dist/src/yarn.lock .
COPY ./dist/src/package.json .
RUN yarn install --production
###############################################################################
# Execution image
# Nothing from the builder image is included here unless explicitly copied
###############################################################################
FROM osgeo/gdal:alpine-normal-3.4.2
# It's seemingly very difficult to build a specific version of node in an Alpine linux
# image, so let's copy node from the builder image into this execution image!
COPY --from=builder /usr/lib /usr/lib
COPY --from=builder /usr/local/share /usr/local/share
COPY --from=builder /usr/local/lib /usr/local/lib
COPY --from=builder /usr/local/include /usr/local/include
COPY --from=builder /usr/local/bin /usr/local/bin
...
CMD ["node", "main"]
Here is a solution I recently used:
# Install nvm/Node.js
ENV NVM_VERSION=0.39.1
ENV NODE_VERSION=16.17.1
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v$NVM_VERSION/install.sh | bash
RUN bash --login -c "nvm install $NODE_VERSION"
# Do whatever with nvm
RUN bash --login -c "nvm use $NODE_VERSION && npm [...]"
2023 to use as dev-container
I started to use the dev-contieners and to set up my enviroment I used the next Dockcerfile that works perfectly with the purpose I've described. I share this because spend a hard time to achive it.
FROM ubuntu:22.04
ENV HOME="/root"
ENV NVM_DIR="${HOME}/.nvm"
ENV NVM_VERSION=v0.39.3
ENV NODE_VERSION=18
RUN apt-get update \
&& apt-get install -y --no-install-recommends build-essential\
libssl-dev \
git \
curl \
ca-certificates \
&& git clone https://github.com/nvm-sh/nvm.git "${NVM_DIR}"
WORKDIR "${NVM_DIR}"
RUN git checkout ${NVM_VERSION} \
&& \. "./nvm.sh" \
&& nvm install "${NODE_VERSION}" \
&& echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> "${HOME}/.bashrc" \
&& echo '[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"' >> "${HOME}/.bashrc"
WORKDIR "${HOME}"
This is intended to work with bash (I don't have idea if works with another type of shell). The command that I used to run the image was:
docker run -ti --rm --name node_test <your-image-name | id-image> /bin/bash

Resources