Contenido

Tutorial de imágenes Docker: pull, images, tag, rmi y estructura por capas

Una imagen (image) es una plantilla para crear contenedores. Cuando ejecutaste docker run nginx:1.30 en la sección anterior, Docker descargó primero la imagen nginx:1.30. En esta sección aprenderás cómo se nombran, descargan, consultan y eliminan las imágenes, y cómo se organizan «capa por capa».

Componentes del nombre de una imagen

El nombre completo de una imagen tiene este aspecto:

docker.io/library/nginx:1.30-alpine
└───┬───┘ └──┬──┘ └─┬─┘ └────┬────┘
 registry  namespace  nombre   tag
ParteDescripciónValor predeterminado si se omite
registryServidor que almacena imágenesdocker.io (Docker Hub)
Espacio de nombresNombre del usuario o la organizaciónlibrary para las imágenes oficiales
Nombre (repository)Nombre de la imagenNo se puede omitir
tagEtiqueta de versiónlatest

Las siguientes tres formas se refieren a la misma imagen:

docker pull nginx
docker pull nginx:latest
docker pull docker.io/library/nginx:latest

Para imágenes de otros registry, escribe la dirección completa. Por ejemplo, ghcr.io/owner/app:1.0 de GitHub y gcr.io/distroless/static-debian13 de Google.

Nombres de tag habituales

Las imágenes oficiales suelen ofrecer varias variantes:

Ejemplo de tagSignificado
python:3.14Versión completa basada en Debian, que incluye muchas herramientas, como las de compilación
python:3.14-slimDebian reducido, que conserva solo lo necesario para ejecutar Python
python:3.14-alpineBasada en Alpine Linux; ocupa el menor espacio
node:24-trixieEspecifica el nombre en clave de la versión de Debian (trixie = Debian 13)
nginx:1.30 / nginx:1.31Versiones stable (pares) y mainline (impares) de nginx

Más adelante, descargarás estas tres imágenes de Python y compararás sus tamaños.

Descargar imágenes: docker pull

Si la imagen no está en el equipo local cuando ejecutas docker run, se descarga automáticamente. docker pull solo la descarga, sin ejecutarla. Si vuelves a ejecutar pull para una imagen que ya tienes, Docker comprueba si hay actualizaciones:

$ docker pull nginx:1.30
1.30: Pulling from library/nginx
Digest: sha256:9bf97bd7714f5e24c1ccd545ecb9eb5435cb6d109c97cebb15e7e455e0239edb
Status: Image is up to date for nginx:1.30
docker.io/library/nginx:1.30

Image is up to date significa que la imagen local ya está actualizada y no se ha vuelto a descargar. La última línea muestra el nombre completo de la imagen; ahí puedes ver el registry predeterminado docker.io y el espacio de nombres library.

Comprueba cómo se comparten las capas

Ahora descarga otra versión de nginx, la 1.31:

$ docker pull nginx:1.31
1.31: Pulling from library/nginx
ecc510c1e359: Already exists
807ab930f3a0: Pull complete
04bdbc7ea6b5: Pull complete
f7e1db57b58b: Pull complete
8020170dc65f: Pull complete
1efc53192927: Pull complete
947d22046304: Pull complete
Digest: sha256:f9ea18bfa4fad859e1ed38259d711da7ccad2c3516e875cec3351a57c859f571
Status: Downloaded newer image for nginx:1.31
docker.io/library/nginx:1.31

La primera capa, ecc510c1e359, muestra Already exists: nginx 1.30 y 1.31 parten de la misma capa base de Debian 13, que ya está en el disco y no hace falta descargar de nuevo. Así se comparten las capas base de las imágenes, como explicamos en la sección 1.

Lo mismo ocurre al descargar python:3.14-slim, que también está basada en Debian 13:

$ docker pull python:3.14-slim
3.14-slim: Pulling from library/python
ecc510c1e359: Already exists
a5883d972f3b: Pull complete
6aaf5b0aae75: Pull complete
bb8166eb34e6: Pull complete
Digest: sha256:a2b82f3c48559aa0a8446d9af49826b6e2b2016f4cd2afabfe6013ec53729170
Status: Downloaded newer image for python:3.14-slim
docker.io/library/python:3.14-slim

