W pliku Docker, jak zaktualizować zmienną środowiskową PATH?

388

Mam plik docker, który pobiera i buduje GTK ze źródła, ale następujący wiersz nie aktualizuje zmiennej środowiskowej mojego obrazu:

RUN PATH="/opt/gtk/bin:$PATH"
RUN export PATH

Przeczytałem, że powinienem używać ENV do ustawiania wartości środowiska, ale wydaje się, że poniższe instrukcje również nie działają:

ENV PATH /opt/gtk/bin:$PATH

To jest cały mój plik Docker:

FROM ubuntu
RUN apt-get update
RUN apt-get install -y golang gcc make wget git libxml2-utils libwebkit2gtk-3.0-dev libcairo2 libcairo2-dev libcairo-gobject2 shared-mime-info libgdk-pixbuf2.0-* libglib2-* libatk1.0-* libpango1.0-* xserver-xorg xvfb

# Downloading GTKcd
RUN wget http://ftp.gnome.org/pub/gnome/sources/gtk+/3.12/gtk+-3.12.2.tar.xz
RUN tar xf gtk+-3.12.2.tar.xz
RUN cd gtk+-3.12.2

# Setting environment variables before running configure
RUN CPPFLAGS="-I/opt/gtk/include"
RUN LDFLAGS="-L/opt/gtk/lib"
RUN PKG_CONFIG_PATH="/opt/gtk/lib/pkgconfig"
RUN export CPPFLAGS LDFLAGS PKG_CONFIG_PATH
RUN ./configure --prefix=/opt/gtk
RUN make
RUN make install

# running ldconfig after make install so that the newly installed libraries are found.
RUN ldconfig

# Setting the LD_LIBRARY_PATH environment variable so the systems dynamic linker can find the newly installed libraries.
RUN LD_LIBRARY_PATH="/opt/gtk/lib"

# Updating PATH environment program so that utility binaries installed by the various libraries will be found.
RUN PATH="/opt/gtk/bin:$PATH"
RUN export LD_LIBRARY_PATH PATH

# Collecting garbage
RUN rm -rf gtk+-3.12.2.tar.xz

# creating go code root
RUN mkdir gocode
RUN mkdir gocode/src
RUN mkdir gocode/bin
RUN mkdir gocode/pkg

# Setting the GOROOT and GOPATH enviornment variables, any commands created are automatically added to PATH
RUN GOROOT=/usr/lib/go
RUN GOPATH=/root/gocode
RUN PATH=$GOPATH/bin:$PATH
RUN export GOROOT GOPATH PATH
Lubię tacos
źródło
1
LD_LIBRARY_PATH i PATH powinny być ustawione przy użyciu ENV bez eksportu. Jesteś także LD_LIBRARY_PATH nie powinien wskazywać na ŚCIEŻKĘ !. Usunięcie plików z pliku Docker nie zmniejsza obrazu, sprawdź stronę centurylinklabs.com/optimizing-docker-images/?hvid=4wO7Yt .
Javier Castellanos,
czy aktualny plik dokera jest prawidłowy?
Hui Wang,
@HuiWang może nie. Zostało napisane, zostało napisane 1,5 roku temu i od tego czasu wiele się zmieniło. Upewnij się, że uwzględnisz zmiany opisane w wybranej odpowiedzi.
ILikeTacos

Odpowiedzi:

608

Możesz użyć funkcji zamiany środowiska w Dockerfilenastępujący sposób:

ENV PATH="/opt/gtk/bin:${PATH}"
Homme Zwaagstra
źródło
14
Czy =znak równości jest konieczny?
IgorGanapolsky
16
@IgorGanapolsky Nie w tym przypadku, ponieważ określa pojedynczą zmienną. Jednak nie boli i jest obowiązkowe przy określaniu wielu zmiennych. Więcej informacji znajduje się w dokumentacji ENV .
Homme Zwaagstra
30
To działa! Proszę dbać o =to, żeby nie było spacji. Jeśli dodać przestrzenie obok =tak ENV PATH = "/opt/gtk/bin:${PATH}"padnie $ PATH
Diego Juliao
2
Czy to nie zaktualizuje obrazu z $PATHdołączonymi hostami?
emmdee
2
ENV PATH="/opt/gtk/bin:${PATH}"może nie być taki sam jak ENV PATH="/opt/gtk/bin:$PATH"poprzedni, z nawiasami klamrowymi, może dostarczyć ścieżkę hosta. Dokumentacja nie sugeruje, aby tak było, ale zauważyłem, że tak jest. RUN echo $PATHRUN echo ${PATH}
Łatwo
49

Chociaż odpowiedź opublikowana przez Guntera była poprawna, nie różni się od tej, którą już napisałem. Problemem nie była ENVdyrektywa, ale późniejsza instrukcjaRUN export $PATH

Nie ma potrzeby eksportowania zmiennych środowiskowych, po ich zadeklarowaniu ENVw pliku Docker.

Gdy tylko RUN export ...linie zostały usunięte, mój obraz został pomyślnie zbudowany

Lubię tacos
źródło
4
RUN A=B,, RUN export Ai RUN export A=Bsą poprawnymi poleceniami powłoki, ale wpływają tylko na środowisko poleceń następujących po tej samej RUNdyrektywie (ale nie podano żadnych). Podobnie, jeśli miałeś RUN export PATH=/foo; prog1; prog2;(w tym samym URUCHOMIENIU), modyfikacja ŚCIEŻKI wpłynie na prog1i prog2. Jest więc RUN export $PATHnoop (ponieważ żaden program nie korzysta ze zmodyfikowanego środowiska) i nie powinno mieć znaczenia, czy ta dyrektywa istnieje, czy nie. Mówiąc „Gunter”, masz na myśli tę odpowiedź ?
init_js
Naprawdę naprawiono zmianę wartości PATH za pomocą dyrektywy ENV, a nie RUN. Następnie zmiany te zostaną przeniesione, gdy konstruktor dokera wywoła następującą komendę RUN.
init_js
5

Jest to odradzane (jeśli chcesz utworzyć / rozpowszechnić czysty obraz Dockera), ponieważ PATHzmienna jest ustawiana przez /etc/profileskrypt, wartość można zastąpić.

head /etc/profile:

if [ "`id -u`" -eq 0 ]; then
  PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
else
  PATH="/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games"
fi
export PATH

Na końcu pliku Docker można dodać:

RUN echo "export PATH=$PATH" > /etc/environment

Dlatego PATH jest ustawiony dla wszystkich użytkowników.

Thomas Decaux
źródło
4
Zgodnie z tą dokumentacją Ubuntu , /etc/environmentjest to lista wyrażeń przypisania, a nie skrypt i nie obsługuje rozszerzania zmiennych, więc jest mało prawdopodobne, aby RUNskładnia działała.
Nicolas Lefebvre
3
Tak, zostanie rozwinięty i export PATH=<some path>zostanie zapisany /etc/environment, co jest nadal niepoprawne, ponieważ ten plik nie jest skryptem, ale listą <var name>=<value>. exportprawdopodobnie sprawi, że się nie powiedzie, chyba że twój system obsługuje czarną magię poza specyfikacją.
Nicolas Lefebvre