Di Dockerfile, Bagaimana cara memperbarui variabel lingkungan PATH?

388

Saya memiliki dockerfile yang mengunduh dan membangun GTK dari sumber, tetapi baris berikut ini tidak memperbarui variabel lingkungan gambar saya:

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

Saya membaca bahwa saya harus menggunakan ENV untuk menetapkan nilai lingkungan, tetapi instruksi berikut ini tampaknya tidak berfungsi baik:

ENV PATH /opt/gtk/bin:$PATH

Ini seluruh Dockerfile saya:

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
ILikeTacos
sumber
1
LD_LIBRARY_PATH dan PATH harus ditetapkan menggunakan ENV bukan ekspor. Anda juga LD_LIBRARY_PATH tidak boleh menunjuk ke PATH !. Menghapus file di Dockerfile tidak membuat gambar Anda lebih kecil, periksa centurylinklabs.com/optimizing-docker-images/?hvid=4wO7Yt .
Javier Castellanos
apakah dockerfile saat ini yang valid?
Hui Wang
@ HaiWang mungkin tidak. Itu ditulis, ditulis 1,5 tahun yang lalu dan banyak yang telah berubah sejak saat itu. Pastikan Anda memasukkan perubahan yang dijelaskan dalam jawaban yang dipilih.
ILikeTacos

Jawaban:

608

Anda dapat menggunakan Lingkungan Penggantian di Anda Dockerfilesebagai berikut:

ENV PATH="/opt/gtk/bin:${PATH}"
Homme Zwaagstra
sumber
14
Apakah =tanda sama dengan itu diperlukan?
IgorGanapolsky
16
@IgorGanapolsky Tidak dalam hal ini karena menentukan variabel tunggal. Namun, tidak ada salahnya dan wajib ketika menentukan beberapa variabel. Lihat dokumentasi ENV untuk lebih jelasnya.
Homme Zwaagstra
30
Itu bekerja! Harap berhati-hati tentang =itu harus tanpa ruang. Jika Anda menambahkan spasi di sebelah =seperti ini, ENV PATH = "/opt/gtk/bin:${PATH}"AKAN MENGHANCURKAN $ PATH ANDA
Diego Juliao
2
Tidakkah ini akan memperbarui gambar dengan HOST yang $PATHditambahkan?
emmdee
2
ENV PATH="/opt/gtk/bin:${PATH}"mungkin tidak sama dengan ENV PATH="/opt/gtk/bin:$PATH"Yang pertama, dengan kurung keriting, mungkin memberi Anda PATH tuan rumah. Dokumentasi tidak menyarankan ini akan menjadi masalah, tetapi saya telah mengamati bahwa itu benar. Ini sederhana untuk memeriksa lakukan RUN echo $PATHdan bandingkanRUN echo ${PATH}
dankirkd
49

Meskipun jawaban yang diposting Gunter benar, itu tidak berbeda dari apa yang sudah saya posting. Masalahnya bukanlah ENVarahan, tetapi instruksi selanjutnyaRUN export $PATH

Tidak perlu mengekspor variabel lingkungan, setelah Anda mendeklarasikannya melalui ENVDockerfile Anda.

Segera setelah RUN export ...garis dihapus, gambar saya berhasil dibangun

ILikeTacos
sumber
4
RUN A=B, RUN export A, Dan RUN export A=B, yang perintah shell yang valid, tapi mempengaruhi lingkungan hanya perintah yang mengikuti yang sama RUNdirektif (tetapi tidak diberikan). Demikian pula, jika Anda memiliki RUN export PATH=/foo; prog1; prog2;(dalam RUN yang sama), modifikasi PATH akan mempengaruhi prog1dan prog2. Jadi, RUN export $PATHadalah noop (karena tidak ada program yang menggunakan lingkungan yang dimodifikasi) dan tidak ada bedanya apakah arahan itu ada atau tidak. Dengan "Gunter", maksud Anda jawaban ini ?
init_js
Cara mengatasinya adalah benar-benar mengubah nilai PATH dengan arahan ENV, bukan RUN. Maka perubahan-perubahan itu akan terbawa ketika tukang bangunan memanggil RUN berikut.
init_js
5

Ini tidak disarankan (jika Anda ingin membuat / mendistribusikan gambar Docker yang bersih), karena PATHvariabel diatur oleh /etc/profileskrip, nilainya dapat diganti.

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

Di akhir Dockerfile, Anda dapat menambahkan:

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

Jadi PATH diatur untuk semua pengguna.

Thomas Decaux
sumber
4
Sesuai dokumentasi Ubuntu ini , /etc/environmentadalah daftar ekspresi penugasan, bukan skrip, dan tidak mendukung ekspansi variabel, sehingga RUNsintaks tidak akan berfungsi.
Nicolas Lefebvre
3
Ya, itu akan diperluas dan export PATH=<some path>akan ditulis /etc/environment, yang masih salah karena file itu bukan skrip tetapi daftar <var name>=<value>. exportkemungkinan akan membuatnya gagal kecuali sistem Anda mendukung sihir hitam di luar spesifikasi.
Nicolas Lefebvre