¿Cómo instalar nvm en Docker?

101

Estoy en el proceso de crear una nueva imagen de Docker y estoy buscando instalar NVM para poder administrar nodejs.

Al leer los documentos sobre cómo instalar NVM, mencionan que necesita obtener su archivo .bashrc para comenzar a usar NVM.

Intenté configurar esto en un Dockerfile, pero hasta ahora la construcción falla con el error:

"bash: nvm: comando no encontrado"

Aquí están las líneas relevantes de mi 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"

Aquí está el resultado de intentar construir:

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

Soy bastante nuevo en Docker, por lo que puede que me esté perdiendo algo fundamental para escribir Dockerfiles, pero hasta ahora toda la lectura que he hecho no me ha mostrado una buena solución.

David Ficociello
fuente
11
No es un duplicado, ya que esto es particular para la instalación dentro de la ventana acoplable y no una instalación estándar
David Ficociello
Dado que solo está instalando una única versión de node, parece innecesario instalar nvm. Los Dockerfiles proporcionados por el repositorio de nodos de Docker se pueden utilizar como referencia sobre cómo instalar node.
Mikwat

Respuestas:

121

Cuando RUN bash...cada vez que se ejecuta en un proceso separado, no se mantiene nada configurado en el entorno. Así es como instalo 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
fuente
para acelerarlo dos veces, simplemente cambie v0.20.0av0.24.1
itsnikolay
8
con nvm 0.31.0y nodo, v4.2.3la ruta es/usr/local/nvm/versions/node/v4.2.3/bin
cwhsu
4
@thiagoh Esto no explica por qué la instalación de nvm del interrogador no funciona y las respuestas de trabajo sí funcionan. No tiene nada que ver con los shells que se ejecutan en procesos separados. Esto se debe a que la pregunta intenta obtener bash.rc para cargar el archivo nvm.sh que carga el comando nvm en bash, pero bash.rc sale temprano cuando se ejecuta de forma no interactiva, por lo que el comando nvm no se carga. Todas las respuestas exitosas obtienen nvm.sh directamente en lugar de hacerlo a través de bash.rc. Esta es la clave para que esto funcione.
tobuslieven
2
En lugar de reemplazar sh con bash, simplemente puede hacerlo . $NVM_DIR/nvm.sh, evitando el código fuente binario.
Razvan Grigore
3
Esto está cerca, pero las rutas necesitan un pequeño ajuste, deberían ser: ENV NODE_PATH $ NVM_DIR / versiones / nodo / v $ NODE_VERSION / lib / node_modules ENV PATH $ NVM_DIR / versiones / nodo / v $ NODE_VERSION / bin: $ PATH
Lunulata
31

Para ayudar a todos los que buscan una forma de instalar Node.js con NVM en Ubuntu (última versión), hice el archivo docker a continuación. Estoy usando la última versión de Docker, Ubuntu, Node.js y el NVM funciona correctamente (se corrigió el $ PATH). Estoy usando esto en un entorno de producción.

$ 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"]
danilodesarrollador
fuente
1
en caso de que NODE_PATH no sea ENV NODE_PATH $ NVM_DIR / versions / node / v $ NODE_VERSION / lib / node_modules
Sentient
Hola @Sentient! Estoy ejecutando esta ventana acoplable en un entorno de producción (ubuntu) y un desarrollador local (OSX), ambos funcionan correctamente, sin errores. ¿Es posible que esté ejecutando un NVM desactualizado?
danilodeveloper
¿Hay alguna razón por la que debería usar SUDO instalando build-essential y libssl-dev? No soy un DevOps experimentado.
a.barbieri
1
La clave essource $NVM_DIR/nvm.sh && nvm install $NODE_VERSION
Vladimir Kornea
24

Las rutas de NVM han cambiado desde la respuesta aceptada, por lo que si desea utilizar una versión de NVM más actualizada, debe realizar algunos cambios. Además, no es necesario reasignar shpara que funcione:

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

No estoy seguro de si necesitará la --delete-prefixopción en nvm use... lo hice, pero eso puede ser algo extraño en mi imagen base.

