'উত্স' দিয়ে একটি ডকফাইলে 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
যা, এটি সম্পর্কে চিন্তা করা, সঠিক। ভার্চুয়ালেনভ্রাপার সম্ভবত ধারক পরিবেশে কোনও ধারণা রাখে না। আমি এটির পিছনে ফিরে যাচ্ছি এবং পরিবর্তে 'নেটিভ' ভার্চুয়ালেনভ ব্যবহার করব।
হুগো রজার-ব্রাউন


চেষ্টা করুনCMD source activate django-py35
বেলটার

উত্তর:


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/references/builder/#run পড়ুন এবং দ্বিতীয় কোডের নমুনার পরে থামবেন না। নোট পড়ুন : অবিলম্বে নিম্নলিখিত। কারণ /bin/sh -cডিফল্ট শেল, RUN এর এই "শেল ফর্ম" অনুবাদ করে RUN ["/bin/sh", "-c", "/bin/bash" "-c" "source /usr/local/bin/virtualenvwrapper.sh"]। আপনার এগিয়ে যাওয়া উচিত এবং আর shRUN ["/bin/bash" "-c" "source /usr/local/bin/virtualenvwrapper.sh"]
ইউএন এর "এক্সিকিউট

8
এটি কেন একটি নেস্টেড তৈরি করে এবং তাই এড়ানো উচিত এই বিষয়টি বুঝতে দয়া করে stackoverflow.com/a/45087082/117471 দেখুন see bashsh
ব্রুনো ব্রোনোস্কি

4
: একটি অনেক ভালো উত্তর এখানে stackoverflow.com/a/42216046/1663462
ক্রিস Stryczynski

150

আসল উত্তর

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

এটি প্রতিটি উবুন্টু ডকার বেস চিত্রের জন্য কাজ করা উচিত। আমি সাধারণত লিখি প্রতিটি ডকফাইফাইলের জন্য এই লাইনটি যুক্ত করি।

কোনও সংশ্লিষ্ট বাইস্ট্যান্ডার সম্পাদনা করুন

আপনি "ব্যবহারের প্রভাব পেতে চান bashপরিবর্তে shছাড়াই এই সমগ্র Dockerfile সর্বত্র" পরিবর্তনকারী এবং সম্ভবত ক্ষতিকর * ধারক ভিতরে ওএস, আপনি শুধু পারেন Docker আপনার উদ্দেশ্য বলতে । এটি যেমন করা হয়:

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

* সম্ভাব্য ক্ষতিটি হ'ল লিনাক্সের অনেকগুলি স্ক্রিপ্ট (নতুন উবুন্টু ইনস্টলের grep -rHInE '/bin/sh' /উপর 2700 ফলাফলের চেয়ে বেশি ফলাফল দেয়) এ সম্পূর্ণ পসিক্স শেল প্রত্যাশা করে /bin/sh। ব্যাশ শেলটি কেবল পসিক্স প্লাস অতিরিক্ত বিল্টিন নয়। এমন বিল্টিনগুলি রয়েছে (এবং আরও অনেকগুলি) যা পসিক্সের চেয়ে সম্পূর্ণ আলাদা আচরণ করে। আমি পসিক্স এড়িয়ে চলার সম্পূর্ণ সমর্থন করি (এবং অন্য শেলের উপর আপনি যে স্ক্রিপ্ট পরীক্ষা করেন নি সেই ফলকটি কাজ করছে কারণ আপনি মনে করেন যে আপনি বেসমিজম এড়িয়ে গেছেন) এবং কেবল বাশিজম ব্যবহার করে using তবে আপনি এটি আপনার স্ক্রিপ্টে সঠিক শেবাং দিয়ে করেন। পুরো ওএসের নীচে থেকে পসিক্স শেলটি বাইরে না নিয়ে। (লিনাক্সের সাথে আসা সমস্ত 2700 প্লাস স্ক্রিপ্টগুলি যাচাই করার সময় না থাকলে আপনি যে কোনও প্যাকেজ ইনস্টল করেন))

নীচে এই উত্তর আরও বিশদ। https://stackoverflow.com/a/45087082/117471


18
এই একটি সামান্য বিট সরলীকৃত করা যেতে পারেln -snf /bin/bash /bin/sh
apottere

