Sử dụng lệnh RUN trong Dockerfile với 'source' không hoạt động


274

Tôi có một Dockerfile mà tôi sắp đặt để cài đặt môi trường python python (trong đó tôi sẽ cài đặt một ứng dụng, nhưng vào một ngày sau đó).

FROM ubuntu:12.04

# required to build certain python libraries
RUN apt-get install python-dev -y

# install pip - canonical installation instructions from pip-installer.org
# http://www.pip-installer.org/en/latest/installing.html
ADD https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py /tmp/ez_setup.py
ADD https://raw.github.com/pypa/pip/master/contrib/get-pip.py /tmp/get-pip.py
RUN python /tmp/ez_setup.py
RUN python /tmp/get-pip.py
RUN pip install --upgrade pip 

# install and configure virtualenv
RUN pip install virtualenv 
RUN pip install virtualenvwrapper
ENV WORKON_HOME ~/.virtualenvs
RUN mkdir -p $WORKON_HOME
RUN source /usr/local/bin/virtualenvwrapper.sh

Bản dựng chạy ổn cho đến dòng cuối cùng, nơi tôi nhận được ngoại lệ sau:

[previous steps 1-9 removed for clarity]
...
Successfully installed virtualenvwrapper virtualenv-clone stevedore
Cleaning up...
 ---> 1fc253a8f860
Step 10 : ENV WORKON_HOME ~/.virtualenvs
 ---> Running in 8b0145d2c80d
 ---> 0f91a5d96013
Step 11 : RUN mkdir -p $WORKON_HOME
 ---> Running in 9d2552712ddf
 ---> 3a87364c7b45
Step 12 : RUN source /usr/local/bin/virtualenvwrapper.sh
 ---> Running in c13a187261ec
/bin/sh: 1: source: not found

Nếu tôi lsvào thư mục đó (chỉ để kiểm tra các bước trước đó đã được cam kết) tôi có thể thấy rằng các tệp tồn tại như mong đợi:

$ docker run 3a87 ls /usr/local/bin
easy_install
easy_install-2.7
pip
pip-2.7
virtualenv
virtualenv-2.7
virtualenv-clone
virtualenvwrapper.sh
virtualenvwrapper_lazy.sh

Nếu tôi thử chạy sourcelệnh tôi sẽ gặp lỗi 'không tìm thấy' như trên. Tuy nhiên, nếu tôi CHẠY một phiên shell tương tác, nguồn sẽ hoạt động:

$ docker run 3a87 bash
source
bash: line 1: source: filename argument required
source: usage: source filename [arguments]

Tôi có thể chạy tập lệnh từ đây, và sau đó vui vẻ truy cập workon, mkvirtualenvv.v.

Tôi đã thực hiện một số hoạt động đào và ban đầu có vẻ như vấn đề có thể nằm ở sự khác biệt giữa bashshell đăng nhập Ubuntu và dashshell hệ thống Ubuntu , dash không hỗ trợ sourcelệnh.

Tuy nhiên, câu trả lời cho điều này dường như là sử dụng '.' thay vì source, nhưng điều này chỉ khiến cho thời gian chạy Docker nổ tung với một ngoại lệ hoảng loạn.

Cách tốt nhất để chạy tập lệnh shell từ lệnh RUN của Dockerfile để khắc phục điều này (đang chạy hình ảnh cơ sở mặc định cho Ubuntu 12.04 LTS).


2
Vì vậy, đừng 'nguồn' nó, chỉ cần chạy lệnh. Hoặc đặc biệt chạy tập lệnh shell với 'bash'.
Alister Bulman

Đã thử rằng - mặc dù kịch bản không thất bại, tôi không có quyền truy cập vào các lệnh khác nhau, điều mà tôi muốn. Vấn đề này là điều tương tự - github.com/dotcloud/docker/issues/2847
Hugo Rodger-Brown

2
Mà, nghĩ về nó, là chính xác. Virtualenvwrapper có lẽ không có ý nghĩa gì trong môi trường container. Thay vào đó, tôi sẽ sao lưu nó và sử dụng virtualenv 'bản địa'.
Hugo Rodger-Brown

1
Cách cơ bản hơn để tiếp cận điều này là stackoverflow.com/questions/4732200/
Gaurav Ojha

Hãy thửCMD source activate django-py35
Belter

Câu trả lời:


315

RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh"


