Ya sabes qué es Docker, lo tienes instalado y entiendes su arquitectura. Toca aprender a hablar con él. La buena noticia es que la CLI de Docker no es una colección arbitraria de comandos que haya que memorizar: está organizada siguiendo exactamente los cuatro tipos de objeto que viste en la lección anterior, con una gramática regular y predecible. Si entiendes esa gramática, deduces la mayoría de los comandos sin consultarlos. En esta lección verás la anatomía de la CLI moderna y sus alias históricos, el sistema de ayuda integrado (que es tu mejor referencia y siempre está actualizado), los comandos esenciales sobre imágenes, contenedores y sistema, una sesión completa comentada de principio a fin, y cómo domar la salida con --format y --filter para que te dé exactamente lo que necesitas.

Contenido

  1. La anatomía de la CLI moderna
  2. Alias cortos: la sintaxis histórica
  3. El sistema de ayuda
  4. Comandos esenciales sobre imágenes
  5. Comandos esenciales sobre contenedores
  6. Comandos de sistema
  7. Una sesión completa comentada
  8. Formatear la salida con --format
  9. Filtrar la salida con --filter

  1. La anatomía de la CLI moderna

La CLI moderna de Docker sigue una estructura de tres piezas:

docker <objeto> <acción> [opciones] [argumentos]
  • objeto: sobre qué tipo de cosa actúas. Son los del daemon: image, container, volume, network, más algunos de gestión (system, context, builder).
  • acción: qué le haces. El vocabulario se repite entre objetos: ls, rm, inspect, prune, create.
  • opciones y argumentos: modificadores y el objeto concreto.

Ejemplos que ilustran la regularidad:

docker container ls
docker image ls
docker volume ls
docker network ls

Los cuatro listan; solo cambia el tipo. Y lo mismo con borrar:

docker container rm mi-contenedor
docker image rm nginx:alpine
docker volume rm datos-aurora
docker network rm red-aurora

Esta tabla de acciones comunes vale para casi todos los objetos:

Acción Qué hace Ejemplo
ls Lista los objetos existentes docker image ls
inspect Muestra todos los metadatos en JSON docker container inspect web
rm Elimina uno o varios objetos docker volume rm datos
prune Elimina todos los objetos no usados de ese tipo docker image prune
create Crea el objeto sin arrancarlo docker network create red-aurora

La conclusión práctica: no memorices comandos, memoriza la gramática. Si necesitas listar volúmenes y nunca lo has hecho, docker volume ls es la apuesta obvia y es correcta.

  1. Alias cortos: la sintaxis histórica

Antes de la reorganización por objetos, los comandos eran planos: docker ps, docker images, docker rmi. Docker los mantuvo por compatibilidad, y en la práctica todo el mundo los sigue usando porque se escriben menos. Verás las dos formas constantemente, en documentación y en el trabajo real.

Alias corto Forma moderna equivalente Qué hace
docker ps docker container ls Lista contenedores en ejecución
docker ps -a docker container ls -a Lista todos los contenedores, también los parados
docker images docker image ls Lista imágenes locales
docker rmi docker image rm Elimina imágenes
docker pull docker image pull Descarga una imagen del registro
docker push docker image push Sube una imagen al registro
docker run docker container run Crea y arranca un contenedor
docker start docker container start Arranca un contenedor parado
docker stop docker container stop Para un contenedor en ejecución
docker restart docker container restart Para y arranca de nuevo
docker rm docker container rm Elimina contenedores
docker logs docker container logs Muestra la salida del contenedor
docker exec docker container exec Ejecuta un comando dentro de un contenedor
docker inspect docker container inspect / docker image inspect Metadatos en JSON
docker build docker buildx build Construye una imagen

Un par de advertencias sobre la tabla:

  • docker rm y docker rmi se parecen peligrosamente. rm borra contenedores; rmi borra imágenes. Una letra de diferencia y consecuencias muy distintas.
  • docker inspect sin objeto es ambiguo: busca primero un contenedor con ese nombre o ID y, si no lo encuentra, una imagen. Cuando quieras certeza, usa la forma larga.
  • docker build frente a docker buildx build: en versiones actuales, docker build ya usa BuildKit por debajo. La forma explícita docker buildx build es la recomendada en 2026 y la que usaremos a partir del módulo 2.