Consultar imágenes locales: docker images

$ docker images
IMAGE                ID             DISK USAGE   CONTENT SIZE   EXTRA
hello-world:latest   5e2309035332       25.9kB         9.49kB   U
nginx:1.30           9bf97bd7714f        242MB         66.5MB
nginx:1.31           f9ea18bfa4fa        243MB         66.7MB
ubuntu:26.04         f144425ff09b        162MB         45.6MB

El formato de salida de docker images en Docker 29 es distinto del de las versiones anteriores. Los campos antiguos eran REPOSITORY TAG IMAGE ID CREATED SIZE, y muchos tutoriales en Internet todavía muestran ese formato. No te preocupes si ves algo diferente: la información es la misma.

CampoSignificado
IMAGENombre y tag
IDLos primeros 12 caracteres del ID de la imagen
DISK USAGEEspacio que ocupa en el disco después de descomprimirse
CONTENT SIZETamaño del contenido comprimido; equivale aproximadamente al tamaño de la descarga
EXTRAU indica que hay un contenedor en uso (In use); en este caso, es el contenedor hello-world que quedó de la sección anterior

docker image ls y docker images son el mismo comando. Estas son algunas formas habituales de filtrar:

$ docker images -q
b9767f56a1cc
a2b82f3c4855
9bf97bd7714f
f9ea18bfa4fa
f6a589d43c42
f144425ff09b
5e2309035332

-q muestra solo los ID y se suele combinar con otros comandos para procesarlos por lotes. docker images nginx muestra solo nginx; docker images --filter dangling=true muestra las imágenes «colgantes», que no tienen nombre y suelen ser versiones antiguas sustituidas tras volver a construir la imagen.

Comparar las versiones slim, alpine y completa

Descarga también las otras dos versiones de Python:

$ docker pull python:3.14-alpine
3.14-alpine: Pulling from library/python
e2de96513ba9: Pull complete
48f6a2588427: Pull complete
2a22c5887fa2: Pull complete
d486488257d0: Pull complete
Digest: sha256:f6a589d43c42b9e7f7dc67a12d37132491f362859a5d750607710cc56da3bc72
Status: Downloaded newer image for python:3.14-alpine
docker.io/library/python:3.14-alpine

$ docker pull python:3.14
3.14: Pulling from library/python
4846f2900730: Pull complete
62fe2e747f69: Pull complete
4dc3950125eb: Pull complete
b2eb680928d4: Pull complete
083b5813628d: Pull complete
9b0ef59a9f4a: Pull complete
6e255bfcc16c: Pull complete
Digest: sha256:b9767f56a1cc620aa72d38cc3557d26412e38a4597c92953476136b78894ccbd
Status: Downloaded newer image for python:3.14
docker.io/library/python:3.14
$ docker images python
IMAGE                ID             DISK USAGE   CONTENT SIZE   EXTRA
python:3.14          b9767f56a1cc       1.63GB          433MB
python:3.14-alpine   f6a589d43c42       82.6MB           21MB
python:3.14-slim     a2b82f3c4855        180MB         45.7MB

Aunque todas son Python 3.14, la diferencia es enorme:

VersiónDescarga (CONTENT SIZE)Espacio en disco (DISK USAGE)
python:3.14433 MB1.63 GB
python:3.14-slim45.7 MB180 MB
python:3.14-alpine21 MB82.6 MB
  • La versión completa incluye herramientas de compilación como gcc; es adecuada cuando necesitas compilar paquetes dentro de la imagen (o como etapa de compilación en una compilación multietapa).
  • slim es una buena opción para la mayoría de las aplicaciones.
  • alpine es la más pequeña, pero usa musl en lugar de glibc. Algunos paquetes que requieren compilación (como ciertos paquetes de Python) son más difíciles de instalar en Alpine. Si tienes dudas, slim suele ser la opción más segura.

