Введение
Docker — это инструмент контейнеризации, который помогает разработчикам создавать и управлять переносимыми, совместимыми с Linux контейнерами.
При разработке или развертывании контейнеров часто возникает необходимость заглянуть внутрь работающего контейнера, чтобы проверить его текущее состояние или устранить неполадки. Для этой цели в Docker предусмотрена команда docker exec для запуска приложений в работающих контейнерах.
В этом руководстве мы узнаем о команде docker exec и о том, как ее использовать для запуска команд и получения интерактивной оболочки в контейнере Docker.
Предпосылки
В этом руководстве предполагается, что вы уже установили Docker и у вашего пользователя есть разрешение на запуск Docker. Если вам нужно запустить Docker от имени пользователя root, не забудьте добавить sudo к командам в этом руководстве.
Дополнительную информацию об использовании Docker без доступа sudo см. в разделе «Выполнение команды Docker без sudo» в нашем руководстве по установке Docker.
Запуск тестового контейнера
Для использования команды docker exec вам потребуется работающий Docker-контейнер. Если у вас его ещё нет, запустите тестовый контейнер с помощью следующей команды docker exec:
docker run -d --name container-name alpine watch "date >> /var/log/date.log"
Эта команда создаёт новый Docker-контейнер из официального образа Alpine. Это популярный образ контейнера Linux, использующий Alpine Linux — лёгкий и минималистичный дистрибутив Linux.
Мы используем флаг -d, чтобы отсоединить контейнер от терминала и запустить его в фоновом режиме. --name имя_контейнера присваивает имя контейнеру. Вы можете выбрать любое имя или вообще не указывать его, чтобы Docker автоматически сгенерировал уникальное имя для нового контейнера.
Далее у нас идет alpine, который определяет изображение, которое мы хотим использовать для контейнера.
И наконец, у нас есть “date >> /var/log/date.log”. Это команда, которую мы хотим запустить в контейнере. По умолчанию часы будут выполнять заданную вами команду каждые две секунды. В данном случае команда, которую часы выполнят, — date >> /var/log/date.log. date выводит текущую дату и время, например:
Output
Fri Jul 23 14:57:05 UTC 2021Раздел >> /var/log/date.log перенаправляет вывод команды date и добавляет его в файл /var/log/date.log. Каждые две секунды в файл добавляется новая строка, и через несколько секунд он будет выглядеть примерно так:
Output
Fri Jul 23 15:00:26 UTC 2021
Fri Jul 23 15:00:28 UTC 2021
Fri Jul 23 15:00:30 UTC 2021
Fri Jul 23 15:00:32 UTC 2021
Fri Jul 23 15:00:34 UTC 2021Далее мы научимся находить имена Docker-контейнеров. Это полезно, если у вас уже есть нужный контейнер, но вы не знаете его имени.
Поиск имени контейнера Docker
Нам необходимо предоставить команде docker exec имя (или идентификатор контейнера), с которым мы хотим работать. Эту информацию можно получить с помощью команды docker ps:
docker ps
Эта команда выводит список всех контейнеров Docker, запущенных на сервере, и предоставляет некоторую общую информацию о них:
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
76aded7112d4 alpine "watch 'date >> /var…" 11 seconds ago Up 10 seconds container-nameВ этом примере выделены идентификатор и имя контейнера. Вы можете использовать любой из них, чтобы указать docker exec, какой контейнер использовать.
Если вы хотите изменить имя своего контейнера, используйте команду docker rename:
docker rename container-name new-name
Далее мы рассмотрим несколько примеров использования docker exec для выполнения команд в контейнере Docker.
Запуск интерактивной оболочки в контейнере Docker
Если вам нужно запустить интерактивную оболочку внутри контейнера Docker, например, для исследования файловой системы или отладки запущенных процессов, используйте docker exec с флагами -i и -t.
Флаг -i оставляет вход в контейнер открытым, а флаг -t создаёт псевдотерминал, к которому может подключиться оболочка. Эти флаги можно комбинировать следующим образом:
docker exec -it container-name sh
Это запустит оболочку в указанном контейнере и выведет на экран приглашение командной строки. Чтобы выйти из контейнера, введите exit и ВХОДИТЬ Нажимать:
exitЕсли ваш образ контейнера включает более продвинутую оболочку, например bash, вы можете заменить sh на bash выше.
Выполнение неинтерактивной команды в контейнере Docker
Если вам нужно запустить команду внутри работающего контейнера, но при этом не требуется взаимодействие, используйте команду docker exec без каких-либо флагов:
docker exec container-name tail /var/log/date.log
Эта команда выполнит команду tail /var/log/date.log для имени контейнера и выведет результаты. По умолчанию команда tail выводит последние десять строк файла. Если вы запустите тестовый контейнер, который мы настроили в первом разделе, вы увидите что-то вроде этого:
Output
Mon Jul 26 14:39:33 UTC 2021
Mon Jul 26 14:39:35 UTC 2021
Mon Jul 26 14:39:37 UTC 2021
Mon Jul 26 14:39:39 UTC 2021
Mon Jul 26 14:39:41 UTC 2021
Mon Jul 26 14:39:43 UTC 2021
Mon Jul 26 14:39:45 UTC 2021
Mon Jul 26 14:39:47 UTC 2021
Mon Jul 26 14:39:49 UTC 2021
Mon Jul 26 14:39:51 UTC 2021По сути, это то же самое, что открыть интерактивную оболочку для контейнера Docker (как это было сделано на предыдущем шаге с помощью docker exec -it container-name sh ) и затем выполнить команду tail /var/log/date.log. Однако вместо открытия оболочки, выполнения команды и её закрытия эта команда возвращает тот же вывод одной командой, не открывая псевдотерминал.
Запуск команд в альтернативном каталоге в контейнере Docker
Чтобы запустить команду в определенном каталоге вашего контейнера, используйте флаг –workdir для указания каталога:
docker exec --workdir /tmp container-name pwd
В этом примере команда устанавливает каталог /tmp в качестве рабочего каталога, а затем запускает команду pwd, которая выводит текущий рабочий каталог:
Output
/tmp
Команда pwd подтвердила, что рабочий каталог — /tmp.
Выполнение команд от имени другого пользователя в контейнере Docker
Чтобы запустить команду от имени другого пользователя внутри контейнера, добавьте флаг --user:
docker exec --user guest container-name whoami
В этом случае гостевой пользователь запускает команду whoami в контейнере. Команда whoami выводит текущее имя пользователя:
Output
guestКоманда whoami подтверждает, что текущий пользователь контейнера является гостем.
Передача переменных среды в контейнер Docker
Иногда вместе с командой run необходимо передать контейнеру переменные окружения. Флаг -e позволяет указать переменную окружения:
docker exec -e TEST=sammy container-name env
Эта команда устанавливает переменную окружения TEST в значение sammy, а затем запускает команду env внутри контейнера. Затем команда env выводит все переменные окружения:
Output
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=76aded7112d4
TEST=sammy
HOME=/rootПеременная TEST установлена на sammy.
Чтобы задать несколько переменных, повторите флаг -e для каждой из них:
docker exec -e TEST=sammy -e ENVIRONMENT=prod container-name env
Если вы хотите передать файл, полный переменных среды, вы можете сделать это с помощью флага –env-file.
Сначала создайте файл в текстовом редакторе. Мы откроем новый файл в nano, но вы можете использовать любой удобный вам редактор:
nano .env
Мы используем .env в качестве имени файла, поскольку это распространенный стандарт использования файлов такого типа для управления информацией вне контроля версий.
Запишите переменные KEY=value в файле, по одной в каждой строке, как показано ниже:
TEST=sammy
ENVIRONMENT=prodСохраните и закройте файл. Чтобы сохранить файл и выйти из nano, нажмите CTRL+O, затем ENTER для сохранения, затем CTRL+X для выхода.
Теперь выполните команду docker exec и укажите правильное имя файла после –env-file:
docker exec --env-file .env container-name env
Output
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=76aded7112d4
TEST=sammy
ENVIRONMENT=prod
HOME=/rootВ файле задаются две переменные.
Вы можете указать несколько файлов, используя несколько флагов –env-file. Если переменные в файлах пересекаются, файл, указанный в последней команде, перезапишет предыдущие файлы.
Распространенные ошибки
При использовании команды docker exec вы можете столкнуться с несколькими распространёнными ошибками:
Error: No such container: container-name
Ошибка «Нет такого контейнера» означает, что указанный контейнер не существует, и может указывать на опечатку в имени контейнера. Используйте команду docker ps для просмотра списка запущенных контейнеров и перепроверьте имя.
Error response from daemon: Container 2a94aae70ea5dc92a12e30b13d0613dd6ca5919174d73e62e29cb0f79db6e4ab is not running
Это сообщение о запуске означает, что контейнер существует, но остановлен. Вы можете запустить контейнер с помощью команды docker start container-name.
Error response from daemon: Container container-name is paused, unpause the container before exec
Ошибка «Контейнер приостановлен» хорошо объясняет проблему. Прежде чем продолжить, необходимо снять контейнер с паузы с помощью команды docker unpause имя_контейнера.
Результат
В этом уроке мы узнали, как выполнять команды в работающем контейнере Docker, а также некоторые параметры командной строки при этом.
Для получения более подробной информации о Docker в целом посетите нашу страницу тегов Docker, на которой размещены ссылки на учебные пособия по Docker, страницы вопросов и ответов, связанные с Docker, и многое другое.









