Работа с контейнерами Docker: команды, SSH и копирование файлов

Быстрые ссылки
- Запуск команд в контейнерах
- Подключение по SSH к контейнеру
- Копирование файлов в контейнер и из него
Обычно приложения в Docker изолированы, но при разработке и автоматизации полезно работать с контейнерами как с легковесными VM. Docker предоставляет инструменты для запуска команд и целых оболочек внутри контейнеров.
Запуск команд в контейнерах
Чтобы выполнить команду в контейнере, нужен его идентификатор контейнера (container ID) или имя. Идентификатор — длинная шестнадцатеричная строка, которую можно получить из списка процессов Docker:
docker psДалее используется команда exec с флагами -it для интерактивного режима и TTY. Например, просмотр лог-файла:
docker exec -it containerID tail /var/log/nginx/access.logМожно запускать и скрипты внутри контейнера:
docker exec -it containerID script.shКраткое пояснение флагов и опций:
-it— интерактивный режим + псевдотерминал (используется почти всегда при запуске интерактивных команд).--workdirили-w— смена рабочей директории перед выполнением команды.--detachили-d— запустить команду в фоне.--envили-e— задать переменные окружения перед запуском.--env-file— задать переменные окружения из файла (удобнее для секретов).--privileged— расширенные привилегии для команды.--user— выполнить команду от имени другого пользователя.
Важно: docker exec работает только для уже запущенных контейнеров. Если нужно внести изменение, которое должно остаться (например, конфигурация), обычно делают новый образ с обновлениями или работают с томами/volume, смонтированными из хоста.
Подключение по SSH к контейнеру
Вместо одиночной команды можно открыть полноценную оболочку, запустив /bin/bash в контейнере. Помните, что базовые образы часто минимальные и в них может не быть привычных утилит:
docker exec -it containerID /bin/bashЭто оболочка, доступная с хоста, и она подходит во многих случаях. Однако запуск SSH-сервиса внутри контейнера превращает его в VPS-подобную систему — это возможно, но часто не рекомендовано по соображениям безопасности и управления. Если всё же требуется SSH, чётко задокументируйте причины и настройте процесс управления ключами и аудит.
Подробнее про разворачивание SSH-сервиса в контейнере обычно описано в отдельных гайдах: при этом учитывайте, что контейнеры предназначены для упрощённого и одноцелевого исполнения сервисов, а не полноценного long-lived администрируемого хоста.
Копирование файлов в контейнер и из него
Хотя docker exec позволяет запускать команды и выводить их на STDOUT, бывает удобнее прямо копировать файлы между хостом и контейнером:
docker cp container:/var/log/nginx/example.log example.logИли скопировать целую директорию:
docker cp nginx:/etc/nginx/ nginxconfig/Если вы часто обмениваетесь файлами между хостом и контейнером, имеет смысл использовать bind-монтирование директории или Docker volume — тогда файлы доступны напрямую из хостовой файловой системы и нет необходимости вручную копировать их.
Когда такой подход не подходит
- Контейнер завершён (stopped):
docker execне сработает на остановленных контейнерах — нужноdocker startили создать новый контейнер. - Минимальные образы: многие базовые образы (alpine, scratch) не содержат bash, tail или других утилит — используйте sh или установите нужные пакеты в образ.
- Недостаточный доступ: если контейнер запущен с непривилегированным пользователем и у вас нет прав,
--userможет потребовать дополнительных разрешений. - Продакшн-процессы: редактирование файлов вручную внутри продакшн-контейнера нарушает иммутабельность; предпочитайте сборку образов и CI/CD.
Альтернативные подходы и приёмы
- docker attach — прикрепляет терминал к процессу внутри контейнера; полезно для просмотра stdout/ stderr основного процесса, но сложнее с управлением команд.
- docker run –rm -v … — для однократной работы с томами можно запустить вспомогательный контейнер, получить доступ к данным и автоудалить контейнер.
- docker-compose exec — аналогично docker exec, но удобнее для проектов с docker-compose.
- Используйте sidecar-контейнеры для задач мониторинга/бэкапа вместо SSH в основном контейнере.
Чек‑лист по ролям
Для разработчика:
- Убедиться, что образ содержит нужные утилиты (bash/sh, curl, jq и т.п.).
- Использовать
docker execдля локальной отладки. - Предпочитать bind-монты при локальной разработке.
Для инженера DevOps:
- Не плодить SSH-сервисы в контейнерах без необходимости.
- Настроить CI/CD для внесения изменений в образы.
- Логировать и мониторить доступы и exec-сессии.
Для администратора безопасности:
- Контролировать использование
--privilegedи--user. - Обеспечивать управление секретами (не хранить пароли в образах).
- Аудитировать команды, запускаемые внутри контейнеров.
Безопасность и обработка секретов
- Не хардкодьте секреты в образах. Используйте Docker secrets, VM secret stores или систему управления секретами (Vault, SSM и т.д.).
- Ограничьте привилегии: избегайте
--privileged, используйте минимальные права пользователя. - Если запускаете SSH, применяйте ключи и аудит; лучше использовать инструменты orchestration (kubernetes exec, bastion host с контролем).
Ментальная модель и шаблоны принятия решений
- Контейнер = иммутабельный артефакт. Изменение должно быть в образе, а не в запущенном экземпляре.
- Exec для отладки и операций восстановления; Build → Deploy для постоянных изменений.
- Volume/Bind = if you need files on host frequently; docker cp = ad-hoc перенос.
Примеры тестов и критерии приёмки
Критерии приёмки для операций с контейнером:
- Удаление/переименование логов не приводит к потере данных (если логи сохраняются в volume).
- Команда
docker exec -it containerID /bin/bashоткрывает оболочку и позволяет выполнить диагностические команды. - Файлы, скопированные через
docker cp, доступны и корректны на принимающей стороне.
Минимальные тесты:
- Попробовать
docker execдля чтения существующего файла. - Попробовать копирование файла из контейнера и сравнить контрольные суммы.
- Попробовать запуск скрипта внутри контейнера и проверить ожидаемый результат.
Факто‑бокс — полезные команды (шпаргалка)
- Показать запущенные контейнеры:
docker ps - Выполнить команду в контейнере:
docker exec -it - Открыть bash:
docker exec -it/bin/bash - Скопировать файл из контейнера:
docker cp: - Скопировать в контейнер:
docker cp: - Запустить однократный контейнер с монтированием:
docker run --rm -v /host/path:/data image ls /data
Советы по миграции и совместимости
- Alpine vs Debian/Ubuntu: проверьте наличие /bin/bash; в alpine используйте /bin/sh.
- Docker Compose: для многоконтейнерных приложений используйте
docker-compose exec service_name command. - Kubernetes: используйте
kubectl exec -it pod -- /bin/shвместо docker exec; подумайте о различиях в сетевой модели и безопасности.
Резюме
Используйте docker exec для быстрой отладки и запуска утилит в запущенных контейнерах. Для регулярного доступа к данным предпочтительнее монтирование томов. Избегайте превращения контейнера в полноценный SSH-хост без серьёзной причины: это усложняет безопасность и управление. Всегда обдумывайте, какие изменения должны быть иммутабельными в образе, а какие — временными для отладки.
Важно: документируйте все админские вмешательства и применяйте практики безопасного управления секретами.