Volver
En desarrollo activo

go-container

Panel de administración de Docker self-hosted, tipo Portainer simplificado

Go Go Vue 3 Vue 3 Vite Vite PostgreSQL PostgreSQL JWT JWT WebSockets WebSockets JavaScript JavaScript Docker Docker

Qué es

Panel web para gestionar containers, imágenes, redes, volúmenes, "stacks" (proyectos docker-compose) y usuarios con roles, todo desde el navegador. El backend actúa como proxy autenticado sobre el Docker Engine API del host, no como una reimplementación de Docker.

Se distribuye como un solo binario Go que embebe el build de producción del frontend, así que en producción es un único contenedor sirviendo tanto la API como la SPA.

Highlights

  • Gestión completa de containers, imágenes, redes, volúmenes y stacks (docker-compose) desde una SPA en Vue 3.
  • Shell interactiva por WebSocket dentro de cada container (xterm.js) y streaming de logs en vivo.
  • Sistema de roles (viewer / editor / administrator) con revalidación de la sesión contra la base en cada request, así desactivar un usuario invalida su acceso al instante.
  • Los "stacks" no son solo un pass-through de Docker: se persisten en Postgres y cada operación (deploy, stop, pull, force-deploy) invoca el CLI real de docker compose, con reintento si un paso falla sin perder el registro.
  • Watcher que escucha eventos de muerte de containers y persiste sus últimos logs, para poder ver por qué murió uno aunque después se borre.
  • Recuperación de crash: si el proceso muere sin un shutdown limpio (panic, OOM-kill), el contenido del log se recupera y se guarda en el próximo arranque.

Arquitectura

  • Backend en Go con Gin como router y GORM + PostgreSQL para persistencia.
  • Cliente propio contra el socket de Docker (sin el SDK oficial), hablando directo la Engine API por HTTP.
  • Frontend en Vue 3 (Composition API) + Vite + Pinia, sin frameworks de CSS.
  • Autenticación con JWT; los WebSockets (shell, logs) aceptan el token también como query param porque el navegador no permite mandar el header Authorization en un WS nativo.
  • Build de producción: un Dockerfile multi-stage compila el frontend, lo embebe en el binario Go (go:embed) y arma una imagen final que solo necesita el binario + el CLI de docker compose.

Cómo correrlo

docker-compose.yml (desarrollo)
services:
  app:
    build:
      context: ./app
      target: dev
    ports:
      - "9000:9000"
    volumes:
      - ./app:/app
      - /app/tmp
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DB_HOST=db
      - DB_PORT=5432
      - DB_USER=postgres
      - DB_PASSWORD=postgres
      - DB_NAME=go_container
      - DOCKER_SOCKET_PATH=/var/run/docker.sock
      - CORS_ALLOWED_ORIGIN=http://localhost:5173
    depends_on:
      - db

  db:
    image: postgres:16-alpine
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=go_container
    ports:
      - "5433:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data

  front:
    build:
      context: ./front
      target: dev
    ports:
      - "5173:5173"
    volumes:
      - ./front:/app
      - /app/node_modules

volumes:
  pgdata:
Levantar el entorno
docker compose up -d

Variables de entorno

VariableDefaultUso
SECRET_KEYdefault_secret_keyFirma de JWT — cambiar en producción.
DB_HOSTlocalhostHost de PostgreSQL.
DB_PORT5432Puerto de PostgreSQL.
DB_USERpostgresUsuario de PostgreSQL.
DB_PASSWORDpostgresContraseña de PostgreSQL.
DB_NAMEgo_containerNombre de la base de datos.
DOCKER_SOCKET_PATH/var/run/docker.sockSocket del Docker Engine a proxear.
CORS_ALLOWED_ORIGINhttp://localhost:5173Único origen permitido por el middleware CORS.
STACKS_DIRstacksDirectorio donde se materializan los docker-compose.yml de cada stack.