Docker Commander

Servidor MCP seguro de monitoreo y gestión de Docker para contenedores, registros, alertas, diagnósticos y control seguro en hosts locales y remotos.

Documentación

Docker Commander

Un panel de monitoreo y control de Docker autohospedado y de código abierto, con una interfaz de nivel empresarial: monitorea contenedores en tiempo real, controla su ciclo de vida completo, explora registros y archivos, administra imágenes, redes y volúmenes, alerta sobre problemas y administra todo desde un solo binario.

Un solo binario Go con la interfaz web integrada. Sin base de datos externa, sin dependencias en tiempo de ejecución, sin CGO. Funciona en Linux, macOS y Windows.

🌐 docker-commander.app — la página principal del proyecto. · Documentación · Lanzamientos · Patrocinar

CI Release Go version License: MIT


📸 Capturas de pantalla

Panel principal — resumen del host, uso de disco y contenedores en ejecución de un vistazo.

Dashboard

Detalle del contenedor — CPU/memoria en vivo con historial, y pestañas para registros, una consola interactiva, procesos, el explorador de archivos, cambios en el sistema de archivos y variables de entorno.

Container detail

Registros agregados — muchos contenedores en una sola transmisión, con código de colores por fuente, filtros de nivel, búsqueda con expresiones regulares y análisis estructurado.

Aggregated logs

✨ Características

Monitoreo

  • Gráficos de CPU/memoria en vivo a través de WebSockets y gráficos históricos (Redis o en memoria).
  • Panel principal que se actualiza casi en tiempo real (transmisión de eventos de Docker): datos del host, uso de disco, un desglose de recursos (la participación de cada contenedor en la CPU/memoria del host, más el rendimiento de red de todo el host) y un escaneo de puertos que identifica qué está realmente escuchando.
  • Telemetría de red — tasa RX/TX por contenedor (derivada, por lo que un reinicio del contador al recrear se lee como una brecha en lugar de un pico), totales, paquetes / descartados / errores y el desglose por interfaz, además de totales por punto final en el detalle de una red, etiquetados según lo que son, ya que Docker no reporta contadores por red.
  • Registros — cola por contenedor, más una vista agregada global con detección de nivel, búsqueda con expresiones regulares y reglas de análisis guardadas que convierten líneas en columnas estructuradas.
  • Transmisión de eventos en vivo, diff / top de contenedores, uso de disco e inspección JSON sin procesar de cualquier objeto.
  • Redes y topología — un gráfico interactivo de contenedores ↔ redes (dirigido por fuerza, con paneo / zoom / pantalla completa, búsqueda, filtro por pila de compose) con una vista de lista compacta (estado, imagen, pila, puertos, redes).

Control

  • Contenedores: crear/ejecutar, iniciar/detener/reiniciar/pausar/reanudar/matar, renombrar, actualizar límites y política de reinicio, confirmar en una imagen, un shell interactivo (xterm.js) y reinicio/detención masiva en una selección múltiple (vista previa, confirmación, paralelismo limitado, resumen de éxito/fallo por contenedor).
  • Explorador de archivos dentro de contenedores y volúmenes — listar, descargar, subir (incl. subir y extraer un .zip/.tar/.tar.gz), eliminar, crear carpetas.
  • Imágenes: extraer (progreso en vivo), construir, enviar, etiquetar, guardar/cargar/importar, historial, podar y escaneo de vulnerabilidades (Trivy — resumen de severidad + tabla de CVE).
  • Volúmenes y redes: listar, inspeccionar, crear, eliminar, podar; las redes también conectan / desconectan contenedores, con un detalle por red (gráfico o lista).
  • Compose — descubre y administra pilas por etiqueta (también las creadas por CLI: iniciar/detener/reiniciar/eliminar, y editar su archivo compose en el host, luego reimplementar — se mantiene donde vive, por lo que las rutas relativas de bind/env_file/build.context aún se resuelven), y Proyectos: carpetas de compose administradas editadas en un editor de código integrado (CodeMirror) con validación en línea y en vivo — compose (consciente de anclas/${VAR}), Dockerfile (docker build --check), YAML/JSON/.env — además de una vista previa Resuelta, un Resumen de servicios/puertos, plantillas, autocompletado de Compose consciente del esquema y sugerencias de nombre-imagen / etiqueta (locales, Docker Hub y registros privados configurados), y implementación a través del CLI docker compose con perfiles (el resumen muestra el estado real de cada servicio y separa claramente lo que está actualmente implementado de lo que está seleccionado para la próxima implementación, por lo que un servicio excluido por perfil se lee como tal — no como detenido) e importación/exportación de .zip — al host local o remoto (una implementación remota copia los configs/scripts montados por bind del proyecto en volúmenes de ese host, y los contextos de build: se suben con la compilación; una reimplementación reconstruye una imagen editada).

Multi-host

  • Administra demonios locales, TCP(+TLS) y SSH; las claves de host SSH se verifican (known_hosts / confianza en el primer uso). Cada vista se reenlaza al host seleccionado, y el motor de alertas vigila todos los hosts. Un panel de detalle por host muestra el hardware / SO / motor, y un host puede deshabilitarse para sacarlo del monitoreo (por ejemplo, una laptop sin conexión).

Alertas e integraciones

  • Reglas sobre estado, umbrales de recursos, patrones de registros y reinicios/bucles de fallos — editables, con severidad y período de enfriamiento.
  • Las alertas de umbral son condiciones con una vida útil (firing → escalated/eased → resolved), una por contenedor + métrica, por lo que las reglas superpuestas producen un incidente en lugar de uno por cada una — y la transmisión está paginada, filtrada y ordenada en el servidor, con quién la reconoció y cada intento de entrega registrado contra ella.
  • Notifica a través de webhooks, correo electrónico (SMTP, enrutamiento por host), una transmisión en la aplicación y un exportador Prometheus /metrics. Las reglas se importan/exportan como un paquete JSON portátil.

Control remoto desde herramientas de IA (MCP)

  • Un servidor Model Context Protocol opcional, desactivado por defecto, permite que las herramientas de IA (Claude Code, Claude Desktop, Cursor) monitoreen y operen de forma segura Docker como tú: herramientas de lectura (contenedores, registros, imágenes, proyectos, estadísticas, eventos, auditoría…), diagnósticos sin shell (docker top / diff, búsqueda de registros entre contenedores), la superficie de alertas (historial, qué está disparando ahora, reglas, si una alerta se entregó realmente, reconocer), y control seguro (iniciar/detener/reiniciar un contenedor o una pila completa, implementar/derribar un proyecto — incluido uno dirigido a un host remoto — además de una vista previa de lo que una implementación cambiaría y un escaneo de imagen Trivy), con recursos y prompts de MCP.
  • Autentica con un token de API bearer (página de autoservicio) o OAuth 2.1 (PKCE, registro dinámico de clientes). Cada llamada reutiliza el RBAC de la aplicación, y un token solo puede reducir tus derechos (un subconjunto de tus secciones y de los hosts a los que llegas, además de solo lectura). Los tokens nuevos expiran después de 30 días por defecto (configurable por el administrador, con tokens que nunca expiran desactivados a menos que se habiliten). Los cambios tienen límite de velocidad (30/min por usuario; las lecturas no) para que un modelo atrapado en un bucle — o un token robado — esté limitado a unos pocos contenedores en lugar de todo tu entorno, y alcanzar ese límite se audita. Deliberadamente sin exec / exportación de imágenes / lectura de archivos / poda / eliminación. Ver MCP.

Seguridad y administración

  • Contraseñas Argon2id + 2FA TOTP o claves de acceso (WebAuthn — resistente a phishing, y ofrecido donde el navegador lo permita: HTTPS o localhost; una clave de acceso que te verifica con un PIN o huella digital también puede iniciar sesión por sí sola una vez que lo actives, con la contraseña aún disponible como camino de regreso si la clave se pierde), opcionalmente exento para localhost, con varios autenticadores por cuenta — empareja el teléfono nuevo antes de borrar el viejo; el último no se puede eliminar. Limitación de velocidad, encabezados estrictos, cookies HttpOnly firmadas. Todos pueden ver qué está iniciado sesión como su cuenta — dirección, navegador, último uso — y cerrar sesión de cualquiera de ellos, o de todo lo demás, desde su perfil.
  • Multi-usuario con roles, permisos por sección, modo solo lectura, indicadores de características globales y un registro de auditoría. Las preferencias de UI por usuario (filtros) siguen la cuenta entre navegadores.
  • Inicio de sesión opcional LDAP / Active Directory con aprovisionamiento automático y mapeo de grupos — un grupo de directorio otorga roles nombrados (o secciones sin procesar), re-derivados en cada inicio de sesión, por lo que la membresía impulsa los permisos. Los secretos de Registro / SMTP / LDAP y las claves privadas TLS del host están cifrados en reposo (AES-256-GCM).

Operaciones

  • Un solo binario sin CGO, UI integrada, unidad systemd, archivo de configuración, HTTPS nativo (asistente integrado de certificado autofirmado --make-certs, o detrás de un proxy), sonda /healthz y registro estructurado de alertas en el journal/syslog. Ver Implementación.
  • Auto-actualización — una actualización y reinicio en la aplicación con un toque para administradores (y un banner de "actualización disponible"), además del comando dockercmd --self-upgrade (verificado con SHA-256, reemplazo atómico del binario).

🏗️ Arquitectura

React + TypeScript SPA  ──REST──▶  Go backend  ──Docker Engine API──▶  dockerd
   (Tailwind, Recharts)  ◀─WebSocket (live stats + logs)─┘

El servidor Go integra la SPA compilada (go:embed) y sirve todo desde un solo origen, por lo que el artefacto de producción es un solo ejecutable.

CapaTecnología
BackendGo, chi, coder/websocket, SDK oficial de Docker
AlmacenamientoSQLite vía modernc.org/sqlite (Go puro, sin CGO); historial de métricas en Redis o memoria
AutenticaciónArgon2id, TOTP (pquerna/otp), JWT, LDAP opcional
FrontendReact, TypeScript, Vite, Tailwind CSS, Recharts, React Flow, xterm.js

🐳 Versiones de Docker

La aplicación habla con Docker de dos maneras: la API del motor a través del SDK oficial de Go, y el CLI docker compose como subproceso para implementaciones de proyectos. Ambos se mueven, y ejecutas lo que tu distribución incluya — así que esto es lo que realmente se prueba, no lo que se espera.

Versión
API mínima del motor1.43 (Docker Engine 24)
Versiones principales del motor probadas24, 25, 26, 27, 28 (nocturno; ver las ejecuciones del flujo de trabajo para el resultado actual)
Parches del motor probadosun puñado de versiones de parche exactas de las versiones principales más nuevas también se fijan y prueban nocturnamente, independientemente de las etiquetas principales flotantes (ver las ejecuciones del flujo de trabajo para las versiones exactas actuales)
Composeel plugin docker compose, v2 o más nuevo (el legado docker-compose v1 no es compatible); un puñado de versiones recientes de v2 se fijan y prueban nocturnamente (ver las ejecuciones del flujo de trabajo)
SDK del clientefijado en go.mod, negociado hacia abajo al demonio en el momento de la conexión

El SDK llama a WithAPIVersionNegotiation(), por lo que un cliente más nuevo habla lo que el demonio entienda — no necesitas igualar versiones. Por debajo de la API 1.43, la aplicación no se prueba ni se afirma que funcione.

Estos números son medidos, no recordados: el flujo de trabajo de compatibilidad ejecuta toda la suite de integración de Docker de la aplicación contra un docker:NN-dind fijado para cada versión principal, nocturnamente y bajo demanda, e imprime la versión de API negociada — más la versión de Compose con la que se ejecutó — para cada ejecución. Tres ejes están fijados: cada versión principal del motor se prueba contra la más nueva de un pequeño conjunto de versiones recientes de Compose, la versión principal más nueva del motor se prueba adicionalmente contra las más antiguas de ese conjunto, y un puñado de versiones de parche exactas del motor (docker:X.Y.Z-dind, no solo docker:NN-dind) también se fijan y prueban — ya que la etiqueta principal simple siempre flota al parche más nuevo cuando se extrae, por sí sola no puede probar que un parche específico sea bueno, solo que el más reciente actualmente lo es. Así que la matriz responde "qué demonios funcionan", "qué versiones recientes de Compose funcionan" y "¿funciona este parche exacto del motor?", sin un producto cruzado completo de Motor × Compose. Reproduce cualquier fila localmente:

docker run -d --name dc-compat --privileged -e DOCKER_TLS_CERTDIR="" \
  -p 127.0.0.1:12375:2375 docker:24-dind --host=tcp://0.0.0.0:2375 --tls=false
DC_COMPAT_DOCKER=tcp://127.0.0.1:12375 DOCKER_HOST=tcp://127.0.0.1:12375 \
  go test -count=1 -run 'TestIntegration|TestCompat' ./internal/docker/

Ambas variables importan: DC_COMPAT_DOCKER apunta la aplicación al demonio, DOCKER_HOST apunta el CLI de Compose al mismo. Establece solo la primera y las pruebas de Compose se implementan en tu propio demonio y se quedan esperando contenedores que se iniciaron en otro lugar.

🚀 Inicio rápido

Opción A — descarga un binario de lanzamiento

Descarga el binario para tu SO/arquitectura desde la página de Releases y luego:

chmod +x dockercmd-linux-amd64
./dockercmd-linux-amd64           # serves on http://127.0.0.1:8470

En Windows, ejecuta dockercmd-windows-amd64.exe desde una terminal.

Los usuarios de Debian/Ubuntu y Fedora pueden obtener un .deb / .rpm desde la misma página: configura el servicio systemd. Consulta Deployment → packages.

Opción B — Homebrew (macOS y Linux)

brew install koduj-dev/tap/dockercmd
dockercmd --version

Instala el binario de la versión firmada para tu SO/arquitectura desde el koduj-dev/homebrew-tap.

Opción C — compilar desde el código fuente

Requiere Go ≥ 1.26, Node.js ≥ 18 (para compilar la interfaz) y un daemon de Docker en ejecución. Consulta Building para los detalles por SO.

git clone https://github.com/koduj-dev/docker-commander.git
cd docker-commander
make build      # builds the UI, then the binary with the UI embedded
./dockercmd     # http://127.0.0.1:8470

Opción D — Docker

docker run -d --name dockercmd \
  -p 127.0.0.1:8470:8470 \
  --group-add "$(stat -c '%g' /var/run/docker.sock 2>/dev/null || stat -f '%g' /var/run/docker.sock)" \
  --read-only --tmpfs /tmp \
  --security-opt no-new-privileges \
  --cap-drop ALL \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v dockercmd-data:/data \
  ghcr.io/koduj-dev/docker-commander:latest

Multi-arquitectura (amd64/arm64), distroless, se ejecuta como un usuario no root con un sistema de archivos raíz de solo lectura y sin capacidades añadidas. Notas:

  • ⚠️ Montar el socket de Docker otorga acceso equivalente al root del host — quien llegue a la interfaz (o escape de la aplicación) controla el daemon, es decir, el host. Mantén la interfaz en localhost (como arriba) o detrás de HTTPS + autenticación fuerte; nunca la expongas sin autenticación. La línea --group-add le da al usuario no root el GID propietario del socket de Docker — leído desde el propio /var/run/docker.sock (stat, con un respaldo para BSD), por lo que funciona incluso sin un grupo docker. En rootless / Docker Desktop, donde el socket es propiedad de tu usuario, elimina la línea --group-add.
  • Los datos residen en el volumen nombrado dockercmd-data (uno nuevo hereda la propiedad correcta). Un bind mount (-v /srv/dc:/data) debe ser escribible por el uid 65532 primero: sudo chown 65532:65532 /srv/dc.
  • En producción, fija un digest inmutable (...@sha256:…) en lugar de :latest, y verifica la imagen (ver más abajo).

Opción E — go install

go install github.com/koduj-dev/docker-commander/cmd/dockercmd@latest

Instala en $(go env GOPATH)/bin/dockercmd. (Compilado de esta manera, la versión reporta dev; los binarios de las versiones y la imagen llevan la versión real).

Verificar una descarga

Cada versión incluye un SHA256SUMS además de un paquete de firma cosign sin clave (SHA256SUMS.bundle) que cubre los binarios y el SBOM SPDX, además de la procedencia de compilación por binario:

sha256sum -c SHA256SUMS --ignore-missing        # checksums (binaries + SBOM)

cosign verify-blob --bundle SHA256SUMS.bundle \
  --certificate-identity-regexp '^https://github\.com/koduj-dev/docker-commander/\.github/workflows/release\.yml@refs/tags/v' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com SHA256SUMS

gh attestation verify dockercmd-linux-amd64 --repo koduj-dev/docker-commander

Verificar el paquete requiere cosign v3+. Las versiones hasta la v1.5.0 inclusive se firmaron con cosign v2 e incluyen un par SHA256SUMS.sig / SHA256SUMS.pem en su lugar; verifica esas con cosign verify-blob --certificate SHA256SUMS.pem --signature SHA256SUMS.sig ….

La imagen del contenedor está firmada y lleva procedencia SLSA + un SBOM también:

# verify the exact digest you'll run (copy it from the release notes or
# `docker buildx imagetools inspect ghcr.io/koduj-dev/docker-commander:latest`):
IMAGE=ghcr.io/koduj-dev/docker-commander@sha256:<digest>
cosign verify "$IMAGE" \
  --certificate-identity-regexp '^https://github\.com/koduj-dev/docker-commander/\.github/workflows/release\.yml@refs/tags/v' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

gh attestation verify "oci://$IMAGE" --repo koduj-dev/docker-commander

Abre http://127.0.0.1:8470, crea la cuenta de administrador, escanea el código QR para activar la 2FA — listo.

⚙️ Configuración

Cada opción es una bandera con un equivalente de variable de entorno, y también puede vivir en un archivo de configuración — consulta deploy/commander.conf.example para la lista completa. La conexión de Docker también respeta las variables estándar DOCKER_HOST / DOCKER_CERT_PATH.

BanderaEnvPredeterminadoDescripción
-hostDC_HOST127.0.0.1Host/interfaz de escucha. Usa 0.0.0.0 para vincular todos (deliberado).
-port / -pDC_PORT8470Puerto de escucha.
-addrDC_ADDR(sin definir)host:port completo heredado; anula -host/-port.
-tls-certDC_TLS_CERT(desactivado)Ruta del certificado PEM; con -tls-key, sirve HTTPS directamente.
-tls-keyDC_TLS_KEY(desactivado)Ruta de la clave privada PEM.
-mcp-enabledDC_MCP_ENABLED=1offHabilita el servidor MCP remoto para herramientas de IA. Desactivado por defecto; sirve detrás de HTTPS. Consulta MCP.
-mcp-public-urlDC_MCP_PUBLIC_URL(sin definir)URL base accesible externamente (https://host) — requerida para el flujo OAuth de MCP (los tokens de portador funcionan sin ella).
-data-dirDC_DATA_DIRDirectorio de configuración del SOBase de datos SQLite + claves de firma/cifrado.
-session-ttl—12hDuración del token de sesión.
-devDC_DEV=1offModo de desarrollo: solo API + CORS permisivo para Vite.
-metrics-tokenDC_METRICS_TOKEN(abierto)Si se define, /metrics necesita Authorization: Bearer <token> (o ?token=).
-redis-addrDC_REDIS_ADDR(memoria)host:port de Redis para el historial de métricas; vacío = anillo en memoria.
-redis-passwordDC_REDIS_PASSWORD(vacío)Contraseña de Redis; DC_REDIS_DB selecciona el índice de la base de datos.
-metrics-retentionDC_METRICS_RETENTION6hRetención del historial (p. ej., 30m, 24h).
-trusted-proxiesDC_TRUSTED_PROXIES(ninguno)IPs/CIDRs del proxy inverso cuyos X-Forwarded-For pueden ser confiables. La IP del cliente clave los límites de tasa, la exención de 2FA de localhost y los registros de auditoría — defínelo detrás de un proxy, y nunca a un rango que no controles.
-self-updateDC_SELF_UPDATEonPermite que los administradores apliquen una actualización desde la interfaz web. 0 mantiene el banner de "actualización disponible" pero prohíbe el auto-reemplazo activado desde la web.

🖥️ Ejecutar como servicio

El servidor mantiene la supervisión, las alertas y el historial de métricas funcionando 24/7, ya sea que un navegador esté conectado o no — así que ejecútalo como un servicio en segundo plano. En Linux/macOS/Windows, el binario se instala solo:

sudo ./dockercmd --install-service     # Linux — systemd (needs root)
./dockercmd --install-service          # macOS — launchd LaunchAgent (your user, not sudo)
dockercmd.exe --install-service        # Windows — native SCM service (elevated PowerShell/cmd)

Crea un usuario dedicado (o, en Windows, se registra con el Administrador de control de servicios), escribe la definición de servicio (endurecida) y lo inicia. Para leer exactamente qué se instala, usa los scripts equivalentes en deploy/:

sudo ./deploy/install-linux.sh ./dockercmd                  # Linux  — systemd
./deploy/install-macos.sh ./dockercmd                       # macOS  — launchd
.\deploy\install-windows.ps1 -BinPath .\dockercmd.exe       # Windows — Scheduled Task (elevated PowerShell)

El script de Tarea programada de Windows sigue siendo una alternativa sin dependencias al servicio SCM nativo anterior.

Consulta Deployment para ver qué hace cada instalador, los pasos manuales de systemd, HTTPS, registro y la referencia de configuración.

Se vincula al loopback por defecto — colócalo detrás de un proxy inverso TLS (nginx, Caddy) para exponerlo, y mantén la exención de 2FA de localhost desactivada en los servidores.

🔨 Compilación

La interfaz se compila con Node y se incrusta en el binario de Go; el resultado es un único ejecutable estático sin CGO.

make build          # current platform → ./dockercmd
make release        # cross-compile all platforms → dist-bin/ (+ SHA256SUMS)
make test vet       # tests + static checks
VERSION=v1.0.0 make release   # stamp the version into the binary

Por SO (compilando desde el código fuente — los usuarios finales pueden simplemente descargar una versión):

SO del hostNotas
Linuxmake build. Objetivo predeterminado para las versiones.
macOSmake build (Intel o Apple Silicon). Compila de forma cruzada para darwin/amd64 y darwin/arm64.
WindowsUsa WSL o Git Bash para make, o ejecuta los dos pasos manualmente: cd web && npm ci && npm run build y luego go build -o dockercmd.exe ./cmd/dockercmd. Las versiones incluyen windows/amd64 + windows/arm64 .exe.

make release compila linux/{amd64,arm64}, darwin/{amd64,arm64} y windows/{amd64,arm64} desde cualquier host (sin necesidad de cadena de herramientas C).

🧑‍💻 Desarrollo

make dev                       # API on :8470 (dev mode)
cd web && npm ci && npm run dev        # UI on :5173, proxies /api → :8470

Pruebas

go test -short ./...   # fast unit tests (what CI runs)
go test ./...          # + integration tests — needs a local Docker daemon
                       #   (spins throwaway Redis / OpenLDAP / MailHog containers)

📈 Supervisión y alertas

Define reglas en la pantalla Alertas:

TipoSe activa cuando…
stateun contenedor emite un evento de ciclo de vida (die, kill, oom, stop, unhealthy)
resourceCPU% o MEM% cruza un umbral durante N segundos
loguna línea de registro coincide con una subcadena / expresión regular
restartun contenedor se reinicia demasiado a menudo dentro de una ventana (bucle de bloqueo)

Las reglas apuntan a contenedores por subcadena de nombre, llevan una severidad + tiempo de reutilización, y pueden notificar a webhooks (cuerpos de plantilla Go) y/o por correo electrónico. Prometheus: extrae /metrics para dockercmd_container_cpu_percent, _mem_bytes, _mem_percent, _container_running (etiquetados por id, name, host).

🔒 Notas de seguridad

  • Local por defecto (se vincula al loopback). Detrás de un servidor, termina TLS en un proxy inverso.
  • La 2FA se aplica en todas partes a menos que un administrador habilite la exención de localhost (Configuración), que se aplica solo a una conexión directa de loopback — una solicitud a través de proxy nunca califica, sin importar cómo se presente. Los intentos fallidos de 2FA tienen límite de tasa y se auditan, por lo que el segundo factor no puede ser forzado por fuerza bruta por alguien que ya tenga la contraseña.
  • Las claves de acceso están vinculadas a la dirección de este sitio. Una página que suplante a esta no puede usar una aserción que capture, y un contador de firmas que retroceda — señal de una clave clonada — se rechaza y se audita.
  • Las sesiones son revocables. Una sesión es una fila registrada, no solo un token firmado: cerrar sesión, revocar una desde tu perfil o cambiar tu contraseña tiene efecto en la próxima solicitud en lugar de cuando el token habría expirado.
  • Los hosts SSH verifican la clave del host del daemon (known_hosts / confianza en el primer uso); una clave cambiada se rechaza como posible MITM.
  • La clave de firma y la clave de cifrado en reposo se generan en la primera ejecución y se almacenan en el directorio de datos; los secretos almacenados nunca se devuelven por la API.
  • El servidor MCP está desactivado por defecto (DC_MCP_ENABLED); cuando está activado, se autentica con portador/OAuth, reutiliza el RBAC de la aplicación (con alcance de solo lectura / de sección por token), y expone solo lecturas + control seguro — sin exec, exportación de imágenes, lectura de archivos ni prune/remove. Las llamadas de control además tienen límite de tasa por usuario para limitar el daño que un token descontrolado o robado puede hacer. Consulta MCP.

🧪 Cómo se prueba

Estás apuntando esto a daemons de Docker reales, por lo que las pruebas rápidas son el piso, no el techo. Junto con ~670 pruebas unitarias de Go y ~190 pruebas de frontend, el repositorio lleva 115 casos "pentest" adversariales que afirman que los ataques se rechazan (falsificación de tokens, reproducción de OAuth, CSRF, IDOR, omisión de alcance por host, escalada de privilegios, travesía de rutas), un nivel de integración contra un daemon de Docker real (además de Redis / OpenLDAP / SMTP desechables), y un nivel de extremo a extremo que despliega en daemons separados tanto por TCP como por SSH — porque un daemon simulado no puede decirte si un despliegue remoto funciona.

Además de las pruebas, el árbol se revisa periódicamente con una revisión adversarial en Claude Fable 5 — revisores independientes por área (autenticación y criptografía, autorización, entrada no confiable, corrección del backend, frontend), cada uno instruido para refutar un hallazgo antes de reportarlo. No es un nivel y no protege nada por sí mismo: un hallazgo cuenta solo una vez que se convierte en una corrección más la prueba que falla sin ella.

CI ejecuta los niveles deterministas; los respaldados por daemon los ejecuta el desarrollador. docs/testing.md describe cada nivel, cómo ejecutarlo y qué está deliberadamente no cubierto.

📚 Documentación

Un manual de usuario por función vive en docs/ — una página por tema (Contenedores, Imágenes, Registros, Alertas, Hosts, Usuarios, Configuración…) además de Getting started, Deployment y How it's tested.

🗺️ Hoja de ruta y registro de cambios

Consulta NEXT.md para el estado y las ideas futuras, y CHANGELOG.md para lo que se incluyó en cada versión.

🤝 Contribuciones

¡Las incidencias y las solicitudes de extracción son bienvenidas! Consulta CONTRIBUTING.md para las pautas de compilación/pruebas/estilo, CODE_OF_CONDUCT.md, y SECURITY.md para reportar vulnerabilidades (en privado, por favor).

🤖 Hecho con IA

Aproximadamente el 95 % de este proyecto se construyó con IA (Claude Code) — código, pruebas y documentación — bajo dirección y revisión humana. 🎉

📄 Licencia

MIT.