Как установить nvm в докере?


103

Я нахожусь в процессе создания нового образа 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"

Вот результат попытки сборки:

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

Я новичок в Docker, поэтому мне может не хватать чего-то важного для написания файлов Docker, но пока все прочитанное мной не показало мне хорошего решения.


11
Не дубликат, поскольку это относится к установке внутри докера, а не к стандартной установке
Дэвид Фикосиелло

Поскольку вы устанавливаете только одну версию узла, кажется, нет необходимости устанавливать nvm. Dockerfiles, предоставленные репозиторием узлов Docker, можно использовать в качестве справочника по установке узла.
mikwat

Ответы:


121

Когда вы 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

чтобы ускорить это в два раза, просто измените v0.20.0наv0.24.1
itsnikolay

8
с nvm 0.31.0и node v4.2.3путь/usr/local/nvm/versions/node/v4.2.3/bin
cwhsu

4
@thiagoh Это не объясняет, почему установка nvm задающим вопрос не работает, а рабочие ответы работают. Это не имеет ничего общего с оболочками, запущенными в отдельных процессах. Это связано с тем, что вопрос пытается использовать источник bash.rc для загрузки файла nvm.sh, который загружает команду nvm в bash, но bash.rc завершает работу раньше, когда выполняется не интерактивно, поэтому команда nvm не загружается. Все успешные ответы отправляют nvm.sh напрямую, а не через bash.rc. Это ключ к работе.
tobuslieven

2
Вместо замены sh на bash вы можете просто сделать это . $NVM_DIR/nvm.sh, избегая исходных двоичных файлов.
Разван Григоре

3
Это близко, но пути требуют небольшой настройки, должны быть: ENV NODE_PATH $ NVM_DIR / versions / node / v $ NODE_VERSION / lib / node_modules ENV PATH $ NVM_DIR / versions / node / v $ NODE_VERSION / bin: $ PATH
Lunulata

31

Чтобы помочь всем, кто ищет способ установить Node.js с NVM в Ubuntu (последняя версия), я создал файл докеров ниже. Я использую последнюю версию 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"]

1
если NODE_PATH не должен быть ENV NODE_PATH $ NVM_DIR / versions / node / v $ NODE_VERSION / lib / node_modules
Sentient

Привет, @Sentient! Я запускаю этот докер в производственной среде (ubuntu) и в локальной среде разработки (OSX), оба работают правильно, без ошибок. Возможно, вы используете устаревший NVM?
danilodeveloper

Есть ли причина, по которой я должен использовать SUDO для установки build-essential и libssl-dev? Я совсем не опытный DevOps.
a.barbieri

1
Ключsource $NVM_DIR/nvm.sh && nvm install $NODE_VERSION
Владимир Корнеа 03

24

Пути 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

Не уверен, что вам понадобится --delete-prefixопция на nvm use- я сделал, но это может быть что-то странное в моем базовом образе.


1
Спасатель жизни! Если бы я видел твой ответ 3 часа назад.
Adrian Marinica 05

Работал для меня, базовый образ php: 7.1.1
Toby Mellor

18

Каждый RUNиз Dockerfile выполняется в другом контейнере. Поэтому, если вы отправляете файл в контейнер, его содержимое не будет доступно в следующем.

Вот почему, когда вы устанавливаете приложение и вам нужно выполнить несколько шагов, вы должны сделать это в одном контейнере.

С вашим примером:

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

Хорошо, большое спасибо за объяснение. Итак, я изменил свой сценарий, чтобы он выглядел так: `FROM ubuntu MAINTAINER dficociello ADD files / nvm_install.sh / root / # Установить nvm RUN [" / bin / bash "," -c "," rm -f / etc / nginx / nginx.conf && touch /root/.bashrc && apt-get update && apt-get install nginx curl -y && chmod a + x /root/nvm_install.sh && source /root/.bashrc && / root / nvm_install. sh && nvm install 0.10.31 "] ДОБАВИТЬ файлы / nginx.conf / etc / nginx / EXPOSE 22` Я получаю следующую ошибку: `/ bin / bash: /root/nvm_install.sh: / bin / bash: плохой интерпретатор: Текстовый файл занят `
Дэвид Фикосиелло

Эта ошибка должна быть связана с вашей линией RUN ["/bin/bash", ...]. Он не должен быть окружен, [...]и вам не нужно указывать интерпретатор /bin/bash -c.
Kuhess

17

Это основано на верхнем ответе и работает в 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

Обратите внимание, что nvmэто не команда bash, это псевдоним. Это может облажаться, если вы полагаетесь на него $PATH.


15

Обновление 20/02/2020 : это решение работает, если вы используете 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

Объяснение

  • Первая строка устанавливает оболочку Dockerfile по умолчанию для оболочки входа в bash . Примечание: это означает, что каждое последующее RUN, CMDи ENTRYPOINTбудет запускаться под текущим пользователем (обычно root) и исходным файлом ~ / .bashrc, если запускаться в форме оболочки .

  • Вторая строка устанавливается nvmс помощью bash. Когда сценарий запускается с помощью bash, он добавляется в файл ~ / .bashrc .

  • Третья строка устанавливает определенную версию nodejs и использует ее. В nvm, npmи nodeкоманды доступны , потому что они работают через Баш оболочку входа (см строка 1).


