node.js 如何在 docker 中安装 nvm?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25899912/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to install nvm in docker?
提问by David Ficociello
I am in the process of building a new Docker image and I'm looking to get NVM installed so I can manage nodejs.
我正在构建一个新的 Docker 镜像,我希望安装 NVM,以便我可以管理 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.
阅读有关如何安装 NVM 的文档时,他们提到您需要获取 .bashrc 文件才能开始使用 NVM。
I've tried to set this up in a Dockerfile, but so far building fails with the error:
我试图在 Dockerfile 中设置它,但到目前为止构建失败并出现错误:
"bash: nvm: command not found"
“bash:nvm:找不到命令”
Here are the relevant lines from my Dockerfile:
以下是我的 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 .
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.
我对 Docker 还很陌生,所以我可能会遗漏一些编写 Dockerfiles 的基本知识,但到目前为止,我所做的所有阅读都没有向我展示一个好的解决方案。
回答by Abdullah Jibaly
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:
当您RUN bash...每次在单独的进程中运行时,环境中设置的任何内容都不会得到维护。这是我的安装方法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
回答by danilodeveloper
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.
为了帮助正在寻找在 Ubuntu(最新版本)上使用 NVM 安装 Node.js 的每个人,我制作了下面的 dockerfile。我使用的是最新版本的 Docker、Ubuntu、Node.js,并且 NVM 工作正常($PATH 已修复)。我在生产环境中使用它。
$ 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"]
回答by Steve Campbell
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 shto make it work:
Nvm 路径自接受的答案以来已更改,因此如果您想使用更新的 nvm 版本,则需要进行一些更改。此外,没有必要重新映射sh以使其工作:
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-prefixoption on the nvm use- I did, but that may be something strange about my base image.
不确定您是否需要- 我需要该--delete-prefix选项nvm use,但这可能对我的基本图像有些奇怪。
回答by Kuhess
Each RUNin 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.
RUNDockerfile 中的每个都在不同的容器中执行。因此,如果您在容器中获取文件,则其内容在下一个容器中将不可用。
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
回答by rjurney
This is based on the top answer and works in 2018:
这是基于最佳答案并在 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 nvmis not a bash command, it is an alias. This can screw you up if you're relying on $PATH.
请注意,这nvm不是 bash 命令,而是别名。如果您依赖$PATH.
回答by Dominic Roy-Stang
Update20/02/2020: This solution works if you're using a debianbase image. If you're using ubuntu, see this answer.
2020 年 2 月 20 日更新:如果您使用的是debian基本映像,则此解决方案有效。如果您正在使用ubuntu,请参阅此答案。
Here is the cleanest way to install nvmthat I have found:
这是nvm我发现的最干净的安装方式:
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, andENTRYPOINTwill be run under the current user (usually root), and source the ~/.bashrcfile if run in the shell form.The second line installs
nvmwith bash. When the script is run with bash, it appends to the ~/.bashrcfile.The third line installs a particular version of nodejs and uses it. The
nvm,npm, andnodecommands are available because they are run via a bash login shell (see line 1).
第一行将 Dockerfile 的默认 shell 设置为bash login shell。注意:这意味着每个后续的
RUN,CMD, 和ENTRYPOINT将在当前用户(通常是 root)下运行,如果以shell 形式运行,则源~/.bashrc文件。第二行
nvm用 bash安装。当脚本使用 bash 运行时,它会附加到~/.bashrc文件中。第三行安装特定版本的 nodejs 并使用它。的
nvm,npm以及node因为它们通过bash登录shell(参照第1行)运行的命令是可用的。
回答by Ryan
Based upon the suggestion in @Kuhess answer, I replaced the source command with the following in my Dockerfile
根据@Kuhess 回答中的建议,我在 Dockerfile 中用以下内容替换了源命令
RUN cat ~/.nvm/nvm.sh >> installnode.sh
RUN echo "nvm install 0.10.35" >> installnode.sh
RUN sh installnode.sh
回答by Tahir Rauf
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.
从@abdulljibali 和@shamisis 的答案中获得帮助。
回答by Shamasis Bhattacharya
I must begin with the fact that I searched all over to get a working example of nvminside dockerand I found none. Even the answers in this thread did not work.
我必须从这样一个事实开始:我到处搜索以获得nvm内部的工作示例,但docker我没有找到。甚至这个线程中的答案也不起作用。
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
nodejsviaapt-getas well. I found that some packages don't get installed inside docker unless this is done.
请注意我是如何安装
nodejs通过的apt-get。我发现除非这样做,否则某些软件包不会安装在 docker 中。
回答by tobuslieven
A key difference between the attempt to get the nvm command in the question:
尝试获取问题中的 nvm 命令之间的主要区别:
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.
是第二个版本直接获取 nvm.sh 脚本,而原始版本尝试通过 .bashrc 文件来实现。
The .bashrc file has a line in it early on which exits if it's being run in a non interactive shell:
.bashrc 文件中有一行,如果它在非交互式 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.
所以它永远不会到达它会提供 nvm.sh 的地方,它实际上将 nvm 命令放在你的 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.
如果 docker 在非交互式 shell 中运行这些东西,我不会感到惊讶。没有明确指出这一点,所以我想我会提到它,因为当我用 vagrant 做类似的事情时,这就是让我注意到的地方。

