---
name: docker_container_list
kind: function
lang: go
domain: infra
version: "1.0.0"
purity: impure
signature: "func DockerContainerList(opts DockerContainerListOpts) ([]DockerContainerInfo, error)"
description: "Lista containers Docker del host via engine API (unix socket o TCP). Sin SDK pesado — net/http directo. Soporta filtros, All=true para exited. Usado por device_agent como capability docker.container.list."
tags: [docker, docker-agent, container, list, infra]
uses_functions: []
uses_types: [error_go_core, docker_container_info_go_infra]
returns: [docker_container_info_go_infra]
returns_optional: false
error_type: "error_go_core"
imports:
  - context
  - encoding/json
  - fmt
  - io
  - net
  - net/http
  - net/url
  - strings
  - time
tested: true
tests:
  - "lista solo running"
  - "All=true incluye exited"
  - "filter label aplica"
test_file_path: "functions/infra/docker_container_list_test.go"
file_path: "functions/infra/docker_container_list.go"
params:
  - name: opts
    desc: "DockerContainerListOpts — All (incluir exited), Filters (expresiones label=k=v / status=running), DockerHost (unix socket o tcp://host:port)"
output: "Slice de DockerContainerInfo con id, names, image, state, ports, networks para cada container."
---

## Ejemplo

```go
// Listar solo containers corriendo con un label específico
containers, err := DockerContainerList(infra.DockerContainerListOpts{
    Filters:    []string{"label=app=agents_and_robots"},
    DockerHost: "unix:///var/run/docker.sock",
})
if err != nil {
    log.Fatal(err)
}
for _, c := range containers {
    fmt.Printf("%s  %-20s  %s  %s\n", c.ID, c.Names[0], c.State, c.Status)
}

// Todos los containers (incluye exited) en host remoto
all, err := DockerContainerList(infra.DockerContainerListOpts{
    All:        true,
    DockerHost: "tcp://192.168.1.10:2375",
})
```

## Cuando usarla

Cuando necesites listar containers Docker desde un agente o servicio sin depender del CLI `docker` instalado en el host — por ejemplo, al implementar la capability `docker.container.list` en un `device_agent` que recibe comandos desde Element/Matrix. También útil en tests y en entornos donde el binario docker no está en el PATH pero el socket sí es accesible.

## Gotchas

- Requiere acceso al docker socket. El proceso debe correr como root o en el grupo `docker`. En WSL2, el socket está en `/var/run/docker.sock` si Docker Desktop está activo.
- `Ports` puede estar vacío para containers en host network mode (`--network host`) — el engine no reporta port bindings en ese caso.
- Para acceso remoto sin TLS (`tcp://`), el daemon Docker debe tener `-H tcp://0.0.0.0:2375` habilitado explícitamente (deshabilitado por defecto por seguridad). Usar SSH tunnel o TLS para producción.
- `DockerHost` acepta `unix://` y `tcp://` solamente. Esquemas `https://` o `ssh://` retornan error.
- El campo `Names` incluye el slash inicial: `["/my-container"]`. Al mostrar al usuario, usar `strings.TrimPrefix(name, "/")`.
- Filters del tipo `label=k=v` incluyen el segundo `=` en el valor (el split es en el primer `=`). Para filtrar por presencia de label sin valor: `"label=app"`.

## Notas

Implementa la misma semántica que `GET /containers/json` del Docker Engine API v1.41+. No requiere el SDK `github.com/docker/docker` (evita ~50 MB de dependencias transitivas). El helper `dockerListHTTPClient` maneja la dialección unix socket requerida por `net/http`.
