Зайти в работающий контейнер

Оболочка внутри контейнера, обращение по короткому ID, запуск клиента напрямую и копирование файлов внутрь

docker exec -it df0 sh
docker exec -it df0 sh -c "bash || ash || sh"
docker exec -it pg psql -U postgres -d postgres
docker compose exec postgres psql -U postgres
docker cp transactions.csv namenode:/transactions.csv

ID контейнера можно сокращать до любого однозначного префикса — df0 вместо полного хеша. Экономит копирование из docker ps каждый раз.

bash есть не везде: в образах на Alpine его нет, и docker exec -it X bash падает с executable file not found. Цепочка bash || ash || sh закрывает вопрос одной командой, не заставляя выяснять, на чём собран образ.

Запускать клиент напрямую обычно удобнее, чем заходить в оболочку и оттуда вызывать его руками: короче и не оставляет лишнюю интерактивную сессию.

Через docker compose exec обращение идёт по имени сервиса из compose-файла — оно стабильно, в отличие от имени контейнера, куда compose подставляет префикс проекта и порядковый номер.

-it нужен именно для интерактива. Для разовой команды в скрипте флаги лучше убрать: без терминала -t иногда ломает вывод, а в CI его может не быть вовсе.