In un file Docker, come aggiornare la variabile di ambiente PATH?


388

Ho un file docker che scarica e costruisce GTK dal sorgente, ma la seguente riga non aggiorna la variabile d'ambiente della mia immagine:

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

Ho letto che dovrei usare ENV per impostare i valori dell'ambiente, ma le seguenti istruzioni non sembrano funzionare neanche:

ENV PATH /opt/gtk/bin:$PATH

Questo è il mio intero Dockerfile:

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

1
LD_LIBRARY_PATH e PATH devono essere impostati utilizzando ENV non esportare. Sei anche LD_LIBRARY_PATH non dovrebbe puntare a PATH !. L'eliminazione dei file nel Dockerfile non riduce le dimensioni dell'immagine, controlla centurylinklabs.com/optimizing-docker-images/?hvid=4wO7Yt .
Javier Castellanos,

il file docker corrente è valido?
Hui Wang,

@HuiWang potrebbe non esserlo. È stato scritto, è stato scritto 1,5 anni fa e da allora molto è cambiato. Assicurati solo di incorporare le modifiche descritte nella risposta selezionata.
ILikeTacos,

Risposte:


608

È possibile utilizzare la sostituzione dell'ambiente nel modo Dockerfileseguente:

ENV PATH="/opt/gtk/bin:${PATH}"

14
Il =segno di uguale è necessario?
IgorGanapolsky,

16
@IgorGanapolsky Non in questa istanza in quanto specifica una singola variabile. Tuttavia, non fa male ed è obbligatorio quando si specificano più variabili. Vedere la documentazione ENV per maggiori dettagli.
Homme Zwaagstra,

30
Che funzioni! Si prega di fare attenzione a =ciò che deve essere senza spazi. Se aggiungi spazi accanto a =questo, ENV PATH = "/opt/gtk/bin:${PATH}"INCIDERAI IL TUO PERCORSO $
Diego Juliao,

2
Questo aggiornamento non aggiorna l'immagine con l'HOST $PATHaggiunto?
emmdee,

2
ENV PATH="/opt/gtk/bin:${PATH}"potrebbe non essere uguale al ENV PATH="/opt/gtk/bin:$PATH"precedente, con parentesi graffe, potrebbe fornire il PERCORSO dell'host. La documentazione non suggerisce che questo sarebbe il caso, ma ho osservato che lo è. Questo è semplice da controllare basta fare RUN echo $PATHe confrontarlo conRUN echo ${PATH}
dankirkd

49

Sebbene la risposta che Gunter abbia pubblicato sia corretta, non è diversa da quella che avevo già pubblicato. Il problema non era la ENVdirettiva, ma le istruzioni successiveRUN export $PATH

Non è necessario esportare le variabili di ambiente, dopo averle dichiarate ENVnel Dockerfile.

Non appena le RUN export ...linee sono state rimosse, la mia immagine è stata creata con successo


4
RUN A=B,, RUN export Ae RUN export A=B, sono comandi shell validi, ma influiscono solo sull'ambiente dei comandi che seguono nella stessa RUNdirettiva (ma non ne viene fornito nessuno). Allo stesso modo, se avessi RUN export PATH=/foo; prog1; prog2;(nello stesso RUN), la modifica del PERCORSO influenzerebbe prog1e prog2. Quindi, RUN export $PATHè un noop (perché nessun programma utilizza quell'ambiente modificato) e non dovrebbe fare alcuna differenza se quella direttiva è presente o meno. Con "Gunter" intendi questa risposta ?
init_js

La soluzione è davvero quella di modificare il valore PATH con una direttiva ENV, non RUN. Quindi tali modifiche verrebbero riportate quando il costruttore docker invoca il seguente RUN.
init_js

5

Questo è sconsigliato (se si desidera creare / distribuire un'immagine Docker pulita), poiché la PATHvariabile è impostata dallo /etc/profilescript, il valore può essere sovrascritto.

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

Alla fine del Dockerfile, è possibile aggiungere:

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

Quindi PATH è impostato per tutti gli utenti.


4
Secondo questa documentazione di Ubuntu , /etc/environmentè un elenco di espressioni di assegnazione, non uno script, e non supporta l'espansione variabile, quindi è improbabile che la RUNsintassi funzioni.
Nicolas Lefebvre,

3
Sì, verrà espanso e export PATH=<some path>verrà scritto in /etc/environment, il che è ancora errato perché quel file non è uno script ma un elenco di <var name>=<value>. exportprobabilmente lo farà fallire a meno che il tuo sistema non supporti qualche magia nera al di fuori delle specifiche.
Nicolas Lefebvre,
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.