Jestem w trakcie tworzenia nowego obrazu Dockera i szukam zainstalowania NVM, abym mógł zarządzać nodejs.
Czytając dokumentację o tym, jak zainstalować NVM, wspominają, że musisz pobrać plik .bashrc, aby rozpocząć korzystanie z NVM.
Próbowałem to ustawić w pliku Dockerfile, ale jak dotąd kompilacja kończy się niepowodzeniem z powodu błędu:
„bash: nvm: nie znaleziono polecenia”
Oto odpowiednie wiersze z mojego pliku 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"
Oto wynik próby zbudowania:
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
Jestem całkiem nowy w Dockerze, więc być może brakuje mi czegoś podstawowego do pisania Dockerfiles, ale jak dotąd cała lektura, którą zrobiłem, nie pokazała mi dobrego rozwiązania.
Odpowiedzi:
Za
RUN bash...
każdym razem, gdy jest uruchamiany w oddzielnym procesie, nic ustawione w środowisku nie jest obsługiwane. Oto jak instalujęnvm
:źródło
v0.20.0
nav0.24.1
0.31.0
i węzłemv4.2.3
ścieżka to/usr/local/nvm/versions/node/v4.2.3/bin
. $NVM_DIR/nvm.sh
, unikając źródłowego pliku binarnego.Aby pomóc wszystkim, którzy szukają sposobu na zainstalowanie Node.js z NVM na Ubuntu (ostatnia wersja), utworzyłem poniżej plik dockerfile. Używam ostatniej wersji Dockera, Ubuntu, Node.js i NVM działa poprawnie (poprawiono $ PATH). Używam tego w środowisku produkcyjnym.
dockerfile:
źródło
source $NVM_DIR/nvm.sh && nvm install $NODE_VERSION
Ścieżki NVM zmieniły się od czasu zaakceptowania odpowiedzi, więc jeśli chcesz użyć bardziej aktualnej wersji NVM, musisz wprowadzić kilka zmian. Nie jest też konieczne ponowne mapowanie,
sh
aby działało:Nie jestem pewien, czy będziesz potrzebować
--delete-prefix
opcjinvm use
- tak, ale to może być coś dziwnego w moim podstawowym obrazie.źródło
Każdy
RUN
plik Dockerfile jest wykonywany w innym kontenerze. Więc jeśli pobierzesz plik w kontenerze, jego zawartość nie będzie dostępna w następnym.Dlatego gdy instalujesz aplikację i musisz wykonać kilka kroków, musisz to zrobić w tym samym kontenerze.
Z twoim przykładem:
źródło
RUN ["/bin/bash", ...]
. Nie może być otoczone[...]
ani nie musisz określać tłumacza/bin/bash -c
.Jest to oparte na najlepszej odpowiedzi i działa w 2018 roku:
Zauważ, że
nvm
nie jest to polecenie bash, to alias. To może cię zepsuć, jeśli polegasz$PATH
.źródło
Aktualizacja 20.02.2020 : To rozwiązanie działa, jeśli używasz
debian
obrazu podstawowego. Jeśli używaszubuntu
, zobacz tę odpowiedź .Oto najczystszy sposób instalacji
nvm
, jaki znalazłem:Wyjaśnienie
Pierwsza linia ustawia domyślną powłokę pliku Dockerfile na powłokę logowania bash . Uwaga: To oznacza, że każdy kolejny
RUN
,CMD
iENTRYPOINT
będą prowadzone w ramach bieżącego użytkownika (zazwyczaj root), a źródłowy ~ / .bashrc plik jeśli prowadzony w formie muszli .Druga linia instaluje się
nvm
z bash. Gdy skrypt jest uruchamiany za pomocą basha, dołącza go do pliku ~ / .bashrc .Trzecia linia instaluje określoną wersję nodejs i używa jej. Polecenia
nvm
,npm
inode
są dostępne, ponieważ są uruchamiane przez powłokę logowania bash (zobacz wiersz 1).źródło
NVM_DIR
(jak pokazano w kilku innych odpowiedziach) naprawiło to za mnie.RUN
polecenieNVM_DIR
w~/.bashrc
.sh
i dlatego jest ignorowany.bashrc
. Czy na pewno.bashrc
jest on rzeczywiście pozyskiwany przed wykonaniemRUN
poleceń? Podczas moich krótkich testów z urzędnikiembash
obrazem wydawało się, że tak nie jest.SHELL
instrukcja). Powoduje, że kolejne polecenia RUN używają powłoki logowania, która pozyskuje.bashrc
plik. Uwaga: działa tylko wtedy, gdy polecenia są uruchamiane w trybie powłoki, np.RUN nvm --version
. Nie będzie działać, jeśli polecenia są uruchamiane w trybie exec, np.RUN ["nvm", "--version"]
. Zaktualizowałem łącze, które udostępniam dla formularza powłoki, aby, mam nadzieję, uczynić to bardziej oczywistym.Opierając się na sugestii w odpowiedzi @Kuhess, zastąpiłem polecenie źródła następującym w moim pliku Dockerfile
źródło
Oto moja wersja robocza
Skorzystałem z pomocy odpowiedzi @abdulljibali i @shamisis.
źródło
~/.nvm/nvm.sh
pliku było kluczem, którego potrzebowałem.Muszę zacząć od tego, że szukałem wszędzie, aby uzyskać działający przykład
nvm
wnętrzadocker
ale nie znalazłem. Nawet odpowiedzi w tym wątku nie zadziałały.Spędziłem więc trochę czasu i wymyśliłem taki, który działa:
źródło
Kluczowa różnica między próbą uzyskania polecenia nvm w pytaniu:
co nie działa i próba zrobienia tego samego w zaakceptowanej odpowiedzi:
Czy to druga wersja bezpośrednio źródła skryptu nvm.sh, podczas gdy oryginał próbuje to zrobić za pośrednictwem pliku .bashrc.
Plik .bashrc zawiera wczesną linię, która kończy pracę, jeśli jest uruchamiany w powłoce nieinteraktywnej:
Tak więc nigdy nie dochodzi do miejsca, w którym mógłby uzyskać plik nvm.sh, który faktycznie umieszcza polecenie nvm w powłoce.
Nie zdziwiłbym się, gdyby docker uruchamiał te rzeczy w powłoce nieinteraktywnej. Nie zostało to wyraźnie zaznaczone, więc pomyślałem, że wspomnę o tym, ponieważ to mnie zaskoczyło, gdy robiłem coś podobnego z włóczęgą.
źródło
Zajęło mi godzinę lub dwie, zanim wymyśliłem najczystszy sposób, aby to zrobić. --login nie wydaje się wykonywać .bashrc, więc musisz podać -i, aby uruchomić go w trybie interaktywnym. To powoduje, że Docker krzyczy na ciebie przez chwilę, więc uruchamiam w ten sposób tylko w celu instalacji, a następnie resetuję do mojej standardowej powłoki.
źródło
ubuntu
jako obraz bazowy (ale twój działa). Używałemdebian
obrazów oparte. Nie jestem pewien, co powoduje rozbieżność między nimi. Jakieś pomysły?Żadne z nich nie działało dla mnie, ponieważ w moim
python3-onbuild
kontenerze musiałem wymusić tworzenie dowiązań symbolicznych do instalacji nvm.źródło
$HOME/.nvm
do mnie.Oto, co zadziałało dla mnie (używam debian buster):
Teraz powinieneś być w stanie to zrobić
nvm install <version>
.źródło
Tylko jedna odpowiedź umieściła instalację curl, ale nie działa w całym pliku Dockerfile
Tutaj mój plik Dockerfile gotowy do kopiowania / wklejania, w którym instaluję najnowszą wersję nvm 2020 z Ubuntu 18.04.3 LTS
źródło