PQ
PQ.Hosting

Валюта

Как подключиться к контейнеру Docker: exec, attach, logs и отладка без оболочки

Автор
PQ
04 марта 2026
6 мин чтения
802 просмотров
Как подключиться к контейнеру Docker: exec, attach, logs и отладка без оболочки

Контейнер работает, но что-то идёт не так. Логи не дают полной картины, конфиг надо проверить изнутри, процесс завис и непонятно почему. Чтобы разобраться, нужно попасть внутрь — и у Docker для этого есть несколько принципиально разных инструментов. Выбор зависит от того, работает ли контейнер прямо сейчас, есть ли в нём оболочка и что именно нужно сделать.

Способ 1: docker exec — правильный способ

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

Открыть интерактивную оболочку bash:

docker exec -it container_name bash

Если bash нет — попробовать sh:

docker exec -it container_name sh

Alpine-образы и многие минималистичные контейнеры не включают bash — только sh. Попытка открыть bash в таком контейнере даст OCI runtime exec failed: executable file not found.

Флаги:

  • -i — интерактивный режим (stdin остаётся открытым)
  • -t — выделить псевдотерминал (TTY)
  • вместе -it дают нормальный интерактивный сеанс с цветами, автодополнением и управляющими символами

Выполнить одну команду без входа в оболочку:

docker exec container_name cat /etc/nginx/nginx.conf
docker exec container_name ps aux
docker exec container_name env

Запустить команду от имени другого пользователя:

docker exec -it -u root container_name bash
docker exec -it -u www-data container_name sh

Полезно когда контейнер запускается от непривилегированного пользователя, но для отладки нужны права root.

Задать переменную окружения для команды:

docker exec -e DEBUG=true container_name python manage.py check

Способ 2: docker attach — подключиться к основному процессу

docker attach подключает ваш терминал к основному процессу контейнера (PID 1), а не запускает новый. Это важное отличие от exec.

docker attach container_name

Используется когда нужно видеть вывод основного процесса в реальном времени или отправить ему ввод. Но есть серьёзное ограничение: нажатие Ctrl+C отправляет SIGINT основному процессу и может остановить контейнер.

Чтобы выйти не останавливая контейнер — использовать escape-последовательность Ctrl+P, затем Ctrl+Q. Этот приём работает только если контейнер запущен с -it.

Способ 3: docker run -it — войти при запуске

Если контейнер ещё не запущен и нужно войти в него сразу при старте:

docker run -it ubuntu:22.04 bash

Для отладки образа — запустить с переопределением точки входа:

docker run -it --entrypoint bash nginx:latest

Это игнорирует ENTRYPOINT из Dockerfile и запускает bash вместо обычного процесса. Удобно когда нужно изучить содержимое образа до запуска приложения или когда сервис сразу падает и exec не успевает.

Способ 4: docker cp — скопировать файл из контейнера

Иногда не нужен интерактивный сеанс — нужно просто достать файл. docker cp работает без оболочки и даже с остановленными контейнерами:

Скопировать из контейнера на хост:

docker cp container_name:/etc/nginx/nginx.conf ./nginx.conf

Скопировать с хоста в контейнер:

docker cp ./new_config.conf container_name:/etc/nginx/nginx.conf

После замены файла конфигурации — перезагрузить процесс внутри контейнера:

docker exec container_name nginx -s reload

Способ 5: docker logs — читать вывод без входа

Прежде чем заходить в контейнер, стоит проверить логи — часто ответ уже там:

docker logs container_name

Следить за логами в реальном времени:

docker logs -f container_name

Показать последние N строк:

docker logs --tail 100 container_name

Добавить временны́е метки:

docker logs -t container_name

Логи за последние 30 минут:

docker logs --since 30m container_name

Найти контейнер: имя, ID и статус

Перед подключением нужно знать идентификатор контейнера.

Список запущенных контейнеров:

docker ps

Все контейнеры включая остановленные:

docker ps -a

Только ID (удобно для скриптов):

docker ps -q

Подключаться можно как по полному имени, так и по первым символам ID:

docker exec -it a3f bash   # достаточно первых символов

Подключение к контейнеру без оболочки: distroless и scratch

Минималистичные образы на основе distroless (Google) или scratch не содержат ни bash, ни sh, ни даже базовых утилит. docker exec ... bash выдаст ошибку. Это намеренно — меньше поверхность атаки.

Способ 1 — nsenter через хост:

Получить PID основного процесса контейнера:

docker inspect --format '{{.State.Pid}}' container_name

Войти в пространства имён контейнера:

sudo nsenter -t <PID> -m -u -i -n -p -- sh

nsenter входит непосредственно в пространства имён (namespaces) контейнера на уровне ядра — без Docker API. Работает даже если в контейнере нет вообще никакого исполняемого файла.

Способ 2 — ephemeral debug container (Docker 20.10+):

docker debug container_name

Команда docker debug (доступна в Docker Desktop и новых версиях CLI) подключает временный debug-контейнер с полным набором инструментов к целевому контейнеру, разделяя его пространства имён.

Способ 3 — добавить утилиты в работающий контейнер через exec:

Если контейнер основан на дистрибутиве с пакетным менеджером но без нужных утилит:

docker exec -it container_name apt-get install -y procps curl
docker exec -it container_name sh

Изменения не переживут пересоздание контейнера, но для отладки этого достаточно.

Подключение к контейнеру по SSH

SSH в Docker — антипаттерн для большинства случаев: контейнер должен делать одно дело, а не быть мини-сервером. Но для специфичных задач (легаси-приложения, требующие SSH, VPN-соединения, обучающие среды) это применяется.

Если в контейнере уже запущен sshd — подключиться как к обычному серверу:

# Узнать порт проброса
docker ps | grep container_name
# PORTS: 0.0.0.0:2222->22/tcp

ssh user@localhost -p 2222

Полезные команды для диагностики изнутри контейнера

После входа в контейнер — быстрая диагностика.

Процессы:

 
ps aux

Сетевые соединения:

 
ss -tlnp

Переменные окружения:

 
env | sort

Дисковое пространство:

 
df -h

Файловая система корня:

 
ls -la /

Какой дистрибутив:

 
cat /etc/os-release

Шпаргалка

Задача Команда
Войти в запущенный контейнер docker exec -it name bash
Войти через sh (Alpine и др.) docker exec -it name sh
Выполнить команду без входа docker exec name команда
Выполнить от имени root docker exec -it -u root name bash
Подключиться к основному процессу docker attach name
Выйти из attach не останавливая Ctrl+P, затем Ctrl+Q
Войти при запуске контейнера docker run -it image bash
Войти переопределив entrypoint docker run -it --entrypoint bash image
Скопировать файл из контейнера docker cp name:/path/file ./file
Смотреть логи в реальном времени docker logs -f name
Войти в distroless контейнер sudo nsenter -t $(docker inspect --format '{{.State.Pid}}' name) -m -u -i -n -p -- sh
Список запущенных контейнеров docker ps

Поделиться статьей

Похожие статьи