在docker中安装nvm

Dav*_*llo 86 node.js nvm docker

我正在构建一个新的Docker镜像,我希望安装NVM,这样我就可以管理nodejs.

阅读有关如何安装NVM的文档,他们提到您需要获取.bashrc文件才能开始使用NVM.

我试图在Dockerfile中设置它,但到目前为止构建失败并出现错误:

"bash:nvm:命令未找到"

以下是我的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"
Run Code Online (Sandbox Code Playgroud)

以下是尝试构建的输出:

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
Run Code Online (Sandbox Code Playgroud)

我对Docker很陌生,所以我可能会遗漏编写Dockerfiles的基本内容,但到目前为止,我所做的所有阅读都没有给我一个很好的解决方案.

谢谢

Abd*_*aly 112

当您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
Run Code Online (Sandbox Code Playgroud)

  • 使用nvm`0.31.0`和节点`v4.2.3`,路径为`/ usr/local/nvm/versions/node/v4.2.3/bin` (7认同)
  • @thiagoh这并不能解释为什么提问者安装nvm不起作用,而且工作答案确实有效.它与在不同进程中运行的shell无关.这是因为该问题试图获取bash.rc来加载nvm.sh文件,该文件将nvm命令加载到bash中,但是bash.rc在非交互式运行时提前退出,因此未加载nvm命令.所有成功的答案直接来源nvm.sh而不是通过bash.rc来做.这是使这项工作的关键. (4认同)
  • 这很接近,但路径需要稍微调整,应该是:ENV NODE_PATH $ NVM_DIR/versions/node/v $ NODE_VERSION/lib/node_modules ENV PATH $ NVM_DIR/versions/node/v $ NODE_VERSION/bin:$ PATH (3认同)
  • 你可以简单地做`而不是用bash替换sh.$ NVM_DIR/nvm.sh`,避免源二进制文件. (2认同)

Dom*_*ang 30

2020 年 2 月 20 日更新:如果您使用的是debian基本映像,则此解决方案有效。如果您正在使用ubuntu,请参阅此答案

这是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
Run Code Online (Sandbox Code Playgroud)

解释

  • 第一行将 Dockerfile 的默认 shell 设置为bash login shell。注意:这意味着每个后续的RUN, CMD, 和ENTRYPOINT将在当前用户(通常是 root)下运行,如果以shell 形式运行,则源~/.bashrc文件。

  • 第二行nvm用 bash安装。当脚本使用 bash 运行时,它会附加到~/.bashrc文件中。

  • 第三行安装特定版本的 nodejs 并使用它。的nvmnpm以及node因为它们通过bash登录shell(参照第1行)运行的命令是可用的。

  • 有趣的是,这对你有用。我尝试了类似的方法,在构建过程中一切看起来都很好,但是当我去运行生成的图像时找不到 NPM。显式设置“NVM_DIR”(如其他几个答案所示)为我解决了这个问题。 (2认同)
  • @esmail 这很奇怪,因为第一个“RUN”命令在“~/.bashrc”中设置“NVM_DIR”。 (2认同)
  • @DominicRoy-Stang,有道理。我正在使用的图像使用“sh”,因此忽略“.bashrc”。另外,您确定在执行“RUN”命令之前确实获取了“.bashrc”吗?在我对官方“bash”图像的简短测试中,似乎并非如此。 (2认同)
  • @esmail 这就是第一行(“SHELL”指令)所解决的问题。它使连续的 RUN 命令使用源自“.bashrc”文件的登录 shell。注意:只有在 shell 模式下运行命令时它才有效,例如。`运行 nvm --version`。如果命令在 exec 模式下运行,它将不起作用,例如。`RUN ["nvm", "--version"]`。我已经更新了为 shell 表单提供的链接,希望使这一点更加明显。 (2认同)

dan*_*per 26

为了帮助每个人都在寻找在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
Run Code Online (Sandbox Code Playgroud)


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"]
Run Code Online (Sandbox Code Playgroud)


Ste*_*ell 21

自接受的答案以来,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
Run Code Online (Sandbox Code Playgroud)