Recomendación para este curso: entiende la forma larga, usa la corta. Escribir docker ps es perfectamente profesional; lo que no es profesional es no saber que equivale a docker container ls.

  1. El sistema de ayuda

La CLI de Docker documenta cada comando y opción. Esta ayuda está siempre sincronizada con tu versión instalada, algo que ninguna web garantiza.

docker --help

Muestra los grupos de comandos por objeto (Management Commands) y los comandos sueltos (Commands), que son los alias del apartado anterior.

docker container --help

Lista todas las acciones disponibles sobre contenedores: attach, commit, cp, create, diff, exec, export, inspect, kill, logs, ls, pause, port, prune, rename, restart, rm, run, start, stats, stop, top, unpause, update, wait.

docker container run --help

Aquí está el detalle de cada opción. Es una salida larguísima —run tiene decenas de opciones— y por eso conviene filtrarla:

docker run --help | grep -i publish
  -p, --publish list       Publish a container's port(s) to the host
  -P, --publish-all        Publish all exposed ports to random ports

Qué hace este comando: encadena la ayuda a grep -i (búsqueda ignorando mayúsculas) para quedarte con las líneas que mencionan "publish". Es la forma más rápida de recordar una opción cuya letra has olvidado.

Dos comandos más de referencia:

docker version
docker system info

Ya los conoces; docker system info es simplemente la forma larga de docker info, y confirma que info también encaja en la gramática objeto-acción.

  1. Comandos esenciales sobre imágenes

Comando Qué hace Ejemplo
docker pull <imagen> Descarga una imagen del registro docker pull nginx:alpine
docker images Lista las imágenes locales docker images
docker rmi <imagen> Elimina una imagen local docker rmi nginx:alpine
docker image prune Borra imágenes "colgadas" (sin etiqueta) docker image prune
docker search <término> Busca imágenes en Docker Hub docker search postgres

Veámoslos en acción:

docker pull alpine:3.20
3.20: Pulling from library/alpine
f18232174bc9: Pull complete
Digest: sha256:1e42bbe2508154c9126d48c2b8a75420c3544343bf86fd041fb7527e017a4b4a
Status: Downloaded newer image for alpine:3.20
docker.io/library/alpine:3.20

Ya sabes leer esto de la lección 01-02: una capa descargada, el digest que identifica la imagen de forma inmutable, y en la última línea el nombre completo que Docker ha resuelto (docker.io/library/alpine:3.20), confirmando lo que viste sobre registros por defecto.

docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
nginx         alpine    3f8a4339aadd   2 days ago     52.5MB
alpine        3.20      a8560b36e8b8   3 weeks ago    8.83MB
hello-world   latest    d2c94e258dcb   9 months ago   13.3kB

Columna a columna:

  • REPOSITORY: el nombre del repositorio de la imagen.
  • TAG: la etiqueta, la "versión". latest es solo un nombre de etiqueta más (lección 01-05).
  • IMAGE ID: identificador corto (los primeros 12 caracteres del digest). Es lo que usarás para referirte a la imagen cuando no tenga nombre.
  • CREATED: cuándo se construyó la imagen, no cuándo la descargaste. Que hello-world diga "9 months ago" es normal.
  • SIZE: tamaño descomprimido. Ojo: estos tamaños no se suman directamente si las imágenes comparten capas, algo que verás con detalle en la lección 01-05.
docker rmi hello-world
Untagged: hello-world:latest
Untagged: hello-world@sha256:940c619fbd418f9b2b1b63e25d8861f9cc1b46e3fc8b018ccfe8b78f19b8cc4f
Deleted: sha256:d2c94e258dcb3c5ac2798d32e1249e42ef01cba4841c2234249495f87264ac5a

Fíjate en la diferencia entre las líneas: Untagged significa que se ha quitado un nombre que apuntaba a la imagen; Deleted significa que las capas se han borrado de verdad del disco. Si otra imagen o un contenedor siguiera usando esas capas, solo verías Untagged.

Un error muy habitual aparece si un contenedor (aunque esté parado) usa la imagen:

Error response from daemon: conflict: unable to remove repository reference "nginx:alpine"
(must force) - container 3f2a9c1b7e4d is using its referenced image 3f8a4339aadd