Añadir una etiqueta a una imagen: docker tag

docker tag no copia la imagen; solo añade otro nombre que apunta al mismo contenido:

$ docker tag nginx:1.30 myname/nginx:v1

$ docker images --filter reference=nginx:1.30 --filter reference=myname/nginx
IMAGE             ID             DISK USAGE   CONTENT SIZE   EXTRA
myname/nginx:v1   9bf97bd7714f        242MB         66.5MB
nginx:1.30        9bf97bd7714f        242MB         66.5MB

El ID es el mismo en ambas líneas, lo que significa que son la misma imagen. Antes de subirla a Docker Hub, debes asignarle un nombre con este formato: tu_cuenta/nombre:tag. Consulta Subir a Docker Hub.

Una etiqueta no fija la versión

Una etiqueta es solo un «tag»; los responsables pueden hacer que apunte a contenido nuevo en cualquier momento. El mes que viene, nginx:1.30 podría apuntar a la versión 1.30.6. Si necesitas fijar la versión por completo, puedes usar un digest (el hash SHA256 del contenido):

$ docker images --digests nginx
REPOSITORY   TAG       DIGEST                                                                    IMAGE ID       CREATED      SIZE
nginx        1.30      sha256:9bf97bd7714f5e24c1ccd545ecb9eb5435cb6d109c97cebb15e7e455e0239edb   9bf97bd7714f   6 days ago   242MB
nginx        1.31      sha256:f9ea18bfa4fad859e1ed38259d711da7ccad2c3516e875cec3351a57c859f571   f9ea18bfa4fa   6 days ago   243MB
docker pull nginx@sha256:9bf97bd7714f5e24c1ccd545ecb9eb5435cb6d109c97cebb15e7e455e0239edb

Al descargarla usando el digest, siempre obtendrás exactamente el mismo contenido.

Eliminar imágenes: docker rmi

Si algún contenedor (incluso uno detenido) está usando esta imagen, no podrás eliminarla:

$ docker run -d --name web nginx:1.30
e34409bcf1727f02fc3b0558d202dd057f2116b4a2e9186f83bbed4625842272

$ docker rmi nginx:1.30
Error response from daemon: conflict: unable to delete nginx:1.30 (must be forced) - container e34409bcf172 is using its referenced image 9bf97bd7714f

Primero elimina el contenedor que la usa y luego elimina la imagen:

$ docker rm -f web
web

$ docker rmi nginx:1.30
Untagged: nginx:1.30
Deleted: sha256:9bf97bd7714f5e24c1ccd545ecb9eb5435cb6d109c97cebb15e7e455e0239edb
  • Untagged: se elimina el nombre.
  • Deleted: la imagen solo se elimina de verdad cuando ningún otro nombre apunta a ella. Si todavía hay alias como myname/nginx:v1 que apuntan a la misma imagen, solo verás Untagged.

Limpia las imágenes que no necesites:

docker image prune      # Elimina solo las imágenes colgantes (sin nombre, <none>)
docker image prune -a   # Elimina todas las imágenes que no estén siendo usadas por contenedores

Estructura en capas de una imagen: docker history

docker history enumera cada capa de una imagen y el comando del Dockerfile que la generó:

$ docker history nginx:1.30
IMAGE          CREATED      CREATED BY                                      SIZE      COMMENT
9bf97bd7714f   6 days ago   CMD ["nginx" "-g" "daemon off;"]                0B        buildkit.dockerfile.v0
<missing>      6 days ago   STOPSIGNAL SIGQUIT                              0B        buildkit.dockerfile.v0
<missing>      6 days ago   EXPOSE map[80/tcp:{}]                           0B        buildkit.dockerfile.v0
<missing>      6 days ago   ENTRYPOINT ["/docker-entrypoint.sh"]            0B        buildkit.dockerfile.v0
<missing>      6 days ago   COPY 30-tune-worker-processes.sh /docker-ent…   16.4kB    buildkit.dockerfile.v0
<missing>      6 days ago   COPY 20-envsubst-on-templates.sh /docker-ent…   12.3kB    buildkit.dockerfile.v0
<missing>      6 days ago   COPY 15-local-resolvers.envsh /docker-entryp…   12.3kB    buildkit.dockerfile.v0
<missing>      6 days ago   COPY 10-listen-on-ipv6-by-default.sh /docker…   12.3kB    buildkit.dockerfile.v0
<missing>      6 days ago   COPY docker-entrypoint.sh / # buildkit          8.19kB    buildkit.dockerfile.v0
<missing>      6 days ago   RUN /bin/sh -c set -x     && groupadd --syst…   88.2MB    buildkit.dockerfile.v0
<missing>      6 days ago   ENV DYNPKG_RELEASE=1~trixie                     0B        buildkit.dockerfile.v0
<missing>      6 days ago   ENV PKG_RELEASE=1~trixie                        0B        buildkit.dockerfile.v0
<missing>      6 days ago   ENV ACME_VERSION=0.4.1                          0B        buildkit.dockerfile.v0
<missing>      6 days ago   ENV NJS_RELEASE=1~trixie                        0B        buildkit.dockerfile.v0
<missing>      6 days ago   ENV NJS_VERSION=1.0.1                           0B        buildkit.dockerfile.v0
<missing>      6 days ago   ENV NGINX_VERSION=1.30.5                        0B        buildkit.dockerfile.v0
<missing>      6 days ago   LABEL maintainer=NGINX Docker Maintainers <d…   0B        buildkit.dockerfile.v0
<missing>      7 days ago   # debian.sh --arch 'amd64' out/ 'trixie' '@1…   87.7MB    debuerreotype 0.17

Lee de abajo hacia arriba:

  1. La capa inferior es la imagen base de Debian 13 (trixie), de 87.7 MB.
  2. En el medio, RUN ... groupadd ... instala nginx; ocupa 88.2 MB y es la capa más grande.
  3. COPY añade los scripts de inicio, que solo ocupan unos pocos KB.
  4. ENV, EXPOSE, CMD y otros solo configuran opciones, por eso ocupan 0B.

<missing> no indica un error. Solo significa que esas capas intermedias se construyeron en otra máquina y no tienen un ID independiente en esta máquina.

Las capas ofrecen dos ventajas:

  • Uso compartido: si varias imágenes usan Debian 13 como base, esa capa se almacena y se descarga una sola vez (el Already exists anterior).
  • Caché: al construir una imagen, las capas que no han cambiado se pueden reutilizar directamente. Esta es la base de la caché de compilación.

Al iniciar un contenedor, Docker añade una capa escribible encima de estas capas de solo lectura. Los archivos que creas o modificas dentro del contenedor se escriben en esta capa. Cuando eliminas el contenedor, la capa también desaparece, así que debes guardar los datos que quieras conservar en un Volume.

En Docker Desktop, también puedes hacer clic en una imagen para ver la misma información de capas:

Docker Desktop muestra las capas de una imagen
Página de detalles de una imagen en Docker Desktop: Layers enumera los comandos y el tamaño de cada capa. Imagen: documentación oficial de Docker (Apache-2.0)

Consultar la configuración de una imagen: docker inspect

docker inspect muestra la configuración completa de una imagen (un bloque grande de JSON). Usa --format para obtener solo los campos que necesitas:

$ docker inspect --format '{{.Config.Cmd}}' nginx:1.30
[nginx -g daemon off;]

$ docker inspect --format '{{.Os}}/{{.Architecture}}' nginx:1.30
linux/amd64

$ docker inspect --format '{{json .Config.ExposedPorts}}' nginx:1.30
{"80/tcp":{}}

$ docker inspect --format '{{range .Config.Env}}{{println .}}{{end}}' nginx:1.30
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NGINX_VERSION=1.30.5
NJS_VERSION=1.0.1
NJS_RELEASE=1~trixie
ACME_VERSION=0.4.1
PKG_RELEASE=1~trixie
DYNPKG_RELEASE=1~trixie

