Skip to content

Deploying on Kubernetes

This guide shows how to run EventSourcingDB in a Kubernetes cluster using a production-ready configuration. It provides a reference manifest and explains the most important settings and their implications.

You should already have a Kubernetes cluster, a configured kubectl context, and an existing namespace. This guide assumes basic knowledge of Kubernetes concepts such as Pods, StatefulSets, Services, and PersistentVolumeClaims.

Reference Manifest

The following manifest shows how to deploy EventSourcingDB in a single-replica setup using HTTP. The configuration uses a PersistentVolumeClaim for durable storage and passes secrets and configuration via arguments:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: esdb
  namespace: <NAMESPACE>
spec:
  serviceName: esdb
  replicas: 1
  selector:
    matchLabels:
      app: esdb
  template:
    metadata:
      labels:
        app: esdb
    spec:
      securityContext:
        fsGroup: 101
      containers:
      - name: esdb
        image: thenativeweb/eventsourcingdb:<VERSION>
        ports:
        - name: http
          containerPort: 3000
        args: [
          "run",
          "--api-token", "<API_TOKEN>",
          "--license-string", "<LICENSE_STRING>",
          "--data-directory", "/var/lib/esdb",
          "--http-enabled",
          "--https-enabled=false"
        ]
        volumeMounts:
        - name: esdb-data
          mountPath: /var/lib/esdb
        resources:
          requests:
            memory: "256Mi"
            cpu: "1000m"
          limits:
            memory: "1Gi"
            cpu: "4000m"
        readinessProbe:
          httpGet:
            path: /api/v1/ping
            port: http
          initialDelaySeconds: 1
        livenessProbe:
          httpGet:
            path: /api/v1/ping
            port: http
          initialDelaySeconds: 1
      automountServiceAccountToken: false
  volumeClaimTemplates:
  - metadata:
      name: esdb-data
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: do-block-storage
      resources:
        requests:
          storage: 100Gi
---
apiVersion: v1
kind: Service
metadata:
  name: esdb
  namespace: <NAMESPACE>
spec:
  clusterIP: None
  ports:
  - name: http
    port: 3000
    targetPort: http
  selector:
    app: esdb

Replace:

  • <NAMESPACE> with the namespace in which to deploy EventSourcingDB
  • <VERSION> with the desired version of the Docker image (e.g., 1.2.0)
  • <API_TOKEN> with a secure string (at least 32 characters, mixed-case letters and digits)
  • <LICENSE_STRING> with your commercial license string

Single Replica Only

EventSourcingDB does not yet support clustered operation. You must set replicas: 1 in your deployment. Multi-replica support will be added in a future version.

Design Considerations

Using HTTP

This example uses HTTP (port 3000) and explicitly disables HTTPS. This is acceptable in private cluster environments where access is tightly controlled via NetworkPolicies or internal-only services.

Internal Access Only

Do not expose this HTTP-based deployment to the public internet. It is your responsibility to restrict access at the network level.

Persistent Storage

The deployment uses a PersistentVolumeClaim named esdb-data, which mounts to /var/lib/esdb inside the container. This is required for durability.

The clusterIP: None setting creates a headless service, which allows direct access to the Pod without load balancing. This is required by the StatefulSet for stable network identity.

DigitalOcean-Specific Storage Class

The storageClassName is set to do-block-storage, which is a DigitalOcean-specific storage class. If you're using a different Kubernetes provider, adjust the value to match your environment.

The requested size is 100Gi, which should be adjusted based on your expected event volume.

Resource Configuration

The resource requests and limits are intentionally generous:

requests:
  memory: "256Mi"
  cpu: "1000m"
limits:
  memory: "1Gi"
  cpu: "4000m"

These values are examples. Adjust them according to your cluster capacity and workload profile.

API Token and License

Both the API token and the commercial license are passed as arguments via --api-token and --license-string. This keeps configuration simple and avoids the need for mounted secrets or files.

If you prefer, you can inject these values using Kubernetes secrets and environment variables, but this is out of scope for this guide.

Enabling Event Signing (Optional)

To enable cryptographic signatures for events, provide the --signing-key-file argument and point it to a valid Ed25519 private key in PKCS#8 PEM format that is mounted into the container.

If no signing key is provided, the signature field of returned events will be null.

Probes

Readiness and liveness probes use the endpoint /api/v1/ping. This ensures the container is only marked ready after the database is up and responsive.

Key Takeaways

This Kubernetes deployment:

  • Uses a pinned Docker image version
  • Stores data in a persistent volume (/var/lib/esdb)
  • Uses HTTP for internal-only communication
  • Disables HTTPS explicitly
  • Requires exactly one replica (replicas: 1)
  • Passes the license and token as runtime arguments
  • Optionally set up event signing
  • Sets up liveness and readiness probes
  • Is isolated to a specific namespace and tightly scoped

Adapt the manifest to your infrastructure and workload. This example is optimized for internal, single-node deployments in managed Kubernetes environments.