66
Hở? Nếu bạn lấy một tập lệnh bên trong một vỏ chỉ tồn tại cho lệnh, thì nó không thể có tác dụng lâu dài đối với bất kỳ lệnh nào trong tương lai, giả sử rằng tổng số hành động của nó là đặt các biến môi trường. Vậy tại sao bạn lại sử dụng source, so với bash /usr/local/bin/virtualenvwrapper.sh, chỉ trong trường hợp đó?
Charles Duffy

13
RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh; my_command; my_command; my_command;"
Leo

28
Điều này là không chính xác mặc dù nó hoạt động. Đọc docs.docker.com/engine/reference/builder/#run và không dừng lại sau mẫu mã thứ hai. Đọc ghi chú: ngay sau đó. Vì /bin/sh -clà shell mặc định, "dạng shell" này của RUN dịch thành RUN ["/bin/sh", "-c", "/bin/bash" "-c" "source /usr/local/bin/virtualenvwrapper.sh"]. Bạn nên tiếp tục và sử dụng "mẫu thực thi" của RUN để bạn có thể rút shra như vậyRUN ["/bin/bash" "-c" "source /usr/local/bin/virtualenvwrapper.sh"]
Bruno Bronosky 13/07/2017

8
Vui lòng xem stackoverflow.com/a/45087082/117471 để hiểu lý do tại sao điều này tạo ra một bashlồng trong shvà do đó nên tránh.
Bruno Bronosky

4
Một câu trả lời tốt hơn nhiều ở đây: stackoverflow.com/a/42216046/1663462
Chris Stryczynski

150

Câu trả lời gốc

FROM ubuntu:14.04
RUN rm /bin/sh && ln -s /bin/bash /bin/sh

Điều này sẽ làm việc cho mọi hình ảnh cơ sở docker Ubuntu. Tôi thường thêm dòng này cho mỗi Dockerfile tôi viết.

Chỉnh sửa bởi một người ngoài cuộc có liên quan

Nếu bạn muốn có được hiệu ứng "sử dụng bashthay vì shtrong toàn bộ Dockerfile này", mà không thay đổicó thể làm hỏng * HĐH bên trong container, bạn chỉ cần nói cho Docker biết ý định của bạn . Điều đó được thực hiện như vậy:

SHELL ["/bin/bash", "-c"]

* Thiệt hại có thể xảy ra là nhiều tập lệnh trong Linux (trên bản cài đặt Ubuntu mới grep -rHInE '/bin/sh' /trả về hơn 2700 kết quả) mong đợi trình bao POSIX đầy đủ tại /bin/sh. Shell bash không chỉ là POSIX cộng với các nội dung bổ sung. Có những nội dung (và hơn thế nữa) hoạt động hoàn toàn khác so với những công cụ trong POSIX. Tôi HOÀN TOÀN hỗ trợ tránh POSIX (và sai lầm rằng bất kỳ tập lệnh nào bạn không kiểm tra trên trình bao khác sẽ hoạt động vì bạn nghĩ rằng bạn đã tránh được các vấn đề cơ bản) và chỉ sử dụng bashism. Nhưng bạn làm điều đó với một shebang thích hợp trong kịch bản của bạn. Không phải bằng cách kéo vỏ POSIX ra khỏi toàn bộ HĐH. (Trừ khi bạn có thời gian để xác minh tất cả 2700 tập lệnh cộng với Linux cộng với tất cả các tập lệnh trong bất kỳ gói nào bạn cài đặt.)

Chi tiết hơn trong câu trả lời dưới đây. https://stackoverflow.com/a/45087082/117471


18
Điều này có thể được đơn giản hóa một chút:ln -snf /bin/bash /bin/sh
apottere

2
@ user1442219 điều này thay thế trình thông dịch lệnh mặc định từ shđếnbash
Bhargav Nanekalva

27
ln -s /bin/bash /bin/shđây là một ý tưởng khủng khiếp mục tiêu ubfox / bin / sh để dash vì một lý do. dash là một vỏ hoàn toàn posix là thứ tự có độ lớn nhanh hơn bash. liên kết / bin / sh đến bash sẽ làm giảm đáng kể hiệu suất của máy chủ của bạn. trích dẫn: wiki.ubfox.com/DashAsBinSh
xero

