bash 스크립트를 실행하는 도커 진입 점이 "권한이 거부되었습니다"


122

내 node.js 앱을 Dockerize하려고합니다. 컨테이너가 빌드되면 a를 실행 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. 내 bash 스크립트에 잘못된 구문이 있습니까?

  2. 이미지에 추가하기 전에 bash 파일의 권한을 어떻게 변경합니까?

  3. bash 스크립트를 사용하지 않고 진입 점에서 여러 git 명령을 실행하는 가장 좋은 방법은 무엇입니까?

감사.


이 질문에 답하려면 파일 권한을 확인해야합니다.
Charles Duffy

BTW, 이것이 sh 스크립트가 아닌 bash 스크립트 인 경우 확장은 어떤 인터프리터가 실행할 수 있는지에 대해 잘못된 인상을 남깁니다. 이를 제거하는 것을 고려할 수 있습니다. UNIX 명령에 확장자가있는 것은 일반적이지 않습니다 ( 예를 들어를 실행하지 않음 ). .shls.elf
Charles Duffy

우리가 할 수있는 execa는 그런 식으로 쉘? bash접두사 가 필요하지 않을 것 입니다.
Jean-François Fabre

@ Jean-FrançoisFabre, 질문이 정확히 무엇을 의미합니까? ( "exec a shell that"이 의미하는 바를 이해하지 못합니다-이 문맥에서 "저것"이 무엇입니까?)
Charles Duffy

2
그런데 어리석은 질문은 이미지에 스크립트 를 추가 하기 전에 스크립트의 권한이 정확 합니까?
Charles Duffy

답변:


184
  1. "Permission denied"는 스크립트가 전혀 호출되지 않도록합니다 . 따라서, 가능하게 관련 될 수있는 유일한 구문은 처음과 같아야 라인 (이하 "오두막")의 것입니다 #!/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를 사용해야합니다. 하지만 bash 스크립트를 복사 한 후에도 권한을 변경해야하는 것 같습니다.
Calvin Hu

명령을 기반으로 .bash 스크립트를 만든 다음 완료되면 제거하는 phar 파일이 있습니다. 따라서 공유 볼륨에 실행 권한 세트가 있어야한다는 점은 제가 여전히 고민하고있는 부분입니다.
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.shtzhe 호스트에서 .NET Framework를 변경하는 것보다 훨씬 간단하기 때문에 실제로 권장되는 솔루션 Dockerfile입니다.
jotrocken

16

나는 같은 문제에 직면했고

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

원래 질문의 Dockerfile의 경우 다음과 같아야합니다.

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

5
이것은 해결 방법이지만 훌륭한 방법은 아닙니다. 이것은 shshebang의 인터프리터 사양을 무시하고 스크립트 를로 해석합니다. 그것은 사용 그렇다면 #!/bin/bash무시되고 그것을 해석됩니다 즉, 그것은 bash는 해석되고 싶어 말하고, sh따라서 같은 언어 기능을 허용하지, 대신 [[ ]]등, 배열,
찰스 더피를

나는 당신의 접근 방식을 사용했으며 효과가 있습니다. 아마도 dos2unix가 트릭을 수행합니다
Wakan Tanka

1

DockerFile을 사용 하지 않는 경우 간단히 bash의 명령 줄 인수로 권한을 추가 할 수 있습니다.

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

1

이것은 내 답변 2 년 전에 묻는 오래된 질문입니다. 어쨌든 저에게 도움이 된 것을 게시 할 것입니다.

내 작업 디렉토리에는 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.sh한 다음 실행 하여 도커 컨테이너의 파일을 실행 가능하게 만들 수있었습니다 docker build ..

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.