La lectura es literal: hay un contenedor usando esa imagen. Borra primero el contenedor.

La gestión avanzada de imágenes (etiquetado, exportación, limpieza fina) se trata en la lección 02-05.

  1. Comandos esenciales sobre contenedores

Comando Qué hace Ejemplo
docker run <imagen> Crea y arranca un contenedor nuevo docker run alpine echo hola
docker ps Lista contenedores en ejecución docker ps
docker ps -a Lista todos, incluidos los parados docker ps -a
docker stop <c> Para un contenedor (señal amable) docker stop web
docker start <c> Arranca un contenedor parado docker start web
docker restart <c> Para y vuelve a arrancar docker restart web
docker rm <c> Elimina un contenedor parado docker rm web
docker logs <c> Muestra su salida docker logs web

El punto conceptual más importante de este apartado:

docker run crea un contenedor NUEVO cada vez. No reutiliza el anterior. Para volver a arrancar uno existente se usa docker start.

Esa confusión es la causa número uno de que a los principiantes se les acumulen decenas de contenedores parados.

docker ps -a
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS                     PORTS                  NAMES
3f2a9c1b7e4d   nginx:alpine   "/docker-entrypoint.…"   2 minutes ago   Up 2 minutes               0.0.0.0:8080->80/tcp   aurora-web-demo
a71c04e9b2f8   alpine:3.20    "echo hola"              5 minutes ago   Exited (0) 5 minutes ago                          nervous_hopper

Cada columna:

  • CONTAINER ID: identificador corto. Puedes usar un prefijo único (3f2a bastaría).
  • IMAGE: de qué imagen nació.
  • COMMAND: el proceso principal que ejecuta, truncado.
  • STATUS: el dato clave. Up 2 minutes = en ejecución. Exited (0) = terminó, y ese 0 es el código de salida: 0 significa que terminó bien; cualquier otro número indica error (Exited (137) suele ser muerte por falta de memoria o kill).
  • PORTS: mapeos de puertos activos. 0.0.0.0:8080->80/tcp se lee "el puerto 8080 de cualquier interfaz del host va al 80 del contenedor".
  • NAMES: el nombre. Si no lo pones tú con --name, Docker inventa uno gracioso (nervous_hopper).

Sobre parar contenedores, conviene conocer la diferencia:

docker stop aurora-web-demo
docker kill aurora-web-demo
  • stop envía SIGTERM al proceso principal y espera 10 segundos a que termine ordenadamente; si no lo hace, entonces sí lo mata con SIGKILL. Es la forma correcta.
  • kill envía SIGKILL directamente: muerte inmediata, sin oportunidad de cerrar conexiones ni guardar nada.

Usa siempre stop salvo que el contenedor esté colgado. El ciclo de vida completo con todos sus estados se estudia en la lección 03-02, y las opciones de docker run en profundidad en la 03-01.

  1. Comandos de sistema

Comando Qué hace
docker info Estado y configuración del daemon
docker system df Espacio en disco por tipo de objeto
docker system df -v El mismo desglose, objeto por objeto
docker system prune Borra contenedores parados, redes sin usar, imágenes colgadas y caché de build
docker system prune -a Además, borra todas las imágenes que no use ningún contenedor
docker system prune -a --volumes Además, borra los volúmenes no usados

prune merece cuidado, porque es destructivo:

docker system prune
WARNING! This will remove:
  - all stopped containers
  - all networks not used by at least one container
  - all dangling images
  - unused build cache

Are you sure you want to continue? [y/N] y

Deleted Containers:
a71c04e9b2f8...

Total reclaimed space: 328.4MB

Lee siempre la lista antes de escribir y. Notas importantes:

  • La versión sin -a es razonablemente segura: borra contenedores parados (que quizá querías conservar, pero rara vez importan) e imágenes dangling, es decir, sin etiqueta, que suelen ser restos de construcciones anteriores.
  • La versión con -a es agresiva: borra todas las imágenes no usadas. Después tendrás que volver a descargarlo todo. En un portátil es un buen recurso cuando falta disco; en un servidor de producción, piénsatelo dos veces.
  • --volumes es el más peligroso: los volúmenes contienen datos. Borrar el volumen de la base de datos de Aurora Libros por error significa perder el catálogo.