2
@ ব্যবহারকারী 1442219 এটি ডিফল্ট কমান্ড ইন্টারপ্রেটার থেকে পরিবর্তিত shকরেbash
ভার্গব নানেকালভা

27
ln -s /bin/bash /bin/shএটি একটি ভয়ানক ধারণা। উবুন্টু কোনও কারণে ড্যাশ করতে / বিন / শ টার্গেট করে। ড্যাশ হ'ল একটি সম্পূর্ণ প্যাসিক্স শেল যা বাশের চেয়ে দ্রুততর আকারের আদেশ। বাশকে / বিন / শ সংযোগ স্থাপন আপনার সার্ভারের কার্যকারিতা মারাত্মকভাবে হ্রাস করবে। cite: wiki.ubuntu.com/DashAsBinSh
xero

7
এটি একটি নোংরা হ্যাক, কোনও সমাধান নয়। যদি আপনার স্ক্রিপ্টটি shশেল দ্বারা চালিত হয় , তবে আপনি চান bashতবে সঠিক সমাধানটি হয় shপ্রক্রিয়াটিকে bashএক-বন্ধ হিসাবে ডাকা হয়, উদাহরণস্বরূপ bash -c 'source /script.sh && …', বা আপনি এমনকি বাশিজম (যেমন source) সম্পূর্ণরূপে এড়াতে এতদূর যেতে পারেন , এবং পরিবর্তে কেবলমাত্র বৈধ পসিক্স সমতুল্য ব্যবহারের বিকল্প বেছে নিন, যেমন . /script.sh। (স্থান পরে মনে মনে. !) শেষ অবধি, যদি আপনার স্ক্রিপ্টটি এক্সিকিউটেবল হয় (কেবল উত্সযোগ্য নয়), আপনার স্ক্রিপ্টটি কখন শেবাংয়ের সাথে মিথ্যা বলবেন #!/bin/shনা যদি তা আসলে শ-সামঞ্জস্যপূর্ণ না হয়। #!/bin/bashপরিবর্তে ব্যবহার করুন।
মার্ক জি।

7
এবং এখন আমি কীভাবে মূল উত্তরটিকে নীচে নামবো এবং 'কোনও সংশ্লিষ্ট' দ্বারা সম্পাদনাটিকে upvote করব?
স্লাভা

65

RUNনির্দেশের জন্য ডিফল্ট শেল ["/bin/sh", "-c"]

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

শেল নির্দেশ ব্যবহার করে RUNআপনি ডকফাইফিলের পরবর্তী নির্দেশাবলীর জন্য ডিফল্ট শেল পরিবর্তন করতে পারেন :

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

এখন, ডিফল্ট শেল পরিবর্তিত হয়েছে এবং আপনার প্রতিটি আরএন নির্দেশে স্পষ্টভাবে এটি সংজ্ঞায়িত করার দরকার নেই

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

অতিরিক্ত দ্রষ্টব্য : আপনি এমন --loginবিকল্প যুক্ত করতে পারেন যা লগইন শেলটি শুরু করবে। এর অর্থ ~/.bachrcউদাহরণস্বরূপ পড়তে হবে এবং আপনার কমান্ডের আগে আপনাকে এটি স্পষ্টভাবে উত্সের প্রয়োজন হবে না


1
ব্যবহারের ক্ষেত্রে দুর্দান্ত পয়েন্টার --login- এই বিষয়টি নিজেই আবিষ্কার করলেন
ম্যাটটেক্স ২

ব্যবহার করে SHELL ["/bin/bash", "-c", "-l"] আমি .bashrc ফাইলে আরও আপডেটগুলি ব্যবহার করতে সক্ষম হয়েছি, যা আমাকে এসিডেফ কমান্ডগুলি সহজে চালানোর অনুমতি দেয়।
রোভিনসন গাল্লেগো

46

আমারও একই সমস্যা ছিল এবং ভার্চুয়ালেনভের ভিতরে পাইপ ইনস্টল করার জন্য আমাকে এই কমান্ডটি ব্যবহার করতে হয়েছিল:

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"

আমি আসা করি এটা সাহায্য করবে.


আপনি যদি আরওএসের উত্তর থেকে এসেছেন তবে হ্যাঁ এটি কার্যকর হয়। এর মতো কিছু: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

সহজ উপায় হ'ল উত্সের জায়গায় ডট অপারেটর ব্যবহার করা, যা বাশ sourceকমান্ডের শ সমতুল্য :

