/bin/sh: npm: command not found - node.js

I am creating a docker image for stf.installing nodejs directly using apt-get install nodejs,had many issues.So i decided to go the nvm way.but after installation RUN npm install fails
I am building the docker image with su username docker build ..
make sure apt is up to date
RUN apt-get update --fix-missing
RUN apt-get install -y curl
RUN sudo apt-get install -y build-essential libssl-dev
ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION 6
# 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
#WORKDIR /usr/app
# Install app dependencies
RUN npm install
and the output
=> Downloading nvm from git to '/usr/local/nvm'
=> Cloning into '/usr/local/nvm'...
* (HEAD detached at v0.30.1)
master
=> Appending source string to /root/.bashrc
=> Close and reopen your terminal to start using nvm
Downloading https://nodejs.org/dist/v6.13.0/node-v6.13.0-linux-x64.tar.xz...
######################################################################## 100.0%
WARNING: checksums are currently disabled for node.js v4.0 and later
Now using node v6.13.0 (npm v3.10.10)
default -> 6 (-> v6.13.0)
Now using node v6.13.0 (npm v3.10.10)
Removing intermediate container eb9cb6c46f34
---> eeef6bf9f0f1
Step 38/52 : ENV NODE_PATH $NVM_DIR/v$NODE_VERSION/lib/node_modules
---> Running in 185bef8e530c
Removing intermediate container 185bef8e530c
---> 0e5bf7b1cfd9
Step 39/52 : ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
---> Running in 00d58493e199
Removing intermediate container 00d58493e199
---> 81ed9823020b
Step 40/52 : RUN npm install
---> Running in 1c7577133e24
/bin/sh: npm: command not found
The command '/bin/sh -c npm install' returned a non-zero code: 127
Please Help.Thanks
Ran the container and checked NPM path
root#69e513b99e68:/home/mobile/MobileFarmDocker#
echo $PATH
/usr/local/nvm/versions/node/v6.13.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
root#69e513b99e68:/home/mobile/MobileFarmDocker# which npm
/usr/local/nvm/versions/node/v6.13.0/bin/npm

Your $NODE_VERSION variable has value 6 as defined in the Dockerfile (ENV NODE_VERSION 6) but it should be 6.13.0 so that the following line may work properly:
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
(mapping to /usr/local/nvm/versions/node/v6.13.0/bin)
Otherwise, you are actually generating the following (wrong) path:
/usr/local/nvm/versions/node/v6/bin

Related

installing nodejs in dockerfile issue

I am trying to install nodejs in dockerfile with pyenv but I keep getting this error when I run it through my gitlab runner. I am trying to install version 16.12.0. Is there a better solution to this issue?
Dockerfile
#install npm
ENV NODE_VERSION=16.12.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
output
Step 15/25 : ENV NODE_VERSION=16.12.0
---> Running in 7623dfe4669c
Removing intermediate container 7623dfe4669c
---> c1486340596a
Step 16/25 : RUN apt install -y curl
---> Running in a4661b68566b
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Reading package lists...
Building dependency tree...
Reading state information...
curl is already the newest version (7.68.0-1ubuntu2.7).
0 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
Removing intermediate container a4661b68566b
---> d727779ba39b
Step 17/25 : RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
---> Running in c3661e8eead3
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
curl: (60) SSL certificate problem: self signed certificate in certificate chain
More details here: https://curl.haxx.se/docs/sslcerts.html
curl failed to verify the legitimacy of the server and therefore could not
establish a secure connection to it. To learn more about this situation and
how to fix it, please visit the web page mentioned above.
Removing intermediate container c3661e8eead3
---> beffd784c86b
Step 18/25 : ENV NVM_DIR=/root/.nvm
---> Running in 22b69a1563b2
Removing intermediate container 22b69a1563b2
---> 821b73dfd5fa
Step 19/25 : RUN . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION}
---> Running in 54c168c88ec7
/bin/sh: 1: .: Can't open /root/.nvm/nvm.sh
The command '/bin/sh -c . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION}' returned a non-zero code: 127
Cleaning up project directory and file based variables
00:00
ERROR: Job failed: exit code 127
In general you should avoid using version managers like nvm in Docker. You shouldn't need more than one version of a language interpreter at a time, and the version managers often require shell dotfile setup that's complicated to configure in Docker.
You don't say why you need Node. The easiest thing to do is to use the Docker Hub node image
FROM node:lts
# and none of what you show in the question
If you're using this to build the front end of your otherwise Python application, you can use a multi-stage build for this
FROM node:lts AS frontend
WORKDIR /frontend
COPY frontend/package*.json ./
RUN npm ci
COPY frontend/ ./
RUN npm build
FROM python:3.10
...
COPY --from=frontend /frontend/dist ./static/
If you really need Node in your otherwise Ubuntu-based image, the next easiest thing to do is just install it. The default Ubuntu nodejs package should work fine for most practical uses.
FROM ubuntu:20.04
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get --no-install-recomends --assume-yes \
nodejs
If you really need it in a custom image, and it really needs to be a super specific version of Node, you should be able to just download Node and install it.
FROM ubuntu:20.04
RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive \
apt-get --no-install-recomends --assume-yes \
curl \
xz-utils
ARG node_version=v16.14.2
RUN cd /opt \
&& curl -LO https://nodejs.org/dist/${node_version}/node-${node_version}-linux-x64.tar.xz \
&& tar xJf node-${node_version}-linux-x64.tar.xz \
&& rm node-${node_version}-linux-x64.tar.xz
ENV PATH=/opt/node-${node_version}-linux-x64/bin:${PATH}

Workers for phantomJs fail to start in a Docker container

I am working on Dockerizing my node app which uses highcharts-export-server and creates images in my code. When I run the created image on my local machine the workers fail to start saying
`
phantom worker 7 error - /usr/src/app/node_modules/phantomjs-
prebuilt/lib/phantom/bin/phantomjs: 1:
/usr/src/app/node_modules/phantomjs-prebuilt/lib/phantom/bin/phantomjs: Syntax error: Unterminated quoted string.
The node version I am using is 8. I have also tried logging platform and architecture using process.platform and process.arch respectively inside my running container and using those values to set in Environment variables PHANTOMJS_PLATFORM and PHANTOMJS_ARCH in my dockerfile. I have also tried to install phantomJs separately using RUN npm i -g phantomjs-prebuilt --unsafe-perm. My Docker file looks like this currently.
FROM node:8
WORKDIR /usr/src/app
COPY package*.json ./
ENV PHANTOMJS_BIN "/usr/local/bin/phantomjs"
ENV PHANTOMJS_PLATFORM "linux"
ENV PHANTOMJS_ARCH "x64"
ENV ACCEPT_HIGHCHARTS_LICENSE="YES"
RUN apt-get update && \
apt-get install -y \
python3 \
python3-pip \
python3-setuptools \
groff \
less \
&& pip3 install --upgrade pip \
&& apt-get clean
RUN pip3 --no-cache-dir install --upgrade awscli
RUN npm set strict-ssl false
RUN npm install
COPY . .
EXPOSE 8080
CMD [ "npm", "start" ]
Not sure if this helps but you can give it a try:
Run npm i phantomjs-prebuilt --unsafe-perm in you app folder, i.e. without -g. This should create a folder in node_modules called "phantomjs-prebuilt".
Also, check if you have phantomjs binary file created in the following path node_modules/phantomjs-prebuilt/lib/phantom/bin/ once you run this command.

The npm command is not found in my NodeJS docker container

I created a Docker image:
$ docker build -t stephaneeybert/nodejs .
Sending build context to Docker daemon 2.56 kB
Step 1 : FROM debian
---> 1b088884749b
Step 2 : RUN apt-get clean && apt-get update
---> Using cache
---> b12133d6342f
Step 3 : RUN apt-get install -y curl
---> Using cache
---> 22dfb4882b12
Step 4 : RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash
---> Using cache
---> 27f2fac45254
Step 5 : RUN . ~/.nvm/nvm.sh; nvm install stable
---> Using cache
---> 20d99d545755
Step 6 : RUN . ~/.nvm/nvm.sh; nvm use stable
---> Using cache
---> 9ec14efb2407
Step 7 : RUN . ~/.nvm/nvm.sh; npm install -g npm
---> Using cache
---> d264d38565f3
Step 8 : EXPOSE 9001
---> Using cache
---> 29e3589557e1
Step 9 : ENTRYPOINT /usr/bin/tail -f /dev/null
---> Using cache
---> 2ce499300fe1
Successfully built 2ce499300fe1
The image script is:
FROM debian
RUN apt-get clean && apt-get update
RUN apt-get install -y curl
# Installing nodesjs
RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash
RUN . ~/.nvm/nvm.sh; nvm install stable
RUN . ~/.nvm/nvm.sh; nvm use stable
RUN . ~/.nvm/nvm.sh; npm install -g npm
EXPOSE 9001
ENTRYPOINT ["/usr/bin/tail", "-f", "/dev/null"]
Then I run the container and open a bash shell:
$ docker run -d -p 127.0.0.1:9001:9001 --name nodejs stephaneeybert/nodejs
c6dddf0a5eb0f11c897f63910eb01f2868fe0f39a80e5e2a580ef3a82935b27b
[stephane#stephane-ThinkPad-X301 nodejs]
$ docker exec -it nodejs bash
root#c6dddf0a5eb0:/#
Once in there, I try to get the version:
root#c6dddf0a5eb0:/# npm -v
bash: npm: command not found
But npm is not found.
When typing the command nvm use stable in the interactive shell, it give the following error: N/A: version "N/A" is not yet installed.
I understand there is an alias against a non existant node version.
The nvm ls command shows:
root#60446f9286d0:/# nvm ls
N/A
node -> stable (-> N/A) (default)
iojs -> N/A (default)
The debugger has this to show:
root#60446f9286d0:/# nvm debug
nvm --version: v0.32.1
$SHELL: /bin/bash
$HOME: /root
$NVM_DIR: '$HOME/.nvm'
$PREFIX: ''
$NPM_CONFIG_PREFIX: ''
nvm current: none
which node:
which iojs:
which npm:
npm config get prefix: bash: npm: command not found
npm root -g: bash: npm: command not found
1- How come I need to source this script . ~/.nvm/nvm.sh; on each command?
2- Why is my Node package manager not found in the bash shell?
EDIT: I changed a bit the content of the Dockerfile file:
RUN curl -o-https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash \
&& . ~/.nvm/nvm.sh \
&& nvm install stable \
&& nvm alias default stable \
&& nvm use default
And building it now shows this:
Step 4 :RUN curl -o https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash && . ~/.nvm/nvm.sh && nvm install stable && nvm alias default stable && nvm use default
---> Running in 7d2c404135dd
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 10250 100 10250 0 0 18258 0 --:--:-- --:--:-- --:--:-- 18238
=> Downloading nvm as script to '/root/.nvm'
=> Appending source string to /root/.bashrc
=> Close and reopen your terminal to start using nvm or run the following to use it now:
export NVM_DIR="/root/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
######################################################################## 100.0%
Computing checksum with sha256sum
Checksums matched!
Now using node v7.2.0 (npm v3.10.9)
Creating default alias: default -> stable (-> v7.2.0 *)
default -> stable (-> v7.2.0 *)
Now using node v7.2.0 (npm v3.10.9)
---> ad960a4addbe
Removing intermediate container 7d2c404135dd
Step 5 : EXPOSE 9001
---> Running in df9284421302
---> 14d386f009fb
Removing intermediate container df9284421302
Step 6 : ENTRYPOINT /usr/bin/tail -f /dev/null
---> Running in fa2d71b6dfdf
---> d02c8e88eb7f
Removing intermediate container fa2d71b6dfdf
Successfully built d02c8e88eb7f
I can see it installed node v7.2.0 and is using it.
But when I log into the container with the command docker exec -it nodejs bash it does not see any node anywhere:
root#f8f2a32b462a:/# nvm --version
0.32.1
root#f8f2a32b462a:/# npm --version
bash: npm: command not found
root#f8f2a32b462a:/# echo $NVM_DIR
/root/.nvm
root#f8f2a32b462a:/# ls -l /root/.nvm
total 100
-rwxr-xr-x 1 root root 313 Nov 26 13:01 nvm-exec
-rw-r--r-- 1 root root 95660 Nov 26 13:01 nvm.sh
root#f8f2a32b462a:/# ls -l /root/.npm
ls: cannot access /root/.npm: No such file or directory
I changed the way I install Node and did it without the nvm tool:
RUN curl -sL https://deb.nodesource.com/setup_7.x | bash
RUN apt-get install -y nodejs
Now, when logging in the container, it can find the Node executable:
$ docker run -d -p 127.0.0.1:9001:9001 --name nodejs stephaneeybert/nodejs
f3a2f054934ef92a9b05486b6f6dbe53abd4390826c06d1b7a490d671d8e3422
[stephane#stephane-ThinkPad-X301 nodejs]
$ docker exec -it nodejs bash
root#f3a2f054934e:/# npm --version
3.10.9
Maybe, when I was using the nvm tool, I should have sourced the npm command in the client shell . ~/.nvm/nvm.sh npm --version.
For amazonlinux (Ubuntu Fedora) you can install it using yum like this inside the Dockerfile:
RUN curl -sL https://rpm.nodesource.com/setup_10.x | bash # for node version 10.x
RUN yum -y install nodejs
RUN node --version # optional to check that it worked
RUN npm --version # optional to check that it worked
Use docker build -t [name] [local_folder_like_dot]
Took me ages to google, don't know much about linux but it seems like every version is so different from the other. It's like google docker npm, use apt get nah doesn't work, figure out wth linux version amasonlinux is.. Ok called Fedora.. it has yum instead of apt.. ok .. you need to answer yes in the yum install, docker doesn't allow it just skips it then.. wth.. I can hackz0r it with | yes nah that just spams y forevah.. ok I canz killall nah not in Fedora.. okiz can yum installz without questionz askz??! -y
2h later and we have this :)

gulp not running on Docker ubuntu

I'm trying to use gulp to start a webpack compiler in a docker environment. Wheneever I try to run the command (in ssh, the Dockerfile, or the Procfile) it fails with error code 1 and prints nothing.
I checked and gulp is installed in node_packages, but when I run it from node_packages/.bin I get the same response. Running "npm" works, but running "node" appears not to work either.
Does anyone know what is going wrong?
Dockerfile
FROM quay.io/aptible/ubuntu:14.04
# Basic dependencies
RUN apt-install build-essential python-dev python-setuptools
RUN apt-install libxml2-dev libxslt1-dev python-dev
# PostgreSQL dev headers and client (uncomment if you use PostgreSQL)
# RUN apt-install libpq-dev postgresql-client-9.3 postgresql-contrib-9.3
# MySQL dev headers (uncomment if you use MySQL)
RUN apt-install libmysqlclient-dev
RUN easy_install pip
RUN apt-install node
RUN apt-install npm
# Add requirements.txt and package.json ONLY, then run pip install, so that Docker cache won't
# bust when changes are made to other repo files
ADD requirements.txt /app/
ADD package.json /app/
WORKDIR /app
RUN pip install -r requirements.txt
RUN npm install
# Add repo contents to image
ADD . /app/
# RUN npm install -g gulp
# RUN gulp webpack:dev
#django environment variables
# ENV DATABASE_URL xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# ENV SECRET_KEY xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# ENV DJANGO_SETTINGS_MODULE xxxxxxxxxxxxx
ENV PORT 3000
EXPOSE 3000
procfile
web: sudo node_modules/.bin/gulp webpack:dev && sudo python app/manage.py runserver 0.0.0.0:$PORT
Change these lines
RUN apt-install build-essential python-dev python-setuptools
...
RUN apt-install node
RUN apt-install npm
to these:
RUN apt-install build-essential curl python-dev python-setuptools
...
RUN curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
RUN apt-get install -y nodejs
You'll note we added curl to your tool installation and we're grabbing the node ppa, then installing it. This is going to give you the more current version of node on that branch. It will also come with npm, you do not need to install that separately.
Uncomment this line, as you want gulp to be a global install
# RUN npm install -g gulp
Correspondingly, in your proc file - use the global gulp

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