DOCKER
#docker#containers#cli#devops

Docker: разница между docker run, docker start и docker exec

Практическое объяснение различий между docker run, docker start и docker exec: когда создавать контейнер, когда запускать и как в него входить.

Как использовать

  1. Первый запуск из образа: docker run -d --name myapp -p 3000:3000 myimage:1.0.
  2. Повторный запуск остановленного контейнера: docker start myapp (имя контейнера, не образа).
  3. Вход в работающий контейнер: 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

Проверка

  1. Перед exec — контейнер должен быть запущен:
docker ps

Контейнер должен быть в списке со статусом Up. Если его нет — сначала docker start CONTAINER. Если контейнера нет в docker ps -a — его ещё не создавали, нужен docker run.

  1. Имя контейнера vs образ:
docker ps -a

В колонке NAMES — имя контейнера (для start и exec). В колонке IMAGE — образ. Команда docker start принимает имя из NAMES (или ID), не IMAGE.

  1. Диагностика ошибки «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.