Wie installiere ich nvm im Docker?

101

Ich bin gerade dabei, ein neues Docker-Image zu erstellen, und ich möchte NVM installieren, damit ich NodeJS verwalten kann.

In den Dokumenten zur Installation von NVM wird erwähnt, dass Sie Ihre .bashrc-Datei als Quelle verwenden müssen, um NVM verwenden zu können.

Ich habe versucht, dies in einer Docker-Datei einzurichten, aber bisher schlägt das Erstellen mit dem Fehler fehl:

"bash: nvm: Befehl nicht gefunden"

Hier sind die relevanten Zeilen aus meiner Docker-Datei:

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"

Hier ist die Ausgabe vom Versuch zu bauen:

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

Ich bin ziemlich neu in Docker, daher fehlt mir möglicherweise etwas Grundlegendes zum Schreiben von Docker-Dateien, aber bisher hat mir all das Lesen, das ich gemacht habe, keine gute Lösung gezeigt.

David Ficociello
quelle
11
Kein Duplikat, da dies speziell für die Installation im Docker gilt und keine Standardinstallation
David Ficociello
Da Sie nur eine einzige Version des Knotens installieren, scheint es nicht erforderlich zu sein, nvm zu installieren. Die vom Docker- Knoten-Repository bereitgestellten Docker-Dateien können als Referenz für die Installation des Knotens verwendet werden.
Mikwat

Antworten:

121

Wenn Sie RUN bash...jedes Mal in einem separaten Prozess ausgeführt werden, wird nichts in der Umgebung festgelegt. So installiere ich 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
Abdullah Jibaly
quelle
v0.20.0v0.24.1
Um
8
mit nvm 0.31.0und node ist v4.2.3der Pfad/usr/local/nvm/versions/node/v4.2.3/bin
cwhsu
4
@thiagoh Dies erklärt nicht, warum die Installation von nvm durch den Fragesteller nicht funktioniert und die funktionierenden Antworten funktionieren. Es hat nichts mit Shells zu tun, die in separaten Prozessen ausgeführt werden. Dies liegt daran, dass die Frage versucht, bash.rc als Quelle zu verwenden, um die Datei nvm.sh zu laden, die den Befehl nvm in bash lädt. Bash.rc wird jedoch vorzeitig beendet, wenn es nicht interaktiv ausgeführt wird, sodass der Befehl nvm nicht geladen wird. Alle erfolgreichen Antworten stammen direkt aus nvm.sh, anstatt über bash.rc. Dies ist der Schlüssel, damit dies funktioniert.
tobuslieven
2
Anstatt sh durch bash zu ersetzen, können Sie einfach die . $NVM_DIR/nvm.shQuellbinärdatei vermeiden.
Razvan Grigore
3
Dies ist nah, aber Pfade müssen ein wenig angepasst werden. ENV NODE_PATH $ NVM_DIR / Versionen / Knoten / v $ NODE_VERSION / lib / Knotenmodule ENV PATH $ NVM_DIR / Versionen / Knoten / v $ NODE_VERSION / bin: $ PATH
Lunulata
30

Um allen zu helfen, die nach einer Möglichkeit suchen, Node.js mit NVM unter Ubuntu (letzte Version) zu installieren, habe ich die folgende Docker-Datei erstellt. Ich verwende die letzte Version von Docker, Ubuntu, Node.js und der NVM funktioniert ordnungsgemäß (der $ PATH wurde behoben). Ich verwende dies in einer Produktionsumgebung.

$ 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


Docker-Datei:

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"]
danilodeveloper
quelle
1
sollte der NODE_PATH nicht ENV sein NODE_PATH $ NVM_DIR / Versionen / Knoten / v $ NODE_VERSION / lib / Knotenmodule
Sentient
Hallo @Sentient! Ich führe diesen Docker in einer Produktionsumgebung (Ubuntu) und einem lokalen Entwickler (OSX) aus. Beide funktionieren ordnungsgemäß und fehlerfrei. Führen Sie möglicherweise einen veralteten NVM aus?
Danilodeveloper
Gibt es einen Grund, warum ich SUDO verwenden sollte, um build-essential und libssl-dev zu installieren? Ich bin überhaupt kein erfahrener DevOps.
a.barbieri
1
Der Schlüssel istsource $NVM_DIR/nvm.sh && nvm install $NODE_VERSION
Vladimir Kornea
24

Die NVM-Pfade haben sich seit der akzeptierten Antwort geändert. Wenn Sie also eine aktuellere NVM-Version verwenden möchten, müssen Sie einige Änderungen vornehmen. Es ist auch nicht erforderlich, eine Neuzuordnung vorzunehmen sh, damit es funktioniert:

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

Ich bin mir nicht sicher, ob Sie die --delete-prefixOption auf dem nvm use- ich habe es brauchen , aber das kann etwas Seltsames an meinem Basis-Image sein.

