Come installare nvm in docker?


101

Sono in procinto di creare una nuova immagine Docker e sto cercando di installare NVM in modo da poter gestire nodejs.

Leggendo i documenti su come installare NVM, viene indicato che è necessario acquisire il file .bashrc per iniziare a utilizzare NVM.

Ho provato a impostarlo in un Dockerfile, ma finora la creazione non riesce con l'errore:

"bash: nvm: comando non trovato"

Ecco le righe rilevanti dal mio 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"

Ecco l'output dal tentativo di compilare:

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

Sono abbastanza nuovo in Docker, quindi potrei perdere qualcosa di fondamentale per scrivere Dockerfiles, ma finora tutte le letture che ho fatto non mi hanno mostrato una buona soluzione.


11
Non è un duplicato in quanto si tratta di un'installazione specifica per l'installazione all'interno di Docker e non per un'installazione standard
David Ficociello

Poiché stai installando solo una singola versione di node, non sembra necessario installare nvm. I Dockerfile forniti dal repository del nodo Docker possono essere utilizzati come riferimento per come installare il nodo.
mikwat

Risposte:


121

Quando RUN bash...ogni volta che viene eseguito in un processo separato, insieme qualsiasi cosa in un ambiente non viene mantenuta. Ecco come installo 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

per accelerarlo in due volte basta cambiare v0.20.0av0.24.1
itsnikolay

8
con nvm 0.31.0e nodo v4.2.3il percorso è/usr/local/nvm/versions/node/v4.2.3/bin
cwhsu

4
@thiagoh Questo non spiega perché l'installazione di nvm da parte dell'interrogante non funziona e le risposte di lavoro funzionano. Non ha nulla a che fare con le shell in esecuzione in processi separati. È perché la domanda tenta di generare bash.rc per caricare il file nvm.sh che carica il comando nvm in bash, ma bash.rc esce presto quando viene eseguito in modo non interattivo, quindi il comando nvm non viene caricato. Tutte le risposte riuscite provengono direttamente da nvm.sh invece di farlo tramite bash.rc. Questa è la chiave per fare in modo che funzioni.
tobuslieven

2
Invece di sostituire sh con bash, puoi semplicemente farlo . $NVM_DIR/nvm.sh, evitando il codice binario di origine.
Razvan Grigore

3
Questo è vicino, ma i percorsi richiedono un piccolo aggiustamento, dovrebbero essere: 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

Per aiutare tutti coloro che cercano un modo per installare Node.js con NVM su Ubuntu (ultima versione), ho creato il dockerfile di seguito. Sto usando l'ultima versione di Docker, Ubuntu, Node.js e NVM funziona correttamente (il $ PATH è stato corretto). Lo sto usando in un ambiente di produzione.

$ 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
dovrebbe il NODE_PATH non essere ENV NODE_PATH $ NVM_DIR / versioni / node / v $ NODE_VERSION / lib / node_modules
Sentient

Ciao @Sentient! Sto eseguendo questa finestra mobile in un ambiente di produzione (ubuntu) e local dev (OSX), entrambi funzionano correttamente, senza errori. È possibile che tu stia utilizzando un NVM obsoleto?
danilodeveloper

C'è un motivo per cui dovrei usare SUDO installando build-essential e libssl-dev? Non sono affatto un DevOps esperto.
a.barbieri

1
La chiave èsource $NVM_DIR/nvm.sh && nvm install $NODE_VERSION
Vladimir Kornea

24

I percorsi di nvm sono cambiati rispetto alla risposta accettata, quindi se vuoi usare una versione di nvm più aggiornata, devi apportare alcune modifiche. Inoltre, non è necessario rimappare shper farlo funzionare:

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

Non sono sicuro se avrai bisogno --delete-prefixdell'opzione su nvm use- l'ho fatto, ma potrebbe essere qualcosa di strano nella mia immagine di base.


1
Salvavita! Se solo avessi visto la tua risposta 3 ore fa.
Adrian Marinica

