Безопасное удаление Docker сетей и томов в 2026: полное руководство по очистке | AdminWiki

Безопасное удаление Docker сетей и томов в 2026: полное руководство по очистке

02 апреля 2026 13 мин. чтения
Содержание статьи

Накопившиеся неиспользуемые Docker сети и тома - это не просто «мусор», а потенциальный источник конфликтов, проблем с безопасностью и нерационального использования дискового пространства. Поспешное удаление контейнеров командой docker rm -f или запуск агрессивной очистки с docker system prune --volumes может привести к остановке критичных сервисов и потере данных. Это практическое руководство поможет DevOps-инженерам и системным администраторам безопасно удалить Docker-сети, тома и неиспользуемые ресурсы: от точечной работы через docker network rm и docker volume rm до контролируемой очистки командами prune, cron и CI/CD.

Краткое резюме: безопасная очистка Docker сводится к трём шагам: проверить зависимости через docker network inspect и docker ps -a --filter volume=..., удалить только подтверждённо неиспользуемые ресурсы командами docker network rm, docker volume rm или prune, затем проверить результат. Фильтр until=168h помогает сузить выборку, но не заменяет проверку данных в томах.

Быстрый выбор команды

ЗадачаКомандаЧто проверить заранее
Удалить одну сетьdocker network rm NETWORKdocker network inspect и подключённые endpoint
Удалить один томdocker volume rm VOLUMEdocker ps -a --filter volume=... и резервную копию данных
Удалить неиспользуемые сетиdocker network pruneБудут затронуты только неиспользуемые пользовательские сети
Удалить неиспользуемые томаdocker volume pruneПоведение для named volumes зависит от версии Docker CLI и флага --all
Очистить несколько типов ресурсовdocker system prune -a --volumesСписки ресурсов, docker system df, резервные копии и влияние на production
WARNING: для docker system prune Docker не предоставляет штатный универсальный dry-run. До запуска соберите инвентаризацию через docker system df, docker network ls, docker volume ls и проверку целевых ресурсов командой inspect.

Краткий чек-лист безопасности перед очисткой

  1. Проверьте зависимости: используйте docker network inspect и docker ps -a --filter volume=... для каждого удаляемого ресурса.
  2. Создайте резервную копию данных: перед удалением томов с базами данных или конфигурациями всегда делайте копию через утилитарный контейнер или штатный механизм резервного копирования приложения.
  3. Используйте фильтры по времени как дополнительное ограничение: --filter "until=168h" уменьшает выборку для поддерживающих его команд, но не подтверждает безопасность удаления тома с данными.
  4. Не используйте -f как способ обхода зависимостей: флаг не заменяет отключение контейнера от сети, остановку сервиса или перенос данных.
  5. Тестируйте в staging: перед запуском новых скриптов очистки в production проверьте их на копии окружения.

Почему нельзя просто удалить всё: риски и необходимые проверки

Удаление сетей (network) и томов (volume) в Docker требует осознанного подхода. Docker обычно не позволяет удалить сеть или том, которые ещё используются контейнером: ошибка в этом случае служит защитой от случайного нарушения работы сервиса. Однако удаление контейнера, принудительное отключение от сети или пересоздание ресурса без проверки зависимостей всё равно может привести к недоступности приложения или потере данных. Основа безопасности - всегда проверять, что удаляемый ресурс не используется.

Как проверить, используется ли сеть или том перед удалением

Первый обязательный шаг - инвентаризация и проверка зависимостей. Начните с общего обзора:

docker network ls
docker volume ls

Обратите внимание на столбцы DRIVER и SCOPE. Для детальной проверки конкретной сети выполните команду инспекции, которая покажет подключённые контейнеры:

docker network inspect my_app_network

В выводе команды найдите раздел "Containers". Если для проверяемой сети в нём нет контейнеров, Docker не видит подключённых к ней контейнерных endpoint. Для проверки тома используйте фильтр, чтобы найти все контейнеры, включая остановленные, которые его монтируют:

docker ps -a --filter volume=my_data_volume

