ใน 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
Javier Castellanos

ไฟล์ dockerfile ปัจจุบันถูกต้องหรือไม่
Hui Wang

@HuiWang มันอาจจะไม่ มันถูกเขียนขึ้นมันถูกเขียนขึ้นเมื่อ 1.5 ปีที่แล้วและมีการเปลี่ยนแปลงมากมายตั้งแต่นั้นมา เพียงให้แน่ใจว่าคุณรวมการเปลี่ยนแปลงที่อธิบายไว้ในคำตอบที่เลือก
ILikeTacos

คำตอบ:


608

คุณสามารถใช้การเปลี่ยนสภาพแวดล้อมในของคุณDockerfileดังนี้:

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

14
เป็น=เครื่องหมายเท่ากับจำเป็น?
IgorGanapolsky

16
@IgorGanapolsky ไม่ได้อยู่ในอินสแตนซ์นี้เนื่องจากกำลังระบุตัวแปรเดียว อย่างไรก็ตามมันไม่เจ็บและจำเป็นสำหรับการระบุตัวแปรหลายตัว ดูเอกสารประกอบของ ENVสำหรับรายละเอียดเพิ่มเติม
Homme Zwaagstra

30
ได้ผลจริง! กรุณาดูแลเกี่ยวกับ=มันจะต้องไม่มีช่องว่าง หากคุณเพิ่มช่องว่างถัดจาก=แบบนี้ENV PATH = "/opt/gtk/bin:${PATH}"จะทำให้คุณเสียเงิน $ PATH
Diego Juliao

2
สิ่งนี้จะไม่อัปเดตภาพเมื่อ$PATHผนวกเข้ากับโฮสต์หรือไม่
emmdee

2
ENV PATH="/opt/gtk/bin:${PATH}"อาจไม่เหมือนENV PATH="/opt/gtk/bin:$PATH"เดิมกับวงเล็บปีกกาอาจให้เส้นทางของโฮสต์ เอกสารไม่แนะนำว่าจะเป็นกรณีนี้ แต่ฉันสังเกตว่ามันเป็น นี่เป็นเรื่องง่ายที่จะตรวจสอบทำRUN echo $PATHและเปรียบเทียบกับRUN echo ${PATH}
dankirkd

49

แม้ว่าคำตอบที่ Gunter โพสต์นั้นถูกต้อง แต่ก็ไม่แตกต่างจากที่ฉันโพสต์ไปแล้ว ปัญหาไม่ได้เป็น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;(ในระยะเดียวกัน), การปรับเปลี่ยนเส้นทางจะส่งผลกระทบและprog1 prog2ดังนั้นRUN export $PATHเป็น noop (เพราะไม่มีโปรแกรมที่ใช้สภาพแวดล้อมที่แก้ไข) และมันไม่ควรสร้างความแตกต่างถ้าคำสั่งนั้นมีหรือไม่ โดย "Gunter" คุณหมายถึงคำตอบนี้หรือไม่
init_js

การแก้ไขเป็นการเปลี่ยนค่า PATH ด้วยคำสั่ง ENV ไม่ใช่ RUN จากนั้นการเปลี่ยนแปลงเหล่านั้นจะดำเนินต่อไปเมื่อตัวสร้างนักเทียบท่าเรียกใช้ RUN ต่อไปนี้
init_js

5

สิ่งนี้เป็นสิ่งท้อแท้ (ถ้าคุณต้องการสร้าง / แจกจ่ายอิมเมจที่สะอาด) สำหรับ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ไวยากรณ์จะทำงาน
Nicolas Lefebvre

3
ใช่มันจะได้รับการขยายตัวและexport PATH=<some path>จะถูกเขียนไป/etc/environmentซึ่งยังคงไม่ถูกต้องเพราะไฟล์ที่ไม่ได้เป็นสคริปต์ <var name>=<value>แต่รายการของ exportจะทำให้มันล้มเหลวเว้นแต่ระบบของคุณรองรับเวทมนต์ดำนอกสเป็ค
Nicolas Lefebvre
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.