docker: виконуваний файл не знайдений у $ PATH


216

У мене встановлено зображення докера, яке встановлюється grunt, але коли я намагаюся запустити його, з’являється помилка:

Error response from daemon: Cannot start container foo_1: \
    exec: "grunt serve": executable file not found in $PATH

Якщо я запускаю bash в інтерактивному режимі, gruntдоступний.

Що я роблю неправильно?

Ось мій Dockerfile:

# https://registry.hub.docker.com/u/dockerfile/nodejs/ (builds on ubuntu:14.04)
FROM dockerfile/nodejs

MAINTAINER My Name, me@email.com

ENV HOME /home/web
WORKDIR /home/web/site

RUN useradd web -d /home/web -s /bin/bash -m

RUN npm install -g grunt-cli
RUN npm install -g bower

RUN chown -R web:web /home/web
USER web

RUN git clone https://github.com/repo/site /home/web/site

RUN npm install
RUN bower install --config.interactive=false --allow-root

ENV NODE_ENV development

# Port 9000 for server
# Port 35729 for livereload
EXPOSE 9000 35729
CMD ["grunt"]

ви можете спробувати створити докер за допомогою CMD grunt? Або ви можете спробувати виконати команду бурчання, пройшовши повний шлях?
mgaido

@ Mark91 ласка , чи не могли б ви уточнити , що ви просите заново побудувати з допомогою CMD grunt?Do ви маєте в виду опускати ["і "]?
Стів Лоример,

Просто спробував - і це спрацювало - спасибі! Тож для всіх, хто заходить, перейдіть CMD ["grunt"]наCMD grunt
Стів Лоример

10
Це тому, що якщо ви CMD ["grunt"]використовуєте іншу оболонку для виконання команди, то в цій оболонці $ PATH, швидше за все, не буде встановлено.
mgaido

Відповіді:


198

Якщо ви використовуєте формат exec для команди (наприклад CMD ["grunt"], масив JSON з подвійними лапками), він буде виконуватися без оболонки. Це означає, що більшість змінних середовища не буде присутній.

Якщо ви вказали свою команду як звичайний рядок (наприклад CMD grunt), то рядок після CMDбуде виконуватися за допомогою /bin/sh -c.

Більш детальну інформацію про це можна отримати в розділі CMD у довідці про Dockerfile .


2
Це посилання на частину CMD посилання на docs.docker.com/engine/reference/builder/#cmd
Calvin

Вибачте це німе питання, але як можна виконати команду linux без оболонки? Що було б рівнозначно зробити це на машині Linux (не використовуючи докер)?
wisbucky

1
Щоб відповісти на моє власне запитання, це схоже на те, sudo setчи робити (exec set). Вони не зможуть, оскільки вони виконують команди без оболонки (і setце вбудована оболонка). Однак sudo lsі (exec ls)буде працювати, тому що lsце фактичний бінарний файл /bin/ls.
wisbucky

315

Це був перший результат в Google, коли я вставив повідомлення про помилку, і це тому, що мої аргументи вийшли з ладу.

Назва контейнера має бути після всіх аргументів.

Погано:

docker run <container_name> -v $(pwd):/src -it

Добре:

docker run -v $(pwd):/src -it <container_name>

132
Якщо ви завжди ретельно читали документацію, перш ніж почати кодування, ви ніколи нічого не зробите. Купуючи свій новий автомобіль, ви читали інструкцію на 200 сторінок, перш ніж їхати додому? Ні. І коли виникла проблема з вашим автомобілем, ви спочатку його гуглили, або ви отримали інструкцію? Це цілком розумно, я можу лише уявити всіх людей, які вважають це корисним, але не натиснули кнопку оновлення! Нерозумним є те, що ця абсолютно незв'язана відповідь є першим результатом google для цього повідомлення про помилку, або що кліп докер неінтуїтивний та невгамовний. Ура.
сарінк

8
У багатьох сценаріях порядок прапорів не важливий, тому я бачу, чому це може трапитися з будь-ким. Відповідь дуже корисна. Зайве говорити, що повідомлення про помилку від докера зовсім не корисне.
marios

9
Нічого собі, я б бився якийсь час, якби не ця відповідь. Чому UNIX вже не має стандартного, гнучкого та потужного аналізатора аргументів CLI? ...
lleaff

1
Це було проблемою для мене. Поставити назву контейнера наприкінці, здавалося, спрацювало
Роб Сегал

3
Мене ввели в оману прийнятою відповіддю, хотіли написати свою, але, здається, це вже є. Тож я можу підтвердити, що це вирішує проблему ...
Arturas M

24

Я знайшов ту саму проблему. Я зробив наступне:

docker run -ti devops -v /tmp:/tmp /bin/bash

Коли я його зміню на

docker run -ti -v /tmp:/tmp devops /bin/bash

це чудово працює.


1
Це працювало для мене людині, але я не розумію використання -vтут. -vце прив’язати гучність монтажу (як описано в docker run --help | grep "\-v"), для мене я вже /tmpвстановлений у File Sharing(налаштуваннях Докера), тож чому я повинен використовувати його знову?
Ахмад

12

Існує кілька можливих причин такої помилки.

У моєму випадку це було пов’язано з тим, що виконуваному файлу ( docker-entrypoint.shіз блогу Ghost Dockerfile ) відсутній режим виконуваного файлу після того, як я його завантажив.

Рішення: chmod +x docker-entrypoint.sh


Це коментар, який вказав мені на правильну відповідь. Мені довелося скопіювати файл, а потім chmod його.
позатеатром

7

Контейнер Docker може бути побудований без оболонки (наприклад, https://github.com/fluent/fluent-bit-docker-image/isissue/19 ).

У цьому випадку ви можете скопіювати статично складений оболонку та виконати його, наприклад

docker create --name temp-busybox busybox:1.31.0
docker cp temp-busybox:/bin/busybox busybox
docker cp busybox mycontainerid:/busybox
docker exec -it mycontainerid /bin/busybox sh

4

Чомусь я отримую цю помилку, якщо не додаю освітлювач "bash". Навіть додавання "#! / Bin / bash" у верхню частину мого файлу вхідної точки не допомогло.

ENTRYPOINT [ "bash", "entrypoint.sh" ]

@SteveLorimer, так. Я зробив COPYа потім RUN chmod +x /compile_nibbler.shдо дзвінка на вхідну точку.
за межітеолу

1

У мене була така ж проблема, Після багатьох гуглінгу я не міг дізнатися, як її виправити.

Раптом я помітив свою дурну помилку :)

Як зазначалося в документах , остання частина команди docker run- це команда, яку потрібно запустити, та її аргументи після завантаження контейнера.

НЕ ІМЯ КОНТЕЙНЕРА !!!

Це була моя бентежна помилка.

Нижче я надав вам зображення мого командного рядка, щоб побачити, що я зробив неправильно.

І це виправлення, як зазначено в документах .

введіть тут опис зображення


-7

щоб він працював, додайте м'які посилання на / usr / bin:

ln -s $ (який вузол) / usr / bin / node

ln -s $ (який npm) / usr / bin / npm


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