Если команда не выводит контейнеров, том не используется контейнерами Docker. При сомнениях дополнительно проверьте его метаданные: docker volume inspect my_data_volume.

Что произойдёт, если ресурс использует контейнер

При штатном выполнении docker network rm и docker volume rm Docker должен отклонить удаление занятого ресурса. Это не ошибка, которую следует обходить автоматически.

  • Используемая сеть: Docker вернёт ошибку о подключённых endpoint. Сначала определите контейнеры через docker network inspect, затем штатно отключите или пересоздайте только те контейнеры, для которых это согласовано.
  • Используемый том: Docker сообщит, что том занят. Остановите и удалите контейнер только после проверки его роли; для тома с данными сначала выполните перенос или резервное копирование.

Сообщения "No such file or directory" и "Input/output error" могут появиться при некорректном монтировании или проблемах хранилища, но не являются штатным результатом отклонённого docker volume rm. Такие ошибки требуют отдельной диагностики данных и storage.

Точные команды для удаления: от одиночных ресурсов до массовой очистки

После проверки зависимостей можно приступать к удалению. Docker предоставляет два типа команд: для точечной работы с конкретными ресурсами (rm) и для массовой очистки неиспользуемых ресурсов (prune).

docker network rm и docker volume rm: точечное удаление

Эти команды предназначены для удаления одного или нескольких явно указанных ресурсов.

Синтаксис удаления сетей:

docker network rm [OPTIONS] NETWORK [NETWORK...]

Пример: удаление двух проверенных тестовых сетей.

docker network rm test_network_1 test_network_2

Синтаксис удаления томов:

docker volume rm [OPTIONS] VOLUME [VOLUME...]

docker volume rm my_old_volume

Флаг -f (force): не рассматривайте его как гарантированный или штатный способ удалить используемый ресурс. Если Docker сообщает "network has active endpoints", сначала определите endpoint и контейнер. Для согласованного отключения сети используйте последовательность:

docker network inspect my_app_network
docker network disconnect my_app_network container_name
docker network rm my_app_network

Для «висячих» endpoint от уже удалённого контейнера принудительное отключение допустимо только после проверки, что endpoint действительно не относится к работающему сервису. Для тома безопасный путь - остановить и удалить ненужный контейнер либо перенести данные, а затем повторить docker volume rm.

Типичная ошибка при попытке удалить используемый ресурс:

Error response from daemon: network my_bridge is in use

Это сигнал вернуться к этапу проверки с помощью docker network inspect, а не добавлять -f в команду без анализа.

docker network prune и docker volume prune: очистка всего лишнего

Команда docker network prune удаляет только неиспользуемые пользовательские сети. Сети по умолчанию, такие как bridge, host и none, она не затрагивает.

docker network prune
WARNING! This will remove all custom networks not used by at least one container.
Are you sure you want to continue? [y/N] y
Deleted Networks:
testnet_old
project_x_backend

Для поддерживающих фильтр версий Docker CLI можно ограничить выборку возрастом сетей:

docker network prune --filter "until=168h"

Команда docker volume prune удаляет неиспользуемые локальные тома в пределах поведения конкретной версии Docker CLI. В CLI, где доступен флаг -a или --all, по умолчанию очистка ориентирована на неиспользуемые anonymous volumes, а --all расширяет её на named volumes. Перед автоматизацией проверьте доступные параметры командой docker volume prune --help.

docker volume prune

docker volume prune --all

Важно: не используйте until=168h как универсальный фильтр для docker volume prune. Поддерживаемые фильтры различаются между версиями Docker CLI; для томов с данными надёжнее использовать явные labels и проверку зависимостей.

Команда docker system prune -a --volumes удаляет несколько типов неиспользуемых ресурсов: остановленные контейнеры, неиспользуемые сети, образы, build-кэш и, с флагом --volumes, тома. Перед её запуском выполните:

docker system df
docker network ls
docker volume ls

