Как использовать команду docker compose exec для взаимодействия с сервисами

DockerDockerBeginner
Практиковаться сейчас

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этой лабораторной работе вы научитесь эффективно использовать команду docker compose exec для взаимодействия с работающими сервисами. Вы изучите выполнение команд внутри контейнера сервиса, запуск команд в detached-режиме, выполнение команд от имени другого пользователя и запуск команд с указанием рабочей директории. Этот практический опыт даст вам необходимые навыки для отладки и управления вашими Docker-приложениями.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/exec("Execute Command in Container") docker/ImageOperationsGroup -.-> docker/pull("Pull Image from Repository") subgraph Lab Skills docker/run -.-> lab-555079{{"Как использовать команду docker compose exec для взаимодействия с сервисами"}} docker/exec -.-> lab-555079{{"Как использовать команду docker compose exec для взаимодействия с сервисами"}} docker/pull -.-> lab-555079{{"Как использовать команду docker compose exec для взаимодействия с сервисами"}} end

Выполнение команды в работающем контейнере сервиса

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

Сначала загрузим простой образ Nginx для демонстрации. Мы будем использовать образ nginx:alpine, так как он имеет небольшой размер и быстро загружается.

docker pull nginx:alpine

Вы должны увидеть вывод, указывающий на загрузку и извлечение образа.

Затем мы запустим этот образ Nginx в detached-режиме, что означает, что контейнер будет работать в фоновом режиме и не займёт ваш терминал. Также мы присвоим ему имя для удобства дальнейшего обращения.

docker run -d --name my-nginx nginx:alpine

В выводе будет указан ID нового созданного и работающего контейнера.

Теперь, когда контейнер запущен, мы можем выполнить команду внутри него с помощью команды docker exec. Базовый синтаксис: docker exec [options] container command [args...]. Давайте попробуем вывести список файлов в корневой директории контейнера.

docker exec my-nginx ls /

Вы должны увидеть список директорий и файлов в корневой файловой системе контейнера Nginx, таких как bin, etc, usr и т.д. Это подтверждает, что команда успешно выполнена внутри работающего контейнера.

Попробуем другую команду. Мы можем проверить версию Nginx, работающего в контейнере.

docker exec my-nginx nginx -v

В выводе будет указана версия Nginx, установленного в контейнере, например: nginx version: nginx/1.24.0.

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

Запуск команды в detached-режиме

На предыдущем шаге мы запускали контейнер в detached-режиме с помощью флага -d. Это стандартная практика, когда нужно, чтобы контейнер работал в фоновом режиме, не занимая терминал. В этом шаге мы подробнее рассмотрим выполнение команд в detached-режиме, в частности с использованием docker exec.

Хотя docker exec обычно используется для интерактивных сессий или выполнения кратковременных команд в работающем контейнере, вы также можете запустить команду в detached-режиме, используя флаг -d с docker exec. Это полезно для запуска фоновых процессов внутри уже работающего контейнера.

Давайте используем контейнер my-nginx, который мы запустили на предыдущем шаге. Мы выполним простую команду в detached-режиме. Например, запустим команду, которая будет записывать текущую дату и время в файл внутри контейнера каждые 5 секунд.

docker exec -d my-nginx sh -c 'while true; do date >> /usr/share/nginx/html/date.txt; sleep 5; done'

В этой команде:

  • docker exec -d my-nginx: Выполняет следующую команду в detached-режиме внутри контейнера my-nginx
  • sh -c '...': Запускает последующую строку команды с использованием оболочки sh
  • while true; do date >> /usr/share/nginx/html/date.txt; sleep 5; done: Это выполняемая команда - простой цикл, который постоянно добавляет текущую дату и время в файл /usr/share/nginx/html/date.txt, затем ждёт 5 секунд перед повторением

После выполнения команды вы увидите ID контейнера в терминале, что указывает на запуск команды в фоновом режиме внутри контейнера.

Чтобы убедиться, что команда выполняется и записывает данные в файл, мы можем выполнить другую команду для просмотра содержимого файла date.txt. Поскольку команда выполняется в фоне, может потребоваться несколько секунд для создания и заполнения файла.

docker exec my-nginx cat /usr/share/nginx/html/date.txt

В выводе вы должны увидеть дату и время, а если повторить команду cat через несколько секунд, появятся новые записи в файле. Это подтверждает, что фоновый процесс, запущенный с помощью docker exec -d, работает как ожидалось.

Выполнение команды от имени другого пользователя