Steve Campbell
fuente
1
Salvavidas! Si tan solo hubiera visto tu respuesta hace 3 horas.
Adrian Marinica
Me funcionó, imagen base php: 7.1.1
Toby Mellor
18

Cada RUN en un Dockerfile se ejecuta en un contenedor diferente. Entonces, si obtiene un archivo en un contenedor, su contenido no estará disponible en el siguiente.

Es por ello que cuando instalas una aplicación y necesitas hacer varios pasos, debes hacerlo en el mismo contenedor.

Con tu ejemplo:

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
fuente
OK, muchas gracias por la explicación. Así que modifiqué mi script para que se vea así: `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 "] AGREGAR archivos / nginx.conf / etc / nginx / EXPOSE 22` Aparece el siguiente error: `/ bin / bash: /root/nvm_install.sh: / bin / bash: bad interpreter: Archivo de texto ocupado `
David Ficociello
Este error debe estar vinculado a su línea RUN ["/bin/bash", ...]. No debe estar rodeado [...]y no es necesario especificar el intérprete /bin/bash -c.
Kuhess
17

Esto se basa en la respuesta principal y funciona en 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

Tenga en cuenta que nvmno es un comando bash, es un alias. Esto puede arruinarte si confías en $PATH.

rjurney
fuente
15

Actualización 20/02/2020 : esta solución funciona si está utilizando una debianimagen base. Si está usando ubuntu, vea esta respuesta .

Aquí está la forma más limpia de instalar nvmque he encontrado:

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

Explicación

  • La primera línea establece el shell predeterminado de Dockerfile en un shell de inicio de sesión bash . Nota: esto significa que todos los posteriores RUN, CMDy ENTRYPOINTse ejecutarán bajo el usuario actual (generalmente root), y el origen del archivo ~ / .bashrc si se ejecuta en forma de shell .

  • La segunda línea se instala nvmcon bash. Cuando el script se ejecuta con bash, se agrega al archivo ~ / .bashrc .

  • La tercera línea instala una versión particular de nodejs y la usa. Los nvm, npmy nodecomandos están disponibles, ya que se ejecutan a través de una cáscara del golpe de inicio de sesión (véase la línea 1).

Dominic Roy-Stang
fuente
1
Muchas gracias !
Gaui
Es interesante que esto te haya funcionado. Intenté algo similar y todo se veía bien durante las compilaciones, pero no se encontró NPM cuando fui a ejecutar la imagen resultante. La configuración explícita NVM_DIR(como se muestra en varias de las otras respuestas) lo arregló para mí.
esmail
1
@esmail que es extraño porque los primeros RUNconjuntos de comandos NVM_DIRen ~/.bashrc.
Dominic Roy-Stang
1
@ DominicRoy-Stang, punto válido. La imagen con la que estaba trabajando usa shy por lo tanto ignora .bashrc. Además, ¿ .bashrcestá seguro de que realmente se obtiene antes de ejecutar los RUNcomandos? En mi breve prueba con la bashimagen oficial , parecía que no lo era.
esmail
1
@esmail, eso es lo que trata la primera línea (la SHELLinstrucción). Hace que los comandos RUN consecutivos utilicen un shell de inicio de sesión que genera el .bashrcarchivo. Nota: solo funciona si los comandos se ejecutan en modo shell, por ejemplo. RUN nvm --version. No funcionará si los comandos se ejecutan en modo exec, por ejemplo. RUN ["nvm", "--version"]. He actualizado el enlace que proporciono para el formulario de shell para que esto sea más obvio.
Dominic Roy-Stang
10

Según la sugerencia en la respuesta de @Kuhess, reemplacé el comando de origen con lo siguiente en mi Dockerfile

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

Aquí está mi versión de trabajo

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;

Recibí ayuda de @abdulljibali y @shamisis responde.

Tahir Rauf
fuente
Obtener el ~/.nvm/nvm.sharchivo era la clave que necesitaba.
Stephane
Esta fue la única solución que funcionó para mí con el contenedor ubuntu 16.04.2.
drohm
7