Steve Campbell
quelle
1
Lebensretter! Wenn ich nur Ihre Antwort vor 3 Stunden gesehen hätte.
Adrian Marinica
Arbeitete für mich, Basisbild php: 7.1.1
Toby Mellor
18

Jedes RUNin einer Docker-Datei wird in einem anderen Container ausgeführt. Wenn Sie also eine Datei in einem Container als Quelle verwenden, ist ihr Inhalt im nächsten nicht verfügbar.

Wenn Sie eine Anwendung installieren und mehrere Schritte ausführen müssen, müssen Sie dies daher im selben Container tun.

Mit Ihrem Beispiel:

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
Kuhess
quelle
OK, vielen Dank für die Erklärung. Also habe ich mein Skript so geändert, dass es so aussieht: `FROM ubuntu MAINTAINER dficociello ADD files / nvm_install.sh / root / # Installiere 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 "] ADD files / nginx.conf / etc / nginx / EXPOSE 22` Ich erhalte die folgende Fehlermeldung: `/ bin / bash: /root/nvm_install.sh: / bin / bash: fehlerhafter Interpreter: Textdatei beschäftigt `
David Ficociello
Dieser Fehler muss mit Ihrer Leitung verknüpft sein RUN ["/bin/bash", ...]. Es darf nicht von umgeben sein [...]und Sie müssen den Interpreter nicht angeben /bin/bash -c.
Kuhess
17

Dies basiert auf der Top-Antwort und funktioniert im Jahr 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

Beachten Sie, dass dies nvmkein Bash-Befehl ist, sondern ein Alias. Dies kann Sie vermasseln, wenn Sie sich darauf verlassen $PATH.

rjurney
quelle
15

Update 20/02/2020 : Diese Lösung funktioniert, wenn Sie ein debianBasis-Image verwenden. Wenn Sie verwenden ubuntu, lesen Sie diese Antwort .

Hier ist der sauberste Weg zur Installation nvm, den ich gefunden habe:

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

Erläuterung

  • In der ersten Zeile wird die Standard-Shell des Dockerfiles auf eine Bash-Login-Shell festgelegt . Hinweis: Dies bedeutet, dass jedes nachfolgende RUN, CMDund ENTRYPOINTunter dem aktuellen Benutzer (normalerweise root) ausgeführt wird und die Datei ~ / .bashrc als Quelle verwendet wird, wenn sie in der Shell-Form ausgeführt wird .

  • Die zweite Zeile wird nvmmit bash installiert . Wenn das Skript mit bash ausgeführt wird, wird es an die Datei ~ / .bashrc angehängt .

  • In der dritten Zeile wird eine bestimmte Version von nodejs installiert und verwendet. Die nvm, npmund nodeBefehle zur Verfügung , weil sie über ein Bash - Login - Shell ausgeführt werden (siehe Zeile 1).

Dominic Roy-Stang
quelle
1
Ich danke dir sehr !
Gaui
Interessant, dass dies für Sie funktioniert hat. Ich habe etwas Ähnliches ausprobiert und während der Erstellung sah alles gut aus, aber NPM wurde nicht gefunden, als ich das resultierende Image ausführte. Das explizite Einstellen NVM_DIR(wie in einigen anderen Antworten gezeigt) hat es für mich behoben.
Esmail
1
@esmail , die aufgrund der ersten seltsam RUNBefehlssätze NVM_DIRin ~/.bashrc.
Dominic Roy-Stang
1
@ DominicRoy-Stang, gültiger Punkt. Das Bild, mit dem ich gearbeitet habe, wird verwendet shund daher ignoriert .bashrc. Sind Sie auch sicher, dass Sie .bashrcwirklich eine Quelle haben, bevor Sie RUNBefehle ausführen ? Bei meinen kurzen Tests mit dem offiziellen bashBild schien es nicht so zu sein.
esmail
1
@esmail das ist, was die erste Zeile (die SHELLAnweisung) adressiert. Aufeinanderfolgende RUN-Befehle verwenden eine Anmeldeshell, die die .bashrcDatei als Quelle verwendet. Hinweis: Dies funktioniert nur, wenn Befehle im Shell-Modus ausgeführt werden, z. RUN nvm --version. Es funktioniert nicht, wenn Befehle im Exec-Modus ausgeführt werden, z. RUN ["nvm", "--version"]. Ich habe den Link, den ich für das Shell-Formular bereitstelle, aktualisiert, um dies hoffentlich deutlicher zu machen.
Dominic Roy-Stang
10

Basierend auf dem Vorschlag in der @ Kuhess-Antwort habe ich den Quellbefehl in meiner Docker-Datei durch den folgenden ersetzt

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

Hier ist meine Arbeitsversion

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;

Hat Hilfe von @abdulljibali und @shamisis Antworten genommen.

Tahir Rauf
quelle
Die Beschaffung der ~/.nvm/nvm.shDatei war der Schlüssel, den ich brauchte.
Stephane
Dies war die einzige Lösung, die für mich mit Ubuntu 16.04.2 Container funktioniert hat.
Drohm
7

