Docker exec: как зайти в контейнер и выполнить команду

Категория: docker · Язык: Bash · Обновлено:

Чтобы зайти в работающий контейнер, выполните docker exec -it имя sh. Если в образе есть Bash, подойдёт docker exec -it имя bash. Одноразовую команду без входа запускают так: docker exec имя ls /app. Ключи -it подключают интерактивный терминал.

Зайти в контейнер

Bash
docker exec -it my-app sh                # оболочка sh есть почти везде
docker exec -it my-app bash              # Bash, если он установлен в образе
docker exec -u root -it my-app sh        # войти от имени root
docker exec -w /app -it my-app sh        # начать в нужной папке

Выйти можно командой exit или сочетанием Ctrl+D. Контейнер при этом продолжает работать: вы завершаете только свою сессию.

Выполнить одну команду

Bash
docker exec my-app ls /app
docker exec my-app cat /etc/os-release
docker exec my-app sh -c "cd /app && ls | wc -l"
docker exec -e DEBUG=1 my-app env

Если нужны перенаправления и конвейеры внутри контейнера, оберните команду в sh -c "...", иначе их выполнит ваша оболочка на хосте.

Что означают ключи

Ключ

Значение

-i

Оставить стандартный ввод открытым

-t

Выделить псевдотерминал

-u

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

-w

Рабочая папка

-e

Переменная окружения для команды

Для интерактивной работы нужны оба ключа -it. В скриптах и CI терминала нет, поэтому там -t не используют: он вызывает ошибку «the input device is not a TTY».

Передать данные в контейнер

Bash
echo "SELECT 1;" | docker exec -i db psql -U postgres
docker exec -i db psql -U postgres < backup.sql

Здесь ключ -i обязателен, а -t нельзя добавлять.

Копировать файлы между хостом и контейнером

Bash
docker cp my-app:/app/config.yml ./config.yml    # из контейнера на хост
docker cp ./settings.json my-app:/app/           # с хоста в контейнер

Docker Compose

Bash
docker compose exec web sh
docker compose exec -T web python manage.py migrate     # -T без терминала, для скриптов
docker compose run --rm web sh                          # новый временный контейнер сервиса

Контейнер остановлен или падает

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

Bash
docker run --rm -it --entrypoint sh my-app-image

Образ без оболочки

В минимальных образах (distroless, scratch) нет ни sh, ни bash. Тогда используйте отладочный контейнер, подключённый к тому же процессному пространству:

Bash
docker run --rm -it --pid=container:my-app --net=container:my-app busybox sh

Частые вопросы

Чем docker exec отличается от docker attach?

attach подключает вас к основному процессу контейнера, и выход через Ctrl+C может его остановить. exec запускает новый отдельный процесс и безопаснее.

Почему «executable file not found: bash»?

В образе нет Bash. Попробуйте sh или ash, у образов на основе Alpine нет Bash по умолчанию.

Как зайти в контейнер в Git Bash на Windows?

Добавьте перед командой winpty: winpty docker exec -it my-app sh.