Debo comenzar con el hecho de que busqué por todas partes para obtener un ejemplo funcional del nvminterior dockery no encontré ninguno. Incluso las respuestas en este hilo no funcionaron.

Entonces, pasé bastante tiempo y se me ocurrió uno que funciona:

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

Observe cómo también he instalado nodejsvia apt-get. Descubrí que algunos paquetes no se instalan dentro de la ventana acoplable a menos que se haga esto.

Shamasis Bhattacharya
fuente
sí, hombre, probé alrededor de 100 soluciones y solo la tuya funciona, ¡10x!
srfrnk
Correcto para usar ~ / .nvm / nvm-tmp.sh, por lo que las versiones de nodo se instalan correctamente dentro del directorio ~ / .nvm
guidoman
6

Una diferencia clave entre el intento de obtener el comando nvm en la pregunta:

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

que no funciona y el intento de hacer lo mismo en la respuesta aceptada:

source $NVM_DIR/nvm.sh

Es que la segunda versión obtiene el script nvm.sh directamente, mientras que la original intenta hacerlo a través del archivo .bashrc.

El archivo .bashrc tiene una línea al principio que sale si se está ejecutando en un shell no interactivo:

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

Por lo tanto, nunca llega al bit en el que habría obtenido nvm.sh, que en realidad coloca el comando nvm en su shell.

No me sorprendería que Docker ejecute estas cosas en un shell no interactivo. Esto no se había señalado explícitamente, así que pensé en mencionarlo, ya que es lo que me sorprendió cuando estaba haciendo algo similar con vagabundo.

tobuslieven
fuente
Gracias por encontrar el origen del problema. Copié el archivo /etc/skel/.bashrc de la imagen base de ubuntu 19.10 y luego comenté las líneas ofensivas anteriores. Luego, en mi Dockerfile, usé el comando COPY para copiar un /etc/skel/.bashrc "corregido" en / etc / skel y solo después de eso usé RUN para crear usuarios con / bin / bash como su shell. Luego, las llamadas subsiguientes a RUN ["/ bin / bash", "-c", "-l", YOUR_COMMAND [S] _HERE] funcionaron bien.
Stephan Doliov
6

Me tomó una hora o dos encontrar la forma más limpia de hacerlo. --login no parece ejecutar .bashrc, por lo que debe proporcionar -i para iniciarlo en modo interactivo. Esto hace que Docker te grite por un momento, así que solo lo ejecuto de esta manera para la instalación, luego reinicio a mi shell estándar.

# 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"]
usuario2896438
fuente
Tu respuesta me hizo darme cuenta de que la mía no funciona ubuntucomo imagen base (pero la tuya sí). Estaba usando debianimágenes basadas. No estoy seguro de qué está causando la discrepancia entre los dos. ¿Algunas ideas?
Dominic Roy-Stang
Estoy usando ubuntu 19:10 como imagen base. Publicaré todas las instrucciones relevantes de Docker para que tengas una idea de lo que funciona para mí. Las instrucciones que he omitido no son relevantes o no puedo proporcionarlas. Los representaré con un comentario. Lo publicaré en el siguiente comentario, ya que el límite de caracteres es demasiado bajo
user2896438
4

Ninguno de estos funcionó para mí, para mi python3-onbuild contenedor tuve que forzar la creación de enlaces simbólicos a la instalación de 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
Corey Cole
fuente
Convenido. Al instalar en un contenedor docker (Debian GNU / Linux 9 (stretch)), nvm también termina en $HOME/.nvmmi lugar.
Dave Stevens
Sí, también era necesario añadir enlaces simbólicos. Me pregunto cómo otros ni siquiera lo necesitaron.
PEZO
0

Esto es lo que funcionó para mí (estoy 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"]

Ahora debería poder hacerlo nvm install <version>.

Alejandro Escobar
fuente
0

Solo una respuesta puso la instalación curl pero no funciona todo el Dockerfile

Aquí mi Dockerfile listo para copiar / pegar en el que instalo la última versión de 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
JRichardsz
fuente