Ответ
docker run и docker exec решают разные задачи, связанные с жизненным циклом контейнера.
-
docker run: Создает и запускает новый контейнер из указанного образа. Эта команда инициирует основной процесс контейнера (определенный вCMDилиENTRYPOINTDockerfile). -
docker exec: Выполняет дополнительную команду внутри уже запущенного контейнера. Это не влияет на основной процесс контейнера, а запускает новый параллельно.
Практический пример:
-
Запускаем новый контейнер с веб-сервером Nginx в фоновом режиме:
# Создаем и запускаем контейнер с именем 'web-server' docker run -d --name web-server nginx -
Выполняем команду внутри этого контейнера, чтобы посмотреть содержимое директории
/usr/share/nginx/html:# Запускаем 'ls -l' внутри контейнера 'web-server' docker exec web-server ls -l /usr/share/nginx/html -
Получаем интерактивный доступ к оболочке контейнера для отладки:
# Подключаемся к bash-сессии внутри контейнера docker exec -it web-server bash
Ключевые отличия:
| Критерий | docker run |
docker exec |
|---|---|---|
| Цель | Создать и запустить новый контейнер | Выполнить команду в существующем контейнере |
| Объект | Образ (e.g., nginx) |
Запущенный контейнер (e.g., web-server) |
| Жизненный цикл | Начинает новый жизненный цикл | Работает в рамках существующего |
| Основной процесс | Запускает основной процесс контейнера | Не затрагивает основной процесс |
Ответ 18+ 🔞
Давай разберём эту дичь, чтобы не путаться, как Герасим с Муму. Представь, что образ — это чертёж табуретки, а контейнер — это уже готовая, хуяк, табуретка.
docker run — это когда ты берёшь чертёж (образ) и собираешь по нему новую табуретку (контейнер), после чего сразу на неё садишься (запускаешь основной процесс). Один раз собрал — один контейнер.
docker exec — это когда табуретка уже стоит, на ней кто-то сидит (основной процесс работает), а ты подбегаешь и, не снимая сидящего, прикручиваешь к ножке, например, фонарик (запускаешь дополнительную команду внутри). Или просто заглядываешь под сиденье.
Пример, чтобы совсем пиздец стало ясно:
-
Создаём и запускаем новую табуретку-вебсервер (это
docker run):# Берём чертёж 'nginx', собираем табуретку и называем её 'web-server'. Флаг -d — чтобы она сама в углу стояла. docker run -d --name web-server nginxВсё, теперь у нас в углу стоит контейнер-табуретка, и на ней автоматически сидит процесс веб-сервера.
-
Лезем в работающую табуретку (это
docker exec). Допустим, хотим посмотреть, что у неё там в кармашке (/usr/share/nginx/html):# Суём руку в карман работающей табуретки 'web-server' и шаримся там командой 'ls' docker exec web-server ls -l /usr/share/nginx/htmlВеб-сервер при этом продолжает спокойно работать, мы его не трогали.
-
А теперь хотим влезть в табуретку с головой и поковыряться там от души:
# Открываем люк (`-it`) в табуретке 'web-server' и запускаем там bash, чтобы похавать docker exec -it web-server bashПопали внутрь. Сидишь в контейнере как в танке, а веб-сервер снаружи пашет. Красота, ёпта.
Главные отличия, если по-простому:
| Критерий | docker run |
docker exec |
|---|---|---|
| Что делает | Собирает новую табуретку из чертежа и сажает на неё процесс. | Лезит в уже собранную и работающую табуретку, чтобы что-то внутри поделать. |
| С чем работает | С образом (чертежом nginx). |
С контейнером (готовой табуреткой web-server). |
| Результат | Появляется новый контейнер. | Внутри старого контейнера выполняется команда. |
| Основной процесс | Его запускает. | Его не трогает, работает параллельно. |
Короче, run — это чтобы создать, exec — это чтобы в созданное вломиться. Всё, как в жизни.