--- 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`.