docker: исполняемый файл не найден в $ PATH

217

У меня есть образ докера, который устанавливает 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? Или вы можете попытаться выполнить команду grunt, пройдя полный путь?
Мгаидо
@ mark91 пожалуйста , не могли бы вы уточнить , что вы просите заново построить с помощью CMD grunt?Do вы имеете в виду опускать ["и "]?
Стив Лоример
Просто попробовал - и это сработало - спасибо! Так что для всех, кто придет, смените CMD ["grunt"]наCMD grunt
Стив Лоример
10
Это потому, что если вы CMD ["grunt"]используете другую оболочку для выполнения команды, то в этой оболочке $ PATH, скорее всего, не будет установлен.
Мгаидо
См. Также stackoverflow.com/q/48001082/798677
Этот бразильский парень

Ответы:

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 (не используя Docker)?
Висбуки
1
Чтобы ответить на мой собственный вопрос, это похоже на выполнение sudo setили (exec set). Те потерпят неудачу, потому что они выполняют команды без оболочки (и setявляется встроенной оболочкой). Тем не менее, sudo lsи (exec ls)будет работать, потому что lsэто фактический двоичный файл /bin/ls.
Висбуки
316

Это был первый результат в Google, когда я вставил свое сообщение об ошибке, и это потому, что мои аргументы были не в порядке.

Имя контейнера должно быть после всех аргументов.

Плохой:

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

Хорошо:

docker run -v $(pwd):/src -it <container_name>
sarink
источник
132
Если вы всегда внимательно читаете документацию до того, как начнете кодировать, вы ничего не сделаете. Когда вы купили свой новый автомобиль, читали ли вы руководство на 200 страниц, прежде чем отправиться домой? Нет. А когда возникла проблема с вашим автомобилем, вы сначала зашли в Google или получили руководство? Это совершенно разумно, я могу только представить всех людей, которые нашли это полезным, но не нажали кнопку upvote! Разумным является то, что этот совершенно не связанный ответ является первым результатом Google для этого сообщения об ошибке, или что докер Cli не интуитивен и не прощает. Приветствия.
Саринк
8
Во многих сценариях порядок флагов не важен, поэтому я понимаю, почему это может случиться с кем угодно. Ответ довольно полезен. Само собой разумеется, что сообщение об ошибке от докера вообще не полезно.
Marios
9
Вау, я бы боролся некоторое время, если бы не этот ответ. Почему в UNIX уже нет стандартного, гибкого и мощного синтаксического анализатора аргументов CLI? ...
lleaff
1
Это была проблема для меня. Поставить имя контейнера в конце, похоже, сработало
Роб Сигал
3
Я был введен в заблуждение принятым ответом, хотел написать свой, но, кажется, он уже здесь. Так что я могу подтвердить, что это решает проблему ...
Артурас М
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(настройках Docker), так почему я должен использовать его снова?
Ахмад
12

Есть несколько возможных причин такой ошибки.

В моем случае это произошло из-за того, что исполняемому файлу ( docker-entrypoint.shиз Dockerfile блога Ghost ) не хватало режима исполняемого файла после того, как я его скачал.

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

Бен Криси
источник
Это комментарий, который указал мне на правильный ответ. Я должен был скопировать файл и затем chmod его.
beyondtheteal
7

Контейнер Docker может быть построен без оболочки (например, https://github.com/fluent/fluent-bit-docker-image/issues/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
Gajus
источник
4

По какой-то причине я получаю эту ошибку, если я не добавляю осветлитель "bash". Даже добавление «#! / Bin / bash» в начало моего файла точки входа не помогло.

ENTRYPOINT [ "bash", "entrypoint.sh" ]
beyondtheteal
источник
@SteveLorimer, да. Я сделал, COPYа затем RUN chmod +x /compile_nibbler.shдо вызова точки входа.
beyondtheteal
1

У меня была такая же проблема. После долгих поисков я не мог найти, как это исправить.

Внезапно я заметил свою глупую ошибку :)

Как уже упоминалось в документации , последняя часть docker run- это команда, которую вы хотите выполнить, и ее аргументы после загрузки контейнера.

НЕ НАЗВАНИЕ КОНТЕЙНЕРА !!!

Это была моя неловкая ошибка.

Ниже я предоставил вам изображение моей командной строки, чтобы увидеть, что я сделал неправильно.

И это исправление, как упомянуто в документации .

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

парса
источник
-7

чтобы это работало, добавьте мягкую ссылку на / usr / bin:

ln -s $ (какой узел) / usr / bin / node

ln -s $ (который npm) / usr / bin / npm

vacavaca
источник
1
Пожалуйста, добавьте описание о том, как это поможет ему.
Мэтьюз Санни