Puedes evitar la pregunta con -f, pero justamente en este comando la confirmación es tu red de seguridad.

  1. Una sesión completa comentada

Vamos a recorrer una sesión de principio a fin, empezando y terminando con el sistema limpio. Ejecútala tú también.

Paso 1. Punto de partida.

docker ps -a
docker images

Si acabas de instalar Docker, verás solo las cabeceras de las tablas, sin filas. Si hiciste el hello-world de la lección 01-02, tendrás esa imagen y uno o dos contenedores parados.

Paso 2. Un contenedor que hace una cosa y muere.

docker run hello-world

Ya conoces la salida. Lo interesante viene ahora:

docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Vacío. El contenedor imprimió su mensaje y su proceso terminó, así que ya no está en ejecución. Pero:

docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED          STATUS                      NAMES
8b1d5e7c9a03   hello-world   "/hello"   30 seconds ago   Exited (0) 29 seconds ago   quirky_lamarr

Ahí sigue, parado, ocupando espacio. Esta es la lección más importante de la sesión: un contenedor que termina no desaparece.

Paso 3. Descargar una imagen y ejecutar un comando concreto.

docker pull alpine:3.20
docker run alpine:3.20 echo "Hola desde Aurora Libros"
Hola desde Aurora Libros

Qué ha ocurrido: Docker creó un contenedor a partir de alpine:3.20, sustituyó el comando por defecto de la imagen por echo "Hola desde Aurora Libros", lo ejecutó, y al terminar el proceso el contenedor pasó a Exited (0). Todo lo que va después del nombre de la imagen es el comando a ejecutar dentro.

Paso 4. Varios contenedores de la misma imagen.

docker run alpine:3.20 uname -a
docker run alpine:3.20 cat /etc/os-release
Linux 4c9e2a71f0b3 6.8.0-52-generic #52-Ubuntu SMP x86_64 Linux
NAME="Alpine Linux"
VERSION_ID=3.20.6
PRETTY_NAME="Alpine Linux v3.20"

Dos observaciones valiosísimas:

  • uname -a muestra el kernel del anfitrión (6.8.0-52-generic, un kernel de Ubuntu). Confirma con tus propios ojos lo de la lección 01-01: el contenedor comparte el kernel del host.
  • cat /etc/os-release dice "Alpine Linux". Es decir: kernel de Ubuntu, espacio de usuario de Alpine. Eso es un contenedor.

Y ahora:

docker ps -a --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
NAMES              IMAGE          STATUS
elegant_hertz      alpine:3.20    Exited (0) 10 seconds ago
zen_mendeleev      alpine:3.20    Exited (0) 25 seconds ago
kind_shirley       alpine:3.20    Exited (0) 50 seconds ago
quirky_lamarr      hello-world    Exited (0) 3 minutes ago

Cuatro contenedores parados de tres docker run con Alpine más el hello-world. Cada run creó uno nuevo. Ese --format que acabas de usar se explica en el apartado 8.

Paso 5. Ver los logs de un contenedor ya terminado.

docker logs elegant_hertz
NAME="Alpine Linux"
VERSION_ID=3.20.6
...

Aunque el contenedor esté parado, su salida se conserva. Es una herramienta de diagnóstico fundamental: si un contenedor muere al arrancar, docker logs te dice por qué.

Paso 6. Limpiar.

docker rm elegant_hertz zen_mendeleev
elegant_hertz
zen_mendeleev

rm acepta varios nombres o IDs y devuelve los que ha borrado. Para borrarlos todos de golpe:

docker container prune -f
Deleted Containers:
4c9e2a71f0b3...
8b1d5e7c9a03...

Total reclaimed space: 0B

container prune elimina todos los contenedores parados; -f salta la confirmación (aquí es seguro porque ya sabes lo que hay). Comprueba:

docker ps -a

Tabla vacía. Las imágenes, en cambio, siguen ahí:

docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
alpine        3.20      a8560b36e8b8   3 weeks ago    8.83MB
hello-world   latest    d2c94e258dcb   9 months ago   13.3kB

