Что не так с этим утверждением Dockerfile? Какой из них я должен использовать? - PullRequest
0 голосов
/ 20 января 2019

Если я хочу запустить, например, wget, в файле Docker, я могу напечатать это:

RUN wget http://example.com

Если я хочу выполнить команду echo, я мог бы сделать это

RUN echo 'Hello' >> /home/file.text

Но я также видел это:

RUN bash -c 'echo $USERNAME:ros | chpasswd'

Если я хочу запустить скрипт оболочки, я мог бы сделать это

RUN 'bash ./install_foo.sh'

Мне также рекомендовали это:

RUN . /home/ros/.bashrc

Я думаю, что есть несколько недопустимых примеров выше, а другие имеют слегка различающуюся семантику.Я хотел бы

  1. Понять это, чтобы я мог выучить
  2. Как правильно использовать, когда я хочу запустить скрипт оболочки

1 Ответ

0 голосов
/ 20 января 2019

Вот мозговая свалка связанных однострочных ответов:

  • Каждая команда RUN запускает новую оболочку (даже в новом контейнере) с новой чистой средой и не читает никаких файлов точек. RUN export ... и RUN . ... - это запретные операции, которые не будут влиять на последующие шаги.

  • Многие стандартные пути Docker (например, docker run ... some command) вообще не включают оболочку, поэтому, если вы создадите файл .bashrc или .profile, он будет проигнорирован во многих распространенных случаях.

  • Без кавычек RUN some command, CMD some command и ENTRYPOINT some command - все автоматически заключены в sh -c '...', и вам, по сути, никогда не требуется говорить это явно. (В случае ENTRYPOINT использование формы без кавычек, вероятно, является ошибкой.) Такие формы, как CMD ["some", "command"], неявным образом не включают оболочку (и не расширяют переменные среды).

  • У GNU bash есть несколько расширений поставщиков, которые, к сожалению, широко используются; Альпийские базовые изображения не включают bash. В частности, никогда не говорите source, когда . входит в стандарт и делает то же самое.

  • Если вы устанавливаете программное обеспечение в образе, ваш лучший выбор - установить его в «системном» месте (pip install без активной виртуальной среды, npm install -g, ./configure --prefix=/usr/local); если вам необходимо установить его где-то еще, используйте директиву Dockerfile ENV, чтобы установить любые необходимые переменные среды; и если вы не можете сделать это, сценарий оболочки ENTRYPOINT может программно установить среду для основного процесса (но не любые оболочки docker exec).

  • Как правило, ./foo.sh запускает сценарий оболочки (при условии, что он исполняемый и начинается со строки #!/bin/sh); bash foo.sh тоже будет (но не требует, чтобы он был исполняемым, и явно указывает, какую оболочку использовать); и . ./foo.sh запускает его в контексте текущей оболочки (например, только эта форма может изменять переменные среды).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...