7
Đây là một hack bẩn, không phải là một giải pháp. Nếu tập lệnh của bạn đang được chạy bởi shshell, nhưng bạn muốn bash, thì giải pháp thích hợp là sử dụng shquy trình bashmột lần, ví dụ bash -c 'source /script.sh && …', hoặc thậm chí bạn có thể đi xa hơn để tránh bashism (như source) hoàn toàn, và thay vào đó chọn chỉ sử dụng tương đương POSIX hợp lệ, vd . /script.sh. (Hãy nhớ khoảng trống sau .!) Cuối cùng, nếu tập lệnh của bạn có thể thực thi được (không chỉ có thể đọc được), đừng bao giờ làm cho tập lệnh của bạn nằm với một #!/bin/shshebang nếu nó không thực sự tương thích với sh. Sử dụng #!/bin/bashthay thế.
Đánh dấu G.

7
Và bây giờ làm thế nào để tôi downvote câu trả lời ban đầu và upvote chỉnh sửa bằng 'một quan tâm'?
Slava

65

Shell mặc định cho RUNhướng dẫn là ["/bin/sh", "-c"].

RUN "source file"      # translates to: RUN /bin/sh -c "source file"

Sử dụng hướng dẫn SHELL , bạn có thể thay đổi shell mặc định cho các RUNhướng dẫn tiếp theo trong Dockerfile:

SHELL ["/bin/bash", "-c"] 

Bây giờ, shell mặc định đã thay đổi và bạn không cần xác định rõ ràng trong mọi lệnh RUN

RUN "source file"    # now translates to: RUN /bin/bash -c "source file"

Lưu ý bổ sung : Bạn cũng có thể thêm --logintùy chọn sẽ bắt đầu một vỏ đăng nhập. Điều này có nghĩa là ~/.bachrcví dụ sẽ được đọc và bạn không cần phải cung cấp nguồn rõ ràng trước lệnh của bạn


1
Con trỏ tuyệt vời khi sử dụng --login- chỉ cần tự mình tìm ra điều này
mattexx

Bằng cách sử dụng, SHELL ["/bin/bash", "-c", "-l"] tôi có thể sử dụng các bản cập nhật tiếp theo cho tệp .bashrc, cho phép tôi chạy các lệnh asdf một cách dễ dàng.
Rowinson Gallego

46

Tôi đã có cùng một vấn đề và để thực hiện cài đặt pip bên trong virtualenv, tôi đã phải sử dụng lệnh này:

RUN pip install virtualenv virtualenvwrapper
RUN mkdir -p /opt/virtualenvs
ENV WORKON_HOME /opt/virtualenvs
RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh \
    && mkvirtualenv myapp \
    && workon myapp \
    && pip install -r /mycode/myapp/requirements.txt"

Tôi hy vọng nó sẽ giúp.


Trong trường hợp bạn đến từ câu trả lời của ROS, vâng, nó hoạt động. Một cái gì đó như:RUN /bin/bash -c "source /opt/ros/melodic/setup.bash && \ cd /home && \ git clone https://angelos.p:$password@gitlab.com/inno/grpc-comms.git && \ cd grpc-comms && \ mkdir build && \ cd build && \ cmake .. && make"
angelos.p

44

Cách đơn giản nhất là sử dụng toán tử dấu chấm thay cho nguồn, tương đương với sh của sourcelệnh bash :

Thay vì:

RUN source /usr/local/bin/virtualenvwrapper.sh

Sử dụng:

RUN . /usr/local/bin/virtualenvwrapper.sh

"nguồn là một vỏ bourne được xây dựng và một POSIX` đặc biệt 'dựng sẵn "- ss64.com/bash/source.html linux.die.net/man/1/sh ... . / sourcecũng chấp nhận các tham số vị trí sau tên tệp
Wes Turner

5
Điều này không hoạt động vì mỗi lệnh RUN hoạt động độc lập. Các thay đổi từ sourcehoặc .bị mất khi lệnh RUN kết thúc. Xem: stackoverflow.com/a/40045930/19501
amit

26

Nếu bạn đang sử dụng Docker 1.12 hoặc mới hơn, chỉ cần sử dụng SHELL!

Câu trả lời ngắn:

chung:

SHELL ["/bin/bash", "-c"] 

cho trăn vituralenv:

SHELL ["/bin/bash", "-c", "source /usr/local/bin/virtualenvwrapper.sh"]

Câu trả lời dài:

từ https://docs.docker.com/engine/reference/builder/#/shell

SHELL ["executable", "parameters"]

Lệnh SHELL cho phép shell mặc định được sử dụng cho dạng lệnh shell được ghi đè. Shell mặc định trên Linux là ["/ bin / sh", "-c"] và trên Windows là ["cmd", "/ S", "/ C"]. Lệnh SHELL phải được viết dưới dạng JSON trong Dockerfile.

