Spin up e-commerce stores on Kubernetes with one API call.
DockStore is a control plane that creates isolated online stores (WordPress + WooCommerce or MedusaJS) inside your Kubernetes cluster. Each store gets its own namespace, database, storage, and domain — fully automated through Helm charts. A React dashboard lets you manage everything from your browser.
Setting up an online store normally means:
- Installing WordPress or MedusaJS manually
- Configuring a database
- Setting up DNS and HTTPS
- Managing backups and isolation between stores
DockStore automates all of that. One POST request = one fully provisioned store, ready to use in about 30 seconds. Each store is completely isolated from others, so a problem in one never affects another.
┌───────────────────────────────────────────┐
│ Orchestrator (Node.js API) │
│ Runs on port 4000 │
│ POST /hubs → creates a store │
│ DELETE /hubs → tears it down │
│ GET /hubs → lists all stores │
└────────────────┬──────────────────────────┘
│
▼
┌───────────────────────────────────────────┐
│ Kubernetes cluster │
│ │
│ ┌──────────────────┐ ┌──────────────────┐│
│ │ Store "hub-abc" │ │ Store "hub-xyz" ││
│ │ │ │ ││
│ │ └─ WordPress │ │ └─ MedusaJS ││
│ │ └─ MySQL │ │ └─ PostgreSQL ││
│ │ └─ PVC (storage)│ │ └─ Redis ││
│ │ └─ Ingress (URL)│ │ └─ Ingress (URL)││
│ └──────────────────┘ └──────────────────┘│
└───────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────┐
│ Bridge (React dashboard) │
│ Runs on port 3000 │
│ Click to create / delete stores │
└───────────────────────────────────────────┘
| Folder | What it does |
|---|---|
orchestrator/ |
Node.js API that talks to Kubernetes. Creates/deletes namespaces, runs Helm installs. |
bridge/ |
React dashboard. Shows all stores, their status, lets you spawn or retire them. |
blueprints/catalog/ |
Helm chart for a WordPress + WooCommerce store (MySQL database). |
blueprints/marketplace/ |
Helm chart for a MedusaJS store (PostgreSQL + Redis). |
k8s/ |
Example raw Kubernetes manifests and a Redis setup for the control plane. |
Catalog — WordPress + WooCommerce
- Best for: traditional e-commerce, physical products, digital downloads
- Database: MySQL 8.0
- Storage: 5GB persistent volume
- Ingress:
your-store.localtest.me
Marketplace — MedusaJS
- Best for: headless commerce, custom frontends, multi-channel selling
- Database: PostgreSQL 15
- Cache: Redis 7
- Ingress:
your-store.localtest.me
You need these installed on your machine:
- Docker Desktop (with Kubernetes enabled — Settings → Kubernetes → Enable)
- Helm (
brew install helm) - Node.js 18+ and npm
- Minikube (
brew install minikube) or Docker Desktop's built-in Kubernetes
If using Minikube:
minikube start --driver=docker
minikube addons enable ingressIf using Docker Desktop:
- Open Docker Desktop → Settings → Kubernetes → Check "Enable Kubernetes" → Apply
Open a second terminal and leave this running:
minikube tunnelcd DockStore
docker compose up --buildThis starts three services:
| Service | Port | What it does |
|---|---|---|
orchestrator |
4000 | Backend API that manages stores |
bridge |
3000 | Dashboard UI |
state-store |
6379 | Redis — tracks store statuses |
Open http://localhost:3000 in your browser.
- Pick a template (Catalog or Marketplace)
- Click "Spawn Hub"
- Wait 30-40 seconds — the status changes from Assembling → Live
- Click the store URL to visit your new store
# List all stores
curl http://localhost:4000/hubs
# Create a new store (WooCommerce)
curl -X POST http://localhost:4000/hubs \
-H "Content-Type: application/json" \
-d '{"template": "catalog"}'
# Delete a store
curl -X DELETE http://localhost:4000/hubs/hub-abc123| Status | Meaning |
|---|---|
Assembling |
Kubernetes is provisioning resources (30s) |
Live |
Store is ready — visit its URL |
Faulted |
Something went wrong (check cluster resources) |
Draining |
Store is being deleted |
Provisioned stores are accessible at:
http://hub-xxxxx.localtest.me
These only work while minikube tunnel is running. Each store is a fully functional e-commerce site — you can log in to the admin panel, add products, configure payments, etc.
DockStore/
│
├── orchestrator/ # Backend API
│ ├── server.js # All the logic — Helm install/uninstall, Redis state
│ ├── Dockerfile # Packages kubectl + helm into a Docker image
│ └── package.json
│
├── bridge/ # Frontend dashboard
│ ├── src/
│ │ ├── App.js # Main dashboard page
│ │ ├── api.js # How the dashboard talks to the API
│ │ └── components/
│ │ ├── HubTable.jsx # Table showing all stores
│ │ ├── HubRow.jsx # A single store row
│ │ ├── StatusBadge.jsx # Green/red/orange status pill
│ │ ├── StatusChart.jsx # Bar chart of store statuses
│ │ └── SummaryCards.jsx # Total stores, live count, etc.
│ └── Dockerfile
│
├── blueprints/ # Helm charts (Kubernetes templates)
│ ├── catalog/ # WordPress + WooCommerce
│ │ └── templates/
│ │ ├── database.yaml # MySQL StatefulSet + Secret + Service
│ │ ├── application.yaml # WordPress Deployment
│ │ ├── storage.yaml # Persistent volume claim
│ │ ├── ingress.yaml # URL routing
│ │ └── service.yaml # Internal networking
│ └── marketplace/ # MedusaJS
│ └── templates/
│ ├── database.yaml # PostgreSQL StatefulSet
│ ├── application.yaml # MedusaJS Deployment
│ ├── cache.yaml # Redis Deployment
│ ├── ingress.yaml
│ └── service.yaml
│
├── k8s/ # Raw Kubernetes manifests (reference only)
│ ├── examples/
│ └── platform/
│
├── docker-compose.yml # Runs everything: Redis + API + Dashboard
├── BUILD.md # How to run without Docker
└── README.md
When you create a store:
- Generate an ID — something like
hub-a3f8k2 - Save to Redis — status is set to
Assembling - Run Helm install —
helm install hub-a3f8k2 ./blueprints/catalog --namespace hub-a3f8k2 - Kubernetes creates:
- A new namespace (
hub-a3f8k2) - MySQL database with 5GB storage
- WordPress instance connected to that database
- An ingress rule for
hub-a3f8k2.localtest.me
- A new namespace (
- After 30 seconds — status updates to
Live
When you delete a store:
- Status changes to
Draining helm uninstallremoves the Kubernetes resources- The namespace is deleted (cleans up everything inside it)
- Redis entry is removed
All state is tracked in Redis. The UI polls the API every 3 seconds to show live updates.
Click the Retire button in the dashboard, or:
curl -X DELETE http://localhost:4000/hubs/hub-a3f8k2This removes everything — namespace, database, storage, and ingress. No leftovers.
Stores keep showing Faulted
- Make sure Minikube is running:
minikube status - Make sure the minikube tunnel is running in another terminal
- Check if your cluster has enough resources:
kubectl get pods -A - The orchestrator needs to be connected to the minikube Docker network
Can't access store URLs
- The
minikube tunnelcommand must be running - Make sure the ingress addon is enabled:
minikube addons enable ingress
Dashboard shows nothing
- Check if Docker containers are running:
docker ps - Restart:
docker compose down && docker compose up --build
Node.js + Express powers the REST API that handles store creation, deletion, and status tracking.
React with React Query builds the dashboard — live-polling every 3 seconds, status charts via Recharts.
Docker and Docker Compose containerize the API, dashboard, and Redis state store into a three-service stack that starts with one command.
Kubernetes runs the actual store workloads. Minikube provides a local cluster. Helm 3 packages each store template into reusable charts.
Redis acts as the source of truth — every store's status (Assembling → Live → Faulted → Draining) lives here.
NGINX Ingress Controller routes *.localtest.me domains to each store's WordPress or MedusaJS instance.
MySQL 8.0 and PostgreSQL 15 back the two store engines. WordPress + WooCommerce runs on MySQL; MedusaJS runs on Postgres with a Redis cache.
Namespace isolation — Each store is a separate Kubernetes namespace. If one store crashes or gets hacked, the others keep running. No shared databases, no shared file systems.
Helm charts — All the Kubernetes YAML is packaged into Helm charts. One command (helm install) creates everything: database, application, storage, networking. No manual YAML juggling.
Redis as source of truth — The API writes store state to Redis immediately, then provisions asynchronously. This means the dashboard always shows the latest status, even while Kubernetes is still spinning things up.
Docker Compose for dev — Three containers (API, dashboard, Redis) defined in one file. One docker compose up and the whole system runs.
| File | What to change |
|---|---|
blueprints/catalog/values.yaml |
WordPress version, MySQL storage size |
blueprints/marketplace/values.yaml |
MedusaJS version, PostgreSQL storage |
orchestrator/server.js line ~45 |
Timeout before marking store as Live (default 30s) |
orchestrator/server.js line ~55 |
Domain pattern (default *.localtest.me) |
bridge/src/api.js line 1 |
API URL if running without Docker |
docker-compose.yml |
Port numbers if 3000/4000 are taken |
DockStore = API + Dashboard that creates fully isolated e-commerce stores on Kubernetes with one click, then tears them down cleanly when you're done.

