बैश स्क्रिप्ट चलाने वाले एंट्रीपॉइंट को "अनुमति से वंचित" कर दिया जाता है


122

मैं अपना नोड.जेएस ऐप डॉकटराइज करने की कोशिश कर रहा हूं। जब कंटेनर बनाया जाता है तो मैं चाहता हूं कि यह एक git cloneऔर फिर नोड सर्वर शुरू करे। इसलिए मैंने इन ऑपरेशनों को एक .sh स्क्रिप्ट में रखा। और स्क्रिप्ट को ENTRYPOINT में एकल कमांड के रूप में चलाएं:

FROM ubuntu:14.04

RUN apt-get update && apt-get install -y build-essential libssl-dev gcc curl npm git

#install gcc 4.9
RUN apt-get install -y software-properties-common python-software-properties
RUN add-apt-repository -y ppa:ubuntu-toolchain-r/test
RUN apt-get update
RUN apt-get install -y libstdc++-4.9-dev

#install newst nodejs
RUN curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
RUN apt-get install -y nodejs

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ADD package.json /usr/src/app/
RUN npm install

ADD docker-entrypoint.sh /usr/src/app/

EXPOSE 8080

ENTRYPOINT ["/usr/src/app/docker-entrypoint.sh"] 

मेरा docker-entrypoint.sh इस तरह दिखता है:

git clone git@<repo>.git
git add remote upstream git@<upstream_repo>.git

/usr/bin/node server.js

इस छवि को बनाने और चलाने के बाद:

docker run --env NODE_ENV=development -p 8080:8080 -t -i <image>

मैं ला रहा हूँ:

docker: Error response from daemon: oci runtime error: exec: "/usr/src/app/docker-entrypoint.sh": permission denied.

मैंने कंटेनर में शेल किया है और docker-entrypoint.sh की अनुमति है:

-rw-r--r-- 1 root root 292 Aug 10 18:41 docker-entrypoint.sh

तीन प्रश्न:

  1. क्या मेरी बैश स्क्रिप्ट में गलत सिंटैक्स है?

  2. छवि में जोड़ने से पहले मैं किसी bash फ़ाइल की अनुमति कैसे बदल सकता हूँ?

  3. बैश स्क्रिप्ट का उपयोग किए बिना प्रविष्टि में कई गिट कमांड चलाने का सबसे अच्छा तरीका क्या है?

धन्यवाद।


हमें इस प्रश्न का उत्तर देने में सक्षम होने के लिए फ़ाइल अनुमतियों को देखने की आवश्यकता है।
चार्ल्स डफी

Btw, अगर यह एक है बैश स्क्रिप्ट, नहीं एक स्क्रिप्ट, एक .shविस्तार एक भ्रामक धारणा के बारे में जो दुभाषियों यह निष्पादित कर सकते हैं छोड़ देता है। आप इसे बाहर ले जाने पर विचार कर सकते हैं - यह UNIX आदेशों के विस्तार के लिए पारंपरिक नहीं है (आप ls.elfउदाहरण के लिए नहीं चलते हैं )।
चार्ल्स डफी

क्या हम execइस तरह से एक खोल दे सकते हैं ? यह bashउपसर्ग की जरूरत नहीं होगी ।
जीन फ़्राँस्वा Fabre