Borrar contenedores no borra imágenes. Una vez más: imagen y contenedor son objetos distintos.

  1. Formatear la salida con --format

Las tablas por defecto son anchas y traen columnas que a menudo no te interesan. --format acepta plantillas del lenguaje Go para que elijas tú.

Modo tabla, manteniendo cabeceras:

docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}"
NAMES              STATUS         PORTS
aurora-web-demo    Up 4 minutes   0.0.0.0:8080->80/tcp

La palabra table al principio activa el formato tabular con cabeceras; {{.Campo}} inserta un campo; \t separa columnas.

Modo línea libre, sin cabeceras, ideal para scripts:

docker ps --format "{{.Names}} está {{.Status}}"
aurora-web-demo está Up 4 minutes

Modo JSON, para procesar con otras herramientas:

docker ps --format json
docker images --format "{{json .}}"

Campos disponibles más útiles:

Objeto Campos frecuentes
docker ps .ID, .Names, .Image, .Command, .Status, .State, .Ports, .Size, .CreatedAt
docker images .ID, .Repository, .Tag, .Digest, .Size, .CreatedSince
docker volume ls .Name, .Driver, .Mountpoint
docker network ls .ID, .Name, .Driver, .Scope

Un ejemplo práctico que usarás mucho: obtener solo los IDs para pasárselos a otro comando.

docker ps -aq
3f2a9c1b7e4d
a71c04e9b2f8

-a (todos) combinado con -q (quiet, solo IDs). Y su uso típico:

docker rm $(docker ps -aq)

Cómo funciona: $(...) ejecuta primero el comando interior y sustituye su salida como argumentos del exterior. El resultado es "borra todos los contenedores parados". Cuidado: si algún contenedor está en ejecución, rm se quejará de ese en concreto y borrará el resto. Y si la lista está vacía, docker rm protestará por falta de argumentos, lo cual es inofensivo.

  1. Filtrar la salida con --filter

Mientras --format decide qué columnas ves, --filter (o -f) decide qué filas.

Filtros de contenedores más útiles:

docker ps -a --filter "status=exited"
docker ps --filter "name=aurora"
docker ps -a --filter "ancestor=alpine:3.20"
docker ps -a --filter "exited=1"

Qué hace cada uno:

  • status=exited: solo los terminados. Otros valores: running, paused, created, restarting, dead.
  • name=aurora: los que contengan "aurora" en el nombre (es subcadena, no coincidencia exacta). Muy útil con la convención de nombres de Aurora Libros.
  • ancestor=alpine:3.20: los creados a partir de esa imagen.
  • exited=1: los que terminaron con código de salida 1, es decir, los que fallaron. Oro puro para diagnosticar.

Filtros de imágenes:

docker images --filter "dangling=true"
docker images --filter "reference=alpine:*"
docker images --filter "before=nginx:alpine"
  • dangling=true: imágenes sin etiqueta, restos de construcciones. Son las que borra docker image prune.
  • reference=alpine:*: las que casan con ese patrón de nombre.
  • before=nginx:alpine: las creadas antes que esa imagen.

Y ahora la combinación de todo, que es donde la CLI brilla:

docker ps -a --filter "status=exited" --filter "exited=1" \
  --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"

Traducción: "muéstrame en una tabla con nombre, imagen y estado todos los contenedores que hayan terminado con error". Dos filtros se combinan con Y lógico.

Otro ejemplo orientado a nuestro proyecto:

docker rm $(docker ps -aq --filter "name=aurora" --filter "status=exited")

"Borra todos los contenedores parados cuyo nombre contenga aurora", sin tocar el resto de tu sistema. Cuando en los próximos módulos tengas aurora-api, aurora-db, aurora-cache y aurora-web conviviendo con otros experimentos, este patrón te ahorrará disgustos.

