A centralized multi-host Docker management dashboard built with Go and React/TypeScript. Monitor and manage containers, images, networks, and volumes across multiple Docker hosts from a single web interface.
flowchart TD
Browser["π Browser"] -->|HTTP / WS| Ingress
subgraph K8S["βΈοΈ Kubernetes Cluster"]
Ingress["π¦ Ingress NGINX<br/>docker-dash.local"]
subgraph Frontend["βοΈ Frontend (React + Vite)"]
ReactUI["React + Tailwind<br/>Charts, xterm.js"]
FrontendSVC["frontend-service<br/>ClusterIP :80"]
ReactUI --> FrontendSVC
end
subgraph Backend["π’ Backend (Go + Chi)"]
APIRouter["API Router + JWT Auth"]
HostMgr["Host Manager"]
ContainerMgr["Container Manager"]
NetworkMgr["Network Manager"]
VolumeMgr["Volume Manager"]
ImageMgr["Image Manager"]
LogStream["Log Streamer<br/>WebSocket"]
StatsMon["Stats Monitor<br/>WebSocket"]
Terminal["Interactive Terminal<br/>WebSocket"]
BackendSVC["backend-service<br/>ClusterIP :8080"]
APIRouter --> HostMgr
APIRouter --> ContainerMgr
APIRouter --> NetworkMgr
APIRouter --> VolumeMgr
APIRouter --> ImageMgr
APIRouter --> LogStream
APIRouter --> StatsMon
APIRouter --> Terminal
APIRouter --> BackendSVC
end
subgraph Database["π PostgreSQL StatefulSet"]
PostgresSVC["postgres-service<br/>ClusterIP :5432"]
PostgresPod["PostgreSQL Pod"]
PV["πΎ PV 1Gi"]
PostgresSVC --> PostgresPod --> PV
end
subgraph Config["βοΈ Configuration"]
CM["π ConfigMap<br/>DATABASE_URL<br/>MIGRATIONS_PATH<br/>POSTGRES_DB / USER"]
Sec["π Secret<br/>POSTGRES_PASSWORD<br/>JWT_SECRET"]
end
Ingress -->|"/ /ws"| FrontendSVC
Ingress -->|"/api"| BackendSVC
HostMgr -.->|Docker Socket| D1
HostMgr -.->|Docker Socket| D2
HostMgr -.->|Docker Socket| DN
ContainerMgr -.->|Docker SDK| D1
NetworkMgr -.->|Docker SDK| D1
VolumeMgr -.->|Docker SDK| D1
ImageMgr -.->|Docker SDK| D1
BackendSVC -->|TCP 5432| PostgresSVC
CM -.->|env| BackendSVC
Sec -.->|env| BackendSVC
CM -.->|env| PostgresPod
Sec -.->|env| PostgresPod
end
subgraph Hosts["π³ Docker Hosts"]
D1["Docker Host 1<br/>Docker Daemon"]
D2["Docker Host 2<br/>Docker Daemon"]
DN["Docker Host N<br/>Docker Daemon"]
end
D1 -.->|"hostPath<br/>/var/run/docker.sock"| Backend
D2 -.->|"registered<br/>TCP endpoint"| Backend
DN -.->|"registered<br/>TCP endpoint"| Backend
- Multi-host management β Register Unix socket, TCP, or SSH Docker hosts
- Container lifecycle β Create, start, stop, and remove containers with port mappings
- Real-time logs β Stream container logs via WebSocket with tail control
- Live stats β CPU, memory, network, and block I/O charts updated in real-time
- Interactive terminal β Browser-based shell via xterm.js and Docker exec
- Network management β Create, delete, connect/disconnect containers from networks
- Volume management β Create and remove volumes
- Image management β Pull and delete images; dangling images filtered by default
- Production-ready β Multi-stage Docker builds, Nginx reverse proxy, health checks
flowchart TD
Browser["π Browser"] -->|http://docker-dash.local| Ingress
subgraph KIND_CLUSTER["βΈοΈ KIND CLUSTER"]
Ingress["π¦ Ingress NGINX<br/>docker-dash.local"]
subgraph Frontend["Frontend Deployment"]
FrontendSVC["frontend-service<br/>ClusterIP: 80"]
ReactPod["βοΈ React + Nginx Pod"]
FrontendSVC --> ReactPod
end
subgraph Backend["Backend Deployment (2 Replicas)"]
BackendSVC["backend-service<br/>ClusterIP: 8080"]
GoPod1["π’ Go Pod 1"]
GoPod2["π’ Go Pod 2"]
BackendSVC --> GoPod1
BackendSVC --> GoPod2
end
subgraph Database["PostgreSQL StatefulSet"]
PostgresSVC["postgres-service<br/>ClusterIP: 5432"]
PostgresPod["π PostgreSQL Pod"]
PV["πΎ PersistentVolume (1Gi)"]
PostgresSVC --> PostgresPod
PostgresPod --> PV
end
subgraph Config["Configuration"]
CM["π ConfigMap<br/>POSTGRES_DB Β· POSTGRES_USER<br/>DATABASE_URL Β· MIGRATIONS_PATH"]
Sec["π Secret<br/>POSTGRES_PASSWORD Β· JWT_SECRET"]
end
Ingress -->|/ & /api/ws| FrontendSVC
Ingress -->|/api| BackendSVC
GoPod1 -->|TCP 5432| PostgresSVC
GoPod2 -->|TCP 5432| PostgresSVC
CM -.->|env vars| GoPod1
CM -.->|env vars| PostgresPod
Sec -.->|env vars| GoPod1
Sec -.->|env vars| PostgresPod
GoPod1 -.->|/var/run/docker.sock| DockerSocket["π Docker Socket (hostPath)"]
GoPod2 -.->|/var/run/docker.sock| DockerSocket
end
git clone https://github.com/YOUR_USERNAME/shipwright.git
cd shipwright
make dev-up| Service | URL |
|---|---|
| Frontend | http://localhost:5173 |
| Backend API | http://localhost:8080 |
| PostgreSQL | localhost:5432 |
cd shipwright
bash scripts/k8s-deploy.shAdd to /etc/hosts:
127.0.0.1 docker-dash.local
Then open http://docker-dash.local
shipwright/
βββ backend/
β βββ cmd/server/ # Entrypoint (--migrate flag for DB migrations)
β βββ internal/ # Handlers, middleware, auth, repository, config
β βββ pkg/dockerclient/ # Docker SDK client + DockerProvider interface
β βββ migrations/ # PostgreSQL schema migrations
β βββ Dockerfile # Multi-stage production build (~11MB)
βββ frontend/
β βββ src/ # React components, pages, services
β βββ Dockerfile # Multi-stage build with Nginx (~21MB)
β βββ nginx.conf # SPA routing, gzip, API proxy
βββ infra/k8s/ # Kubernetes manifests
β βββ kind-cluster.yaml
β βββ namespace.yaml
β βββ postgres-*.yaml
β βββ backend-*.yaml
β βββ frontend-*.yaml
β βββ ingress.yaml
βββ docker-compose.yaml # Dev stack
βββ docker-compose.prod.yaml # Production stack
βββ Makefile
βββ scripts/k8s-deploy.sh
make test # Backend tests
make test-cover # Tests with coverage report
make lint # Lint backend + frontend
make lint-backend # Backend lint only
make lint-frontend # Frontend lint only (or lint-frontend-fix)This project is private and proprietary.