จุดเข้านักเทียบท่าที่เรียกใช้สคริปต์ทุบตีได้รับ“ การอนุญาตถูกปฏิเสธ”


122

ฉันกำลังพยายามเทียบท่าแอป node.js เมื่อคอนเทนเนอร์ถูกสร้างขึ้นฉันต้องการให้มันรัน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. อะไรคือวิธีที่ดีที่สุดในการรันคำสั่ง git หลายคำสั่งในจุดเข้าโดยไม่ต้องใช้ bash script

ขอบคุณ


เราต้องดูสิทธิ์ของไฟล์จึงจะสามารถตอบคำถามนี้ได้
Charles Duffy

BTW หากนี่เป็นสคริปต์ทุบตีไม่ใช่สคริปต์sh.shส่วนขยายจะทำให้เกิดความเข้าใจผิดว่าล่ามใดสามารถดำเนินการได้ คุณอาจลองนำสิ่งนั้นออก - ไม่ใช่เรื่องธรรมดาสำหรับคำสั่ง UNIX ที่จะมีส่วนขยาย (เช่นคุณไม่ได้เรียกใช้ls.elf)
Charles Duffy

เราสามารถexecใช้เปลือกหอยแบบนั้นได้หรือไม่? มันไม่จำเป็นต้องมีbashคำนำหน้า
Jean-François Fabre

@ Jean-FrançoisFabreคำถามของคุณหมายถึงอะไร? (ฉันไม่เข้าใจว่า "exec a shell that way" แปลว่าอะไร - "วิธีนั้น" ในบริบทนี้คืออะไร)
Charles Duffy

2
คำถามโง่ ๆ - สิทธิ์ของสคริปต์ถูกต้องหรือไม่ก่อนที่คุณจะเพิ่มลงในภาพ
Charles Duffy

คำตอบ:


186
  1. "ไม่อนุญาต" ป้องกันไม่ให้สคริปต์ของคุณจากการถูกเรียกในทุก ดังนั้นไวยากรณ์เดียวที่อาจตรงประเด็นคือบรรทัดแรก ("shebang") ซึ่งควรมีลักษณะเหมือน#!/usr/bin/env bashหรือ#!/bin/bashหรือคล้ายกันขึ้นอยู่กับเค้าโครงระบบไฟล์ของเป้าหมายของคุณ

  2. เป็นไปได้มากว่าสิทธิ์ระบบไฟล์ไม่ได้ถูกตั้งค่าให้อนุญาตให้ดำเนินการได้ นอกจากนี้ยังเป็นไปได้ว่าบางสิ่งบางอย่างที่อ้างอิง shebang ที่ไม่ได้เป็นปฏิบัติการ แต่นี่คือไกลโอกาสน้อย

  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 แทน แต่ดูเหมือนว่าฉันยังคงต้องเปลี่ยนสิทธิ์หลังจากคัดลอกสคริปต์ทุบตี
Calvin Hu

ฉันมีไฟล์ phar ที่สร้างสคริปต์. bash ตามคำสั่งแล้วลบออกเมื่อเสร็จสิ้น ดังนั้นความจำเป็นในการแชร์ไดรฟ์ข้อมูลเพื่อตั้งค่าสิทธิ์ในการดำเนินการจึงเป็นสิ่งที่ฉันยังคงดิ้นรน
raupie

@raupie ถ้าคุณต้องการเรียกใช้สคริปต์จากจุดเชื่อมต่อที่มีnoexecแฟล็กให้รันbash yourscriptแทน./yourscript.
Charles Duffy

1
ฉันไม่ยอมรับเมื่อฉันเรียกใช้docker buildคอนเทนเนอร์ชั้นกลางก็ใช้ได้ดี แต่เมื่อฉันทำdocker runมันเกิดข้อผิดพลาดดังกล่าว ดูเหมือนว่าฉันมีภาชนะกลางวิเศษ
Tiina

46

ไฟล์ปฏิบัติการจำเป็นต้องมีสิทธิ์สำหรับการตั้งค่าก่อนที่จะดำเนินการได้

ในเครื่องของคุณที่คุณกำลังสร้างอิมเมจนักเทียบท่า (ไม่ใช่ในอิมเมจนักเทียบท่าเอง) ให้ลองรัน:

ls -la path/to/directory

คอลัมน์แรกของเอาต์พุตสำหรับไฟล์ปฏิบัติการของคุณ (ในกรณีนี้คือ docker-entrypoint.sh) ควรมีการตั้งค่าบิตที่เรียกใช้งานได้ดังนี้:

-rwxrwxr-x

ถ้าไม่ลอง:

chmod +x docker-entrypoint.sh

แล้วสร้างภาพนักเทียบท่าของคุณอีกครั้ง

Docker ใช้ระบบไฟล์ของตัวเอง แต่จะคัดลอกทุกอย่าง (รวมถึงบิตสิทธิ์) จากไดเรกทอรีต้นทาง


13
chmod +x docker-entrypoint.shบนโฮสต์เป็นวิธีการแก้ปัญหาที่แนะนำเนื่องจากง่ายกว่าการเปลี่ยนDockerfileไฟล์.
jotrocken

18

ฉันประสบปัญหาเดียวกันและได้รับการแก้ไขโดย

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

สำหรับ Dockerfile ในคำถามดั้งเดิมควรเป็นดังนี้:

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

5
นี่เป็นวิธีแก้ปัญหา แต่ไม่ใช่วิธีที่ดี - เป็นการตีความสคริปต์ด้วยshโดยไม่สนใจข้อกำหนดของล่ามของ Shebang ดังนั้นหากใช้#!/bin/bashโดยบอกว่าต้องการตีความด้วย bash สิ่งนั้นจะถูกละเว้นและจะถูกตีความด้วยshแทนดังนั้นจึงไม่อนุญาตให้ใช้คุณลักษณะภาษาเช่น[[ ]]อาร์เรย์ ฯลฯ
Charles Duffy

ฉันใช้แนวทางของคุณแล้วและได้ผล บางที dos2unix ก็ใช้เคล็ดลับ
Wakan Tanka

2

หากคุณไม่ได้ใช้ DockerFile คุณสามารถเพิ่มสิทธิ์เป็นอาร์กิวเมนต์บรรทัดคำสั่งของ bash:

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

1

นี่เป็นคำถามเก่าที่ถามเมื่อสองปีก่อนคำตอบของฉันฉันจะโพสต์สิ่งที่ได้ผลสำหรับฉันต่อไป

ในไดเร็กทอรีการทำงานของฉันฉันมีสองไฟล์: Dockerfile & Provision.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.shdocker build .

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.