# docker debug

**Descripción:** Obtén una shell en cualquier contenedor o imagen. Una alternativa para depurar con `docker exec`.

**Uso:** `debug [OPTIONS] {CONTAINER|IMAGE}`










## Descripción

Docker Debug es un comando de CLI que te ayuda a seguir las buenas prácticas manteniendo tus imágenes pequeñas y seguras.
Con Docker Debug, puedes depurar tus imágenes mientras estas contienen lo mínimo indispensable para ejecutar tu aplicación.
Logra esto permitiéndote crear y trabajar con imágenes o contenedores slim (ligeros) que a menudo son difíciles de depurar porque se han eliminado todas las herramientas.
Por ejemplo, mientras que los enfoques de depuración habituales como `docker exec -it my-app bash` podrían no funcionar en un contenedor slim, `docker debug` funcionará.

Con `docker debug` puedes obtener una shell de depuración en cualquier contenedor o imagen, incluso si no contienen una shell.
No necesitas modificar la imagen para usar Docker Debug.
Además, usar Docker Debug no modificará tu imagen en absoluto.
Docker Debug trae su propia caja de herramientas (toolbox) que puedes personalizar.
La caja de herramientas viene con muchas herramientas estándar de Linux preinstaladas, como `vim`, `nano`, `htop` y `curl`.
Usa el comando integrado `install` para añadir herramientas adicionales disponibles en https://search.nixos.org/packages.
Docker Debug es compatible con `bash`, `fish` y `zsh`.
Por defecto, intenta autodetectar tu shell.


