Dockerfile में RUN निर्देश का उपयोग करने से 'स्रोत' काम नहीं करता है


274

मेरे पास एक डॉकरफ़ाइल है जिसे मैं एक वेनिला पायथन पर्यावरण स्थापित करने के लिए एक साथ रख रहा हूं (जिसमें मैं एक ऐप स्थापित करूंगा, लेकिन बाद की तारीख में)।

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

बिल्ड अंतिम पंक्ति तक ठीक चलता है, जहां मुझे निम्नलिखित अपवाद मिलते हैं:

[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

यदि मैं lsउस निर्देशिका में हूँ (केवल यह परीक्षण करने के लिए कि पिछले चरण प्रतिबद्ध थे) तो मैं देख सकता हूँ कि फाइलें अपेक्षित रूप से मौजूद हैं:

$ 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

अगर मैं सिर्फ sourceकमांड चलाने की कोशिश करता हूं तो मुझे ऊपर जैसा 'त्रुटि नहीं मिला' मिलता है। अगर मैं एक इंटरेक्टिव शेल सत्र चलाता हूं, तो स्रोत काम करता है:

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

मैं यहां से स्क्रिप्ट चला सकता हूं, और फिर खुशी से पहुंच सकता हूं workon, mkvirtualenvआदि।

मैं कुछ खुदाई किया है, और शुरू में यह करता है, तो समस्या के बीच अंतर में झूठ हो सकता है के रूप में देखा बैश उबंटू के रूप में लॉगिन खोल , और पानी का छींटा उबंटू के रूप में प्रणाली खोल , पानी का छींटा का समर्थन नहीं sourceआदेश।

हालाँकि, इसका उत्तर उपयोग के लिए प्रतीत होता है '।' इसके बजाय source, लेकिन इससे डॉक रनटाइम को एक अपवाद के रूप में जाना जाता है।

इसके चारों ओर पाने के लिए डॉकरफाइल आरयूएन निर्देश से शेल स्क्रिप्ट चलाने का सबसे अच्छा तरीका क्या है (उबंटू 12.04 एलटीएस के लिए डिफ़ॉल्ट आधार छवि को बंद कर रहा है)।


2
तो यह 'स्रोत' नहीं है, बस कमांड चलाएं। या विशेष रूप से शेल स्क्रिप्ट को 'बैश' के साथ चलाएं।
एलिस्टर बुलमैन

कोशिश की कि - हालांकि स्क्रिप्ट विफल नहीं होती है, मुझे विभिन्न कमांडों तक पहुंच नहीं है, जो मुझे चाहिए था। यह मुद्दा समान है - github.com/dotcloud/docker/issues/2847
ह्यूगो रोडर-ब्राउन

2
जो, इसके बारे में सोचना, सही है। Virtualenvwrapper संभवतः कंटेनर वातावरण में कोई अर्थ नहीं रखता है। मैं इसे वापस लेने जा रहा हूं और इसके बजाय 'देशी' virtualenv का उपयोग कर रहा हूं।
ह्यूगो रॉजर-ब्राउन

1
इस से संपर्क करने का अधिक मूल तरीका है stackoverflow.com/questions/4732200/…
गौरव ओझा

प्रयास करेंCMD source activate django-py35
Belter

जवाबों:


315

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


66
एह? यदि आप एक शेल के अंदर एक स्क्रिप्ट का स्रोत बनाते हैं जो केवल कमांड के लिए मौजूद है, तो यह भविष्य के किसी भी कमांड रन पर स्थायी प्रभाव नहीं डाल सकता है, यह मानते हुए कि इसकी कार्रवाई का कुल योग पर्यावरण चर सेट कर रहा है। तो आप उस मामले में source, बनाम सिर्फ bash /usr/local/bin/virtualenvwrapper.sh, का उपयोग क्यों करेंगे ?
चार्ल्स डफी

13
RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh; my_command; my_command; my_command;"
सिंह

29
यह काम करते हुए भी सही नहीं है। Docs.docker.com/engine/reference/builder/#run पढ़ें और दूसरे कोड नमूने के बाद बंद न करें। नोट पढ़ें : जो तुरंत इस प्रकार है। क्योंकि /bin/sh -cडिफ़ॉल्ट शेल है, RUN का यह "शेल फॉर्म" है RUN ["/bin/sh", "-c", "/bin/bash" "-c" "source /usr/local/bin/virtualenvwrapper.sh"]। आपको आगे बढ़ना चाहिए और RUN के " shRUN ["/bin/bash" "-c" "source /usr/local/bin/virtualenvwrapper.sh"]
एक्जीक्यूट

8
कृपया यह देखने के लिए कि यह एक नेस्टेड क्यों बनाता है और इसलिए इसे टाला जाना चाहिए, यह समझने के लिए कृपया stackoverflow.com/a/45087082/117471 देखें । bashsh
ब्रूनो ब्रोंस्की

4

150

मूल उत्तर

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

यह हर Ubuntu docker आधार छवि के लिए काम करना चाहिए। मैं आमतौर पर मेरे द्वारा लिखे गए हर डॉकरीफाइल के लिए इस लाइन को जोड़ता हूं।

एक संबंधित bystander द्वारा संपादित करें

यदि आप " इस पूरे डॉकरीफाइल के bashबजाय " उपयोग के प्रभाव को प्राप्त करना चाहते हैं , तो कंटेनर के अंदर ओएस shको बदलकर और संभवतः नुकसान पहुँचाए बिना , आप केवल डॉकर को अपना इरादा बता सकते हैं । ऐसा किया जाता है:

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

* संभावित नुकसान यह है कि लिनक्स में कई स्क्रिप्ट (एक ताजा उबंटू grep -rHInE '/bin/sh' /पर 2700 से अधिक परिणाम स्थापित करते हैं ) पूरी तरह से POSIX खोल की उम्मीद करते हैं /bin/sh। बैश शेल सिर्फ POSIX प्लस अतिरिक्त निर्मित नहीं है। बिलिंस (और अधिक) हैं जो पोसिक्स की तुलना में पूरी तरह से अलग व्यवहार करते हैं। मैं पूरी तरह से POSIX से बचने का समर्थन करता हूं (और यह गिरावट कि किसी भी स्क्रिप्ट को आपने किसी अन्य शेल पर परीक्षण नहीं किया था, काम करने जा रहा है क्योंकि आपको लगता है कि आपने आधारवाद से बचा है) और बस बैशवाद का उपयोग कर रहे हैं। लेकिन आप अपनी स्क्रिप्ट में एक उचित शेबंग के साथ ऐसा करते हैं। पूरे OS के नीचे से POSIX शेल को खींचकर नहीं। (जब तक आपके पास सभी 2700 प्लस स्क्रिप्ट को सत्यापित करने का समय न हो, जो आपके द्वारा स्थापित किसी भी पैकेज में लिनक्स प्लस के साथ आते हैं।)

नीचे इस जवाब में और विस्तार। https://stackoverflow.com/a/45087082/117471


18
इसे थोड़ा सरल किया जा सकता है:ln -snf /bin/bash /bin/sh
एपोटेक्टर

2
@ user1442219 इस जगह से डिफ़ॉल्ट कमांड दुभाषिया की जगह लेती shहैbash
भार्गव नेनकलेवा

27
ln -s /bin/bash /bin/shयह एक भयानक विचार है। ubuntu एक कारण के लिए डैश के लिए लक्ष्य / बिन / श। पानी का छींटा एक पूरी तरह से पॉज़िक्स शेल है जो बैश की तुलना में तेज़ी से बढ़ता है। / बिन / श को बाश से जोड़ना आपके सर्वर के प्रदर्शन को काफी कम कर देगा। cite: wiki.ubuntu.com/DashAsBinSh
xero

7
यह एक गंदा हैक है, एक समाधान नहीं है। यदि आपकी स्क्रिप्ट shशेल द्वारा चलाई जा रही है , लेकिन आप चाहते हैं bash, तो उचित समाधान या तो shप्रक्रिया bashको एकबारगी बंद करने के लिए है, उदाहरण के लिए bash -c 'source /script.sh && …', या आप sourceपूरी तरह से बशीश (जैसे ) से बचने के लिए इतनी दूर तक जा सकते हैं और इसके बजाय केवल कभी वैध POSIX समकक्ष का उपयोग करने का विकल्प चुनें, जैसे . /script.sh। (माइंड स्पेस के बाद .!) अंत में, यदि आपकी स्क्रिप्ट निष्पादन योग्य है (सिर्फ खट्टा नहीं है), तो अपनी स्क्रिप्ट को कभी भी#!/bin/sh शेबंग के साथ झूठ बनाएं अगर यह वास्तव में श-संगत नहीं है। #!/bin/bashइसके बजाय उपयोग करें ।
मार्क जी।

7
और अब मैं मूल उत्तर को कैसे नीचा दिखाऊं और 'संबंधित' द्वारा संपादन को बढ़ाऊं?
स्लाव

65

RUNनिर्देश के लिए डिफ़ॉल्ट शेल है ["/bin/sh", "-c"]

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

SHELL निर्देश का उपयोग करके , आप RUNDockerfile में बाद के निर्देशों के लिए डिफ़ॉल्ट शेल बदल सकते हैं :

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

अब, डिफ़ॉल्ट शेल बदल गया है और आपको इसे हर RUN निर्देश में स्पष्ट रूप से परिभाषित करने की आवश्यकता नहीं है

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

अतिरिक्त नोट : आप --loginविकल्प भी जोड़ सकते हैं जो एक लॉगिन शेल शुरू करेगा। ~/.bachrcउदाहरण के लिए इसका मतलब यह होगा कि आप इसे पढ़ेंगे और आपको अपने आदेश से पहले इसे स्पष्ट रूप से बताने की आवश्यकता नहीं है


1
का उपयोग करने पर महान सूचक --login- बस यह पता लगा लिया
mattexx

उपयोग करके SHELL ["/bin/bash", "-c", "-l"] मैं .bashrc फ़ाइल में और अपडेट का उपयोग करने में सक्षम था, जिसने मुझे आसानी से asdf कमांड चलाने की अनुमति दी।
रोविंसन गैलेगो

46

मुझे भी यही समस्या थी और virtualenv के अंदर pip install करने के लिए मुझे इस कमांड का उपयोग करना था:

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"

मुझे उम्मीद है यह मदद करेगा।


यदि आप ROS उत्तर से आते हैं, तो यह काम करता है। कुछ इस तरह: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"
एंजेलो.प

44

स्रोत के स्थान पर डॉट ऑपरेटर का उपयोग करना सबसे सरल तरीका है, जो bash sourceकमांड के बराबर है :

के बजाय:

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

उपयोग:

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

"स्रोत एक बोर्न शेल बिलिन है और एक POSIX` विशेष ' बिलिन "- ss64.com/bash/source.html linux.die.net/man/1/sh ... . / sourceफ़ाइल नाम के बाद स्थिती मापदंडों को भी स्वीकार करता है
वेस। टर्नर

5
यह काम नहीं करता है क्योंकि प्रत्येक RUN कमांड स्वतंत्र रूप से काम करता है। जब RUN कमांड समाप्त हो जाती है तब से परिवर्तन sourceया .खो जाते हैं। देखें: stackoverflow.com/a/40045930/19501
amit

26

यदि आप डॉकर 1.12 या नए का उपयोग कर रहे हैं, तो बस उपयोग करें SHELL!

संक्षिप्त जवाब:

सामान्य:

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

अजगर विट्रेलेंव के लिए:

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

लंबा जवाब:

से https://docs.docker.com/engine/reference/builder/#/shell

SHELL ["executable", "parameters"]

शेल निर्देश, कमांड के शेल रूप के लिए उपयोग किए जाने वाले डिफ़ॉल्ट शेल को ओवरराइड करने की अनुमति देता है। लिनक्स पर डिफ़ॉल्ट शेल ["/ bin / sh", "-c"] और विंडोज पर ["cmd", "/ S", "/ C"] है। SHELL निर्देश को JSON फॉर्म में डॉकफ़ाइल में लिखा जाना चाहिए।

शेल निर्देश विशेष रूप से विंडोज पर उपयोगी है जहां दो सामान्य रूप से उपयोग किए जाते हैं और काफी अलग देशी गोले हैं: सीएमडी और पॉवरशेल, साथ ही साथ वैकल्पिक शेल भी उपलब्ध हैं।

शेल निर्देश कई बार दिखाई दे सकता है। प्रत्येक शेल निर्देश पिछले सभी शेल निर्देशों को ओवरराइड करता है, और बाद के सभी निर्देशों को प्रभावित करता है। उदाहरण के लिए:

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

निम्नलिखित निर्देश SHELL निर्देश से प्रभावित हो सकते हैं, जब उनका शेल रूप एक डॉकफाइल में उपयोग किया जाता है: RUN, CMD और ENTRYPOINT।

निम्न उदाहरण विंडोज पर पाया जाने वाला एक सामान्य पैटर्न है जिसे शेल अनुदेश का उपयोग करके सुव्यवस्थित किया जा सकता है:

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

कमांडर द्वारा किया जाएगा:

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

यह दो कारणों से अक्षम है। सबसे पहले, एक आवश्यक-आवश्यक cmd.exe कमांड प्रोसेसर (उर्फ शेल) है, जिसे आमंत्रित किया जा रहा है। दूसरा, शेल रूप में प्रत्येक RUN निर्देश को कमांड को उपसर्ग करने के लिए एक अतिरिक्त पॉवरशेल -कमांड की आवश्यकता होती है।

इसे और अधिक कुशल बनाने के लिए, दो तंत्रों में से एक को नियोजित किया जा सकता है। एक RUN कमांड के JSON फॉर्म का उपयोग करना है:

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

जबकि JSON फॉर्म असंदिग्ध है और संयुक्त राष्ट्र के आवश्यक cmd.exe का उपयोग नहीं करता है, इसमें दोहरे-उद्धरण और भागने के माध्यम से अधिक वाचालता की आवश्यकता होती है। वैकल्पिक तंत्र शेल अनुदेश और शेल फॉर्म का उपयोग करना है, जो विंडोज उपयोगकर्ताओं के लिए एक अधिक प्राकृतिक वाक्यविन्यास बनाता है, खासकर जब एस्केप पार्सर निर्देश के साथ संयुक्त:

# 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'

जिसके परिणामस्वरूप:

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>

शेल निर्देश का उपयोग उस तरीके को संशोधित करने के लिए भी किया जा सकता है जिसमें एक शेल संचालित होता है। उदाहरण के लिए, SHELL cmd / S / C / V: ON | OFF का उपयोग करके Windows पर, विलंबित पर्यावरण चर विस्तार शब्दार्थ को संशोधित किया जा सकता है।

SHELL निर्देश का उपयोग लिनक्स पर भी किया जा सकता है एक वैकल्पिक शेल की आवश्यकता होनी चाहिए जैसे कि zsh, csh, tcsh और अन्य।

शेलर फीचर को डॉकर 1.12 में जोड़ा गया था।


20

इस पृष्ठ पर दिए गए उत्तरों के आधार पर मैं यह जानना चाहूंगा कि प्रत्येक RUN स्टेटमेंट दूसरों के साथ स्वतंत्र रूप से चलता है /bin/sh -cऔर इसलिए कोई भी पर्यावरण संस्करण नहीं मिलेगा जो सामान्य रूप से लॉगिन गोले में खट्टा होगा।

अभी तक मुझे जो सबसे अच्छा तरीका मिला है वह है स्क्रिप्ट को जोड़ना /etc/bash.bashrcऔर फिर प्रत्येक कमांड को बैश लॉगिन के रूप में लागू करना।

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

उदाहरण के लिए आप virtualenvwrapper को इंस्टाल और इंस्टाल कर सकते हैं, वर्चुअल एनवी बना सकते हैं, क्या इसे तब एक्टिवेट किया जाता है जब आप बैश लॉगिन का उपयोग करते हैं, और फिर इस ईवेंट में अपने पायथन मॉड्यूल को स्थापित करते हैं:

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 ..."

बैश स्टार्टअप फाइलों पर मैनुअल पढ़ने से यह समझने में मदद मिलती है कि कब क्या खट्टा होता है।


1
कूल, आपके समाधान के आधार पर जो मैंने सिर्फ वर्णन करने के लिए किया था: ADD env-file /etc/profile.d/installerenv.sh RUN /bin/bash --login -c 'env' RUN /bin/bash -c 'rm /etc/profile.d/installerenv.sh' यदि किसी के उपयोग के मामले में इंजेक्टर एनवायर्नमेंट वैरिएबल्स को डॉक करने के लिए परिप्रेक्ष्य का निर्माण होता है, जैसे कि मैंने docs.docker.com/compose/yml पर एक नज़र डालने की सिफारिश की है / # env-file भी।
daniel.kahlenberg

1
इस समस्या के साथ, मेरा मानना ​​है कि, आप प्रत्येक RUNआदेश के परिणामों को समाप्त नहीं करते हैं , जिसका अर्थ है कि आप बहुत सारी परियोजना निर्भरता स्थापित नहीं कर सकते हैं और फिर स्रोत कोड की प्रतिलिपि बना सकते हैं और लाभ का लाभ उठा सकते हैं डॉकर का मध्यवर्ती कदम कैशिंग। यह हर बार सभी परियोजना निर्भरता को पुनर्स्थापित करेगा।
इरुकोक

/etc/bashrcRedhat के लिए उपयोग , /etc/bash.bashrcऊपर बताए अनुसार (For Ubuntu)
जॉर्डन जीई

मैंने सेंट के लिए /root/.bashrc का उपयोग किया।
schmudu

RUN इको "source /yourscript.bash" >> /etc/bash.bashrc ट्रिक करता है। यदि आप docker के अंदर ros का उपयोग कर रहे हैं और पर्यावरण को स्थापित करना चाहते हैं तो आपको यही करना चाहिए
user27221

17

Https://docs.docker.com/engine/reference/builder/#run के अनुसार इसके लिए डिफ़ॉल्ट [लिनक्स] शेल RUNहै /bin/sh -c। आप बशीज़ की उम्मीद करते हैं, इसलिए आपको RUNअपने शेल को निर्दिष्ट करने के लिए "निष्पादन फ़ॉर्म" का उपयोग करना चाहिए ।

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

अन्यथा, RUN के "शेल फॉर्म" का उपयोग करके और अलग शेल के परिणामों को निर्दिष्ट करने के लिए नेस्टेड शेल हैं।

# 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"]

यदि आपके पास 1 से अधिक कमांड है जिसे एक अलग शेल की आवश्यकता है, तो आपको https://docs.docker.com/engine/reference/builder/#shell को पढ़ना चाहिए और अपने RUN कमांड से पहले इसे रखकर अपना डिफ़ॉल्ट शेल बदलना चाहिए :

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

अंत में, यदि आपने रूट उपयोगकर्ता की .bashrcफ़ाइल में कुछ भी रखा है, जिसकी आपको आवश्यकता है, तो आप -lध्वज को SHELLया RUNकमांड को एक लॉगिन शेल बनाने के लिए जोड़ सकते हैं और यह सुनिश्चित कर सकते हैं कि यह खट्टा हो जाता है।

नोट: मैंने जानबूझकर इस तथ्य को नजरअंदाज किया है कि यह एक स्क्रिप्ट को केवल RUN में एकमात्र कमांड के रूप में स्रोत के लिए व्यर्थ है।


SHELL ["/bin/sh", "-c", "-l"]तो यह स्रोत ~ / .bashrc आदि के मामले में आपके पास आधार कंटेनर से पर्यावरण सेटिंग है
मोर्टेनबी

1
@MortenB, लेकिन आपने (टाइपो?) निर्दिष्ट किया है, /bin/shजो उपयोग नहीं किए जा रहे बैश की समस्या को हल नहीं करेगा। इसके अलावा, जब docker buildयह संभव नहीं है कि रूट उपयोगकर्ता के .bashrc में कुछ भी उपयोगी होने वाला है जिसकी आपको आवश्यकता है। लेकिन, अगर आप पहले डॉकरीफाइल में कुछ वहां डालते हैं (जैसे कि शायद ए JAVA_HOME, तो हाँ। मैं अपने जवाब में इसके बारे में एक नोट
डालूंगा

टाइपो के लिए क्षमा करें, मैं pyenv का उपयोग कर रहा हूं जिसे मेरी आधार छवियों में सही अजगर संस्करण के लिए पथ निर्धारित करने के लिए ~ / .bashrc को स्रोत की आवश्यकता है। इससे मुझे जो कुछ भी linux बेस है उसका उपयोग करने और दो लाइनों के साथ अजगर पर कोई भी संस्करण जोड़ने की सुविधा मिलती है। Ubuntu16.04 पर अजगर 3.7 की तरह जहां बेस अजगर 3.5.2 है
मोर्टेनबी

11

डॉकर प्रलेखन के अनुसार

एक अलग शेल का उपयोग करने के लिए, '' बिन / श 'के अलावा, वांछित शेल में पास होने वाले निष्पादन फॉर्म का उपयोग करें। उदाहरण के लिए,

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

Https://docs.docker.com/engine/reference/builder/#run देखें


यह वास्तविक सही उत्तर है। चयनित उत्तर के लेखक stackoverflow.com/a/25086628/117471 को लगता है कि इस लिंक से जुड़े दस्तावेज़ में केवल पहला उदाहरण पढ़ा है। उन्हें लगता है कि आपने जो अगला पैराग्राफ पढ़ा है, वह आपके द्वारा उद्धृत किया गया है।
ब्रूनो ब्रोंस्की

4

यदि आपके पास SHELLउपलब्ध है तो आपको इस उत्तर के साथ जाना चाहिए - स्वीकार किए गए एक का उपयोग करें, जो आपको इस टिप्पणी के अनुसार बाकी डॉकटराइल को एक कमांड में रखने के लिए मजबूर करता है ।

यदि आप एक पुराने डॉकर संस्करण का उपयोग कर रहे हैं और उस तक पहुंच नहीं है SHELL, तो यह तब तक काम करेगा जब तक आपको कुछ भी करने की आवश्यकता न हो .bashrc(जो डॉकफाइल्स में एक दुर्लभ मामला है):

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

ध्यान दें कि -ibash को rcfile को बिल्कुल पढ़ने के लिए आवश्यक है।


3

आप यह देखने के लिए दौड़ bash -vसकते हैं कि क्या खट्टा हो रहा है।

मैं सिमिलिंक के साथ खेलने के बजाय निम्नलिखित कार्य करूंगा:

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


3

मेरे पास sourceडॉकफ़िले में चलने के मुद्दे भी थे

सेंटोस 6.6 डॉकटर कंटेनर के निर्माण के लिए यह पूरी तरह से ठीक है, लेकिन डेबियन कंटेनरों में मुद्दे दिए गए हैं

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

इस तरह से मैंने इसे निपटाया, यह एक सुंदर तरीका नहीं हो सकता है लेकिन यह मेरे लिए काम कर रहा है

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

2

यह हो सकता है क्योंकि sourceफाइलसिस्टम पर कहीं न कहीं बाइनरी के बजाय बिल्ट-इन बैश है। क्या आप उस स्क्रिप्ट के लिए अपना इरादा रखते हैं जिसे आप कंटेनर को बदलने के लिए सोर्स कर रहे हैं?


1
स्क्रिप्ट कंटेनर को अपडेट करती है - लेकिन ईमानदार होने के लिए मैं कुछ ऐसा करने की कोशिश कर रहा था जिसका कोई मतलब नहीं था, इसलिए इस मुद्दे को दरकिनार कर दिया।
ह्यूगो रॉजर-ब्राउन

1

मैंने अपना env सामान अंदर डाला .profileऔर SHELLकुछ ऐसा परिवर्तन किया

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
"-सी" के लिए अंतिम तर्क (कमांड करने से पहले निष्पादित किया जाना चाहिए)
पीटर

0

अगर आप बस virtualenv में कुछ स्थापित करने के लिए पाइप का उपयोग करने की कोशिश कर रहे हैं, तो आप पहले virtualenv के बिन फ़ोल्डर में देखने के लिए PATH env को संशोधित कर सकते हैं

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

फिर pip installDockerfile में अनुसरण करने वाली कोई भी कमांड पहले / path / to / venv / bin / pip को खोजेगी और उसका उपयोग करेगी, जो उस virtualenv में इंस्टॉल हो जाएगा न कि सिस्टम अजगर।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.