Фильтр docker system prune -a --volumes --filter "until=168h" ограничивает очистку по времени там, где его применяет Docker CLI, но не проверяет ценность данных в томах и не является гарантией безопасности. В production такую команду запускайте только после инвентаризации, резервного копирования и проверки поведения на используемой версии Docker.

Проверка версии Docker CLI и совместимости

Основные команды rm и prune стабильны, но набор фильтров и параметры очистки томов могут отличаться. Перед применением примеров в Docker Desktop, managed-среде или production-сервере проверьте установленный CLI:

docker version --format '{{.Client.Version}}'
docker network prune --help
docker volume prune --help
docker system prune --help

Практические сценарии: как удалить ресурс, если он всё же используется

Если проверка показала, что сеть или том необходимы работающему контейнеру, удалять их напрямую не следует. Алгоритм зависит от критичности сервиса и требований к данным.

Аккуратное отключение контейнера и перенос данных

Этот метод подходит для production-сервисов, где downtime должен быть минимальным, а данные - сохранены.

Алгоритм для тома с данными БД:

  1. Остановите контейнер: docker stop postgres_container.
  2. Создайте новый том: docker volume create postgres_data_new.
  3. Скопируйте данные со старого тома на новый с помощью утилитарного контейнера:
    docker run --rm -v postgres_data_old:/from -v postgres_data_new:/to \
    alpine ash -c "cd /from ; cp -a . /to"
    
  4. Пересоздайте контейнер, указав в его конфигурации новый том postgres_data_new.
  5. Запустите контейнер и убедитесь в его работоспособности.
  6. Удалите старый том: docker volume rm postgres_data_old.

Для БД файловое копирование допустимо только после корректной остановки сервиса. Если приложение требует логического бэкапа или специальной процедуры восстановления, используйте её. Для сетей логика аналогична: создайте новую сеть, пересоздайте или подключите связанные контейнеры к новой сети, проверьте связность и только затем удалите старую.

Что делать с "осиротевшими" (dangling) ресурсами

Для томов фильтр dangling=true означает, что Docker не связывает том ни с одним контейнером. Такой том не является автоматически «не удаляемым» стандартным prune: его обработка зависит от типа тома и параметров версии Docker CLI.

Различие томов: anonymous volumes создаются без явно заданного имени и часто остаются после временных запусков контейнеров. Named volumes создаются с именем и нередко содержат постоянные данные. Поэтому named volume нельзя считать безопасным для удаления только из-за отсутствия контейнерной привязки.

Оценка масштаба: команда docker system df покажет общий объём данных в категориях Build Cache и Reclaimable.

Ручная проверка: сначала получите список, затем проверьте каждый кандидат:

docker volume ls -f dangling=true
docker volume inspect my_old_volume

Если используемая версия Docker показывает фильтр dangling=true в справке docker volume prune --help, можно применить его после проверки:

docker volume prune --filter "dangling=true" -f

Если фильтр не поддерживается, Docker вернёт ошибку. В этом случае используйте список docker volume ls -f dangling=true и удаляйте проверенные тома по одному.

Автоматизация очистки: готовые bash-скрипты для интеграции в CI/CD

Автоматизация полезна только при явной политике отбора ресурсов. Не запускайте docker system prune -a --volumes безусловно по cron на shared-host или production-сервере. Ниже скрипт по умолчанию работает в режиме проверки, использует блокировку от параллельного запуска, очищает только ресурсы с label cleanup=weekly и явно исключает тома с label environment=production.

Скрипт для безопасной еженедельной очистки (cron job)

#!/bin/bash
# /usr/local/bin/docker-cleanup-weekly.sh

set -Eeuo pipefail

LOG_FILE="/var/log/docker-cleanup.log"
LOCK_FILE="/var/lock/docker-cleanup-weekly.lock"
CLEANUP_LABEL="cleanup=weekly"
PRODUCTION_ENVIRONMENT="production"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

echo "[$TIMESTAMP] Начало очистки Docker." >> "$LOG_FILE"

if ! command -v docker >/dev/null 2>&1 || ! docker info >/dev/null 2>&1; then
  echo "[$TIMESTAMP] Docker daemon недоступен." >> "$LOG_FILE"
  exit 1