পরিবর্তে:

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

ব্যবহার করুন:

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

"উত্স হ'ল বোর্ন শেল বিল্টিন এবং একটি পসিক্স- বিশেষ ' বিল্টিন " - 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/references/builder/#/shell থেকে

SHELL ["executable", "parameters"]

শেল নির্দেশ আদেশের শেল ফর্মের জন্য ব্যবহৃত ডিফল্ট শেলকে ওভাররাইড করার অনুমতি দেয়। লিনাক্সের ডিফল্ট শেলটি হ'ল "" / বিন / শ "," -সি "], এবং উইন্ডোজে [" সেমিডি "," / এস "," / সি "] রয়েছে। শেল নির্দেশটি অবশ্যই ডকফাইফাইলে জেএসএন আকারে লিখতে হবে।

শেল নির্দেশিকাটি উইন্ডোজটিতে বিশেষত কার্যকর যেখানে দুটি ব্যবহৃত এবং বেশ আলাদা আলাদা নেটিভ শেল রয়েছে: সেমিডি এবং পাওয়ারশেল, পাশাপাশি এসএইচ সহ বিকল্প শেলগুলি উপলভ্য।

শেল নির্দেশটি একাধিকবার উপস্থিত হতে পারে। প্রতিটি শেল নির্দেশ পূর্ববর্তী সমস্ত শেল নির্দেশকে ওভাররাইড করে এবং পরবর্তী সমস্ত নির্দেশকে প্রভাবিত করে। উদাহরণ স্বরূপ:

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

নিম্নলিখিত নির্দেশাবলী শেল নির্দেশ দ্বারা প্রভাবিত হতে পারে যখন সেগুলির শেল ফর্মটি ডকফাইফিলে ব্যবহৃত হয়: রান, সিএমডি এবং ENTRYPOINT।

নিম্নলিখিত উদাহরণটি উইন্ডোজে পাওয়া একটি সাধারণ প্যাটার্ন যা শেল নির্দেশ ব্যবহার করে প্রবাহিত করা যেতে পারে:

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

ডকার দ্বারা চালিত আদেশটি হ'ল:

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

এটি দুটি কারণে অকার্যকর। প্রথমত, একটি অপ্রয়োজনীয় cmd.exe কমান্ড প্রসেসর (ওরফে শেল) চালু করা হচ্ছে। দ্বিতীয়ত, শেল ফর্মের প্রতিটি আরএনইউ নির্দেশের জন্য একটি অতিরিক্ত পাওয়ারশেল-কমান্ডের পূর্বনির্ধারণের প্রয়োজন হয়।

এটিকে আরও দক্ষ করার জন্য, দুটি পদ্ধতির মধ্যে একটিরও কাজে লাগানো যেতে পারে। একটি হ'ল রুন কমান্ডের 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>

শেল নির্দেশটি শেল যেভাবে চালিত হয় তা সংশোধন করতেও ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, উইন্ডোজে শেল সিএমডি / এস / সি / ভি: অন | অফ ব্যবহার করে, বিলম্বিত পরিবেশের পরিবর্তনশীল সম্প্রসারণ শব্দার্থকে পরিবর্তন করা যেতে পারে।

একটি বিকল্প শেল যেমন zsh, csh, tcsh এবং অন্যান্য প্রয়োজন হলে লিনাক্সেও শেল নির্দেশ ব্যবহার করা যেতে পারে।

শেল বৈশিষ্ট্যটি ডকার 1.12 এ যুক্ত করা হয়েছে।


20

এই পৃষ্ঠায় উত্তরের ভিত্তিতে আমি যুক্ত করব যে আপনার প্রতিটি সচেতন বিবৃতিটি অন্যদের সাথে স্বতন্ত্রভাবে চলে of /bin/sh -c এবং তাই কোনও পরিবেশের ভার পাবেন না যা সাধারণত লগইন শেলগুলিতে উত্সাহিত হয়।

আমি এখন পর্যন্ত সবচেয়ে ভাল উপায়টি খুঁজে পেয়েছি হ'ল স্ক্রিপ্টটি যুক্ত করা /etc/bash.bashrcএবং তারপরে প্রতিটি কমান্ডকে বাশ লগইন হিসাবে প্রার্থনা করা।

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