不确定你是否需要--delete-prefix选项nvm use- 我做了,但这对我的基本图像可能有些奇怪.

  • 救星!要是我三小时前看到你的回复就好了。 (3认同)
  • 您可能需要添加“RUN mkdir -p $NVM_DIR”。似乎较新版本的 nvm 检查该目录是否存在。 (3认同)
  • 2023 年 3 月在这里,也是唯一有效的解决方案! (2认同)

Kuh*_*ess 17

RUNDockerfile中的每个都在不同的容器中执行.因此,如果您在容器中提供文件,则其内容将在下一个文件中不可用.

这就是为什么当您安装应用程序并且需要执行多个步骤时,必须在同一容器中执行此操作.

用你的例子:

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
Run Code Online (Sandbox Code Playgroud)


use*_*438 17

我花了一两个小时才找到最干净的方法。--login 似乎没有执行 .bashrc 所以你必须提供 -i 以交互模式启动它。这会导致 Docker 对您大喊大叫,所以我只以这种方式启动安装,然后重置为我的标准 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"]
Run Code Online (Sandbox Code Playgroud)


rju*_*ney 13

这是基于最佳答案,并在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
Run Code Online (Sandbox Code Playgroud)

请注意,这nvm不是bash命令,而是别名.如果你依赖,这可能会搞砸你$PATH.


小智 10

2021 年 2 月 25 日 主要问题在于使用“source”指令,该指令是 bash shell 特有的。对我有用的是将“来源”替换为“。” 对于 Ubuntu 18 安装。我的 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
Run Code Online (Sandbox Code Playgroud)


Rya*_*yan 8

根据@Kuhess答案中的建议,我在我的Dockerfile中用以下代码替换了source命令

RUN cat ~/.nvm/nvm.sh >> installnode.sh
RUN echo "nvm install 0.10.35" >> installnode.sh
RUN sh installnode.sh
Run Code Online (Sandbox Code Playgroud)


小智 8

这是我的工作版本

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;
Run Code Online (Sandbox Code Playgroud)

从@abdulljibali和@shamisis的答案中获得帮助.


Sha*_*rya 6

我必须从这样一个事实开始,即我搜索到了一个nvm内部的工作示例,但docker我没有找到.即使这个帖子中的答案也行不通.

所以,我花了很长时间想出一个有效的方法:

# 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;
Run Code Online (Sandbox Code Playgroud)

注意我也是如何安装nodejsvia的apt-get.我发现有些软件包没有安装在docker中,除非这样做.


tob*_*ven 6

尝试在问题中获取nvm命令之间的关键区别:

RUN bash -l -c "source /root/.bashrc"
Run Code Online (Sandbox Code Playgroud)

哪个不起作用,并尝试在接受的答案中做同样的事情:

source $NVM_DIR/nvm.sh
Run Code Online (Sandbox Code Playgroud)

是第二个版本直接来源nvm.sh脚本,而原始版本尝试通过.bashrc文件来完成.

.bashrc文件在它的早期有一行,如果它在非交互式shell中运行则退出:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
    *) return;;
esac
Run Code Online (Sandbox Code Playgroud)

所以它永远不会得到它会产生nvm.sh的位,它实际上将nvm命令放在你的shell中.

如果docker在非交互式shell中运行这些东西,我不会感到惊讶.这没有明确指出,所以我想我会提到它,因为当我做与流浪汉类似的事情时,它是什么引起了我的注意.


JRi*_*dsz 6

只有一个答案将 curl 安装,但不适用于整个 Dockerfile

这里我的 Dockerfile 准备复制/粘贴,我在其中安装了最新的nvm 2020 版本Ubuntu 18.04.3 LTS

FROM ubuntu

RUN apt-get update
RUN echo "y" | apt-get install curl
ENV NVM_DIR /usr/local/nvm
RUN mkdir -p /usr/local/nvm
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash
ENV NODE_VERSION v10
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
Run Code Online (Sandbox Code Playgroud)


Cor*_*ole 5

这些都不适合我,对于我的python3-onbuild容器,我必须强制创建到 nvm 安装的符号链接。

# 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
Run Code Online (Sandbox Code Playgroud)