Errores Comunes y Consejos

  • Usar docker run para reanudar un contenedor. run siempre crea uno nuevo. Para reanudar, docker start <nombre>. Si te encuentras con 30 contenedores parados idénticos, esta es la causa.
  • Confundir docker rm con docker rmi. El primero borra contenedores, el segundo imágenes. Si dudas, usa las formas largas docker container rm y docker image rm.
  • Ejecutar docker system prune -a --volumes sin leer el aviso. Puedes borrar los datos de una base de datos de desarrollo en un segundo. Lee siempre la lista de lo que va a eliminar.
  • Creer que los contenedores parados no ocupan. Ocupan: su capa de escritura, sus logs y sus metadatos. Míralo con docker system df.
  • Olvidar -a en docker ps. "No tengo contenedores" suele significar "no tengo contenedores en ejecución". Ante la duda, docker ps -a.
  • Consejo: nombra siempre tus contenedores con --name. Los nombres aleatorios son imposibles de recordar. Con la convención aurora-api, aurora-db, etc., los filtros por nombre funcionan solos.
  • Consejo: usa prefijos de ID. No hace falta el ID completo: basta con los primeros caracteres si son únicos. docker stop 3f2a funciona.
  • Consejo: --help antes que Google. La ayuda integrada corresponde exactamente a tu versión; los blogs, a menudo no.

Ejercicios

Ejercicio 1: traduce a la forma larga

Reescribe estos comandos en la forma moderna docker <objeto> <acción> y explica qué hace cada uno:

docker ps -a
docker images
docker rmi alpine:3.20
docker logs -f aurora-web-demo
docker rm -f aurora-web-demo

Después, responde: ¿qué hace exactamente la opción -f en los dos últimos comandos? ¿Significa lo mismo?

Ejercicio 2: inventario y limpieza selectiva

Prepara el escenario ejecutando:

docker run --name aurora-prueba-1 alpine:3.20 echo "catalogo"
docker run --name aurora-prueba-2 alpine:3.20 sh -c "exit 1"
docker run --name otra-cosa alpine:3.20 echo "no tocar"

Ahora, usando --filter y --format:

  1. Lista en una tabla (nombre, imagen, estado) solo los contenedores cuyo nombre contenga aurora.
  2. Averigua cuál de ellos terminó con error, sin leer estado a estado.
  3. Borra en un único comando solo los contenedores parados cuyo nombre contenga aurora, dejando otra-cosa intacto.
  4. Comprueba que otra-cosa sigue ahí y que las imágenes no se han tocado.

Ejercicio 3: cuánto ocupa esto

Responde con comandos, no de memoria:

  1. ¿Cuánto espacio total ocupan tus imágenes y cuánto podrías recuperar?
  2. ¿Qué imagen concreta es la más grande que tienes?
  3. Si ejecutaras docker system prune (sin -a), ¿qué se borraría exactamente en tu sistema ahora mismo? Averígualo antes de ejecutarlo.

Soluciones

Solución al ejercicio 1

Forma corta Forma larga Qué hace
docker ps -a docker container ls -a Lista todos los contenedores, en ejecución y parados
docker images docker image ls Lista las imágenes locales
docker rmi alpine:3.20 docker image rm alpine:3.20 Elimina esa imagen del disco local
docker logs -f aurora-web-demo docker container logs -f aurora-web-demo Muestra la salida del contenedor y sigue mostrándola en vivo
docker rm -f aurora-web-demo docker container rm -f aurora-web-demo Elimina el contenedor aunque esté en ejecución

Sobre -f: no significa lo mismo en los dos casos, y es una fuente clásica de confusión.

  • En docker logs -f, -f es --follow: no cierra la salida, se queda escuchando y muestra las nuevas líneas según aparecen (como tail -f). Se sale con Ctrl+C, lo cual no afecta al contenedor.
  • En docker rm -f, -f es --force: mata el contenedor si está en ejecución y luego lo elimina. Sin -f, docker rm sobre un contenedor activo devuelve un error pidiéndote que lo pares primero.

Moraleja: las letras de opción se reutilizan con significados distintos según el comando. Ante la duda, --help.

Solución al ejercicio 2

# 1. Tabla filtrada por nombre
docker ps -a --filter "name=aurora" \
  --format "table {{.Names}}\t{{.Image}}\t{{.Status}}"
NAMES              IMAGE         STATUS
aurora-prueba-2    alpine:3.20   Exited (1) 5 seconds ago
aurora-prueba-1    alpine:3.20   Exited (0) 10 seconds ago

(El filtro name=aurora es por subcadena, así que solo aparecen aurora-prueba-1 y aurora-prueba-2.)

