Если вам когда-либо потребовалось выполнить одну или две команды в вашем контейнере Docker при запуске, этот учебник для вас. С использованием инструкций Dockerfile ENTRYPOINT
и CMD
вы можете запускать столько команд при запуске, сколько вам нужно.
В этом учебнике вы узнаете, как использовать инструкции ENTRYPOINT
и CMD
для выполнения команд при запуске в Dockerfile, а также поймете различия между ними.
Предварительные требования
Поскольку этот учебник предполагает практическую демонстрацию, убедитесь, что у вас есть следующее:
- A Windows 10 PC – Windows 10 v10.0.19042 was used in this tutorial.
- Docker Desktop – В этом учебнике используется Docker Desktop v3.3.1.
Создание Dockerfile
Прежде чем вы сможете выполнять команды запуска контейнера Docker, вам необходимо создать Dockerfile. Dockerfile – это текстовый документ, который содержит список команд для создания контейнеров, образов Docker, и определяет, как создается образ Docker.
1. Во-первых, откройте PowerShell от имени администратора.
2. Создайте новую папку для хранения Dockerfile и всех связанных файлов, которые будут использоваться в этом руководстве, и перейдите в этот каталог. Это руководство использует ~/docker.
3. Теперь создайте пустой текстовый файл с именем Dockerfile с помощью следующей команды.
Кроме того, вы можете создать Dockerfile с помощью следующей команды, если вы используете Linux или Mac OS.
4. Наконец, добавьте следующее содержимое в файл Dockerfile
Теперь у вас есть созданный в скором времени Dockerfile!
Создание образа Docker
Теперь, когда вы создали свой Dockerfile, вам нужно создать образ Docker, чтобы выполнить команды, написанные в вашем Dockerfile в инструкциях ENTRYPOINT и CMD. Один из способов создать образ – использовать build
команду.
Находясь в каталоге ~/docker, выполните следующую команду. Эта команда создает образ Docker с именем demo (-t demo
) из Dockerfile в ~/docker, указывая текущий рабочий каталог (.
).

Запуск контейнера Docker
После того как вы создали образ Docker, вам понадобится контейнер для запуска образа Docker, который выполнит команды из инструкций ENTRYPOINT и CMD в Dockerfile.
Чтобы запустить контейнер Docker, вызовите команду run
, чтобы создать записываемый контейнерный слой над образом Docker (demo
). Приведенный ниже пример использует параметр -it
для интерактивного подключения к контейнеру, чтобы вы могли увидеть пример вывода.

Exec против Shell Form
Когда вы начинаете работать с Dockerfile и разбираетесь, как выполнять команды запуска, вы можете столкнуться с двумя разными методами определения этих команд. Каждый метод вызывает команды, но делает это немного по-разному.
Когда Docker выполняет команды, он может делать это непосредственно с помощью вызова exec
или через оболочку контейнера (/bin/sh -c
в Linux или cmd /S /C
в Windows), называемую shell
.
Вы заметите, что команды, выполненные с помощью exec
, имеют инструкцию, за которой следуют исполняемые файлы для вызова, а затем один или несколько аргументов командной строки, как показано ниже.
Написание команд в форме shell
, с другой стороны, не требует оборачивания команд в квадратные скобки, как показано ниже.
Если вы не указываете аргумент для
CMD
, Docker всегда будет выполнять команду в форме exec, например,CMD <command>
.
Если вы только начинаете, различие между этими двумя вызовами команд не будет иметь большого значения, но по мере того как вы становитесь более опытными, вы вскоре увидите плюсы и минусы каждого из них.
Выполнение команд запуска
Давайте теперь перейдем к сути этого учебного пособия и погрузимся в дело, пройдя несколько примеров выполнения команд запуска внутри Dockerfile с помощью инструкций ENTRYPOINT
и CMD.
1. Откройте Dockerfile, который вы создали ранее, в вашем предпочтительном текстовом редакторе.
2. Скопируйте и вставьте пример содержимого Dockerfile в ваш Dockerfile, как показано ниже, и сохраните его.
Этот Dockerfile создает слой, используя образ ubuntu:20.04
в качестве базового образа. Затем он сообщает Docker вызвать команду echo
, передавая ей аргумент Hello world
как для инструкций Dockerfile CMD
, так и ENTRYPOINT
, используя форму exec
и shell
.
3. Находясь в каталоге ~/docker, соберите новый образ, запустив docker build
и назовите его demo
. Введенная ниже команда маркирует образ как demo
и ищет Dockerfile в текущем рабочем каталоге (.
).

