докер вхідної точки запуск сценарію bash отримує "дозвіл відхилено"


122

Я намагаюся докерізувати додаток node.js. Коли контейнер побудований, я хочу, щоб він запустив 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. Який найкращий спосіб запустити кілька команд git в точку входу, не використовуючи скрипт bash?

Дякую.


Нам потрібно переглянути дозволи для файлів, щоб мати можливість відповісти на це питання.
Чарльз Даффі

До речі, якщо це Баш скрипт, а НЕ ш скрипт, .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-скрипту.
Кальвін Ху

У мене є файл phar, який створює .bash скрипти на основі команди, а потім видаляє їх після їх завершення. Тому необхідність у спільних томах для встановлення дозволу на виконання - це те, з чим я все ще борюся.
raupie

@raupie, якщо ви хочете запустити сценарій з точки монтажу з noexecпрапором, запустіть bash yourscriptзамість ./yourscript.
Чарльз Даффі

1
Я не беруся, коли запускаю docker buildконтейнер з негайною роботою, працює добре. Але коли я це роблю docker run, це кидає таку помилку. Схоже, що у мене є чарівний проміжний контейнер.
Тіна

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

16

Я зіткнувся з тією ж проблемою, і це вирішило

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

Для Dockerfile в оригінальному запитанні він повинен бути таким:

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

5
Це вирішення, але не велике - це трактує сценарій sh, ігноруючи його шебангські характеристики перекладача; тож якщо він використовує #!/bin/bash, кажучи, що хоче інтерпретувати bash, це буде ігноруватися, і shзамість цього буде інтерпретовано , тим самим забороняючи такі мовні функції, як [[ ]]масиви тощо.
Чарльз Даффі

Я використав ваш підхід, і він спрацював. Можливо, також dos2unix робить трюк
Вакан Танка

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

Це старе запитання, задане за два роки до моєї відповіді, я все одно буду публікувати те, що працювало для мене.

У своєму робочому каталозі я маю два файли: Dockerfile & забезпеченість.sh

Докерфайл:

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

забезпеченість.sh:

#!/usr/bin/env bash

yum upgrade

Мені вдалося зробити файл у контейнері docker виконуваним, встановивши файл поза контейнером як виконуваний, chmod 700 provision.shа потім запустивши docker build ..

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.