Dockhand es una interfaz web para gestionar Docker que despliega stacks de Compose, trae sus propios escáneres de vulnerabilidades y guarda su estado en SQLite. Lo instalé el 7 de octubre de 2026 en su versión 1.0.51, con Docker Compose y un socket proxy delante del socket de Docker. En esta guía tienes el fichero Compose que ejecuté, lo que vi al desplegar un stack y escanear una imagen, y la letra pequeña de su licencia. También tienes la versión en inglés.

Puntos clave

  • La versión 1.0.51 salió el 3 de octubre de 2026. Es una aplicación SvelteKit sobre Bun cuya imagen ocupa 199 MB en arm64 y que usa SQLite por defecto, o PostgreSQL si lo configuras.
  • Su licencia es Business Source License 1.1: gratis para uso personal, organizaciones sin ánimo de lucro y educación, y de pago para quien la use en los sistemas en producción de una empresa.
  • Con la autenticación desactivada, que es el estado inicial, cualquiera que llegue al puerto controla Docker. En mi prueba la API listó entornos y creó uno sin credenciales.
  • Detrás de un socket proxy, Dockhand desplegó un stack y escaneó una imagen. nginx:1.29-alpine dio 217 vulnerabilidades con Grype 0.119.0: 26 críticas, 97 altas, 75 medias, 13 bajas y 6 desconocidas.
  • Frente a Portainer, Komodo y Dockge ocupa un hueco propio: escáneres y Git integrados, pero sin la madurez de los dos primeros.

Qué es Dockhand y qué hace

Dockhand gestiona contenedores, imágenes, volúmenes, redes y stacks de Compose de uno o más hosts Docker desde un único panel. El README del proyecto[1] lo define así: "Dockhand is a modern, efficient Docker management application providing real-time container management, Compose stack orchestration, and multi-environment support."

Esto es lo que ofrece, según su documentación y lo que comprobé:

  • Stacks de Compose con un editor de YAML junto a las variables de entorno y un editor visual en grafo
  • Despliegues desde Git con webhooks y sincronización automática (no los probé; los describe el README)
  • Escaneo de vulnerabilidades con Grype o Trivy, que Dockhand ejecuta como contenedores efímeros
  • Autenticación con usuarios locales y OIDC (OpenID Connect, el protocolo de inicio de sesión único); los permisos por roles son de la edición Enterprise
  • Entornos múltiples: el socket local, un agente propio llamado Hawser o una conexión TCP directa

Es un proyecto joven. El repositorio se creó el 28 de diciembre de 2025 y tenía 6 639 estrellas en GitHub el día de la prueba.

Qué licencia tiene y cuándo hay que pagar

La licencia de Dockhand es la Business Source License 1.1 (BSL 1.1), que publica el código pero limita el uso comercial. No es una licencia de código abierto según la definición de la Open Source Initiative, y conviene leerla antes de ponerlo en una empresa.

El fichero LICENSE.txt[2], actualizado el 14 de septiembre de 2026, lo resume así: "Paid (Commercial License, Part B): production use by or for any business, public body or other organization not listed above." En la práctica:

  • Gratis en producción: personas para uso personal (un homelab), organizaciones sin ánimo de lucro y centros educativos
  • Gratis para todos, empresas incluidas: desarrollo, pruebas, preproducción, integración continua, evaluación, demostraciones y formación
  • De pago: gestionar con Dockhand los sistemas reales de una organización con empleados
  • Prohibido sin otro acuerdo: ofrecerlo a terceros como servicio gestionado

Cada versión pasa a Apache 2.0 cuatro años después de publicarse. El README y el fichero de licencia coinciden en este resumen, pero el texto legal manda sobre él.

Cómo instalar Dockhand con un socket proxy

Dockhand necesita hablar con la API de Docker, y la forma más directa es montar /var/run/docker.sock en su contenedor. Eso le da control total sobre el host, así que la documentación de Dockhand[3] propone poner delante el socket proxy de Tecnativa[4], que solo deja pasar las llamadas que activas.

Este es el fichero que usé, con el nombre de proyecto b8p11, el puerto 29100 en lugar del 3000 por defecto, y los permisos que la documentación marca como necesarios:

services:
  socket-proxy:
    image: tecnativa/docker-socket-proxy
    restart: unless-stopped
    environment:
      - CONTAINERS=1
      - IMAGES=1
      - NETWORKS=1
      - VOLUMES=1
      - EVENTS=1
      - POST=1
      - DELETE=1
      - INFO=1
      - SYSTEM=1
      - ALLOW_START=1
      - ALLOW_STOP=1
      - ALLOW_RESTARTS=1
      - ALLOW_LOGS=1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    networks:
      - socket-proxy

El proxy monta el socket en solo lectura y solo habilita contenedores, imágenes, redes, volúmenes, eventos y logs. La segunda mitad define Dockhand y las redes:

  dockhand:
    image: fnsys/dockhand:latest
    restart: unless-stopped
    depends_on:
      - socket-proxy
    ports:
      - "29100:3000"
    volumes:
      - dockhand_data:/app/data
    networks:
      - socket-proxy
      - default

networks:
  socket-proxy:
    internal: true

volumes:
  dockhand_data:

La red socket-proxy es internal, de modo que el proxy no sale a Internet ni publica ningún puerto. Dockhand es el único servicio con puerto abierto, y guarda su base de datos en el volumen dockhand_data.

Arranca el conjunto con docker compose -f compose.yaml -p b8p11 up -d. En mi máquina la imagen de Dockhand pesa 199 MB sin comprimir y la del proxy 20,5 MB. Tras desplegar un stack y escanear una imagen, docker stats marcó 212,3 MiB para Dockhand y 33,6 MiB para el proxy. Con la etiqueta latest, la interfaz informó de la versión fnsys/dockhand:v1.0.51.

Para producción, fija la versión en lugar de latest. El contenedor corre sin privilegios de root, y por eso la documentación dedica una sección a los permisos del socket cuando lo montas directamente.

Qué ocurre en el primer arranque

Al abrir http://localhost:29100 Dockhand no pide crear un usuario: entra directo al panel con la lista de entornos vacía. curl localhost:29100/api/auth/session devolvió {"authenticated":false,"authEnabled":false}, y la API respondió sin credenciales. Eso significa que, hasta que actives la autenticación en Ajustes, cualquiera con acceso al puerto gestiona Docker.

Por eso no publiques el puerto a Internet sin más. Activa los usuarios locales o el inicio de sesión con OIDC antes de abrirlo, o déjalo detrás de una VPN o de un proxy inverso con autenticación, como Traefik con Docker Compose.

El fichero de la base de datos es /app/data/db/dockhand.db, un SQLite en modo WAL. Tras mi prueba el directorio /app/data entero ocupaba 4,8 MB. Para hacer una copia de seguridad, copia el volumen con el contenedor parado.

Cómo conectar el entorno local a través del proxy

Un entorno es un host Docker que Dockhand gestiona, y el local se añade en Ajustes, Entornos. Como el contenedor no monta el socket, elegí la conexión por TCP y apunté al proxy. Yo lo hice con la API para dejarlo reproducible, y la interfaz pide los mismos campos:

curl -s -X POST localhost:29100/api/environments \
  -H 'content-type: application/json' \
  -d '{"name":"local-proxy","connectionType":"direct",
       "host":"socket-proxy","port":2375,"protocol":"http"}'

La respuesta devolvió el entorno con id 1, y el panel pasó a mostrar la información del host: Debian GNU/Linux 13, Docker 29.5.2, 18 núcleos y 47 GB de RAM. Eso confirma que el proxy deja pasar las llamadas de INFO y SYSTEM.

Hay una consecuencia que no esperaba: Dockhand ve todo el daemon, no solo lo que crea. En la pantalla de stacks aparecieron todos los proyectos de Compose de mi máquina marcados como "Untracked", entre ellos otros que no son míos. Gestiona solo lo que tú crees y trata el resto como de solo lectura.

Cómo desplegar un stack de Compose

Crear un stack se hace desde Stacks, Create: escribes el nombre, pegas el YAML en el editor y pulsas "Create & Start". Dockhand guarda el fichero en /app/data/stacks/<entorno>/<stack>/compose.yaml y lanza el despliegue por la API de Docker. El stack que usé tiene dos servicios:

services:
  web:
    image: nginx:1.29-alpine
    ports:
      - "29101:80"
    depends_on:
      - cache
  cache:
    image: redis:8-alpine

Después del despliegue, docker ps mostró b8p11-demo-web-1 y b8p11-demo-cache-1 en marcha, y curl localhost:29101 devolvió 200. El despliegue funcionó a través del proxy, así que las llamadas de creación (POST=1) y de arranque (ALLOW_START=1) bastan.

Una limitación del proxy: la terminal dentro del contenedor, el explorador de volúmenes y el explorador de ficheros usan la API exec. Con EXEC desactivado, la documentación dice que Dockhand recibe un 403. No lo comprobé; si necesitas esas funciones, añade EXEC=1 y reinicia el proxy, sabiendo que amplías lo que Dockhand puede hacer en el host.

Cómo escanear una imagen con Grype

El escáner viene desactivado: GET /api/settings/scanner devolvió "scanner":"none" y "availability":{"grype":false,"trivy":false}. Lo activé con curl -X POST localhost:29100/api/settings/scanner -H 'content-type: application/json' -d '{"scanner":"grype"}', que es lo mismo que elegir Grype en Ajustes.

Después, en Imágenes, expandí la fila de nginx, localicé la etiqueta 1.29-alpine y pulsé "Scan for vulnerabilities". Dockhand descargó anchore/grype:v0.119.0, lo ejecutó como contenedor efímero a través del proxy y leyó el resultado por la API de logs, por eso ALLOW_LOGS=1 es obligatorio. El resultado:

Gravedad Vulnerabilidades
Críticas 26
Altas 97
Medias 75
Bajas 13
Desconocidas 6
Total 217

Las críticas se concentran en cuatro paquetes. libcrypto3 y libssl3 están en la versión 3.5.6-r0 (corregidas en la 3.5.8-r0). curl y libcurl están en la 8.17.0-r1 (corregidas en la 8.22.0-r0). La imagen era de abril de 2026.

Esto apunta a la utilidad real del escáner: no mide Dockhand, mide lo viejo que es lo que despliegas. La solución es reconstruir con una etiqueta más reciente. Si quieres contraste, la comparación de Trivy y Grype explica en qué se diferencian, y Docker Scout cubre la alternativa de Docker.

Cómo se compara con Portainer, Komodo y Dockge

Dockhand compite en el mismo terreno que tres gestores más veteranos, y la diferencia está en lo que cada uno incluye de serie. Para elegir entre los tres clásicos, la guía Komodo vs Portainer vs Dockge los compara a fondo. Estos son los datos de GitHub del 7 de octubre de 2026:

Gestor Licencia Última versión Estrellas
Dockhand BSL 1.1 1.0.51 (3 oct 2026) 6 639
Komodo GPL-3.0 2.3.3 (1 sep 2026) 12 642
Dockge MIT 1.5.0 (30 mar 2025) 24 559
Portainer CE zlib 2.45.1 (17 sep 2026) 38 623

Lo que Dockhand aporta frente a ellos es el escáner de Grype y Trivy integrado, el despliegue desde Git y el editor visual en el mismo panel. Lo que le falta es recorrido: tiene menos de un año y su licencia no es de código abierto. Dockge no publica una versión desde marzo de 2025.

Mi criterio es este: para un homelab o un equipo pequeño que quiere escanear imágenes sin montar otra herramienta, Dockhand merece la prueba. Para más de un host con su propio agente, Portainer con Docker Compose o Komodo tienen más historia detrás.

Preguntas frecuentes

¿Dockhand es gratis?

Depende de quién lo use. Es gratis para uso personal, organizaciones sin ánimo de lucro y educación, y para desarrollo y pruebas en cualquier empresa. Usarlo en los sistemas en producción de una organización con empleados requiere una licencia comercial.

¿Es seguro montar el socket de Docker en Dockhand?

Montar el socket directamente da control total sobre el host. Un socket proxy como el de Tecnativa lo reduce a las llamadas que activas, y la guía de seguridad de Docker[5] lo explica al describir la superficie de ataque del demonio. Activa además la autenticación de Dockhand, porque viene desactivada.

¿Puedo usar Dockhand con más de un servidor?

Sí. Admite entornos remotos con un agente propio, Hawser, o con una conexión TCP directa. Probé solo el entorno local a través del proxy.

Conclusión

Dockhand 1.0.51 se instala con dos servicios de Compose, desplegó un stack sin problemas a través de un socket proxy y su escáner dio un resultado útil en la primera imagen. Los puntos débiles son la autenticación desactivada de partida y una licencia que obliga a pagar a las empresas.

Si lo pruebas, empieza en un homelab, deja el proxy con los permisos mínimos y activa los usuarios antes de abrir el puerto.

Fuentes: [1] Repositorio de Dockhand en GitHub[1], [2] Documentación de Dockhand[3], [3] Licencia de Dockhand (LICENSE.txt)[2], [4] Socket proxy de Tecnativa[4], [5] Grype de Anchore[6], [6] Seguridad de Docker Engine[5].

Fuentes

  1. README del proyecto
  2. LICENSE.txt
  3. documentación de Dockhand
  4. socket proxy de Tecnativa
  5. guía de seguridad de Docker
  6. Grype de Anchore