quickstart
provisioning

Quick Start

Get a fully managed PostgreSQL cluster running on your local Kubernetes in 5 minutes.

Prerequisites

  • Kubernetes cluster — minikube, Docker Desktop, kind, or k3s
  • kubectl configured and pointing at your cluster
  • Go 1.24+ (to build the server)

1. Start minikube (if needed)

minikube start --memory 8192 --cpus 4

2. Install CloudNativePG operator

kubectl apply --server-side -f \
  https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-1.23/releases/cnpg-1.23.0.yaml

Wait for it to be ready:

kubectl get pods -n cnpg-system
# NAME                                      READY   STATUS    RESTARTS   AGE
# cnpg-controller-manager-...               1/1     Running   0          30s

3. Install metrics-server (for CPU/memory monitoring)

kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml

# Patch for local clusters (self-signed certs)
kubectl patch deployment metrics-server -n kube-system \
  --type=json \
  -p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'

4. Deploy LocalStack for S3 backups

kubectl create namespace localstack
kubectl apply -n localstack -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: localstack
spec:
  replicas: 1
  selector:
    matchLabels:
      app: localstack
  template:
    metadata:
      labels:
        app: localstack
    spec:
      containers:
      - name: localstack
        image: localstack/localstack:latest
        ports:
        - containerPort: 4566
        env:
        - name: SERVICES
          value: s3
        - name: DEFAULT_REGION
          value: us-east-1
        - name: LOCALSTACK_ACKNOWLEDGE_ACCOUNT_REQUIREMENT
          value: "1"
---
apiVersion: v1
kind: Service
metadata:
  name: localstack
spec:
  selector:
    app: localstack
  ports:
  - port: 4566
    targetPort: 4566
EOF

Create the S3 bucket:

kubectl exec -n localstack deployment/localstack -- \
  sh -c "AWS_ACCESS_KEY_ID=test AWS_SECRET_ACCESS_KEY=test \
  aws --endpoint-url=http://localhost:4566 s3 mb s3://postgres-backups"

5. Build and start the server

cd server-go
go build -o excalibase-server ./cmd/server/
PORT=24005 STORAGE_PATH=../provisioning-data ./excalibase-server

6. Provision a database

curl -X POST http://localhost:24005/api/provision \
  -H "Content-Type: application/json" \
  -d '{
    "projectName": "my-db",
    "orgId": "myorg",
    "databaseType": "POSTGRESQL",
    "tier": "FREE",
    "backup": {
      "enabled": true,
      "schedule": "0 2 * * *",
      "retention": 30
    },
    "parameters": {
      "shared_preload_libraries": "pg_stat_statements",
      "pg_stat_statements.max": "10000",
      "pg_stat_statements.track": "all"
    }
  }'

The 8-stage pipeline runs. Takes 60-90 seconds on a local cluster.

7. Get credentials

curl http://localhost:24005/api/provision/my-db/credentials
{
  "projectId": "my-db",
  "host": "my-db-postgres-rw.myorg-my-db.svc.cluster.local",
  "port": 5432,
  "databaseName": "app",
  "username": "app",
  "password": "...",
  "sslMode": "require",
  "connectionUrl": "postgresql://app:...@my-db-postgres-rw..."
}

8. Check metrics

curl http://localhost:24005/api/provision/my-db/metrics/current
{
  "metricsAvailable": true,
  "healthStatus": "HEALTHY",
  "cpuUsageCores": 0.023,
  "cpuLimitCores": 0.5,
  "memoryUsageMB": 105,
  "memoryLimitMB": 512,
  "activeConnections": 1,
  "maxConnections": 100,
  "pods": [
    { "name": "my-db-postgres-1", "role": "primary", "cpuCores": 0.023, "memoryMB": 105 }
  ]
}

Next steps