На этом шаге вы узнаете, как выполнять команды внутри работающего контейнера от имени конкретного пользователя. По умолчанию docker exec выполняет команды от имени root внутри контейнера, но вы можете указать другого пользователя с помощью флага -u или --user. Это важно для безопасности и соблюдения принципа минимальных привилегий.

Продолжим использовать контейнер my-nginx. Сначала посмотрим, от имени какого пользователя выполняется команда ls / по умолчанию.

docker exec my-nginx whoami

Скорее всего, вывод будет root, так как это пользователь по умолчанию для docker exec.

Теперь попробуем выполнить команду от имени другого пользователя. Образ Nginx обычно запускает процесс Nginx от имени непривилегированного пользователя, часто с именем nginx. Выполним команду whoami от имени пользователя nginx.

docker exec -u nginx my-nginx whoami

Вы должны увидеть вывод nginx, что подтверждает выполнение команды от имени этого пользователя.

Можно также указать ID пользователя (UID) вместо имени. Чтобы найти UID пользователя nginx внутри контейнера, посмотрим файл /etc/passwd.

docker exec my-nginx cat /etc/passwd | grep nginx

Вывод покажет запись для пользователя nginx, включая его UID и GID (Group ID). Например, это может выглядеть как nginx:x:101:101:nginx user,,,:/nonexistent:/bin/false. В этом примере UID равен 101.

Теперь выполним команду whoami, используя UID. Замените 101 на фактический UID, если он отличается в вашем случае.

docker exec -u 101 my-nginx whoami

Вывод снова должен быть nginx, что демонстрирует возможность использования как имени пользователя, так и его UID для указания пользователя в docker exec.

Выполнение команд от имени непривилегированного пользователя — это хорошая практика безопасности, особенно при работе с конфиденциальными файлами или выполнении операций, не требующих прав root.

Выполнение команды в указанной рабочей директории

В этом завершающем шаге вы узнаете, как выполнять команды внутри работающего контейнера с указанием конкретной рабочей директории. По умолчанию docker exec выполняет команды в рабочей директории, определённой в Dockerfile образа контейнера (часто это /). Однако вы можете изменить это с помощью флага -w или --workdir. Это полезно, когда нужно выполнять команды относительно определённого пути в файловой системе контейнера.

Продолжим использовать контейнер my-nginx. Сначала посмотрим рабочую директорию по умолчанию при выполнении команды без её указания. Для этого используем команду pwd (print working directory).

docker exec my-nginx pwd

Скорее всего, вывод будет / — корневая директория.

Теперь выполним команду в другой рабочей директории. В контейнере Nginx есть директория /usr/share/nginx/html, из которой веб-сервер обслуживает файлы. Изменим рабочую директорию на этот путь и выведем список файлов в ней.

docker exec -w /usr/share/nginx/html my-nginx ls

В этой команде:

  • docker exec -w /usr/share/nginx/html my-nginx: Выполняет следующую команду в контейнере my-nginx, устанавливая рабочую директорию /usr/share/nginx/html
  • ls: Команда для выполнения, которая выводит список файлов в текущей рабочей директории

Вы должны увидеть файлы в директории /usr/share/nginx/html, такие как index.html и date.txt (который мы создали на предыдущем шаге).

Рассмотрим ещё один пример. Создадим новую директорию внутри /usr/share/nginx/html, затем изменим рабочую директорию на вновь созданную перед выполнением команды.

docker exec my-nginx mkdir /usr/share/nginx/html/new_dir
docker exec -w /usr/share/nginx/html/new_dir my-nginx pwd

Первая команда создаёт директорию new_dir внутри /usr/share/nginx/html. Вторая команда изменяет рабочую директорию на /usr/share/nginx/html/new_dir и выводит текущую рабочую директорию.

Вывод второй команды должен быть /usr/share/nginx/html/new_dir, что подтверждает успешное изменение рабочей директории для выполнения команды pwd.

Использование флага -w с docker exec позволяет выполнять команды в контексте конкретной директории внутри контейнера, что значительно упрощает навигацию и взаимодействие с файловой системой контейнера.

Итоги

В этой лабораторной работе вы научились использовать команду docker exec для взаимодействия с работающим Docker-контейнером. Вы попрактиковались в выполнении команд внутри контейнера, включая вывод списка файлов и проверку версии Nginx, что продемонстрировало возможность отладки и взаимодействия с сервисами без их остановки.

Вы также кратко познакомились с запуском контейнеров в фоновом режиме с использованием флага -d — фундаментальной концепцией для фонового выполнения контейнеров. Хотя последующие шаги не были подробно рассмотрены, начальные этапы заложили прочную основу для понимания принципов выполнения команд в работающей контейнерной среде.