The modern open-source Kubernetes interface.
graph TD
subgraph Control Plane
Panel["Panel\n:8081"]
Core["Core\n:8080 REST\n:10101 gRPC"]
DB["PostgreSQL"]
Panel -->|reverse proxy| Core
Core --- DB
end
Core -->|gRPC :10101| AgentA
Core -->|gRPC :10101| AgentB
Core -->|gRPC :10101| AgentC
subgraph Cluster A
AgentA["Agent"]
end
subgraph Cluster B
AgentB["Agent"]
end
subgraph Cluster C
AgentC["Agent"]
end
Control Plane — Core API + Panel UI + PostgreSQL. Deploy once on a VM or Kubernetes cluster.
Agent — One per managed cluster. Connects to the control plane via gRPC. Deploy after creating a cluster in the PodDeck UI.
Best for VMs, bare metal, or local testing.
git clone https://github.com/poddeck/poddeck-deployment.git
cd poddeck-deployment/docker
cp .env.example .envEdit .env with your configuration:
# Generate JWT secrets
openssl rand -hex 16 # use for AUTH_KEY
openssl rand -hex 16 # use for REFRESH_KEY
# Set your database password
DB_PASSWORD=your-secure-password
# Set the hostname that agents will use to connect (must be reachable from K8s clusters)
GRPC_HOST=poddeck.example.comStart the control plane:
docker compose up -dCreate your first user:
./create-user.shPodDeck is now accessible at http://localhost:8081 (or the port configured in PANEL_PORT).
Pull the latest images and restart the stack:
docker compose pull
docker compose down && docker compose up -d| Port | Service | Purpose |
|---|---|---|
| 8081 | Panel | Web UI |
| 10101 | Core (gRPC) | Agent connections — must be reachable from managed clusters |
Best for production deployments on Kubernetes.
- Helm 3.x
- A Kubernetes cluster for the control plane
helm repo add poddeck https://poddeck.github.io/poddeck-deployment
helm repo updateUsing the provided values file:
# Edit helm/values-control-plane.yaml with your settings
helm install poddeck poddeck/poddeck -f helm/values-control-plane.yamlOr inline:
helm install poddeck poddeck/poddeck \
--set postgresql.auth.password=your-db-password \
--set core.grpcHost=poddeck.example.comJWT keys are auto-generated if not provided.
After deploying the control plane:
- Open the PodDeck UI
- Go to the Cluster page
- Click + Add cluster, fill in name and icon
- The Deploy Agent dialog will show a Helm command with your cluster credentials pre-filled
- Run the command in the target Kubernetes cluster
Or manually:
helm install poddeck-agent poddeck/poddeck-agent \
--set core.hostname=poddeck.example.com \
--set core.port=10101 \
--set cluster.id=<CLUSTER_ID> \
--set cluster.key=<AGENT_KEY>The cluster.id and cluster.key are provided by the PodDeck UI when you create a cluster.
To upgrade an existing agent to a new image tag without losing its cluster credentials:
helm upgrade poddeck-agent poddeck/poddeck-agent \
--reuse-values \
--set image.tag=v1.0.0 \
--set image.pullPolicy=IfNotPresent--reuse-values preserves the previously set cluster.id, cluster.key, and core.hostname.
PodDeck can resolve login sessions to geographic locations using the MaxMind GeoLite2 database. This is fully optional — without it, sessions will simply have empty country/city fields.
- Download
GeoLite2-City.mmdbfrom MaxMind (free account required) - Place it at
docker/geo/GeoLite2-City.mmdb - Uncomment the volume mount in
docker-compose.yml:
volumes:
- ./geo/GeoLite2-City.mmdb:/app/geo/GeoLite2-City.mmdb:roMount the database file into the core pod at /app/geo/GeoLite2-City.mmdb using a ConfigMap, Secret, or PersistentVolume.
The gRPC port (default 10101) on the control plane must be reachable from every managed Kubernetes cluster. Ensure:
- Firewall rules allow inbound TCP on the gRPC port
- DNS or IP is resolvable from the managed clusters
- For Helm deployments, the
core.grpcService.type: LoadBalancercreates an external endpoint automatically
| Variable | Required | Default | Description |
|---|---|---|---|
DB_PASSWORD |
Yes | — | PostgreSQL password |
AUTH_KEY |
Yes | — | JWT signing key (32 hex chars) |
REFRESH_KEY |
Yes | — | JWT refresh key (32 hex chars) |
GRPC_HOST |
Yes | localhost |
Hostname for agent connections |
GRPC_PORT |
No | 10101 |
gRPC port |
PANEL_PORT |
No | 8081 |
Panel web UI port |
ALLOWED_ORIGINS |
No | http://localhost |
CORS origins |
DB_USERNAME |
No | poddeck |
PostgreSQL username |
DB_DATABASE |
No | poddeck |
PostgreSQL database name |
See helm/values-control-plane.yaml for all available values.
See helm/values-agent.yaml for all available values.