1
Спасибо вам большое !
Гауи

Интересно, что это сработало для вас. Я пробовал нечто подобное, и все выглядело нормально во время сборки, но NPM не был найден, когда я пошел запускать получившийся образ. Явная настройка NVM_DIR(как показано в нескольких других ответах) исправила это для меня.
письмо

1
@esmail это странно , потому что первые RUNнаборы команд NVM_DIRв ~/.bashrc.
Доминик Рой-Станг,

1
@ DominicRoy-Stang, верная точка зрения. Изображение, с которым я работал, использует shи поэтому игнорирует .bashrc. Кроме того, вы уверены, что .bashrcэто действительно источник перед выполнением RUNкоманд? В моем кратком тестировании с официальным bashизображением мне показалось, что это не так.
письмо

1
@esmail это то, что первая линия ( SHELLинструкция) адрес. Он заставляет последовательные команды RUN использовать оболочку входа в систему, которая является источником .bashrcфайла. Примечание: это работает, только если команды выполняются в режиме оболочки, например. RUN nvm --version. Это не будет работать, если команды выполняются в режиме exec, например. RUN ["nvm", "--version"]. Я обновил ссылку на форму оболочки, чтобы, надеюсь, сделать это более очевидным.
Доминик Рой-Станг,

10

Основываясь на предложении в ответе @Kuhess, я заменил исходную команду следующей в моем Dockerfile

RUN cat ~/.nvm/nvm.sh >> installnode.sh
RUN echo "nvm install 0.10.35" >> installnode.sh
RUN sh installnode.sh

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;

Получил помощь от ответов @abdulljibali и @shamisis.


Поиск ~/.nvm/nvm.shфайла был ключевым моментом, который мне был нужен.
Стефан

Это было единственное решение, которое сработало для меня с контейнером ubuntu 16.04.2.
drohm 03

7

Я должен начать с того, что я искал повсюду, чтобы найти рабочий пример 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;

Обратите внимание, как я установил nodejsчерез apt-get. Я обнаружил, что некоторые пакеты не устанавливаются внутри докера, если это не сделано.


ага - чувак - пробовал около 100 решений и работает только ваше - 10х!
srfrnk 09

Правильно использовать ~ / .nvm / nvm-tmp.sh, чтобы версии узлов правильно устанавливались внутри каталога ~ / .nvm
guidoman

7

Ключевое отличие попытки получить команду nvm в вопросе:

RUN bash -l -c "source /root/.bashrc"

который не работает, и попытка сделать то же самое в принятом ответе:

source $NVM_DIR/nvm.sh

В том, что вторая версия напрямую использует сценарий nvm.sh, тогда как исходная версия пытается сделать это через файл .bashrc.

В файле .bashrc есть строка в начале, которая завершается, если он запускается в неинтерактивной оболочке:

# If not running interactively, don't do anything
case $- in
    *i*) ;;
    *) return;;
esac

Таким образом, он никогда не доходит до того места, где он мог бы получить nvm.sh, который фактически помещает команду nvm в вашу оболочку.

Я не удивлюсь, если докер запустит все это в неинтерактивной оболочке. Это не было явно указано, поэтому я подумал, что упомяну об этом, потому что это то, что меня привлекло, когда я делал что-то подобное с vagrant.


Спасибо, что нашли источник проблемы. Я скопировал файл /etc/skel/.bashrc из базового образа ubuntu 19.10, а затем закомментировал приведенные выше оскорбительные строки. Затем в моем Dockerfile я использовал команду COPY, чтобы скопировать «исправленный» /etc/skel/.bashrc в / etc / skel и только после этого использовать RUN для создания пользователей с / bin / bash в качестве оболочки. Затем последующие вызовы RUN ["/ bin / bash", "-c", "-l", YOUR_COMMAND [S] _HERE] работали нормально.
Стефан Долиев

6

Мне потребовался час или два, чтобы придумать самый чистый способ сделать это. --login, похоже, не выполняет .bashrc, поэтому вам нужно указать -i, чтобы запустить его в интерактивном режиме. Это заставляет Docker немного кричать на вас, поэтому я запускаю этот способ только для установки, а затем возвращаюсь к своей стандартной оболочке.

# 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"]

Ваш ответ заставил меня понять, что мой не работает ubuntuв качестве базового изображения (а ваш - работает). Я использовал debianизображения на основе. Я не уверен, что вызывает несоответствие между ними. Любые идеи?
Доминик Рой-Станг,

Я использую ubuntu 19:10 в качестве базового образа. Я опубликую все соответствующие инструкции Docker, чтобы вы имели представление о том, что мне подходит. Любые инструкции, которые я пропустил, либо не актуальны, либо я не могу их предоставить. Представлю их с комментарием. Я опубликую его в следующем комментарии, так как ограничение на количество символов слишком низкое
опубликую

4

У меня ничего из этого не сработало, для моего 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

Согласовано. При установке в докер-контейнер (Debian GNU / Linux 9 (stretch)) nvm тоже оказался у $HOME/.nvmменя.
Дэйв Стивенс

Да, мне тоже нужно было добавить символические ссылки. Мне интересно, как это вообще не нужно было другим.
PEZO

0

Вот что у меня сработало (я использую 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"]

Теперь вы можете это сделать nvm install <version>.


0

Всего один ответ - установка 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.