Domina `docker inspect`: Cómo extraer metadatos de contenedores e imágenes
Introducción
Cuando trabajás con Docker, saber qué tiene una imagen o un contenedor es vital. Ya sea que quieras depurar un comportamiento inesperado, optimizar la puesta en producción o simplemente entender la configuración que se le está pasando a un contenedor, el comando docker inspect es tu herramienta de referencia. Este post va a:
- Explicar de qué va a tratar cada campo más relevante del JSON que devuelve.
- Mostrarse ejemplos de uso, con la salida esperada para que tengas una referencia.
- Darte buenas prácticas y errores comunes al manejar estas respuestas.
Está dirigido a desarrolladores, DevOps y a cualquiera que esté empezando con Docker y necesite leer los metadata de sus recursos.
¿Qué es docker inspect?
docker inspect es un comando de Docker que devuelve información estructurada en JSON sobre objetos de Docker: contenedores, imágenes, volúmenes, redes, etc. A diferencia de docker ps o docker images, que ofrecen una vista tabular y resumida, inspect te entrega el gordo del objeto, con todas sus propiedades internas.
docker inspect <objeto>El <objeto> puede ser un ID, un nombre o cualquier referencia válida. Por ejemplo, docker inspect my_container o docker inspect ubuntu:latest.
A continuación, profundizaremos en los campos más útiles.
1. Metadatos de un contenedor
Cuando inspeccionás un contenedor, Docker devuelve un array con un solo elemento que contiene toda la información. La estructura más relevante es la siguiente:
| Campo | Descripción | Tipo | Ejemplo | Comentario |
|---|---|---|---|---|
Id |
SHA-1 del contenedor | string | a1b2c3d4... |
Útil para referenciarlo internamente. |
Image |
SHA-1 de la imagen base | string | sha256:7890... |
Toma nota que no es el tag. |
Command |
El comando ejecutado al iniciar | array | ['/bin/sh', '-c', 'python app.py'] |
Representa el CMD o ENTRYPOINT. |
Created |
Timestamp | string | 2024-07-01T12:34:56.789Z |
En UTC. |
State |
Estado actual | object | { "Running": true, "Paused": false, ... } |
Incluye ExitCode, Error, StartedAt. |
NetworkSettings |
Info de redes, IPs, puertos | object | { "Networks": { "bridge": { "IPAddress": "172.17.0.2" } } } |
Crucial para depurar puertos expuestos. |
Mounts |
Volúmenes montados | array | [{ "Source": "/tmp/data", "Destination": "/app/data", "Mode": "rw", "RW": true, "Propagation": "private" }] |
Sirve para ver bind-mounts y volúmenes. |
Config |
Configuración de ejecución | object | { "Hostname": "my_container", "Env": ["VAR=value"], "Cmd": ["python", "app.py"] } |
Mostrará variables de entorno y comando. |
HostConfig |
Configuración de host | object | { "Binds": ["/tmp/data:/app/data"], "PortBindings": { "80/tcp": [{ "HostPort": "8080" }] } } |
Información de puertos y mounts a nivel de host. |
1.1 Ejemplo práctico
Creemos un contenedor simple y luego lo inspeccionemos.
# Creamos un contenedor con bind-mount y puerto expuesto
run: bash
docker run -d --name demo_container \
-v $(pwd)/data:/app/data \
-p 8080:80 \
nginx:alpineAhora inspeccionamos:
run: bash
docker inspect demo_container > demo_container_inspect.jsonSalida esperada (fragmento reducido):
[
{
"Id": "f6d2c6e9b5e5...",
"Image": "sha256:9c2d...",
"Command": ["/usr/sbin/nginx", "-g", "daemon off;"] ,
"Created": "2024-07-02T14:12:45.123Z",
"State": {
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 1234,
"ExitCode": 0,
"Error": "",
"StartedAt": "2024-07-02T14:12:46.789Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"NetworkSettings": {
"Networks": {
"bridge": {
"IPAddress": "172.17.0.3"
}
}
},
"Mounts": [
{
"Source": "/home/user/data",
"Destination": "/app/data",
"Mode": "rw",
"RW": true,
"Propagation": "private"
}
],
"Config": {
"Hostname": "demo_container",
"Env": [],
"Cmd": ["/usr/sbin/nginx", "-g", "daemon off;"],
"Image": "nginx:alpine"
},
"HostConfig": {
"Binds": ["/home/user/data:/app/data:rw"],
"PortBindings": {
"80/tcp": [
{
"HostPort": "8080"
}
]
}
}
}
]Interpretación clave:
MountsyHostConfig.Bindscoinciden; el primero es la vista a nivel de contenedor, el segundo a nivel de host.NetworkSettings.Networks.bridge.IPAddresste muestra la IP interna asignada.HostConfig.PortBindingsrefleja la relación entre puertos internos y externos.
2. Metadatos de una imagen
La inspección de imágenes devuelve una lista de objetos, cada uno con información sobre la capa, sus comandos, variables de entorno y más.
| Campo | Descripción | Tipo | Ejemplo |
|---|---|---|---|
Id |
SHA-1 de la imagen | string | sha256:... |
RepoTags |
Los tags asociados | array | ["myapp:1.0", "myapp:latest"] |
Created |
Timestamp de construcción | string | |
Size |
Tamaño en bytes | integer | |
VirtualSize |
Tamaño total de capas | integer | |
Config |
Configuración del contenedor que se crea a partir de esta imagen | object | { "Env": ["DEBUG=1"], "Cmd": ["python", "app.py"] } |
RootFS |
Información de capas | object | { "Layers": ["sha256:abc...", "sha256:def..."], "Type": "layers" } |
Architecture |
Arquitectura | string | amd64 |
Os |
Sistema operativo | string | linux |
Labels |
Etiquetas de metadata | object | { "maintainer": "alice@example.com" } |
2.1 Ejemplo práctico
run: bash
docker pull busybox:1.36Inspeccionamos la imagen:
run: bash
docker inspect busybox:1.36 > busybox_inspect.jsonSalida esperada (fragmento reducido):
[
{
"Id": "sha256:1a2b3c...",
"RepoTags": ["busybox:1.36"],
"RepoDigests": [],
"Parent": "",
"Comment": "",
"Created": "2024-06-30T10:22:11.123Z",
"Container": "",
"ContainerConfig": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [],
"Cmd": ["/bin/sh"],
"Image": "",
"Volumes": {},
"WorkingDir": "",
"Entrypoint": [],
"OnBuild": [],
"Labels": {}
},
"DockerVersion": "26.1.0",
"Author": "",
"Config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [],
"Cmd": ["/bin/sh"],
"ArgsEscaped": true,
"Image": "",
"Volumes": {},
"WorkingDir": "",
"Entrypoint": [],
"OnBuild": [],
"Labels": {}
},
"Architecture": "amd64",
"Os": "linux",
"Size": 1457726,
"VirtualSize": 1457726,
"GraphDriver": {
"Data": {},
"Name": "overlay2"
},
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:abcd..."
]
}
}
]Interpretación clave:
Sizete da el tamaño de la capa ya reducida a su estado final.VirtualSizeindica el tamaño acumulado de todas las capas que componen la imagen.- La sección
Configreproduce elDockerfilede la última capa: comandos, variables y entrada.
3. Filtrar la salida JSON
En la práctica, la salida completa suele ser demasiado verbosa. Docker permite filtrar con --format o con jq locales.
3.1 Usar la plantilla --format
run: bash
# Obtener solo el IP interno del contenedor
Docker inspect demo_container --format '{{.NetworkSettings.Networks.bridge.IPAddress}}'3.2 Usar jq (ejemplo)
run: bash
cat demo_container_inspect.json | jq '.[0].Mounts[].Source'4. Buenas prácticas y errores comunes
| Problema | Solución | Comentarios |
|---|---|---|
| Múltiples contenedores con el mismo nombre | Usar `docker inspect $(docker ps -q --filter |
DUGLAS MORENO
Comentarios (0)
Sé el primero en comentar.