Em um Dockerfile, como atualizar a variável de ambiente PATH?

388

Eu tenho um dockerfile que baixa e cria o GTK a partir da fonte, mas a seguinte linha não está atualizando a variável de ambiente da minha imagem:

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

Eu li que eu deveria estar usando ENV para definir valores de ambiente, mas a instrução a seguir também não parece funcionar:

ENV PATH /opt/gtk/bin:$PATH

Este é o meu Dockerfile inteiro:

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
Eu gosto de tacos
fonte
11
O LD_LIBRARY_PATH e PATH devem ser configurados usando ENV para não exportar. Você também está LD_LIBRARY_PATH não deve estar apontando para PATH !. A exclusão de arquivos no Dockerfile não diminui sua imagem, consulte centurylinklabs.com/optimizing-docker-images/?hvid=4wO7Yt .
Javier Castellanos
o arquivo docker atual é válido?
21716 Hui Wang
@HuiWang não pode. Foi escrito, foi escrito há 1,5 anos e muita coisa mudou desde então. Apenas certifique-se de incorporar as alterações descritas na resposta selecionada.
ILikeTacos

Respostas:

608

Você pode usar a substituição de ambiente no Dockerfileseguinte:

ENV PATH="/opt/gtk/bin:${PATH}"
Homme Zwaagstra
fonte
14
O =sinal de igual é necessário?
IgorGanapolsky
16
@IgorGanapolsky Não neste caso, pois está especificando uma única variável. No entanto, não dói e é obrigatório ao especificar várias variáveis. Consulte a documentação ENV para mais detalhes.
Homme Zwaagstra 30/03
30
Isso funciona! Por favor, tome cuidado com o =que precisa ser sem espaços. Se você adicionar espaços ao lado =como esta ENV PATH = "/opt/gtk/bin:${PATH}"vai travar o seu $ PATH
Diego Juliao
2
Isso não atualizará a imagem com os HOST's $PATHanexados?
emmdee 6/01
2
ENV PATH="/opt/gtk/bin:${PATH}"pode não ser o mesmo que ENV PATH="/opt/gtk/bin:$PATH"O primeiro, com colchetes, pode fornecer o CAMINHO do host. A documentação não sugere que esse seria o caso, mas observei que sim. Isso é simples de verificar, basta fazer RUN echo $PATHe compará-lo comRUN echo ${PATH}
dankirkd 13/01
49

Embora a resposta que Gunter postou fosse correta, não é diferente do que eu já havia postado. O problema não era a ENVdiretiva, mas a instrução subsequenteRUN export $PATH

Não há necessidade de exportar as variáveis ​​de ambiente, depois que você as declarar ENVno Dockerfile.

Assim que as RUN export ...linhas foram removidas, minha imagem foi criada com sucesso

Eu gosto de tacos
fonte
4
RUN A=B,, RUN export Ae RUN export A=B, são comandos válidos do shell, mas afetam o ambiente apenas dos comandos que seguem na mesma RUNdiretiva (mas nenhum é fornecido). Da mesma forma, se você tivesse RUN export PATH=/foo; prog1; prog2;(no mesmo RUN), a modificação PATH afetaria prog1e prog2. Portanto, RUN export $PATHé um noop (porque nenhum programa usa esse ambiente modificado) e não deve fazer diferença se essa diretiva existe ou não. Por "Gunter", você quer dizer esta resposta ?
init_js
A correção é realmente alterar o valor PATH com uma diretiva ENV, não RUN. Em seguida, essas alterações serão transferidas quando o construtor do docker chamar a seguinte EXECUÇÃO.
init_js
5

Isso é desencorajado (se você deseja criar / distribuir uma imagem limpa do Docker), uma vez que a PATHvariável é definida por /etc/profilescript, o valor pode ser substituído.

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

No final do Dockerfile, você pode adicionar:

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

Portanto, PATH está definido para todos os usuários.

Thomas Decaux
fonte
4
De acordo com esta documentação do Ubuntu , /etc/environmenthá uma lista de expressões de atribuição, não um script, e não suporta expansão de variáveis, portanto, é improvável que a RUNsintaxe funcione.
Nicolas Lefebvre
3
Sim, ele será expandido e export PATH=<some path>gravado /etc/environment, o que ainda está incorreto porque esse arquivo não é um script, mas uma lista de <var name>=<value>. exportprovavelmente fará com que ela falhe, a menos que seu sistema suporte alguma magia negra fora das especificações.
Nicolas Lefebvre