4. Теперь запустите контейнер, используя образ, затем запустите контейнер Docker на основе созданного ранее образа Docker. Теперь вы увидите, что контейнер возвращает Hello world
, который был передан в инструкции CMD
в Dockerfile.

Использование переменных в Dockerfile
Иногда вы можете не знать точные аргументы командной строки заранее. Аргументы, которые вам нужно передать команде, доступны только во время выполнения. Вместо статического назначения аргументов команды вы можете захватывать и передавать эти аргументы командам с использованием переменных.
Вы можете использовать переменные Dockerfile только в форме
shell
. Docker не поддерживает переменные в командах, вызванных с использованием формыexec
.
Откройте Dockerfile в вашем предпочтенном текстовом редакторе снова, замените все внутри следующей серией команд и сохраните.
Вы заметите, что на этот раз Dockerfile использует переменные среды и отображается с использованием ENV
. В приведенном ниже примере Dockerfile определяет переменную среды с именем name
со значением friend
. После создания этой переменной среды на нее можно ссылаться с помощью $name
.
Когда Docker запускает контейнер на основе этого Dockerfile, он вызывает команду echo
и передает аргумент Welcome, friend
.
Теперь создайте Docker-образ и снова запустите контейнер, при необходимости предоставив тег с именем shellform
. Вы заметите, что Docker вызвал команду echo
и вернул ожидаемый результат.

Комбинирование инструкций Dockerfile ENTRYPOINT и CMD
Большую часть времени вы будете вызывать команды запуска, либо в командной строке CMD, либо в инструкции ENTRYPOINT. В конце концов, вы можете вызывать столько команд, сколько захотите, используя каждый из этих методов. Однако вы также можете вызывать одну команду и “добавлять к ней” используя обе инструкции.
Основываясь на предыдущих примерах, возможно, у вас есть Dockerfile, который выглядит примерно как в следующем примере. Как есть, если вы создадите образ и запустите контейнер с этого образа, Docker вызовет команду echo
и вернет Hello
.
Возможно, у вас есть еще один аргумент, который вы хотели бы передать команде echo
, но не сразу. Возможно, вы хотели бы сделать это позже в Dockerfile. Вызывая инструкцию CMD
без команды, вы можете это сделать.
Когда вы указываете команду для выполнения с помощью инструкции
ENTRYPOINT
, за которой следует инструкцияCMD
, Docker автоматически предполагает, что переданное значениеCMD
является аргументом, а не командой.
Теперь добавьте ссылку на инструкцию CMD
без команды, только с аргументом под названием world
, как показано ниже.
Совмещение инструкций должно всегда быть записано в виде exec-формы из-за ее “массивоподобного” поведения, при котором значения указываются индивидуально, разделенные запятыми, а не в одной строке.
После создания образа и запуска контейнера из образа вы увидите, что вместо двух строк вывода (Hello
и world
) Docker возвращает только одну, что означает выполнение только одной команды echo
.

Заключение
Вы теперь должны хорошо понимать, как выполнять команды запуска контейнера Docker с использованием инструкций Dockerfile CMD
и ENTRYPOINT
. Каждая инструкция немного отличается, но выполняет ту же задачу и даже может быть использована вместе.
Можете ли вы представить себе сценарий, когда вы предпочли бы использовать CMD
вместо ENTRYPOINT
для выполнения команды запуска?