В Dockerfile, Как обновить переменную среды PATH?

388

У меня есть dockerfile, который загружает и собирает GTK из исходного кода, но следующая строка не обновляет переменную окружения моего образа:

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

Я прочитал, что я должен использовать ENV для установки значений среды, но следующая инструкция, похоже, тоже не работает:

ENV PATH /opt/gtk/bin:$PATH

Это весь мой 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 и PATH должны быть установлены с использованием ENV, а не экспорта. Вы также LD_LIBRARY_PATH не должны указывать на PATH !. Удаление файлов в Dockerfile не делает ваше изображение меньше, проверьте centurylinklabs.com/optimizing-docker-images/?hvid=4wO7Yt .
Хавьер Кастелланос
Является ли текущий dockerfile действительным?
Хуэй Ван
@HuiWang это не может. Оно было написано 1,5 года назад, и с тех пор многое изменилось. Просто убедитесь, что вы включили изменения, описанные в выбранном ответе.
ILikeTacos

Ответы:

608

Вы можете использовать замену среды в вашем Dockerfileследующем:

ENV PATH="/opt/gtk/bin:${PATH}"
Homme Zwaagstra
источник
14
=Нужен ли знак равенства?
Игорь Ганапольский
16
@IgorGanapolsky Не в этом случае, поскольку он указывает одну переменную. Тем не менее, это не повредит и является обязательным при указании нескольких переменных. См. Документацию ENV для более подробной информации.
Homme Zwaagstra
30
Это работает! Пожалуйста, позаботьтесь о том, =чтобы он был без пробелов. Если вы добавите пробелы рядом с таким, =как это, ENV PATH = "/opt/gtk/bin:${PATH}"будет
разбивать вашу
2
Не приведет ли это к обновлению изображения с $PATHдобавленным хостом?
Эмми
2
ENV PATH="/opt/gtk/bin:${PATH}"может не совпадать с тем, что ENV PATH="/opt/gtk/bin:$PATH"первый, с фигурными скобками, может предоставить вам PATH хоста. Документация не предполагает, что это было бы так, но я заметил, что это так. Это просто проверить, просто сделайте RUN echo $PATHи сравните это сRUN echo ${PATH}
dankirkd
49

Хотя ответ, который выложил Гюнтер, был правильным, он не отличается от того, что я уже написал. Проблема была не в ENVдирективе, а в последующей инструкцииRUN export $PATH

Нет необходимости экспортировать переменные среды, если вы объявили их через ENVсвой Dockerfile.

Как только RUN export ...линии были удалены, мое изображение было успешно построено

Я люблю тако
источник
4
RUN A=B,, RUN export Aи RUN export A=B, являются допустимыми командами оболочки, но влияют на среду только тех команд, которые следуют в той же RUNдирективе (но ни одна не указана). Точно так же, если бы вы имели RUN export PATH=/foo; prog1; prog2;(в том же RUN), модификация PATH затронула бы prog1и prog2. Таким образом, RUN export $PATHэто noop (потому что ни одна программа не использует эту измененную среду), и не должно иметь значения, есть ли эта директива или нет. Под "Гюнтером" ты имеешь в виду этот ответ ?
init_js
Исправление заключается в том, чтобы изменить значение PATH с помощью директивы ENV, а не RUN. Затем эти изменения будут перенесены, когда сборщик док-станции вызовет следующий RUN.
init_js
5

Это не рекомендуется (если вы хотите создать / распространить чистый образ Docker), так как PATH переменная устанавливается /etc/profileскриптом, значение может быть переопределено.

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

В конце Dockerfile вы можете добавить:

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

Таким образом, PATH установлен для всех пользователей.

Томас Деко
источник
4
Согласно этой документации по Ubuntu , /etc/environmentэто список выражений присваивания, а не сценарий, и он не поддерживает расширение переменных, поэтому маловероятно, что RUNсинтаксис будет работать.
Николя Лефевр
3
Да, он будет расширен и export PATH=<some path>будет записан /etc/environment, что по-прежнему неверно, поскольку этот файл - не скрипт, а список <var name>=<value>. exportскорее всего, он потерпит неудачу, если ваша система не поддерживает черную магию за пределами спецификации.
Николя Лефевр