Herramientas integradas personalizadas:
- `install [herramienta1] [herramienta2]`: Añade paquetes de Nix desde: https://search.nixos.org/packages, consulta el [ejemplo](#managing-your-toolbox-using-the-install-command).
- `uninstall [herramienta1] [herramienta2]`: Desinstala paquetes de Nix.
- `entrypoint`: Muestra en pantalla, analiza (lint) o ejecuta el punto de entrada (entrypoint), consulta el [ejemplo](#understanding-the-default-startup-command-of-a-container-entry-points).
- `builtins`: Muestra las herramientas integradas personalizadas.

> [!NOTE]
>
> Para imágenes y contenedores detenidos, todos los cambios se descartan al salir de la shell.
> En ningún momento los cambios afectan a la imagen o contenedor real.
> Al acceder a contenedores en ejecución o pausados, todos los cambios en el sistema de archivos son directamente visibles para el contenedor.
> El directorio `/nix` nunca es visible para la imagen o el contenedor real.


## Opciones

| Opción                                                        | Predeterminado                                        | Descripción                                                                                                                                    |
| ------------------------------------------------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|  | `--shell` | `auto` |  Selecciona una shell. Compatibles: `bash`, `fish`, `zsh`, `auto`. |

 | `-c`, `--command` |  |  Evalúa los comandos especificados en lugar de iniciar una sesión interactiva, consulta el [ejemplo](#running-commands-directly-eg-for-scripting). |

 | `--host` |  |  Socket de Docker del demonio al que conectarse. Ej.: `ssh://root@example.org`, `unix:///some/path/docker.sock`, consulta el [ejemplo](#remote-debugging-using-the---host-option). |




## Ejemplos

### Depurar contenedores que no tienen shell (contenedores slim)

La imagen `hello-world` es muy simple y solo contiene el binario `/hello`.
Es un buen ejemplo de una imagen slim.
No hay otras herramientas ni shell.

Ejecuta un contenedor a partir de la imagen `hello-world`:

```console
$ docker run --name my-app hello-world
```

El contenedor finaliza inmediatamente. Para obtener una shell de depuración dentro, ejecuta:

```console
$ docker debug my-app
```

La shell de depuración te permite inspeccionar el sistema de archivos:

```console
docker > ls
dev  etc  hello  nix  proc  sys
```

El archivo `/hello` es el binario que se ejecutó al iniciar el contenedor.
Puedes confirmar esto ejecutándolo directamente:

```console
docker > /hello
```

Después de ejecutar el binario, produce la misma salida.

### Depurar imágenes (slim)

Puedes depurar imágenes directamente ejecutando:

```console
$ docker debug hello-world
...
docker > ls
dev  etc  hello  nix  proc  sys
```

Ni siquiera necesitas descargar (pull) la imagen, ya que `docker debug` lo hará automáticamente al igual que el comando `docker run`.

### Modificar archivos de un contenedor en ejecución

Docker Debug te permite modificar archivos en cualquier contenedor en ejecución.
La caja de herramientas viene con `vim` y `nano` preinstalados.

Ejecuta un contenedor nginx y cambia el `index.html` predeterminado:

```console
$ docker run -d --name web-app -p 8080:80 nginx
d3d6074d0ea901c96cac8e49e6dad21359616bef3dc0623b3c2dfa536c31dfdb
```

Para confirmar que nginx se está ejecutando, abre un navegador y ve a http://localhost:8080.
Deberías ver la página predeterminada de nginx.
Ahora, cámbiala usando vim:

```console
vim /usr/share/nginx/html/index.html
```

Cambia el título a "Welcome to my app!" y guarda el archivo.
Ahora, recarga la página en el navegador y deberías ver la página actualizada.

### Gestionar tu caja de herramientas usando el comando `install`

El comando integrado `install` te permite añadir cualquier herramienta de https://search.nixos.org/packages a la caja de herramientas.
Ten en cuenta que añadir una herramienta nunca modifica la imagen o el contenedor real.
Las herramientas solo se añaden a tu propia caja de herramientas.
Ejecuta `docker debug` y luego instala `nmap`:

```console
$ docker debug nginx
...
docker > install nmap
Tip: You can install any package available at: https://search.nixos.org/packages.
installing 'nmap-7.93'
these 2 paths will be fetched (5.58 MiB download, 26.27 MiB unpacked):
/nix/store/brqjf4i23fagizaq2gn4d6z0f406d0kg-lua-5.3.6
/nix/store/xqd17rhgmn6pg85a3g18yqxpcya6d06r-nmap-7.93
copying path '/nix/store/brqjf4i23fagizaq2gn4d6z0f406d0kg-lua-5.3.6' from 'https://cache.nixos.org'...
copying path '/nix/store/xqd17rhgmn6pg85a3g18yqxpcya6d06r-nmap-7.93' from 'https://cache.nixos.org'...
building '/nix/store/k8xw5wwarh8dc1dvh5zx8rlwamxfsk3d-user-environment.drv'...

docker > nmap --version
Nmap version 7.93 ( https://nmap.org )
Platform: x86_64-unknown-linux-gnu
Compiled with: liblua-5.3.6 openssl-3.0.11 libssh2-1.11.0 nmap-libz-1.2.12 libpcre-8.45 libpcap-1.10.4 nmap-libdnet-1.12 ipv6
Compiled without:
Available nsock engines: epoll poll select
```

Puedes confirmar que `nmap` ahora forma parte de tu caja de herramientas obteniendo una shell de depuración en una imagen diferente:

```console
$ docker debug hello-world
...
docker > nmap --version

Nmap version 7.93 ( https://nmap.org )
Platform: x86_64-unknown-linux-gnu
Compiled with: liblua-5.3.6 openssl-3.0.11 libssh2-1.11.0 nmap-libz-1.2.12 libpcre-8.45 libpcap-1.10.4 nmap-libdnet-1.12 ipv6
Compiled without:
Available nsock engines: epoll poll select

docker > exit
```

`nmap` sigue ahí.

### Entender el comando de inicio predeterminado de un contenedor (entrypoints)

Docker Debug viene con una herramienta integrada, `entrypoint`.
Entra en la imagen `hello-world` y confirma que el entrypoint es `/hello`:

```console
$ docker debug hello-world
...
docker > entrypoint --print
/hello
```

El comando `entrypoint` evalúa las instrucciones `ENTRYPOINT` y `CMD` de la imagen subyacente
y te permite mostrar en pantalla, analizar (lint) o ejecutar el entrypoint resultante.
Sin embargo, puede ser difícil entender todos los casos particulares explicados en [Understand how CMD and ENTRYPOINT interact](/reference/dockerfile/#understand-how-cmd-and-entrypoint-interact).
En estas situaciones, `entrypoint` te puede ayudar.

Usa `entrypoint` para investigar qué sucede realmente cuando ejecutas un contenedor desde la imagen de nginx:

```console
$ docker debug nginx
...
docker > entrypoint
Understand how ENTRYPOINT/CMD work and if they are set correctly.
From CMD in Dockerfile:
 ['nginx', '-g', 'daemon off;']

From ENTRYPOINT in Dockerfile:
 ['/docker-entrypoint.sh']

By default, any container from this image will be started with following   command:

/docker-entrypoint.sh nginx -g daemon off;

path: /docker-entrypoint.sh
args: nginx -g daemon off;
cwd:
PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Lint results:
 PASS: '/docker-entrypoint.sh' found
 PASS: no mixing of shell and exec form
 PASS: no double use of shell form

Docs:
- https://docs-docker.esdocu.com/reference/dockerfile/#cmd
- https://docs-docker.esdocu.com/reference/dockerfile/#entrypoint
- https://docs-docker.esdocu.com/reference/dockerfile/#understand-how-cmd-and-entrypoint-interact
```

La salida te indica que al iniciar la imagen de nginx, se ejecuta el script `/docker-entrypoint.sh` con los argumentos `nginx -g daemon off;`.
Puedes probar el entrypoint usando la opción `--run`:

```console
$ docker debug nginx
...
docker > entrypoint --run
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2024/01/19 17:34:39 [notice] 50#50: using the "epoll" event method
2024/01/19 17:34:39 [notice] 50#50: nginx/1.25.3
2024/01/19 17:34:39 [notice] 50#50: built by gcc 12.2.0 (Debian 12.2.0-14)
2024/01/19 17:34:39 [notice] 50#50: OS: Linux 5.15.133.1-microsoft-standard-WSL2
2024/01/19 17:34:39 [notice] 50#50: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2024/01/19 17:34:39 [notice] 50#50: start worker processes
2024/01/19 17:34:39 [notice] 50#50: start worker process 77
...
```

Esto inicia nginx en tu shell de depuración sin tener que ejecutar realmente un contenedor.
Puedes apagar nginx presionando `Ctrl`+`C`.

### Ejecutar comandos directamente (ej. para scripting)

Usa la opción `--command` para evaluar un comando directamente en lugar de iniciar una sesión interactiva.
Por ejemplo, esto es similar a `bash -c "arg1 arg2 ..."`.
El siguiente ejemplo ejecuta el comando `cat` en la imagen de nginx sin iniciar una sesión interactiva.

```console
$ docker debug --command "cat /usr/share/nginx/html/index.html" nginx

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
```

### Depuración remota usando la opción --host

Los siguientes ejemplos muestran cómo usar la opción `--host`. El primer ejemplo usa SSH a fin de conectarse a una instancia remota de Docker en `example.org` como usuario `root` y obtener una shell dentro del contenedor `my-container`.

```console
$ docker debug --host ssh://root@example.org my-container
```

El siguiente ejemplo se conecta a un Docker Engine local diferente y obtiene una
shell en el contenedor `my-container`.

```console
$ docker debug --host=unix:///some/path/docker.sock my-container
```



