Skip to main content

Як зупинити і видалити контейнер?

Зупинка і видалення container це cleanup-половина lifecycle. Дві операції розділені свідомо: stop зупиняє, rm видаляє. Знання, як їх комбінувати і як bulk-чистити, це щоденна ops-гігієна.

Теорія

TL;DR

  • docker stop <name> = graceful shutdown (SIGTERM, 10-секундний grace, тоді SIGKILL).
  • docker kill <name> = негайно (SIGKILL, без grace). Тільки для зависнутих процесів.
  • docker rm <name> = видалити метадані container + writable-шар. Container має бути спершу зупинений.
  • docker rm -f <name> = stop + remove у одній команді (шле SIGKILL, без graceful).
  • docker rm -v <name> = ще видалити анонімні volume. Named volume НІКОЛИ автоматично не видаляються (свідомий захист).
  • docker container prune = bulk-видалити всі зупинені container.
  • docker run --rm ... = позначити container для авто-видалення при exit. Найкраще для one-off команд.

Швидкий приклад

bash
# Запуск container $ docker run -d --name web nginx:1.27-alpine # Зупинка graceful $ docker stop web web # (взяло ~0с, nginx обробляє SIGTERM чисто) # Container ще існує, просто зупинений $ docker ps -a --filter name=web STATUS NAMES Exited (0) 2 seconds ago web # Тепер видаляємо $ docker rm web web # Або все одним махом наступного разу $ docker run -d --name web nginx:1.27-alpine $ docker rm -f web # stop + remove разом

Два кроки розгорнуто і явно. Комбінований rm -f це те, що використовує більшість ops-скриптів.

stop vs kill vs rm -f

bash
docker stop <name> # SIGTERM, чекає 10с, SIGKILL якщо треба docker stop -t 30 <name> # кастомний grace (30с) docker kill <name> # негайно SIGKILL (або --signal=SIGUSR1 тощо) docker rm -f <name> # SIGKILL + remove (без grace взагалі)