উদাহরণস্বরূপ, আপনি ভার্চুয়ালএনভ্রাপার ইনস্টল ও সেটআপ করতে পারেন, ভার্চুয়াল এনভিভি তৈরি করতে পারেন, আপনি যখন ব্যাশ লগইন ব্যবহার করেন তখন এটি সক্রিয় করতে এবং তারপরে আপনার পাইথন মডিউলগুলি এই এনভিটিতে ইনস্টল করতে পারেন:

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' যদি কারও ব্যবহারের ক্ষেত্রে আমার মতো পরিবেশের ভেরিয়েবলকে ডেকার তৈরি করার জন্য আরও কিছু যুক্ত করা হয় তবে আমি ডকস.ডকার / কমপোজ / জিম এ একবার দেখার পরামর্শ দিই did / # এনভী-ফাইলও
daniel.kahlenberg 10

1
আমি বিশ্বাস করি এটির সাথে সমস্যাটি হ'ল আপনি প্রতিটি ফলাফলের ক্যাশে শেষ করবেন না RUN কমান্ডের , যার অর্থ আপনি প্রকল্পের সম্পূর্ণ নির্ভরতা ইনস্টল করতে পারবেন না এবং উত্স কোডের উপর অনুলিপি করতে পারবেন না এবং এর সুবিধাগুলি গ্রহণ করতে পারবেন ডকারের মধ্যবর্তী পদক্ষেপে ক্যাচিং। এটি প্রতিবার সমস্ত প্রকল্প নির্ভরতা পুনরায় ইনস্টল করবে।
এরেকো

/etc/bashrcপরিবর্তে, রেডহ্যাটের জন্য ব্যবহার করুন/etc/bash.bashrcউপরে বর্ণিত (উবুন্টুর জন্য)
জর্দান জি

আমি সেন্টোসের জন্য /root/.Bashrc ব্যবহার করেছি।
schmudu

RUN প্রতিধ্বনি "উত্স /yourscript.bash" >> /etc/bash.bashrc কৌশলটি করে। আপনি যদি ডকারের ভিতরে রস ব্যবহার করছেন এবং পরিবেশ স্থাপন করতে চান তবে আপনার যা করা উচিত তা হল
user27221

17

Https://docs.docker.com/engine/references/builder/#r অনুযায়ী ডিফল্ট [লিনাক্স] শেলটি RUNরয়েছে /bin/sh -c। আপনি বাশিজমের প্রত্যাশা করছেন বলে মনে হচ্ছে, সুতরাং RUNআপনার শেলটি নির্দিষ্ট করার জন্য আপনার "এক্সিকিউট ফর্ম" ব্যবহার করা উচিত ।

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

অন্যথায়, আরুনের "শেল ফর্ম" ব্যবহার করে এবং নেস্টেড শেলগুলির জন্য আলাদা শেলের ফলাফল নির্দিষ্ট করে।

# 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/references/builder/#shell পড়তে হবে এবং আপনার RUN কমান্ডের আগে এটি রেখে ডিফল্ট শেলটি পরিবর্তন করা উচিত :

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

অবশেষে, আপনি যদি রুট ব্যবহারকারীর কিছু রেখেছি .bashrcযে ফাইলটি, আপনি যোগ করতে পারেন -lপতাকা SHELLবাRUN লগইন শেল তৈরির জন্য কমান্ডের সাথে যুক্ত করতে পারেন এবং নিশ্চিত হয়ে যায় যে এটি উত্সাহিত হয়েছে।

দ্রষ্টব্য: আমি ইচ্ছাকৃতভাবে এড়িয়ে গিয়েছি যে এটি কোনও রুনে একমাত্র কমান্ড হিসাবে কোনও স্ক্রিপ্ট উত্সাহ দেওয়া অর্থহীন।


SHELL ["/bin/sh", "-c", "-l"]সুতরাং এটি বেস কনটেইনার থেকে আপনার পরিবেশ সেটিংসের ক্ষেত্রে। / .bashrc ইত্যাদির উত্স
মর্টেনবি