# 2. Solo los que fallaron
docker ps -a --filter "exited=1" --format "{{.Names}}"
aurora-prueba-2

El filtro exited=1 selecciona por código de salida. aurora-prueba-2 ejecutaba sh -c "exit 1", que termina con código 1, de ahí que sea el único que aparece. Es mucho más rápido que leer la columna STATUS de una lista larga.

# 3. Borrado selectivo
docker rm $(docker ps -aq --filter "name=aurora" --filter "status=exited")
9c1e77ab4d20
5b3f0a2e8c14

Desglose: el comando interior docker ps -aq --filter ... --filter ... devuelve solo los IDs (-q) de los contenedores parados cuyo nombre contiene "aurora". La sustitución $(...) los pasa como argumentos a docker rm. Como otra-cosa no casa con el filtro de nombre, no entra en la lista y sobrevive.

# 4. Comprobaciones
docker ps -a --format "table {{.Names}}\t{{.Status}}"
docker images

Verás únicamente otra-cosa en la lista de contenedores, y alpine:3.20 intacta en las imágenes. Borrar contenedores nunca borra imágenes.

Solución al ejercicio 3

# 1. Total y recuperable
docker system df

Lee la fila Images: la columna SIZE es el total ocupado y RECLAIMABLE lo que liberarías eliminando las imágenes que ningún contenedor usa. El porcentaje entre paréntesis te da la proporción de un vistazo.

# 2. La imagen más grande
docker images --format "{{.Size}}\t{{.Repository}}:{{.Tag}}" | sort -h -r | head -5

--format produce una línea por imagen con tamaño y nombre; sort -h -r ordena por tamaño legible por humanos (-h entiende "MB", "GB") de mayor a menor (-r); head -5 se queda con las cinco primeras. La primera línea es tu imagen más grande.

# 3. Qué se borraría con prune (sin ejecutarlo)
docker ps -a --filter "status=exited" --format "table {{.Names}}\t{{.Status}}"
docker images --filter "dangling=true"
docker network ls
docker builder du

Razonamiento: docker system prune sin -a elimina cuatro cosas, así que las inspeccionas por separado antes: los contenedores parados (primer comando), las imágenes colgadas sin etiqueta (segundo), las redes no usadas por ningún contenedor (tercero; las redes por defecto bridge, host y none nunca se borran) y la caché de construcción (cuarto, que muestra cuánto ocupa). Con esa foto previa sabes exactamente qué vas a perder antes de confirmar con y.

Conclusión

La CLI de Docker no se memoriza, se deduce: docker <objeto> <acción> [opciones], donde los objetos son los que gestiona el daemon (image, container, volume, network, system) y las acciones se repiten entre ellos (ls, rm, inspect, prune). Los alias históricos —docker ps, docker images, docker rmi— siguen siendo la forma habitual de escribirlos, y ahora sabes a qué corresponden.

Te llevas los comandos esenciales sobre imágenes (pull, images, rmi), sobre contenedores (run, ps, ps -a, stop, start, rm, logs) y de sistema (info, system df, system prune), y dos ideas que evitarán la mitad de tus tropiezos futuros: docker run crea siempre un contenedor nuevo, y un contenedor que termina no desaparece. Además, con --format y --filter puedes pedirle a Docker exactamente las filas y columnas que necesitas, algo que resulta imprescindible en cuanto tienes más de tres o cuatro objetos entre manos.

En la sesión práctica has visto algo revelador: un contenedor de Alpine mostrando el kernel de Ubuntu del anfitrión. Ese sistema de archivos de Alpine, empaquetado y descargado en segundos, es una imagen, y todavía no sabes realmente qué hay dentro. En la siguiente lección, Entendiendo las Imágenes de Docker, abrirás esa caja: capas, copy-on-write, digests, etiquetas, imágenes base, y por qué latest no significa lo que crees.

Docker: De Principiante a Avanzado

Módulo 1: Introducción a Docker

Módulo 2: Trabajando con Imágenes Docker

Módulo 3: Contenedores Docker

Módulo 4: Docker Compose

Módulo 5: Conceptos Avanzados de Docker

Módulo 6: Docker en Producción

Módulo 7: Ecosistema y Herramientas de Docker

© Copyright 2026. Todos los derechos reservados