Hướng dẫn SHELL đặc biệt hữu ích trên Windows khi có hai shell riêng được sử dụng phổ biến và khá khác nhau: cmd và powershell, cũng như các shell thay thế có sẵn bao gồm sh.

Lệnh SHELL có thể xuất hiện nhiều lần. Mỗi lệnh SHELL ghi đè tất cả các hướng dẫn SHELL trước đó và ảnh hưởng đến tất cả các hướng dẫn tiếp theo. Ví dụ:

FROM microsoft/windowsservercore

# Executed as cmd /S /C echo default
RUN echo default

# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default

# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello

# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello

Các hướng dẫn sau đây có thể bị ảnh hưởng bởi lệnh SHELL khi dạng vỏ của chúng được sử dụng trong Dockerfile: RUN, CMD và ENTRYPOINT.

Ví dụ sau đây là một mẫu phổ biến được tìm thấy trên Windows có thể được sắp xếp hợp lý bằng cách sử dụng lệnh SHELL:

...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...

Lệnh được gọi bởi docker sẽ là:

cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"

Điều này là không hiệu quả vì hai lý do. Đầu tiên, có một bộ xử lý lệnh cmd.exe không cần thiết (hay còn gọi là shell) đang được gọi. Thứ hai, mỗi lệnh RUN ở dạng shell yêu cầu thêm một quyền hạn -command tiền tố lệnh.

Để làm cho điều này hiệu quả hơn, một trong hai cơ chế có thể được sử dụng. Một là sử dụng dạng JSON của lệnh RUN, chẳng hạn như:

...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...

Mặc dù biểu mẫu JSON không rõ ràng và không sử dụng cmd.exe không cần thiết, nhưng nó đòi hỏi nhiều tính chi tiết hơn thông qua trích dẫn kép và thoát. Cơ chế thay thế là sử dụng lệnh SHELL và dạng shell, tạo một cú pháp tự nhiên hơn cho người dùng Windows, đặc biệt là khi kết hợp với chỉ thị trình phân tích cú pháp thoát:

# escape=`

FROM microsoft/nanoserver
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'

Kết quả là:

PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 4.096 kB
Step 1/5 : FROM microsoft/nanoserver
 ---> 22738ff49c6d
Step 2/5 : SHELL powershell -command
 ---> Running in 6fcdb6855ae2
 ---> 6331462d4300
Removing intermediate container 6fcdb6855ae2
Step 3/5 : RUN New-Item -ItemType Directory C:\Example
 ---> Running in d0eef8386e97


    Directory: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       10/28/2016  11:26 AM                Example


 ---> 3f2fbf1395d9
Removing intermediate container d0eef8386e97
Step 4/5 : ADD Execute-MyCmdlet.ps1 c:\example\
 ---> a955b2621c31
Removing intermediate container b825593d39fc
Step 5/5 : RUN c:\example\Execute-MyCmdlet 'hello world'
 ---> Running in be6d8e63fe75
hello world
 ---> 8e559e9bf424
Removing intermediate container be6d8e63fe75
Successfully built 8e559e9bf424
PS E:\docker\build\shell>

Lệnh SHELL cũng có thể được sử dụng để sửa đổi cách thức hoạt động của trình bao. Ví dụ: sử dụng SHELL cmd / S / C / V: ON | OFF trên Windows, ngữ nghĩa mở rộng biến môi trường bị trì hoãn có thể được sửa đổi.

Lệnh SHELL cũng có thể được sử dụng trên Linux nếu cần phải có vỏ thay thế như zsh, csh, tcsh và các loại khác.

Tính năng SHELL đã được thêm vào Docker 1.12.


20

Dựa trên các câu trả lời trên trang này tôi sẽ nói thêm rằng bạn phải biết rằng mỗi câu lệnh RUN chạy độc lập với các câu lệnh khác với /bin/sh -c và do đó sẽ không nhận được bất kỳ bình môi trường nào thường có nguồn gốc trong các vỏ đăng nhập.

Cách tốt nhất mà tôi đã tìm thấy cho đến nay là thêm tập lệnh vào /etc/bash.bashrcvà sau đó gọi từng lệnh dưới dạng đăng nhập bash.

RUN echo "source /usr/local/bin/virtualenvwrapper.sh" >> /etc/bash.bashrc
RUN /bin/bash --login -c "your command"

