Docker: разница между docker run, docker start и docker exec
Практическое объяснение различий между docker run, docker start и docker exec: когда создавать контейнер, когда запускать и как в него входить.
Как использовать
- Первый запуск из образа: docker run -d --name myapp -p 3000:3000 myimage:1.0.
- Повторный запуск остановленного контейнера: docker start myapp (имя контейнера, не образа).
- Вход в работающий контейнер: docker exec -it myapp sh; перед exec проверьте docker ps.
Три команды часто путают: все они «запускают что-то» в Docker, но делают разное. run создаёт и запускает новый контейнер из образа; start только запускает уже существующий остановленный контейнер; exec выполняет команду внутри уже запущенного контейнера. Проблема: вызывают docker exec для остановленного контейнера (ошибка «Container is not running») или передают в docker start имя образа вместо имени контейнера. Симптомы: «No such container: nginx:alpine», «Container myapp is not running». Ниже — что делает каждая команда, типичные сценарии, примеры и проверка по официальной документации Docker CLI.
Решение
docker run — создание и запуск нового контейнера из образа. Каждый вызов создаёт новый контейнер. Использовать: первый запуск, одноразовые задачи, новый контейнер с другими опциями.
docker start — запуск уже существующего остановленного контейнера. Не принимает образ, только имя или ID контейнера. Использовать: после docker stop, после перезагрузки хоста.
docker exec — выполнение команды в уже работающем контейнере. Контейнер должен быть в состоянии running. Использовать: отладка, оболочка, миграции, разовые команды.
docker run — создание и запуск
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 — повторный запуск
docker start myapp
docker start -a myapp
docker start myapp db redis
Список всех контейнеров (включая остановленные): docker ps -a.
docker exec — команда внутри контейнера
docker exec -it myapp sh
docker exec myapp cat /etc/hostname
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) нужны для интерактивной оболочки.
Состояние контейнера
- run — контейнера ещё нет, создаётся и запускается.
- start — контейнер есть (exited), переводится в running.
- exec — контейнер уже running, внутри выполняется команда.
Полный цикл (copy-paste)
docker run -d --name web -p 8080:80 nginx:alpine
docker ps
docker exec -it web sh
# exit
docker stop web
docker start web
docker exec -it web sh
Проверка
- Перед exec — контейнер должен быть запущен:
docker ps
Контейнер должен быть в списке со статусом Up. Если его нет — сначала docker start CONTAINER. Если контейнера нет в docker ps -a — его ещё не создавали, нужен docker run.
- Имя контейнера vs образ:
docker ps -a
В колонке NAMES — имя контейнера (для start и exec). В колонке IMAGE — образ. Команда docker start принимает имя из NAMES (или ID), не IMAGE.
- Диагностика ошибки «Container is not running»:
docker ps -a --filter "name=myapp"
docker start myapp
docker exec -it myapp sh
Типичные ошибки
- docker exec в остановленный контейнер — сначала
docker start CONTAINER, затемdocker exec. - docker start с именем образа —
docker start nginx:alpineдаёт «No such container». В start передаётся только имя или ID контейнера изdocker ps -a. - Повторный docker run с тем же —name — ошибка «The container name “/myapp” is already in use». Либо удалите старый контейнер (
docker rm myapp), либо используйте другой имя, либо для повторного запуска —docker start myapp.
Где применять
- Разработка и prod: первый запуск — run; перезапуск после stop или перезагрузки — start; отладка и команды внутри контейнера — exec.
- CI/скрипты: одноразовые задачи —
docker run --rm; постоянные сервисы — run один раз, далее start/stop.
Связанные сниппеты: Сеть между контейнерами (localhost), Volumes vs bind mounts.
Ссылки: docker run, docker start, docker exec.