Reputation: 2809
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.
Upvotes: 203
Views: 170581
Reputation: 8289
Directly from nvm's site:
When invoking bash as a non-interactive shell, like in a Docker container, none of the regular profile files are sourced. In order to use
nvm
,node
, andnpm
like normal, you can instead specify the specialBASH_ENV
variable, which bash sources when invoked non-interactively.# Use bash for the shell SHELL ["/bin/bash", "-o", "pipefail", "-c"] # Create a script file sourced by both interactive and non-interactive bash shells ENV BASH_ENV /home/user/.bash_env RUN touch "${BASH_ENV}" RUN echo '. "${BASH_ENV}"' >> ~/.bashrc # Download and install nvm RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.2/install.sh | PROFILE="${BASH_ENV}" bash RUN echo node > .nvmrc RUN nvm install
Upvotes: 0
Reputation: 16505
This is my Dockerfile ready to copy/paste in which I install the latest nvm 2025 version with latest Ubuntu
FROM ubuntu
ENV NVM_DIR /usr/local/nvm
ENV NODE_VERSION v23.6.0
RUN mkdir -p /usr/local/nvm && apt-get update && echo "y" | apt-get install curl
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
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/bin
ENV PATH $NODE_PATH:$PATH
Just create a Dockerfile and run
docker build -t foo . && docker run -it foo bash
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 v23.6.0
# Install latest nvm
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.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
nvm install v19
, nvm will install v19.9.0
in a folder /usr/local/nvm/versions/node/v19.9.0
. You will need this folder to add it to the PATHFROM node:16
directlyUpvotes: 48
Reputation: 31
Okay so I spent far too long trying to get this working, but here it is (As of 29/09/2024). I'm using debian:stable-slim
.
The key issue here is you need to source your nvm.sh, which means you must know where it is, which means you must explicitly specify it via environment variables. The reason you can't just go ahead here like a regular terminal or RUN is because our RUN instances do not carry over session/context data and they essentially run inside their own container (this is a simplification).
Furthermore, a lot of the answers here are rather outdated now due to changes to the nvm file paths which would just introduce additional headaches for skim readers.
Before you integrate this solution please go to https://github.com/nvm-sh/nvm and copy the update script path to make sure you're using the latest one (for security purposes).
# Install NVM and NodeJS
ENV NVM_DIR=/usr/local/nvm
ENV NODE_VERSION=v20.17.0
RUN mkdir -p $NVM_DIR && curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
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
Large thank you to @Steve-Campbell for his solution.
Upvotes: 3
Reputation: 6715
Here's an option that makes NVM run natively out of the box, so that if you issue commands in your running container you don't need to first call source ~/.nvm/nvm.sh
.
This assumes curl
has already been installed.
The way it works is to make a bash script in /usr/local/bin
(or any other location that features in $PATH
) that acts as a wrapper. The script sources nvm.sh in the current shell and then runs it directly, forwarding any arguments with "$@".
ARG NVM_VERSION=v0.39.7
ENV NVM_DIR=/usr/local/nvm
RUN mkdir -p ${NVM_DIR} \
&& curl -o- "https://raw.githubusercontent.com/nvm-sh/nvm/${NVM_VERSION}/install.sh" | bash \
&& echo ". ${NVM_DIR}/nvm.sh --no-use && nvm \"\$@\"" > /usr/local/bin/nvm \
&& chmod +x /usr/local/bin/nvm
I found I also had to add --no-use when sourcing nvm.sh as otherwise if a .nvmrc file is in the current directory it can fail in some shells.
Upvotes: 1
Reputation: 459
2024
I have been struggling with this since 2022 trying to set up a circle ci machine to run a simple playwright test. I ended up using run: | curl nvm | bash etc.
and basically treating as if i were sshed into the machine
enter root
USER root
yes ik this is not secure, but what can a few lines hurt to curl nvm and do what you're probably familiar with:
RUN mkdir -p $NVM_DIR; curl -o- https://nvm-dl-link/install.sh | bash
RUN . "$NVM_DIR/nvm.sh"
etc.
then you just change back to whatever user you want, which on ubuntu 20 for me is circleci
Upvotes: 0
Reputation: 4392
and here is a version invariant that just gets latest lts
ENV NVM_DIR /root/.nvm
RUN mkdir -p $NVM_DIR && curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash && . ~/.bashrc && nvm install --lts
RUN . $NVM_DIR/nvm.sh && ln -s $NVM_DIR/$(nvm current) $NVM_DIR/cur && ln -s $NVM_DIR/versions/node/$(nvm current) $NVM_DIR/versions/node/cur
ENV NODE_PATH $NVM_DIR/cur/lib/node_modules
ENV PATH $NVM_DIR/versions/node/cur/bin:$PATH
Upvotes: 2
Reputation: 11890
I got overwhelmed going through all the dockerfiles here, so I just wanted to share the relevant copy-pastable snippet:
# Install node and npm
# Installing a specific version of node directly is dificult. Use `nvm` to
# install it (which installs both `node` and `npm`)
# Set this to any desired version
ENV NODE_VERSION 14.17.5
# Can be anything, but this is a good default
ENV NVM_DIR /usr/local/nvm
# Must match one of the tag versions on https://github.com/nvm-sh/nvm/tags
ENV NVM_VERSION 0.39.5
RUN mkdir -p $NVM_DIR \
&& curl https://raw.githubusercontent.com/creationix/nvm/v$NVM_VERSION/install.sh | bash \
&& . $NVM_DIR/nvm.sh \
&& nvm install $NODE_VERSION \
&& nvm alias default $NODE_VERSION \
&& nvm use default \
&& node -v \
&& npm -v
# Update the $PATH to make your installed `node` and `npm` available!
ENV PATH $NVM_DIR/versions/node/v$NODE_VERSION/bin:$PATH
Upvotes: 3
Reputation: 452
Another cleanish solution for those who only have sh shell installed, or depends on sh shell. The difference between this and other solutions is the fact that you have to alter PATH for node bin to be available in another shell. Hopefully it helps.
# install node with nvm and within bash, then carry node bin to sh
SHELL ["/bin/bash", "--login", "-c"]
ENV NODE 14.21.3
ENV NODE_BIN /root/.nvm/versions/node/v$NODE/bin/
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
RUN nvm install $NODE
ENV PATH="${PATH}:${NODE_BIN}"
SHELL ["/bin/sh", "-c"]
replace 14.21.3 and 0.39.3 with desired node and nvm versions
Upvotes: -1
Reputation: 3605
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 mkdir -p $NVM_DIR
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.
Upvotes: 57
Reputation: 336
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
Upvotes: 3
Reputation: 1991
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
Upvotes: 1
Reputation: 4136
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
.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.profile
as it didn't exist, otherwise nvm is not activated in subsequent RUN commands
touch .bashrc
didn't workUpvotes: 2
Reputation: 34
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 [...]"
Upvotes: 0
Reputation: 918
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
Upvotes: 2
Reputation: 14985
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"]
Upvotes: 0
Reputation: 1675
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"
}
Upvotes: 2
Reputation: 99
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
Upvotes: 3
Reputation: 340
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
Upvotes: 10
Reputation: 174
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>
.
Upvotes: 2
Reputation: 2171
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
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).
Upvotes: 108
Reputation: 944
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"]
Upvotes: 49
Reputation: 3880
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"]
Upvotes: 42
Reputation: 5140
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
.
Upvotes: 17
Reputation: 2432
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
Upvotes: 5
Reputation: 54790
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
Upvotes: 184
Reputation: 1534
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.
Upvotes: 10
Reputation: 514
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.
Upvotes: 15
Reputation: 3502
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
viaapt-get
as well. I found that some packages don't get installed inside docker unless this is done.
Upvotes: 9
Reputation: 3815
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
Upvotes: 10
Reputation: 2591
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
Upvotes: 27