Aquí puedes ver que, al iniciar el contenedor, el comando predeterminado es nginx -g daemon off;, que esta es la versión linux/amd64, que se expone el puerto 80 y cuáles son las variables de entorno incluidas en la imagen.

Exportar e importar: docker save / load

Para transferir imágenes entre máquinas sin conexión a Internet, puedes guardarlas en un archivo tar:

$ docker save -o nginx-1.30.tar nginx:1.30

$ ls -lh nginx-1.30.tar
-rw-------    1 root     root       63.4M Oct 12 14:41 nginx-1.30.tar

$ docker rmi nginx:1.30
Untagged: nginx:1.30
Deleted: sha256:9bf97bd7714f5e24c1ccd545ecb9eb5435cb6d109c97cebb15e7e455e0239edb

$ docker load -i nginx-1.30.tar
Loaded image: nginx:1.30

Copia el archivo tar a otra máquina y ejecuta docker load para usar la imagen; no necesitas conectarte a Docker Hub.

Administrar imágenes con Docker Desktop

Haz clic en Images en el menú lateral de Docker Desktop para ver todas las imágenes locales, lo que equivale a docker images. Los botones de la derecha permiten ejecutarlas o eliminarlas directamente:

Pantalla Images de Docker Desktop
La pantalla Images muestra las imágenes locales, sus tags, tamaño y fecha de creación. Imagen: documentación oficial de Docker (Apache-2.0)

Resumen de comandos

ComandoFunción
docker pull nombre:tagDescargar una imagen
docker imagesEnumerar las imágenes locales
docker images -qMostrar solo los ID
docker tag origen nombre-nuevoAñadir un nombre / tag nuevo
docker rmi nombreEliminar una imagen
docker image prune -aEliminar todas las imágenes sin usar
docker history nombreConsultar las capas
docker inspect nombreConsultar la configuración
docker save -o a.tar nombreExportar a un archivo tar
docker load -i a.tarImportar desde un archivo tar

En la siguiente sección veremos los estados por los que pasa un contenedor desde su creación hasta su eliminación.

Resumen

  • El nombre de una imagen tiene el formato [registry/]repositorio:tag; las imágenes oficiales no llevan prefijo.
  • Varias imágenes pueden compartir la misma capa base, que solo se descarga y almacena una vez.
  • slim es una buena opción para la mayoría de las aplicaciones; alpine ocupa menos, pero tiene menos compatibilidad.
  • docker history muestra qué comando generó cada capa.

Ejercicios

Ejercicio 1: Descarga alpine:3.23 y python:3.14-alpine, y observa si aparece Already exists durante la segunda descarga.

Pista

Si ambos usan la misma capa base de Alpine, la segunda descarga mostrará Already exists para esa capa y no será necesario volver a descargarla. Puedes comparar las capas más inferiores de ambos con docker history.

Ejercicio 2: Añade un nombre nuevo, mysite/web:test, a nginx:1.30 y, después, elimina ese nombre. ¿Sigue estando nginx:1.30?

Respuesta
docker tag nginx:1.30 mysite/web:test
docker rmi mysite/web:test

Sí. Al eliminar un nombre, docker rmi solo muestra Untagged. Mientras la imagen tenga otro nombre, su contenido real no se eliminará.

Preguntas frecuentes

¿latest es la versión más reciente?

No necesariamente. latest es solo un nombre de tag común, y quien lo mantiene decide a qué versión apunta. En producción, indica una versión concreta, por ejemplo nginx:1.30.

¿Por qué los campos de docker images en Docker 29 son distintos de los que veo en Internet?

Docker 29 cambió el formato a IMAGE ID DISK USAGE CONTENT SIZE EXTRA; las versiones anteriores usaban REPOSITORY TAG IMAGE ID CREATED SIZE. Consulta la explicación de este capítulo.

¿Debo elegir slim o alpine?

Para la mayoría de las aplicaciones, elige slim. alpine es la más pequeña, pero usa musl libc, por lo que algunos paquetes que requieren compilación, especialmente Python, pueden fallar o tardar mucho en instalarse.

Actualizado 14 de octubre de 2026