Ich muss mit der Tatsache beginnen, dass ich überall gesucht habe, um ein funktionierendes Beispiel für das nvmInnere zu erhalten, dockerund keines gefunden habe. Auch die Antworten in diesem Thread haben nicht funktioniert.

Also habe ich einige Zeit verbracht und mir eine ausgedacht, die funktioniert:

# 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;

Beachten Sie, wie ich installiert habe nodejsüber apt-getals auch. Ich habe festgestellt, dass einige Pakete erst dann in Docker installiert werden, wenn dies geschehen ist.

Shamasis Bhattacharya
quelle
yup - man - hat ungefähr 100 Lösungen ausprobiert und nur deine funktioniert - 10x!
srfrnk
Richtig, um ~ / .nvm / nvm-tmp.sh zu verwenden, damit die Knotenversionen korrekt im Verzeichnis ~ / .nvm installiert werden
guidoman
6

Ein wesentlicher Unterschied zwischen dem Versuch, den Befehl nvm zu erhalten, in der Frage:

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

was nicht funktioniert und der Versuch, dasselbe in der akzeptierten Antwort zu tun:

source $NVM_DIR/nvm.sh

Ist das, dass die zweite Version das Skript nvm.sh direkt bezieht, während das Original versucht, dies über die .bashrc-Datei zu tun.

Die .bashrc-Datei enthält frühzeitig eine Zeile, die beendet wird, wenn sie in einer nicht interaktiven Shell ausgeführt wird:

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

Es kommt also nie zu dem Punkt, an dem es nvm.sh bezogen hätte, wodurch der Befehl nvm tatsächlich in Ihre Shell eingefügt wird.

Es würde mich nicht wundern, wenn Docker dieses Zeug in einer nicht interaktiven Shell ausführt. Darauf wurde nicht ausdrücklich hingewiesen, daher dachte ich, ich würde es erwähnen, da es mich auffiel, als ich etwas Ähnliches mit Vagabunden machte.

tobuslieven
quelle
Vielen Dank, dass Sie die Ursache des Problems gefunden haben. Ich habe die Datei /etc/skel/.bashrc aus dem Ubuntu 19.10-Basisbild kopiert und dann die obigen fehlerhaften Zeilen auskommentiert. Dann habe ich in meiner Docker-Datei den Befehl COPY verwendet, um ein "korrigiertes" /etc/skel/.bashrc nach / etc / skel zu kopieren und erst danach RUN zu verwenden, um Benutzer mit / bin / bash als Shell zu erstellen. Dann funktionierten nachfolgende Aufrufe von RUN ["/ bin / bash", "-c", "-l", YOUR_COMMAND [S] _HERE] einwandfrei.
Stephan Doliov
6

Ich habe ein oder zwei Stunden gebraucht, um herauszufinden, wie ich das am saubersten machen kann. --login scheint .bashrc nicht auszuführen, daher müssen Sie -i angeben, um es im interaktiven Modus zu starten. Dies führt dazu, dass Docker Sie ein wenig anschreit, sodass ich nur auf diese Weise für die Installation starte und dann auf meine Standard-Shell zurücksetze.

# 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"]
user2896438
quelle
Ihre Antwort hat mir klar gemacht, dass meine nicht ubuntuals Basis-Image funktioniert (aber Ihre). Ich habe debianbasierte Bilder verwendet. Ich bin mir nicht sicher, was die Diskrepanz zwischen den beiden verursacht. Irgendwelche Ideen?
Dominic Roy-Stang
Ich benutze Ubuntu 19:10 als Basis-Image. Ich werde alle relevanten Docker-Anweisungen veröffentlichen, damit Sie eine Vorstellung davon haben, was für mich funktioniert. Alle Anweisungen, die ich ausgelassen habe, sind entweder nicht relevant oder ich kann sie nicht bereitstellen. Ich werde sie mit einem Kommentar vertreten. Ich werde es im nächsten Kommentar veröffentlichen, da das
Zeichenlimit
4

Nichts davon funktionierte für mich, für meinen python3-onbuildContainer musste ich zwangsweise symbolische Links zur NVM-Installation erstellen.

# 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
Corey Cole
quelle
Einverstanden. Bei der Installation in einem Docker-Container (Debian GNU / Linux 9 (Stretch)) landet nvm auch $HOME/.nvmfür mich.
Dave Stevens
Ja, symbolische Links waren notwendig, um mich ebenfalls zu ergänzen. Ich frage mich, wie andere es nicht einmal brauchten.
PEZO
0

Das hat bei mir funktioniert (ich benutze 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"]

Sie sollten jetzt in der Lage sein zu tun nvm install <version>.

Alejandro Escobar
quelle
0

Mit nur einer Antwort wurde die Curl-Installation ausgeführt, es funktioniert jedoch nicht die gesamte Docker-Datei

Hier ist meine Docker-Datei zum Kopieren / Einfügen bereit, in der ich die neueste Version von nvm 2020 mit Ubuntu 18.04.3 LTS installiere

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
JRichardsz
quelle