Dans un Dockerfile, comment mettre à jour la variable d'environnement PATH?

388

J'ai un dockerfile qui télécharge et construit GTK à partir de la source, mais la ligne suivante ne met pas à jour la variable d'environnement de mon image:

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

J'ai lu que je devrais utiliser ENV pour définir les valeurs d'environnement, mais l'instruction suivante ne semble pas fonctionner non plus:

ENV PATH /opt/gtk/bin:$PATH

Voici mon Dockerfile complet:

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
J'aime les tacos
la source
1
LD_LIBRARY_PATH et PATH doivent être définis en utilisant ENV et non l'exportation. Vous êtes également LD_LIBRARY_PATH ne devrait pas pointer vers PATH !. La suppression de fichiers dans le Dockerfile ne réduit pas votre image, consultez centurylinklabs.com/optimizing-docker-images/?hvid=4wO7Yt .
Javier Castellanos
le dockerfile actuel est-il valide?
Hui Wang
@HuiWang ce n'est peut-être pas le cas. Elle a été écrite, elle a été écrite il y a 1,5 ans et beaucoup de choses ont changé depuis. Assurez-vous simplement d'intégrer les changements décrits dans la réponse sélectionnée.
ILikeTacos

Réponses:

608

Vous pouvez utiliser le remplacement de l'environnement dans votre Dockerfilecomme suit:

ENV PATH="/opt/gtk/bin:${PATH}"
Homme Zwaagstra
la source
14
Un =signe égal est-il nécessaire?
IgorGanapolsky
16
@IgorGanapolsky Pas dans ce cas car il spécifie une seule variable. Cependant, cela ne fait pas de mal et est obligatoire lors de la spécification de plusieurs variables. Voir la documentation ENV pour plus de détails.
Homme Zwaagstra
30
Ça marche! Veuillez prendre soin de ce =qu'il doit être sans espaces. Si vous ajoutez des espaces à côté de =celui-ci, ENV PATH = "/opt/gtk/bin:${PATH}"CASSERA VOTRE CHEMIN $
Diego Juliao
2
Cela ne mettra-t-il pas à jour l'image avec l'hôte en $PATHannexe?
emmdee
2
ENV PATH="/opt/gtk/bin:${PATH}"peut ne pas être le même que ENV PATH="/opt/gtk/bin:$PATH"l'ancien, avec des accolades, peut vous fournir le CHEMIN de l'hôte. La documentation ne suggère pas que ce serait le cas, mais je l'ai observé. C'est simple à vérifier, faites-le RUN echo $PATHet comparez-le àRUN echo ${PATH}
dankirkd
49

Bien que la réponse que Gunter ait publiée était correcte, elle n'est pas différente de celle que j'avais déjà publiée. Le problème n'était pas la ENVdirective, mais l'instruction suivanteRUN export $PATH

Il n'est pas nécessaire d'exporter les variables d'environnement, une fois que vous les avez déclarées via ENVdans votre Dockerfile.

Dès que les RUN export ...lignes ont été supprimées, mon image a été construite avec succès

J'aime les tacos
la source
4
RUN A=B,, RUN export Aet RUN export A=B, sont des commandes shell valides, mais n'affectent l'environnement que des commandes qui suivent dans cette même RUNdirective (mais aucune n'est donnée). De même, si vous aviez RUN export PATH=/foo; prog1; prog2;(dans le même RUN), la modification PATH affecterait prog1et prog2. Donc, RUN export $PATHc'est un noop (car aucun programme n'utilise cet environnement modifié) et cela ne devrait faire aucune différence si cette directive est là ou non. Par "Gunter", voulez-vous dire cette réponse ?
init_js
Le correctif est vraiment de changer la valeur PATH avec une directive ENV, pas RUN. Ces modifications seraient alors reportées lorsque le générateur de docker invoquerait le RUN suivant.
init_js
5

Ceci est déconseillé (si vous souhaitez créer / distribuer une image Docker propre), puisque la PATHvariable est définie par /etc/profilescript, la valeur peut être remplacée.

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

À la fin du Dockerfile, vous pouvez ajouter:

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

Ainsi, PATH est défini pour tous les utilisateurs.

Thomas Decaux
la source
4
Selon cette documentation Ubuntu , /etc/environmentest une liste d'expressions d'affectation, pas un script, et ne prend pas en charge l'expansion des variables, il est donc peu probable que la RUNsyntaxe fonctionne.
Nicolas Lefebvre
3
Oui, il sera développé et export PATH=<some path>sera écrit /etc/environment, ce qui est toujours incorrect car ce fichier n'est pas un script mais une liste de <var name>=<value>. exportle fera probablement échouer à moins que votre système ne prenne en charge la magie noire en dehors des spécifications.
Nicolas Lefebvre