1
@ মর্টেনবি, তবে আপনি নির্দিষ্ট করেছেন (টাইপড?) /bin/shযা ব্যাশ ব্যবহার না করার সমস্যার সমাধান করবে না। এছাড়াও, এটি করার সময় docker buildএটির সম্ভাব্যতা নেই যে আপনার ব্যবহারকারীর .bashrc এর মূল ব্যবহারকারীর জন্য দরকারী কিছু আছে। তবে, আপনি যদি আগে ডকফাইলে কিছু রেখেছিলেন (যেমন একটি হতে পারে JAVA_HOMEতবে হ্যাঁ। আমি আমার উত্তরে এটি সম্পর্কে একটি নোট রেখে দেব
ব্রুনো ব্রোনসকি

টাইপোর জন্য দুঃখিত, আমি পাইয়নভ ব্যবহার করছি যা আমার বেস ইমেজগুলিতে সঠিক পাইথন সংস্করণের জন্য পাথ সেট করতে ~ / .bashrc উত্সের প্রয়োজন। এটি আমাকে লিনাক্স বেস যেখানেই আছে তা ব্যবহার করতে এবং দুটি লাইন দিয়ে পাইথনে কোনও সংস্করণ যুক্ত করে। উবুন্টু ১.0.০৪-তে পাইথনটির মতো where.7 যেখানে বেস
পাইথনটি ৩.৩.২

11

ডকার ডকুমেন্টেশন অনুসারে

'/ Bin / sh' ব্যতীত অন্য কোনও শেল ব্যবহার করতে পছন্দসই শেলটিতে পাস করে এক্সিকিউর ফর্মটি ব্যবহার করুন। উদাহরণ স্বরূপ,

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

Https://docs.docker.com/engine/references/builder/#run দেখুন


এটি সত্যিকারের সঠিক উত্তর। নির্বাচিত উত্তর stackoverflow.com/a/25086628/117471 এর লেখক মনে হচ্ছে আপনার লিঙ্ক করা ডকুমেন্টেশনের মধ্যে কেবল প্রথম উদাহরণটি পড়েছেন। তারা মনে হয় না যে পরের অনুচ্ছেদটি পড়েছেন যা আপনি উদ্ধৃত করেছেন।
ব্রুনো ব্রোনোস্কি

4

আপনার যদি SHELLউপলভ্য থাকে তবে আপনার এই উত্তরটি নিয়ে যাওয়া উচিত - স্বীকৃত উত্তরটি ব্যবহার করবেন না , যা আপনাকে এই মন্তব্যটির জন্য বাকী ডকস্পাইলকে একটি কমান্ডে রাখতে বাধ্য করে

আপনি যদি কোনও পুরানো ডকার সংস্করণ ব্যবহার করে থাকেন এবং এতে অ্যাক্সেস না রাখেন তবে এটি SHELLএতক্ষণ কাজ করবে যেহেতু আপনার কোনও কিছুর প্রয়োজন নেই .bashrc(যা ডকফায়াইলগুলিতে বিরল ঘটনা):

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

-iবাশকে একেবারে আরসিফাইলটি পড়ার জন্য প্রয়োজনীয়টি নোট করুন ।


3

আপনি চালাতে চান bash -vকী উত্সাহিত হচ্ছে তা দেখতে ।

আমি সিমলিংকগুলি না খোলার পরিবর্তে নিম্নলিখিতটি করব:

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


3

দৌড়ানোর ক্ষেত্রে আমারও সমস্যা ছিল sourceডকফাইফিলে ক্ষেত্রে আমারও

এটি CentOS 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
স্ক্রিপ্টটি ধারকটিকে আপডেট করে - তবে সত্য কথা বলতে আমি এমন কিছু করার চেষ্টা করছিলাম যা কোনও অর্থহীন হয়নি, তাই সমস্যাটিকে বাইপাস করে ফেলেছি।
হুগো রজার-ব্রাউন 16

1

আমি আমার এনভির স্টাফগুলি inুকিয়ে শেষ করেছি .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

আপনি যদি কেবল ভার্চুয়ালেনভের মধ্যে কিছু ইনস্টল করার জন্য পিপ ব্যবহার করার চেষ্টা করছেন তবে প্রথমে ভার্চুয়ালেনভের বিন ফোল্ডারটি সন্ধান করার জন্য আপনি PATH env পরিবর্তন করতে পারেন

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

তারপরে pip installডকফাইফিলের অনুসরণকারী যে কোনও কমান্ড প্রথমে / পাথ / টু / ভেন্ট / বিন / পাইপ খুঁজে পাবে এবং এটি ব্যবহার করবে, যা সিস্টেমটি পাইথন নয় বরং সেই ভার্চুয়ালেনভের মধ্যে ইনস্টল করবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.