Trong Dockerfile, Làm thế nào để cập nhật biến môi trường PATH?


388

Tôi có một dockerfile tải xuống và xây dựng GTK từ nguồn, nhưng dòng sau không cập nhật biến môi trường của hình ảnh của tôi:

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

Tôi đọc rằng tôi nên sử dụng ENV để đặt giá trị môi trường, nhưng hướng dẫn sau đây dường như không hoạt động:

ENV PATH /opt/gtk/bin:$PATH

Đây là toàn bộ Dockerfile của tôi:

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
Nên đặt LD_LIBRARY_PATH và PATH bằng cách sử dụng ENV không xuất. Bạn cũng là LD_LIBRARY_PATH không nên chỉ vào PATH!. Xóa các tệp trong Dockerfile sẽ không làm cho hình ảnh của bạn nhỏ hơn, hãy kiểm tra centurylinklabs.com/optimizing-docker-images/?hvid=4wO7Yt .
Javier Castellanos

dockerfile hiện tại có hợp lệ không?
Hui Wang

@HuiWang có thể không. Nó đã được viết, nó đã được viết cách đây 1,5 năm và rất nhiều thứ đã thay đổi kể từ đó. Chỉ cần đảm bảo bạn kết hợp các thay đổi được mô tả trong câu trả lời đã chọn.
ILikeTacos

Câu trả lời:


608

Bạn có thể sử dụng môi trường thay thế trong của bạn Dockerfilenhư sau:

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

14
=dấu bằng cần thiết?
IgorGanapolsky

16
@IgorGanapolsky Không phải trong trường hợp này vì nó chỉ định một biến duy nhất. Tuy nhiên, nó không gây hại và là bắt buộc khi chỉ định nhiều biến. Xem tài liệu ENV để biết thêm chi tiết.
Homme Zwaagstra

30
Đó là công việc! Xin hãy quan tâm đến =nó cần phải có không gian. Nếu bạn thêm khoảng trắng bên cạnh =như thế này ENV PATH = "/opt/gtk/bin:${PATH}"SILL TẠO $ PATH CỦA BẠN
Diego Juliao

2
Điều này có cập nhật hình ảnh với HOST được $PATHnối không?
emmdee

2
ENV PATH="/opt/gtk/bin:${PATH}"có thể không giống như ENV PATH="/opt/gtk/bin:$PATH"trước đây, với dấu ngoặc nhọn, có thể cung cấp cho bạn PATH của máy chủ. Các tài liệu không đề xuất điều này sẽ là trường hợp, nhưng tôi đã quan sát thấy rằng nó là. Điều này thật đơn giản để kiểm tra chỉ cần làm RUN echo $PATHvà so sánh nó vớiRUN echo ${PATH}
dankirkd

49

Mặc dù câu trả lời mà Gunter đăng là chính xác, nó không khác gì những gì tôi đã đăng. Vấn đề không phải là ENVchỉ thị, mà là hướng dẫn tiếp theoRUN export $PATH

Không cần xuất các biến môi trường, một khi bạn đã khai báo chúng qua ENVDockerfile.

Ngay khi các RUN export ...dòng được xóa, hình ảnh của tôi đã được xây dựng thành công


4
RUN A=B, RUN export A, Và RUN export A=B, là các lệnh shell hợp lệ, nhưng ảnh hưởng đến môi trường chỉ của lệnh tiếp theo trong cùng RUNchỉ thị (nhưng không ai được cho). Tương tự, nếu bạn có RUN export PATH=/foo; prog1; prog2;(trong cùng CHẠY), sửa đổi PATH sẽ ảnh hưởng prog1prog2. Vì vậy, RUN export $PATHlà một noop (vì không có chương trình nào sử dụng môi trường được sửa đổi đó) và nó sẽ không có sự khác biệt nếu lệnh đó có hay không. "Gunter", ý bạn là câu trả lời này ?
init_js

Cách khắc phục thực sự là thay đổi giá trị PATH bằng chỉ thị ENV, không phải RUN. Sau đó, những thay đổi đó sẽ tiếp tục khi người xây dựng docker gọi RUN sau.
init_js

5

Điều này không được khuyến khích (nếu bạn muốn tạo / phân phối hình ảnh Docker sạch), vì PATHbiến được đặt bởi /etc/profiletập lệnh, giá trị có thể bị ghi đè.

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

Ở cuối Dockerfile, bạn có thể thêm:

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

Vì vậy, PATH được thiết lập cho tất cả người dùng.


4
Theo tài liệu Ubuntu này , /etc/environmentlà một danh sách các biểu thức gán, không phải là tập lệnh và không hỗ trợ mở rộng biến, do đó, RUNcú pháp sẽ không hoạt động.
Nicolas Lefebvre

3
Có, nó sẽ được mở rộng và export PATH=<some path>sẽ được ghi vào /etc/environment, điều này vẫn không chính xác vì tệp đó không phải là một tập lệnh mà là một danh sách <var name>=<value>. exportsẽ có khả năng làm cho nó thất bại trừ khi hệ thống của bạn hỗ trợ một số ma thuật đen bên ngoài thông số kỹ thuật.
Nicolas Lefebvre
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.