Limpieza en Docker: por qué, cuándo y cómo (variantes seguras)

Gabriel Gómez Gómez ·

Limpieza en Docker: por qué, cuándo y cómo (variantes seguras)

  • Mantener Docker limpio es clave para recuperar espacio, evitar conflictos de puertos/huérfanos, acelerar builds y mejorar la seguridad (imágenes obsoletas con vulnerabilidades). Aquí tienes un playbook con niveles de limpieza —de suave a quirúrgico— y comandos explicados. Funciona en Linux/macOS/WSL/PowerShell (prefiere docker CLI moderno y docker compose).

  • Revisa tu consumo antes de borrar (diagnóstico):

  • terminalBASH
    docker system df -v   # Uso detallado de imágenes, contenedores, volúmenes y cachés
    
  • Nivel 1 — Limpieza ligera (segura, no toca volúmenes):

  • terminalBASH
    # Contenedores detenidos
    docker container prune    # confirma interactivo
    # Imágenes 'dangling' (<none>)
    docker image prune
    # Redes sin uso (no touches 'bridge', 'host', 'none' si están en uso)
    docker network prune
    # (Opcional) Caché de build heredado
    docker builder prune
  • ¿Por qué? Elimina artefactos huérfanos típicos del ciclo dev (contenedores que ya no corren, capas temporales de builds). No borra datos persistentes.

  • Nivel 2 — Limpieza media (más agresiva, aún sin volúmenes):

  • terminalBASH
    # Todo lo que no esté en uso por al menos un contenedor en ejecución
    docker system prune -a   # -a elimina imágenes no usadas por NINGÚN contenedor
    # Builder cache (BuildKit) incluyendo stages intermedios
    docker builder prune -a  # borra caché de compilación
    
  • ¿Cuándo? Tras muchas iteraciones de builds/tags. Mejora mucho el espacio y fuerza builds frescos. No borra volúmenes (datos persistentes siguen intactos).

  • Nivel 3 — Limpieza con volúmenes (⚠️ BORRA DATOS):

  • terminalBASH
    # Incluye volúmenes no referenciados (datos persistentes)
    docker system prune -a --volumes
    # O solo volúmenes 'dangling'
    docker volume prune
    
  • ¿Cuándo? Ambientes desechables (CI, entornos efímeros) o cuando estás seguro de no necesitar los datos (p.ej., caches, DBs de prueba). Haz backup antes si hay dudas.

  • Limpieza quirúrgica por proyecto (evita dañar otros stacks):

  • terminalBASH
    # Etiqueta tus recursos al crear (ejemplo de build/compose):
    # docker build --label project=plan-hidrico -t app:dev .
    # En docker-compose.yml usa 'labels:' en servicios/volúmenes
    
    # Borra solo artefactos con cierta etiqueta
    docker image prune -a --filter "label=project=plan-hidrico"
    docker container prune   --filter "label=project=plan-hidrico"
    docker volume prune      --filter "label=project=plan-hidrico"
    docker network prune     --filter "label=project=plan-hidrico"
  • ¿Por qué? En hosts multi-proyecto compartidos evitarás tocar recursos de otros equipos.

  • Con Docker Compose (proyectos específicos):

  • terminalBASH
    # Apaga y elimina contenedores/REDES del proyecto actual (en la carpeta del compose)
    docker compose down
    # + Volúmenes declarados en el compose (⚠️ datos)
    docker compose down -v
    # + Contenedores huérfanos de corridas previas
    docker compose down --remove-orphans
    # Remueve servicios detenidos del proyecto (sin derribar todo)
    docker compose rm -f
  • Utiliza esto para limpiar por proyecto sin afectar otros stacks que corren en el mismo host.

  • 🔐 Seguridad y mantenibilidad: ¿por qué es necesario limpiar?

  • Espacio y rendimiento: capas y cachés antiguos consumen GBs y ralentizan builds.
    Reproducibilidad: eliminar imágenes obsoletas evita que se usen bases vulnerables por accidente.
    Menos ruido: redes/volúmenes/containers huérfanos dificultan el soporte y el monitoreo.
    CICD saludable: runners con disco lleno fallan; limpieza automática evita pipelines rotas.

  • 🧠 Patrones recomendados (dev/CI/producción):

  • Dev: docker system prune semanal; mensual -a; evita --volumes salvo que sean datos de prueba.
    CI: al final de cada job:
    docker system prune -af; y docker builder prune -af para caches.
    Prod: limpieza quirúrgica por etiqueta/proyecto; nunca borres volúmenes de DB sin backup/verificación.

  • 🧾 Trucos útiles:

  • terminalBASH
    # Listar solo lo 'dangling' antes de borrar (simula un dry-run)
    docker images -f dangling=true
    docker volume ls -f dangling=true
    
    # Borrar contenedores detenidos específicos (por filtro)
    docker ps -a --filter status=exited
    # Ejemplo: remover todos los 'exited'
    docker rm $(docker ps -aq -f status=exited)
    
    # Borrar imágenes sin etiquetas (none)
    docker rmi $(docker images -q -f dangling=true)
    
    # Caché BuildKit por antigüedad
    docker builder prune --filter until=168h   # > 7 días
    
    # Limitar logs en producción (daemon.json)
    # /etc/docker/daemon.json
    {
      "log-driver": "json-file",
      "log-opts": { "max-size": "10m", "max-file": "3" }
    }
    # Reinicia el daemon tras editar nsudo systemctl restart docker
  • Riesgos y cómo mitigarlos:

  • Pérdida de datos: -v/--volumes borra volúmenes; confirma que son caches/DBs de prueba. Usa backups.
    Servicios en producción: valida que el recurso no está en uso (
    docker ps, docker volume inspect).
    Dependencias ocultas: usa labels por proyecto y
    docker compose down para aislar el alcance.

  • Resumen operativo:

  • 1) Diagnostica: docker system df -v.
    2) Limpieza ligera:
    docker container/image/network prune.
    3) Limpieza media:
    docker system prune -a + docker builder prune -a.
    4) Con datos:
    docker system prune -a --volumes (solo si es seguro).
    5) Por proyecto: etiquetas +
    docker compose down(-v) y filtros --filter label=....