Ha funzionato per me, immagine di base php: 7.1.1
Toby Mellor

18

Ciascuno RUNin un Dockerfile viene eseguito in un contenitore diverso. Quindi, se provieni un file in un contenitore, il suo contenuto non sarà disponibile in quello successivo.

Questo è il motivo per cui quando installi un'applicazione e devi eseguire diversi passaggi, devi farlo nello stesso contenitore.

Con il tuo esempio:

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

OK, grazie mille per la spiegazione. Quindi ho modificato il mio script in questo modo: `FROM ubuntu MAINTAINER dficociello ADD files / nvm_install.sh / root / # Install 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` Ricevo il seguente errore: `/ bin / bash: /root/nvm_install.sh: / bin / bash: bad interpreter: File di testo occupato `
David Ficociello

Questo errore deve essere collegato alla tua linea RUN ["/bin/bash", ...]. Non deve essere circondato da [...]e non è necessario specificare l'interprete /bin/bash -c.
Kuhess

17

Questo si basa sulla risposta migliore e funziona nel 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

Nota che nvmnon è un comando bash, è un alias. Questo può rovinarti se fai affidamento $PATH.


15

Aggiornamento 20/02/2020 : questa soluzione funziona se stai utilizzando debianun'immagine di base. Se stai usando ubuntu, vedi questa risposta .

Ecco il modo più pulito per installare nvmche ho trovato:

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

Spiegazione

  • La prima riga imposta la shell predefinita del Dockerfile su una shell di login bash . Nota: questo significa che ogni successivo RUN, CMDe ENTRYPOINTverrà eseguito sotto l'utente corrente (di solito root), e il file ~ / .bashrc di origine se eseguito nella forma della shell .

  • La seconda riga viene installata nvmcon bash. Quando lo script viene eseguito con bash, viene aggiunto al file ~ / .bashrc .

  • La terza riga installa una particolare versione di nodejs e la utilizza. I nvm, npme nodecomandi sono disponibili perché sono gestiti tramite una shell bash login (vedi linea 1).


1
Grazie mille !
Gaui

È interessante che questo funzionasse per te. Ho provato qualcosa di simile e tutto sembrava a posto durante le build, ma NPM non è stato trovato quando sono andato a eseguire l'immagine risultante. L'impostazione esplicita NVM_DIR(come mostrato in molte altre risposte) l'ha risolta per me.
esmail

1
@esmail è strano perché il primo RUNcomando viene impostato NVM_DIRin ~/.bashrc.
Dominic Roy-Stang

1
@ DominicRoy-Stang, punto valido. L'immagine con cui stavo lavorando usa she quindi ignora .bashrc. Inoltre, sei sicuro .bashrcche provenga davvero prima di eseguire i RUNcomandi? Nel mio breve test con l' bashimmagine ufficiale , sembrava che non lo fosse.
esmail

1
@esmail questo è ciò che la prima riga (l' SHELListruzione) indirizza. Fa in modo che i comandi RUN consecutivi utilizzino una shell di login che genera il .bashrcfile. Nota: funziona solo se i comandi vengono eseguiti in modalità shell es. RUN nvm --version. Non funzionerà se i comandi vengono eseguiti in modalità exec, ad es. RUN ["nvm", "--version"]. Ho aggiornato il collegamento che fornisco per il modulo di shell per renderlo più ovvio.
Dominic Roy-Stang,

10

In base al suggerimento nella risposta di @Kuhess, ho sostituito il comando sorgente con il seguente nel mio Dockerfile

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

8

Ecco la mia versione funzionante

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;

Ho ricevuto aiuto da @abdulljibali e @shamisis risponde.


L'approvvigionamento del ~/.nvm/nvm.shfile era la chiave di cui avevo bisogno.
Stephane

Questa è stata l'unica soluzione che ha funzionato per me con il contenitore Ubuntu 16.04.2.
drohm

7

Devo iniziare dal fatto che ho cercato dappertutto per avere un esempio funzionante di nvmdentro dockere non ho trovato nessuno. Anche le risposte in questo thread non hanno funzionato.

Quindi, ho passato un po 'di tempo e ne ho trovato uno che funziona:

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

Notare come ho installato anche nodejstramite apt-get. Ho scoperto che alcuni pacchetti non vengono installati nella finestra mobile a meno che ciò non venga fatto.


yup - amico - ho provato circa 100 soluzioni e solo la tua funziona - 10x!
srfrnk

È corretto usare ~ / .nvm / nvm-tmp.sh, in modo che le versioni del nodo siano installate correttamente nella directory ~ / .nvm
guidoman

7

Una differenza fondamentale tra il tentativo di ottenere il comando nvm nella domanda:

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

che non funziona e il tentativo di fare lo stesso nella risposta accettata:

source $NVM_DIR/nvm.sh

È che la seconda versione proviene direttamente dallo script nvm.sh, mentre l'originale cerca di farlo tramite il file .bashrc.

Il file .bashrc ha una riga nella prima parte che esce se viene eseguito in una shell non interattiva:

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

Quindi non arriva mai al punto in cui avrebbe preso nvm.sh che in realtà inserisce il comando nvm nella tua shell.

Non sarei sorpreso se docker eseguisse questa roba in una shell non interattiva. Questo non era stato esplicitamente indicato, quindi ho pensato di menzionarlo perché è ciò che mi ha sorpreso quando stavo facendo qualcosa di simile con vagabondo.


Grazie per aver trovato l'origine del problema. Ho copiato il file /etc/skel/.bashrc dall'immagine di base di Ubuntu 19.10 e poi ho commentato le linee offensive sopra. Quindi nel mio Dockerfile, ho usato il comando COPY per copiare un /etc/skel/.bashrc "corretto" in / etc / skel e solo successivamente ho usato RUN per creare utenti con / bin / bash come shell. Quindi le chiamate successive a RUN ["/ bin / bash", "-c", "-l", YOUR_COMMAND [S] _HERE] hanno funzionato bene.
Stephan Doliov

6

Mi ci sono volute un'ora o due per trovare il modo più pulito per farlo. --login non sembra eseguire .bashrc quindi devi fornire -i per avviarlo in modalità interattiva. Questo fa sì che Docker ti urli contro per un po ', quindi avvio solo in questo modo per l'installazione, quindi ripristino la mia shell standard.

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

La tua risposta mi ha fatto capire che la mia non funziona usando ubuntucome immagine di base (ma la tua sì). Stavo usando debianimmagini basate. Non sono sicuro di cosa stia causando la discrepanza tra i due. Qualche idea?
Dominic Roy-Stang,

Sto usando Ubuntu 19:10 come immagine di base. Pubblicherò tutte le istruzioni Docker pertinenti in modo che tu abbia un'idea di cosa funziona per me. Eventuali istruzioni che ho tralasciato non sono pertinenti o non posso fornire. Li rappresenterò con un commento. Lo
posterò

4

Nessuno di questi ha funzionato per me, per il mio python3-onbuildcontenitore ho dovuto forzare la creazione di collegamenti simbolici all'installazione di 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

Concordato. Quando installo in un container docker (Debian GNU / Linux 9 (stretch)), nvm finisce anche $HOME/.nvmper me.
Dave Stevens

Sì, anche i collegamenti simbolici erano necessari da aggiungere a me. Mi chiedo come mai gli altri non ne avessero nemmeno bisogno.
PEZO

0

Questo è ciò che ha funzionato per me (sto usando 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"]

Ora dovresti essere in grado di farlo nvm install <version>.


0

Solo una risposta inserisce l'installazione curl ma non funziona l'intero Dockerfile

Qui il mio Dockerfile pronto per copiare / incollare in cui installo l'ultima versione di nvm 2020 con 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.