Volver
Go
Vue 3
Vite
PostgreSQL
JWT
WebSockets
JavaScript
Docker
En desarrollo activo
go-container
Panel de administración de Docker self-hosted, tipo Portainer simplificado
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 -dVariables de entorno
| Variable | Default | Uso |
|---|---|---|
| SECRET_KEY | default_secret_key | Firma de JWT — cambiar en producción. |
| DB_HOST | localhost | Host de PostgreSQL. |
| DB_PORT | 5432 | Puerto de PostgreSQL. |
| DB_USER | postgres | Usuario de PostgreSQL. |
| DB_PASSWORD | postgres | Contraseña de PostgreSQL. |
| DB_NAME | go_container | Nombre de la base de datos. |
| DOCKER_SOCKET_PATH | /var/run/docker.sock | Socket del Docker Engine a proxear. |
| CORS_ALLOWED_ORIGIN | http://localhost:5173 | Único origen permitido por el middleware CORS. |
| STACKS_DIR | stacks | Directorio donde se materializan los docker-compose.yml de cada stack. |