Docker: разница между docker run, docker start и docker exec
Практическое объяснение различий между docker run, docker start и docker exec: когда создавать контейнер, когда запускать и как в него входить.
Как использовать
- Скопируйте нужный фрагмент кода.
- Вставьте в свой проект и при необходимости измените под задачу.
- Проверьте зависимости и окружение (версии, переменные).
Три команды часто путают, потому что все они так или иначе «запускают что-то» в Docker. На самом деле они решают разные задачи: run создаёт и запускает новый контейнер, start только запускает уже существующий остановленный контейнер, exec выполняет команду внутри уже запущенного контейнера. Ниже — строго по официальной документации Docker.
docker run — создание и запуск нового контейнера
Описание (из документации): Create and run a new container from an image. Команда запускает команду в новом контейнере, при необходимости подтягивает образ и стартует контейнер.
Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
Каждый вызов docker run создаёт новый контейнер из образа. Если контейнер с таким именем уже есть — будет ошибка «Conflict. The container name “/myapp” is already in use», если не использован --rm и не задано уникальное имя.
Типичные сценарии:
- Первый запуск приложения из образа.
- Запуск одноразовой задачи (с
--rmконтейнер удалится после выхода). - Запуск с новыми опциями (порты, переменные, тома).
# Создать и запустить контейнер в фоне, с именем и портом
docker run -d --name myapp -p 3000:3000 myimage:1.0
# Создать и запустить с автоматическим удалением после выхода
docker run --rm -it alpine sh
# Создать и запустить с переменными и томом
docker run -d --name db -e POSTGRES_PASSWORD=secret -v pgdata:/var/lib/postgresql/data postgres:16
docker start — повторный запуск остановленного контейнера
Описание (из документации): Start one or more stopped containers. Запускает один или несколько остановленных контейнеров. Контейнер при этом не создаётся заново — используется уже существующий, со всеми прежними настройками и данными.
Usage: docker container start [OPTIONS] CONTAINER [CONTAINER...]
Alias: docker start
Контейнер должен уже существовать (был создан ранее через docker run или API). Команда не принимает имя образа и не создаёт новый контейнер.
Типичные сценарии:
- Контейнер остановили (
docker stop) и нужно снова его запустить. - После перезагрузки хоста — запуск ранее созданных контейнеров.
# Запустить контейнер по имени
docker start myapp
# Запустить и сразу прикрепиться к выводу (STDOUT/STDERR)
docker start -a myapp
# Запустить с интерактивным STDIN
docker start -i myapp
# Запустить несколько контейнеров
docker start myapp db redis
Просмотр всех контейнеров (включая остановленные): docker ps -a.
docker exec — выполнение команды внутри запущенного контейнера
Описание (из документации): Run a command in a running container. Выполняет команду в уже запущенном контейнере. Новый контейнер не создаётся, существующий не перезапускается — внутри него просто запускается дополнительный процесс.
Usage: docker container exec [OPTIONS] CONTAINER COMMAND [ARG...]
Alias: docker exec
Контейнер должен быть в состоянии running. Если контейнер остановлен, будет ошибка «Container myapp is not running».
Типичные сценарии:
- Войти в оболочку контейнера для отладки.
- Выполнить разовую команду (миграции, бэкап, проверка).
- Запустить процесс рядом с основным (PID 1).
# Интерактивная оболочка (sh в Alpine, bash в полных образах)
docker exec -it myapp sh
# Выполнить одну команду
docker exec myapp cat /etc/hostname
# Команда с аргументами; для цепочек использовать sh -c
docker exec myapp sh -c "cd /app && npm run migrate"
# Запуск от другого пользователя и в указанной директории
docker exec -u www-data -w /var/www/html myapp pwd
Флаги -i (interactive) и -t (TTY) нужны для интерактивной оболочки; без них ввод с клавиатуры работать не будет.
Сравнение команд
docker run
- Создаёт новый контейнер из образа.
- Аргументы: образ, опции, опционально COMMAND.
- Использовать: первый запуск, одноразовые задачи, новый контейнер с другими опциями.
docker start
- Не создаёт контейнер; запускает уже существующий остановленный.
- Аргументы: имя/ID контейнера (одного или нескольких).
- Использовать: после
docker stop, после перезагрузки хоста.
docker exec
- Не создаёт и не запускает контейнер; выполняет команду в уже работающем.
- Аргументы: контейнер, команда и аргументы.
- Использовать: отладка, миграции, любые команды внутри running-контейнера.
Состояние контейнера:
docker run— контейнера ещё нет, он создаётся и запускается.docker start— контейнер есть, состояние «exited», переводится в «running».docker exec— контейнер уже «running», внутри него выполняется команда.
Практические примеры (copy-paste)
Полный цикл: создание, остановка, запуск, вход.
# 1. Создать и запустить контейнер
docker run -d --name web -p 8080:80 nginx:alpine
# 2. Проверить, что запущен
docker ps
# 3. Войти в контейнер
docker exec -it web sh
# Внутри контейнера (например, посмотреть конфиг)
# cat /etc/nginx/nginx.conf
# exit
# 4. Остановить контейнер
docker stop web
# 5. Контейнер уже существует, просто запускаем снова
docker start web
# 6. Снова войти
docker exec -it web sh
Ошибка новичка: exec в остановленный контейнер.
docker stop web
docker exec -it web sh
# Error: Container web is not running.
# Правильно: сначала запустить, потом exec
docker start web
docker exec -it web sh
Ошибка новичка: start с образом вместо контейнера.
docker start nginx:alpine
# Error: No such container: nginx:alpine
# docker start принимает только имя или ID контейнера
docker start web
Просмотр контейнеров перед выбором команды.
# Все контейнеры (и запущенные, и остановленные)
docker ps -a
# Только запущенные
docker ps
Типичная ошибка и как её избежать
Ошибка: Пытаются войти в контейнер через docker exec, не проверив, что он запущен. Или вызывают docker start с именем образа вместо имени контейнера.
Как избежать:
- Перед
docker execпроверять:docker ps— контейнер в списке и в статусе «Up». Если его нет — сначалаdocker start CONTAINER. - Для
docker startиспользовать только имя или ID контейнера (из выводаdocker ps -a), не образ. - Для первого запуска из образа — только
docker run; повторный запуск того же контейнера —docker start.
Ссылки на официальную документацию: