У Dockerfile, як оновити змінну середовища PATH?


388

У мене є докерфайл, який завантажує та створює 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 .
Хав'єр Кастелланос,

чи дійсний поточний докерфайл?
Хуй Ван

@HuiWang це не може. Це було написано, воно було написане 1,5 роки тому і з того часу багато що змінилося. Просто переконайтеся, що ви включили зміни, описані у вибраній відповіді.
ILikeTacos

Відповіді:


608

Ви можете використовувати заміну середовища в Dockerfileнаступному:

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

14
Чи =потрібен знак рівності?
ІгорГанапольський

16
@IgorGanapolsky Не в цьому випадку, оскільки він вказує одну змінну. Однак це не зашкодить і є обов'язковим при визначенні кількох змінних. Детальнішу інформацію див. У документації ENV .
Homme Zwaagstra

30
Це працює! Будь ласка, подбайте про те, щоб =воно було без пробілів. Якщо ви додасте пробіли поруч із =цим, ENV PATH = "/opt/gtk/bin:${PATH}"БУДЕ ВІДКРИТИ СВОЮ $
ПАТУ

2
Чи не буде це оновлення зображення $PATHдоданим хост-хостом ?
emmdee

2
ENV PATH="/opt/gtk/bin:${PATH}"може бути не такою, як ENV PATH="/opt/gtk/bin:$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. Тоді ці зміни перенесуться, коли конструктор докерів викликає наступний запуск.
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це, швидше за все, не вдасться, якщо ваша система не підтримує чорну магію за межами специфікації.
Ніколя Лефевр
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.