@ जीन-फ्रांस्वा फाबरे, आपके सवाल का वास्तव में क्या मतलब है? (मुझे समझ में नहीं आया कि "शेल को उस तरह से कैसे निष्पादित करें" का अर्थ है - इस संदर्भ में "ऐसा क्या है?"
चार्ल्स डफी

2
मूर्खतापूर्ण सवाल, वैसे - क्या स्क्रिप्ट की अनुमति सही है इससे पहले कि आप उन्हें छवि में जोड़ दें?
चार्ल्स डफी

जवाबों:


183
  1. "अनुमति अस्वीकृत" आपकी स्क्रिप्ट को बिल्कुल भी लागू होने से रोकता है । इस प्रकार, केवल वाक्य रचना कि संभवतः प्रासंगिक हो सकता है पहली पंक्ति ( "मामला"), जो की तरह दिखना चाहिए का है #!/usr/bin/env bash, या #!/bin/bash, या इसी तरह अपने लक्ष्य के फाइल सिस्टम लेआउट के आधार पर।

  2. सबसे अधिक संभावना है कि फ़ाइल सिस्टम अनुमतियों को निष्पादित करने की अनुमति नहीं दी जा रही है। यह भी संभव है कि शेबंग किसी ऐसी चीज का संदर्भ दे जो निष्पादन योग्य न हो, लेकिन इसकी संभावना बहुत कम है।

  3. पूर्व के मुद्दों की मरम्मत में आसानी से लूटा गया।


का सरल पठन

docker: Error response from daemon: oci runtime error: exec: "/usr/src/app/docker-entrypoint.sh": permission denied.

... यह है कि स्क्रिप्ट निष्पादन योग्य चिह्नित नहीं है।

RUN ["chmod", "+x", "/usr/src/app/docker-entrypoint.sh"]

कंटेनर के भीतर इसे संबोधित करेंगे। वैकल्पिक रूप से, आप यह सुनिश्चित कर सकते हैं कि Dockerfile द्वारा संदर्भित स्थानीय प्रतिलिपि निष्पादन योग्य है , और फिर COPY(जिसे मेटाडेटा बनाए रखने के लिए स्पष्ट रूप से प्रलेखित किया गया है) का उपयोग करें।


मेरे विचार से आप सही है। मुझे इसके बजाय COPY का उपयोग करना चाहिए। लेकिन ऐसा लगता है कि मुझे अभी भी बैश स्क्रिप्ट कॉपी करने के बाद अनुमति बदलने की आवश्यकता है।
केल्विन हू

मेरे पास एक फ़ार फ़ाइल है जो एक कमांड के आधार पर .bash स्क्रिप्ट बनाती है और फिर एक बार पूरी होने के बाद उन्हें हटा देती है। तो साझा संस्करणों के लिए निष्पादन की अनुमति सेट की आवश्यकता कुछ ऐसा है जो मैं अभी भी संघर्ष कर रहा हूं।
रपी डे

@raupie, यदि आप noexecध्वज के साथ माउंट बिंदु से स्क्रिप्ट को चलाना चाहते हैं, तो bash yourscriptइसके बजाय चलाएँ ./yourscript
चार्ल्स डफी

1
मैं नहीं docker buildकरता हूँ, जब मैं imtermediate कंटेनर चलाता है ठीक काम करता है। लेकिन जब मैं करता हूं docker run, यह ऐसी त्रुटि फेंकता है। मुझे एक जादुई मध्यवर्ती कंटेनर जैसा लगता है।
टिआना

46

एक निष्पादन योग्य फ़ाइल को निष्पादित करने से पहले आपको सेट करने के लिए अनुमतियों की आवश्यकता होती है।

अपनी मशीन में जहां आप docker की छवि बना रहे हैं (docker की छवि के अंदर नहीं) स्वयं चलाने की कोशिश करें:

ls -la path/to/directory

आपके निष्पादन योग्य के लिए आउटपुट का पहला कॉलम (इस मामले में docker-entrypoint.sh) निष्पादन योग्य बिट्स के लिए कुछ होना चाहिए:

-rwxrwxr-x

यदि नहीं तो कोशिश करें:

chmod +x docker-entrypoint.sh

और फिर अपनी डॉकटर छवि फिर से बनाएं।

Docker इसका स्वयं का फ़ाइल सिस्टम उपयोग करता है, लेकिन यह स्रोत निर्देशिकाओं से सब कुछ (अनुमतियों बिट्स सहित) की प्रतिलिपि बनाता है।


13
chmod +x docker-entrypoint.shtzhe होस्ट पर वास्तव में अनुशंसित समाधान है, क्योंकि यह आपके बदलने की तुलना में बहुत सरल है Dockerfile
19

16

मैंने उसी मुद्दे का सामना किया और इसे हल किया

ENTRYPOINT ["sh", "/docker-entrypoint.sh"]

मूल प्रश्न में डॉकरफाइल के लिए यह इस प्रकार होना चाहिए:

ENTRYPOINT ["sh", "/usr/src/app/docker-entrypoint.sh"]

5
यह एक वर्कअराउंड है, लेकिन एक महान नहीं है - यह स्क्रिप्ट की व्याख्या shकरता है, एक इंटरप्रेटर के शेल्हांग के विनिर्देश को अनदेखा करता है; इसलिए यदि यह उपयोग करता है #!/bin/bash, तो यह कहना चाहता है कि इसे बैश के साथ व्याख्या किया जाना चाहिए, इसे अनदेखा किया जाएगा और इसकी व्याख्या shइसके साथ की जाएगी , इस प्रकार भाषा सुविधाओं को बंद करना [[ ]], सरणियाँ, आदि
चार्ल्स डफी

मैंने आपके दृष्टिकोण का उपयोग किया है और यह काम किया है। शायद dos2unix भी चाल करता है
टंका

1

यदि आप DockerFile का उपयोग नहीं करते हैं, तो आप बस बैश के कमांड लाइन तर्क के रूप में अनुमति जोड़ सकते हैं:

docker run -t <image>  /bin/bash -c "chmod +x /usr/src/app/docker-entrypoint.sh; /usr/src/app/docker-entrypoint.sh"

1

यह एक पुराना सवाल है जो मेरे उत्तर से दो साल पहले पूछा गया था, मैं पोस्ट करने जा रहा हूं जो मेरे लिए वैसे भी काम करता है।

मेरी कार्यशील निर्देशिका में मेरे पास दो फाइलें हैं: Dockerfile & प्रावधानों.sh

Dockerfile:

FROM centos:6.8

# put the script in the /root directory of the container
COPY provision.sh /root

# execute the script inside the container
RUN /root/provision.sh

EXPOSE 80

# Default command
CMD ["/bin/bash"]

provision.sh:

#!/usr/bin/env bash

yum upgrade

मैं कंटेनर के बाहर फ़ाइल को निष्पादन योग्य के रूप में फ़ाइल के निष्पादन योग्य बनाने में सक्षम था, chmod 700 provision.shफिर निष्पादन योग्य के रूप में कंटेनर के बाहर फ़ाइल को चलाकर docker build .

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