Ví dụ, bạn có thể cài đặt và thiết lập virtualenvwrapper, tạo env ảo, kích hoạt nó khi bạn sử dụng thông tin đăng nhập bash, sau đó cài đặt các mô-đun python của bạn vào env này:

RUN pip install virtualenv virtualenvwrapper
RUN mkdir -p /opt/virtualenvs
ENV WORKON_HOME /opt/virtualenvs
RUN echo "source /usr/local/bin/virtualenvwrapper.sh" >> /etc/bash.bashrc
RUN /bin/bash --login -c "mkvirtualenv myapp"
RUN echo "workon mpyapp" >> /etc/bash.bashrc
RUN /bin/bash --login -c "pip install ..."

Đọc hướng dẫn về các tập tin khởi động bash giúp hiểu được nguồn gốc khi nào.


1
Thật tuyệt, dựa trên giải pháp của bạn, điều tôi đã làm chỉ để minh họa là: ADD env-file /etc/profile.d/installerenv.sh RUN /bin/bash --login -c 'env' RUN /bin/bash -c 'rm /etc/profile.d/installerenv.sh' Nếu trường hợp sử dụng của một người thêm nhiều biến môi trường tiêm vào phối cảnh xây dựng docker như của tôi, tôi đã khuyên bạn nên xem docs.docker.com/compose/yml / # env-file cũng vậy.
daniel.kahlenberg

1
Vấn đề với điều này, tôi tin rằng, bạn không kết thúc bộ nhớ đệm kết quả của mỗi RUNlệnh, điều đó có nghĩa là bạn không thể cài đặt toàn bộ phụ thuộc dự án và sau đó sao chép mã nguồn và tận dụng lợi ích của Bộ nhớ đệm bước trung gian của Docker. Nó sẽ cài đặt lại tất cả các phụ thuộc dự án mỗi lần.
erewok

Sử dụng /etc/bashrccho Redhat, thay vì /etc/bash.bashrcnhư đã đề cập ở trên (Đối với Ubuntu)
Jordan Gee

Tôi đã sử dụng /root/.bashrc cho centos.
schmudu

RUN echo "source /yourscript.bash" >> /etc/bash.bashrc thực hiện thủ thuật. nếu bạn đang sử dụng ros bên trong docker và muốn thiết lập môi trường thì đây là điều bạn nên làm
user27221

17

Theo https://docs.docker.com/engine/reference/builder/#run trình bao [Linux] mặc định cho RUN/bin/sh -c . Có vẻ như bạn đang mong đợi bashism, vì vậy bạn nên sử dụng "biểu mẫu thực thi" RUNđể chỉ định shell của mình.

RUN ["/bin/bash", "-c", "source /usr/local/bin/virtualenvwrapper.sh"]

Mặt khác, sử dụng "mẫu vỏ" của RUN và chỉ định một vỏ khác dẫn đến các vỏ được lồng vào nhau.

# don't do this...
RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh"
# because it is the same as this...
RUN ["/bin/sh", "-c", "/bin/bash" "-c" "source /usr/local/bin/virtualenvwrapper.sh"]

Nếu bạn có nhiều hơn 1 lệnh cần shell khác nhau, bạn nên đọc https://docs.docker.com/engine/reference/builder/#shell và thay đổi shell mặc định của bạn bằng cách đặt lệnh này trước các lệnh RUN của bạn:

SHELL ["/bin/bash", "-c"]

Cuối cùng, nếu bạn đã đặt bất cứ thứ gì vào .bashrctập tin người dùng root mà bạn cần, bạn có thể thêm-l cờ vào lệnh SHELLhoặc RUNđể làm cho nó một vỏ đăng nhập và đảm bảo rằng nó có nguồn gốc.

Lưu ý: Tôi đã cố tình bỏ qua thực tế rằng việc lấy một tập lệnh là lệnh duy nhất trong RUN là vô nghĩa.


SHELL ["/bin/sh", "-c", "-l"]vì vậy nó sẽ nguồn ~ / .bashrc, v.v. trong trường hợp bạn có cài đặt môi trường từ thùng chứa cơ sở
MortenB