fi

if ! command -v flock >/dev/null 2>&1; then
  echo "[$TIMESTAMP] Команда flock недоступна." >> "$LOG_FILE"
  exit 1
fi

exec 9>"$LOCK_FILE"
if ! flock -n 9; then
  echo "[$TIMESTAMP] Очистка уже выполняется, запуск пропущен." >> "$LOG_FILE"
  exit 0
fi

# 1. Анализ текущего состояния
 echo "[$TIMESTAMP] Текущее использование:" >> "$LOG_FILE"
docker system df >> "$LOG_FILE" 2>&1

# Без CONFIRM=1 скрипт ничего не удаляет.
if [[ "${CONFIRM:-0}" != "1" ]]; then
  echo "[$TIMESTAMP] Режим проверки: для удаления задайте CONFIRM=1." >> "$LOG_FILE"
  docker network ls --filter "label=$CLEANUP_LABEL" >> "$LOG_FILE" 2>&1
  docker volume ls --filter "label=$CLEANUP_LABEL" >> "$LOG_FILE" 2>&1
  exit 0
fi

# 2. Очистка неиспользуемых сетей старше 168 часов с явной меткой.
echo "[$TIMESTAMP] Запуск очистки неиспользуемых ресурсов старше 7 дней..." >> "$LOG_FILE"
DELETED_OUTPUT=$(docker network prune --filter "until=168h" --filter "label=$CLEANUP_LABEL" -f 2>&1)

# Том удаляется только при наличии cleanup=weekly, отсутствии контейнерной привязки
# и отсутствии label environment=production.
while IFS= read -r volume; do
  [[ -z "$volume" ]] && continue
  VOLUME_ENVIRONMENT=$(docker volume inspect --format '{{ index .Labels "environment" }}' "$volume")
  if [[ "$VOLUME_ENVIRONMENT" == "$PRODUCTION_ENVIRONMENT" ]]; then
    DELETED_OUTPUT+=$'\n'"Пропущен production-том: $volume"
    continue
  fi

  if VOLUME_OUTPUT=$(docker volume rm "$volume" 2>&1); then
    DELETED_OUTPUT+=$'\n'"$VOLUME_OUTPUT"
  else
    DELETED_OUTPUT+=$'\n'"Не удалось удалить том $volume: $VOLUME_OUTPUT"
  fi
done < <(docker volume ls -q --filter "label=$CLEANUP_LABEL" --filter "dangling=true")

echo "$DELETED_OUTPUT" >> "$LOG_FILE"
docker system df >> "$LOG_FILE" 2>&1

TIMESTAMP_END=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$TIMESTAMP_END] Очистка завершена." >> "$LOG_FILE"
echo "---" >> "$LOG_FILE"

Перед включением cron назначайте label cleanup=weekly только ресурсам, которые разрешено удалять автоматически. Для production-томов используйте label environment=production. У томов нет универсального безопасного возрастного фильтра, поэтому скрипт отбирает их по labels и статусу dangling=true.

Настройка в cron (crontab -e):

# Запускать каждое воскресенье в 03:00 после предварительной проверки
0 3 * * 0 CONFIRM=1 /usr/local/bin/docker-cleanup-weekly.sh

Очистка Docker в CI/CD: GitHub Actions и GitLab CI

В CI/CD (GitLab CI, GitHub Actions) после тестов могут оставаться временные сети и тома. Labels должны назначаться именно сетям и томам: label контейнера не передаётся автоматически связанным ресурсам.

Создание тестовых ресурсов с label:

docker network create --label "ci-job=$CI_JOB_ID" ci_network
docker volume create --label "ci-job=$CI_JOB_ID" ci_volume

Пример этапа в .gitlab-ci.yml:

cleanup_docker:
  stage: .post
  script:
    - |
      echo "Удаление тестовых ресурсов Docker с label=ci-job=$CI_JOB_ID"
      docker network ls --filter "label=ci-job=$CI_JOB_ID" -q | while IFS= read -r network; do
        [ -z "$network" ] && continue
        if ! docker network rm "$network"; then
          echo "Сеть $network не удалена: проверьте подключённые контейнеры"
        fi
      done
    - |
      docker volume ls --filter "label=ci-job=$CI_JOB_ID" -q | while IFS= read -r volume; do
        [ -z "$volume" ] && continue
        if ! docker volume rm "$volume"; then
          echo "Том $volume не удалён: проверьте контейнеры и данные"
        fi
      done
  when: always

Конструкции while IFS= read -r корректно обрабатывают пустой список, а кавычки вокруг идентификаторов предотвращают ошибки при специальных символах. Перед этапом очистки убедитесь, что тестовые контейнеры остановлены и удалены; принудительный -f здесь не требуется.

Для более глубокого понимания основ контейнеризации, которые лежат в основе управления этими ресурсами, рекомендуем наше полное руководство по Docker для системных администраторов и DevOps. Для комплексной очистки Docker, включая образы и контейнеры, также полезно руководство по полной очистке Docker.

Итог: стратегия поддержания порядка в Docker-окружении

  1. Проверяйте перед удалением. Используйте inspect и фильтры для ps, чтобы убедиться в отсутствии зависимостей.
  2. Используйте правильный инструмент. Для отдельного проверенного ресурса применяйте rm; для плановой очистки неиспользуемых сетей и томов - prune с понятными фильтрами и labels.
  3. Не подменяйте проверку фильтром по времени. until=168h снижает охват очистки, но не определяет ценность данных и не заменяет резервную копию.
  4. Автоматизируйте только явные политики. Для cron и CI/CD используйте labels, блокировку от параллельного запуска и отдельный режим подтверждения.
  5. Проверяйте результат. После удаления выполните docker network ls, docker volume ls, docker system df и повторную проверку целевого ресурса через inspect.

Следование этим правилам позволяет поддерживать Docker-окружение в порядке без необоснованного риска для сервисов и данных. Для решения более сложных задач оркестрации, таких как отладка пользовательских ресурсов в Kubernetes, вам может пригодиться наш гайд по полной диагностике Custom Resources.

Часто задаваемые вопросы (FAQ)

Как удалить неиспользуемые Docker-сети?

Для удаления всех неиспользуемых пользовательских сетей используйте docker network prune. Для одной предварительно проверенной сети выполните docker network rm имя_сети. Если Docker сообщает, что сеть занята, проверьте подключённые контейнеры через docker network inspect; не используйте -f вместо устранения зависимостей.

Как удалить все неиспользуемые тома Docker разом?

Начните с docker volume prune. В Docker CLI, где доступен --all, команда без этого флага удаляет неиспользуемые anonymous volumes, а docker volume prune --all добавляет named volumes. Перед запуском проверьте справку своей версии и инвентаризацию docker volume ls, поскольку named volumes могут содержать данные, нужные после пересоздания контейнера.

Как удалить том, который занят контейнером?

Найдите контейнеры командой docker ps -a --filter volume=имя_тома. Если контейнер больше не нужен, остановите и удалите его, затем повторите docker volume rm имя_тома. Если том содержит данные приложения или БД, сначала перенесите данные либо создайте проверенную резервную копию. Принудительное удаление не является заменой этому процессу.

Чем docker volume prune отличается от docker system prune?

docker volume prune работает только с неиспользуемыми локальными томами и подходит для узкой задачи. docker system prune затрагивает также контейнеры, сети, образы и build-кэш, а с --volumes - тома. Перед docker system prune нет универсального dry-run, поэтому сначала используйте docker system df, docker network ls, docker volume ls и проверку зависимостей.

Как найти и удалить «висячие» (dangling) тома?

Найдите кандидатов командой docker volume ls -f dangling=true. Затем проверьте каждый через docker volume inspect имя_тома. «Висячие» тома не привязаны к контейнерам, но могут содержать данные. Массовая очистка через docker volume prune зависит от поведения конкретной версии Docker CLI; фильтр dangling=true для prune используйте только если он указан в справке команды.

Поделиться: