SpecsModelExplore
Overview
IOModel Stack
Reverse ProxyIOModel StudioYjs Realtime ServerKeycloakPostgreSQLRedis
Why it's needed
Deployment
SpecsModelExplore
PostgreSQL
OverviewPostgreSQL GuideLinks and Communications

PostgreSQL is the system of record. It stores projects, model and spec content, versioning history, and — when Keycloak uses it — identity data. This is the one component you must back up.

Role in the stack

Studio reads and writes application data here, and the Yjs Realtime Server persists collaboration documents into it. It is the durable heart of the stack.

Why it’s needed

  • Durable state — everything that must survive a restart lives here.
  • Transactional integrity — consistent writes for projects, content, and version history.
  • Single source of truth — other components are disposable; this is not.

Deployment

PostgreSQL is stateful: it needs stable storage and a stable network identity, so it is deployed as a StatefulSet (Kubernetes) or a single-node pinned service with a named volume (Swarm).

apiVersion: apps/v1kind: StatefulSetmetadata:  name: postgres  namespace: iomodelspec:  serviceName: postgres  replicas: 1  selector: { matchLabels: { app: postgres } }  template:    metadata: { labels: { app: postgres } }    spec:      containers:        - name: postgres          image: postgres:16          ports: [{ containerPort: 5432 }]          volumeMounts:            - name: pgdata              mountPath: /var/lib/postgresql/data  volumeClaimTemplates:    - metadata: { name: pgdata }      spec:        accessModes: ['ReadWriteOnce']        resources: { requests: { storage: 20Gi } }

The volumeClaimTemplates block is what makes storage durable and bound to the pod identity. Never run the database off an emptyDir.

Back it up and test restores

A backup you have not restored is a hope, not a plan. Schedule regular dumps or volume snapshots with retention, and rehearse restores.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
  namespace: iomodel
spec:
  serviceName: postgres
  replicas: 1
  selector: { matchLabels: { app: postgres } }
  template:
    metadata: { labels: { app: postgres } }
    spec:
      containers:
        - name: postgres
          image: postgres:16
          ports: [{ containerPort: 5432 }]
          volumeMounts:
            - name: pgdata
              mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
    - metadata: { name: pgdata }
      spec:
        accessModes: ['ReadWriteOnce']
        resources: { requests: { storage: 20Gi } }