1
@MortenB, nhưng bạn đã chỉ định (lỗi đánh máy?) /bin/shSẽ không giải quyết được vấn đề bash không được sử dụng. Ngoài ra, khi thực hiện docker build, không có khả năng sẽ có bất cứ thứ gì hữu ích trong .bashrc của người dùng gốc mà bạn cần. Nhưng, nếu bạn đặt một cái gì đó vào đó sớm hơn trong Dockerfile (như có thể là một JAVA_HOME, thì có. Tôi sẽ ghi chú về nó trong câu trả lời của tôi.
Bruno Bronosky

Xin lỗi vì lỗi đánh máy, tôi đang sử dụng pyenv cần nguồn ~ / .bashrc để đặt đường dẫn cho phiên bản python chính xác trong hình ảnh cơ sở của tôi. điều này khiến tôi sử dụng bất cứ cơ sở linux nào có và với hai dòng thêm bất kỳ phiên bản nào trên python. Giống như python 3.7 trên ubfox16.04 trong đó python cơ sở là 3.5.2
MortenB

11

Theo tài liệu của Docker

Để sử dụng trình bao khác, ngoài '/ bin / sh', hãy sử dụng biểu mẫu thực thi chuyển qua trình bao mong muốn. Ví dụ,

RUN ["/bin/bash", "-c", "echo hello"]

Xem https://docs.docker.com/engine/reference/builder/#run


Đây là câu trả lời đúng THỰC TẾ. Tác giả của câu trả lời được chọn stackoverflow.com/a/25086628/117471 dường như chỉ đọc ví dụ đầu tiên trong tài liệu bạn liên kết đến. Họ dường như không đọc đoạn tiếp theo, đó là những gì bạn đã trích dẫn.
Bruno Bronosky

4

Nếu bạn có SHELLsẵn, bạn nên đi với câu trả lời này - không sử dụng câu trả lời được chấp nhận, điều này buộc bạn phải đặt phần còn lại của dockerfile vào một lệnh cho mỗi nhận xét này .

Nếu bạn đang sử dụng phiên bản Docker cũ và không có quyền truy cập SHELL, điều này sẽ hoạt động miễn là bạn không cần bất cứ thứ gì .bashrc(đây là trường hợp hiếm gặp trong Dockerfiles):

ENTRYPOINT ["bash", "--rcfile", "/usr/local/bin/virtualenvwrapper.sh", "-ci"]

Lưu ý -ilà cần thiết để làm cho bash đọc RCfile cả.


3

Bạn có thể muốn chạy bash -v để xem những gì có nguồn gốc.

Tôi sẽ làm như sau thay vì chơi với symlink:

RUN echo "source /usr/local/bin/virtualenvwrapper.sh" >> /etc/bash.bashrc


3

Tôi cũng gặp vấn đề trong việc chạy source trong Dockerfile

Điều này chạy hoàn toàn tốt để xây dựng bộ chứa Dock Dock CentOS 6.6, nhưng đã gặp sự cố trong bộ chứa Debian

RUN cd ansible && source ./hacking/env-setup

Đây là cách tôi giải quyết nó, có thể không phải là một cách thanh lịch nhưng đây là những gì làm việc cho tôi

RUN echo "source /ansible/hacking/env-setup" >> /tmp/setup
RUN /bin/bash -C "/tmp/setup"
RUN rm -f /tmp/setup

2

Điều này có thể xảy ra vì sourcelà một bash tích hợp sẵn chứ không phải là nhị phân ở đâu đó trên hệ thống tập tin. Ý định của bạn cho tập lệnh mà bạn tìm nguồn để thay đổi container sau đó?


1
Kịch bản không cập nhật container - nhưng thành thật mà nói, tôi đã cố gắng làm điều gì đó vô nghĩa, vì vậy đã bỏ qua vấn đề.
Hugo Rodger-Brown

1

Cuối cùng tôi đã đưa công cụ env của mình vào .profilevà biến đổi SHELLmột cái gì đó như

SHELL ["/bin/bash", "-c", "-l"]

# Install ruby version specified in .ruby-version
RUN rvm install $(<.ruby-version)

# Install deps
RUN rvm use $(<.ruby-version) && gem install bundler && bundle install

CMD rvm use $(<.ruby-version) && ./myscript.rb

3
"-C" cần phải là đối số cuối cùng (trước lệnh.to được thực thi)
peterk

0

Nếu bạn chỉ đang cố gắng sử dụng pip để cài đặt một cái gì đó vào virtualenv, trước tiên bạn có thể sửa đổi PATH env để tìm trong thư mục bin của virtualenv

ENV PATH="/path/to/venv/bin:${PATH}"

Sau đó, bất kỳ pip installlệnh nào theo Dockerfile sẽ tìm / path / to / venv / bin / pip trước và sử dụng lệnh đó, sẽ cài đặt vào virtualenv đó chứ không phải python hệ thống.

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.