Kubernetes

Deploy Stategraph on Kubernetes using raw manifests.

Note: A Helm chart is coming soon. For now, use the raw manifests below.

Prerequisites

  • Kubernetes 1.24+
  • kubectl configured for your cluster
  • Ingress controller (for external access)

Quick Start

1. Create the manifest file

Save the following as stategraph.yaml, then edit the values marked # CHANGE THIS:

apiVersion: v1
kind: Namespace
metadata:
  name: stategraph
---
apiVersion: v1
kind: Secret
metadata:
  name: stategraph
  namespace: stategraph
stringData:
  db-password: "stategraph"  # CHANGE THIS for production
  # Uncomment for OAuth:
  # oauth-client-id: "your-client-id"
  # oauth-client-secret: "your-client-secret"
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: stategraph
  namespace: stategraph
data:
  STATEGRAPH_UI_BASE: "http://localhost:8080"  # CHANGE THIS to your public URL
  STATEGRAPH_OAUTH_REDIRECT_BASE: "http://localhost:8080"  # CHANGE THIS to match UI base
  STATEGRAPH_PORT: "8180"
  DB_HOST: "postgres"
  DB_PORT: "5432"
  DB_USER: "stategraph"
  DB_NAME: "stategraph"
  # Uncomment for OAuth (Google):
  # STATEGRAPH_OAUTH_TYPE: "google"
  # STATEGRAPH_OAUTH_EMAIL_DOMAIN: "*"
  # Uncomment for OAuth (OIDC):
  # STATEGRAPH_OAUTH_TYPE: "oidc"
  # STATEGRAPH_OAUTH_OIDC_ISSUER_URL: "https://your-provider.com"
  # STATEGRAPH_OAUTH_EMAIL_DOMAIN: "*"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
  namespace: stategraph
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:17-alpine
          env:
            - name: POSTGRES_USER
              value: "stategraph"
            - name: POSTGRES_DB
              value: "stategraph"
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: stategraph
                  key: db-password
          ports:
            - containerPort: 5432
          volumeMounts:
            - name: data
              mountPath: /var/lib/postgresql/data
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: postgres
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgres
  namespace: stategraph
spec:
  accessModes: [ReadWriteOnce]
  resources:
    requests:
      storage: 10Gi
---
apiVersion: v1
kind: Service
metadata:
  name: postgres
  namespace: stategraph
spec:
  selector:
    app: postgres
  ports:
    - port: 5432
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: stategraph
  namespace: stategraph
spec:
  replicas: 1
  selector:
    matchLabels:
      app: stategraph
  template:
    metadata:
      labels:
        app: stategraph
    spec:
      containers:
        - name: stategraph
          image: ghcr.io/stategraph/stategraph-server:latest
          envFrom:
            - configMapRef:
                name: stategraph
          env:
            - name: DB_PASS
              valueFrom:
                secretKeyRef:
                  name: stategraph
                  key: db-password
            # Uncomment for OAuth:
            # - name: STATEGRAPH_OAUTH_CLIENT_ID
            #   valueFrom:
            #     secretKeyRef:
            #       name: stategraph
            #       key: oauth-client-id
            # - name: STATEGRAPH_OAUTH_CLIENT_SECRET
            #   valueFrom:
            #     secretKeyRef:
            #       name: stategraph
            #       key: oauth-client-secret
          ports:
            - containerPort: 8080
          readinessProbe:
            httpGet:
              path: /api/v1/health
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /api/v1/health
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: stategraph
  namespace: stategraph
spec:
  selector:
    app: stategraph
  ports:
    - port: 80
      targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: stategraph
  namespace: stategraph
spec:
  ingressClassName: nginx  # CHANGE THIS if using different ingress controller
  rules:
    - host: stategraph.example.com  # CHANGE THIS to your domain
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: stategraph
                port:
                  number: 80

2. Deploy

kubectl apply -f stategraph.yaml

3. Verify

kubectl get pods -n stategraph
kubectl logs -n stategraph -l app=stategraph

4. Access

If using the Ingress, access via your configured domain. For local testing:

kubectl port-forward -n stategraph svc/stategraph 8080:80

Then open http://localhost:8080.

Authentication

To enable OAuth, uncomment and configure the OAuth settings in the ConfigMap and Secret, then redeploy. See the Authentication guide for detailed setup.

Configuration

Edit the ConfigMap and Secret in stategraph.yaml before deploying:

What Where Example
Public URL ConfigMap STATEGRAPH_UI_BASE https://stategraph.example.com
OAuth callback ConfigMap STATEGRAPH_OAUTH_REDIRECT_BASE Same as UI base
OAuth type ConfigMap STATEGRAPH_OAUTH_TYPE google or oidc
OIDC issuer ConfigMap STATEGRAPH_OAUTH_OIDC_ISSUER_URL https://accounts.google.com
DB password Secret db-password Use a strong password
OAuth credentials Secret oauth-client-id, oauth-client-secret From your OAuth provider
Domain Ingress rules[0].host stategraph.example.com

Using External PostgreSQL

To use an existing PostgreSQL database instead of the bundled one:

  1. Delete the postgres Deployment, Service, and PVC from the manifest
  2. Update the ConfigMap: yaml DB_HOST: "your-postgres-host.example.com" DB_PORT: "5432" DB_USER: "stategraph" DB_NAME: "stategraph"

Troubleshooting

# Check pod status
kubectl get pods -n stategraph

# View logs
kubectl logs -n stategraph -l app=stategraph

# Check events
kubectl get events -n stategraph --sort-by='.lastTimestamp'

Next Steps