Як зупинити і видалити контейнер?
Зупинка і видалення 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 команд.
Швидкий приклад
# Запуск 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
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
# Дефолт: анонімні 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-операції
# Зупинити все
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 запусків
# 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
$ 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 webDocker за замовчуванням відмовляється видаляти running container, захист від випадкового знищення.
Забути -v і накопичити orphan-volume
$ docker rm web # анонімний volume осиротів
$ docker volume ls -f dangling=true # знайти їх
$ docker volume prune -f # видалити їхЗа місяці orphan-анонімні volume можуть взяти багато гігабайтів. docker rm -v на час видалення не дає orphan з'явитися.
Використання rm -f на базі мід-write
# НЕПРАВИЛЬНО: вбиває postgres без flush, можлива корупція даних на наступному старті
$ docker rm -f pg
# ПРАВИЛЬНО: stop graceful, postgres коректно завершиться
$ docker stop pg && docker rm pgБазам потрібен grace-період.
Плутати docker stop з docker pause
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
$ docker run --rm -it alpine sh
/ # uname -a
Linux 4f06b3e2c0c1 ...
/ # exit
$ docker ps -a --filter name=alpine
# (нічого, container авто-видалено по виходу)--rm робить ad-hoc container схожими на запуск скриптів.
Чистий рестарт сервісу
$ 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
# Зупинити все
$ 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 деструктивний, запускай тільки коли впевнений.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.
Коментарі
Ще немає коментарів