Для баз: завжди docker stop (або зупини застосунок всередині, тоді rm). Ніколи kill або rm -f на running базі, пропустиш WAL flush. Для зламаних container / debug: kill або rm -f нормально. Для сервісів: stop дефолт; застосунок має обробляти SIGTERM коректно (flush, закрити з'єднання, exit 0).

Cleanup volume через -v

bash
# Дефолт: анонімні volume осиротіють, named lишаються $ docker rm web # З -v: анонімні volume теж видаляються $ docker rm -v web # Named volume все одно не зачіпаються.

Анонімні volume (без імені, авто-згенеровані, коли директива VOLUME image відпрацьовує без -v) легко витекти. Бери -v на rm, щоб їх прибрати. Named volume свідомо захищені; маєш docker volume rm їх явно.

Bulk-операції

bash
# Зупинити все docker stop $(docker ps -q) # Видалити всі зупинені docker container prune # просить підтвердження docker container prune -f # без prompt # Видалити ВСЕ (running force-kill'нуться) docker rm -f $(docker ps -aq) # Фільтрований cleanup: зупинені > 24 годин тому docker container prune --filter 'until=24h' -f # Stop + prune у compose docker compose down # stop + remove container + project-мережу docker compose down -v # ще й стирає named volume (ДЕСТРУКТИВНО)

--rm для self-cleaning запусків

bash
# One-off задача: container виходить, container видаляється $ docker run --rm alpine echo hi hi # Ніякого container у `docker ps -a`. # Корисно у CI: $ docker run --rm -v $PWD:/work node:22 npm test

--rm єдиний найкращий флаг для тримання дев-машини чистою, кожен тест, білд або one-off зникає по завершенні.

Типові помилки

rm на running container без -f

bash
$ docker rm web Error response from daemon: cannot remove container "web": container is running: stop the container before removing or force remove # Фікс: спершу stop, АБО використай -f $ docker stop web && docker rm web # АБО $ docker rm -f web

Docker за замовчуванням відмовляється видаляти running container, захист від випадкового знищення.

Забути -v і накопичити orphan-volume

bash
$ docker rm web # анонімний volume осиротів $ docker volume ls -f dangling=true # знайти їх $ docker volume prune -f # видалити їх

За місяці orphan-анонімні volume можуть взяти багато гігабайтів. docker rm -v на час видалення не дає orphan з'явитися.

Використання rm -f на базі мід-write

bash
# НЕПРАВИЛЬНО: вбиває postgres без flush, можлива корупція даних на наступному старті $ docker rm -f pg # ПРАВИЛЬНО: stop graceful, postgres коректно завершиться $ docker stop pg && docker rm pg

Базам потрібен grace-період.

Плутати docker stop з docker pause

bash
docker stop # → exited (процес зник, можна рестарт) docker pause # → paused (процес заморожений, можна unpause)

Різні операції. Pause рідко; stop щодня.

Реальне застосування

  • Прод-деплої: docker stop old-container && docker rm old-container (або довірся Compose / Swarm / K8s).
  • Локальний dev між сесіями: docker compose down (container зникли) або docker compose stop (container збережені, швидший рестарт).
  • CI cleanup hooks: docker rm -f $(docker ps -aq) || true в кінці job, щоб запобігти витоку стану між job.
  • Cleanup диску: docker container prune --filter 'until=24h' -f && docker image prune -f && docker volume prune -f.

Питання для поглиблення

Q: Яка різниця між docker rm -f і docker kill && docker rm?


A: Функціонально схоже. rm -f робить це одним кроком; явна пара дозволяє обрати сигнал (docker kill -s SIGUSR1) або побачити kill окремо. Обидва дають негайне завершення + видалення.

Q: Чому docker stop іноді бере цілих 10 секунд?


A: Твій застосунок всередині не обробляє SIGTERM. Docker чекає grace-період для graceful shutdown; якщо застосунок сам не виходить, Docker шле SIGKILL. Фікс: перехопи SIGTERM у коді застосунку і чисто завершуйся.

Q: Як зупинити один Compose-сервіс, не зупиняючи весь стек?


A: docker compose stop <service-name> або docker compose rm <service-name>. Зупиняє лише той; інші продовжують крутитися.

Q: Чи видаляє docker rm ще й image?


A: Ні. Image і container окремі. docker rm видаляє container (writable-шар + метадані); image лишається у локальному кеші. Щоб видалити image: docker rmi <image>.

Q: (Senior) Як безпечно зупинити довгоживучий stateful container, що бере хвилини на flush?


A: Збільш grace-період: docker stop -t 300 dbcontainer (5 хвилин). Docker тримає SIGTERM-and-wait до цього timeout. Переконайся, що застосунок реально обробляє SIGTERM, ініціюючи свій drain/flush. Для баз як Postgres docker stop дозволяє postmaster зробити fast або smart shutdown залежно від config; перевір docs image.

Приклади

Чистий запуск з --rm

bash
$ docker run --rm -it alpine sh / # uname -a Linux 4f06b3e2c0c1 ... / # exit $ docker ps -a --filter name=alpine # (нічого, container авто-видалено по виходу)

--rm робить ad-hoc container схожими на запуск скриптів.

Чистий рестарт сервісу

bash
$ docker stop web # graceful $ docker rm web # видалити запис + writable-шар $ docker run -d --name web --restart=unless-stopped \ -p 8080:80 nginx:1.27-alpine # свіжий container, те саме ім'я

Канонічний update flow для single-container деплою. З Compose docker compose up -d робить те саме автоматично (рестартять лише змінені сервіси).

Ядерний cleanup

bash
# Зупинити все $ docker stop $(docker ps -q) # Видалити усі container (running чи ні) $ docker rm -f $(docker ps -aq) # Звільнити диск: image, volume, мережі, build-cache $ docker system prune -af --volumes Total reclaimed space: 8.4GB

Знести все. Корисно перед чистою state-демонстрацією або коли host повний. Флаг --volumes деструктивний, запускай тільки коли впевнений.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.

Коментарі

Ще немає коментарів