En un Dockerfile, ¿Cómo actualizar la variable de entorno PATH?

388

Tengo un dockerfile que descarga y construye GTK desde el origen, pero la siguiente línea no actualiza la variable de entorno de mi imagen:

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

Leí que debería usar ENV para establecer valores de entorno, pero las siguientes instrucciones tampoco parecen funcionar:

ENV PATH /opt/gtk/bin:$PATH

Este es todo mi 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
Me gustan los tacos
fuente
1
LD_LIBRARY_PATH y PATH deben establecerse usando ENV no exportar. También eres LD_LIBRARY_PATH, ¡no deberías apuntar a PATH !. Eliminar archivos en el Dockerfile no hace que su imagen sea más pequeña, consulte centurylinklabs.com/optimizing-docker-images/?hvid=4wO7Yt .
Javier Castellanos
¿Es válido el dockerfile actual?
Hui Wang
@HuiWang puede que no. Fue escrito, fue escrito hace 1.5 años y mucho ha cambiado desde entonces. Solo asegúrese de incorporar los cambios descritos en la respuesta seleccionada.
ILikeTacos

Respuestas:

608

Puede utilizar el Reemplazo de entorno en su de la Dockerfilesiguiente manera:

ENV PATH="/opt/gtk/bin:${PATH}"
Homme Zwaagstra
fuente
14
¿Es =necesario el signo igual?
IgorGanapolsky
16
@IgorGanapolsky No en este caso, ya que está especificando una sola variable. Sin embargo, no duele y es obligatorio al especificar múltiples variables. Consulte la documentación de ENV para más detalles.
Homme Zwaagstra
30
¡Eso funciona! Por favor, tenga en =cuenta que debe estar sin espacios. Si agregas espacios al lado de =este como, ENV PATH = "/opt/gtk/bin:${PATH}"DESPLEGARÁ TU CAMINO DE $
Diego Juliao
2
¿Esto no actualizará la imagen con los HOST $PATHañadidos?
Emmdee
2
ENV PATH="/opt/gtk/bin:${PATH}"puede no ser lo mismo que ENV PATH="/opt/gtk/bin:$PATH"El primero, con llaves, puede proporcionarle la RUTA del host. La documentación no sugiere que este sea el caso, pero he observado que sí. Esto es fácil de verificar, simplemente hazlo RUN echo $PATHy compáraloRUN echo ${PATH}
dankirkd
49

Aunque la respuesta que Gunter publicó fue correcta, no es diferente de lo que ya había publicado. El problema no era la ENVdirectiva, sino las instrucciones posteriores.RUN export $PATH

No es necesario exportar las variables de entorno, una vez que las haya declarado ENVen su Dockerfile.

Tan pronto como RUN export ...se eliminaron las líneas, mi imagen se construyó con éxito

Me gustan los tacos
fuente
44
RUN A=B,, RUN export Ay RUN export A=B, son comandos de shell válidos, pero afectan el entorno solo de los comandos que siguen en la misma RUNdirectiva (pero ninguno se da). Del mismo modo, si tuviera RUN export PATH=/foo; prog1; prog2;(en el mismo EJECUTAR), la modificación de la RUTA afectaría prog1y prog2. Entonces, RUN export $PATHes un noop (porque ningún programa usa ese entorno modificado) y no debería hacer ninguna diferencia si esa directiva está allí o no. Por "Gunter", ¿te refieres a esta respuesta ?
init_js
La solución es realmente cambiar el valor de RUTA con una directiva ENV, no EJECUTAR. Luego, esos cambios se trasladarían cuando el generador de acopladores invoque el siguiente EJECUTAR.
init_js
5

Esto se desaconseja (si desea crear / distribuir una imagen limpia de Docker), ya que la PATHvariable se establece mediante /etc/profilesecuencia de comandos, el valor puede anularse.

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

Al final del Dockerfile, puede agregar:

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

Entonces PATH está configurado para todos los usuarios.

Thomas Decaux
fuente
44
Según esta documentación de Ubuntu , /etc/environmentes una lista de expresiones de asignación, no un script, y no admite expansión variable, por lo que es poco probable que la RUNsintaxis funcione.
Nicolas Lefebvre
3
Sí, se ampliará y export PATH=<some path>se escribirá en él /etc/environment, lo que sigue siendo incorrecto porque ese archivo no es un script sino una lista de <var name>=<value>. exportprobablemente hará que falle a menos que su sistema admita algo de magia negra fuera de las especificaciones.
Nicolas Lefebvre