_Docs/
Get StartedModulesPlatformDeployCookbookChangelogReference
_Deploy
  • Deployment Overview
    • Overview
    • Requirements
    • Demo
      • All-in-one Demo Chart
    • Installation
      • Operator Setup
      • Control Plane SetupEE
    • Infrastructure Services
      • PostgreSQL
      • Message Broker
      • Temporal
    • Module Configuration
      • Stack Configuration
      • Gateway Module
      • Ledger Module
      • Payments Module
      • Auth ModuleEE
      • Orchestration ModuleEE
      • Reconciliation ModuleEE
      • Wallets ModuleEE
      • Webhooks ModuleEE
    • Configuration Reference
      • Operator settings reference
      • API Reference
    • Backups management
    • Troubleshooting
    • Configure OpenTelemetry
    • Traces
    • Metrics
    • Upgrade from the operator
    • Database update
  1. Deploy
  2. Self-Hosted
  3. Infrastructure Services
  4. PostgreSQL
Deploy

PostgreSQL

This page requires self-hosted edition.
Deployment

Version 14 or higher is required.

Bundled PostgreSQL#

The unified formance Helm chart includes a Bitnami PostgreSQL instance enabled by default:

YAML
postgresql:
  enabled: true  # default

This deploys a single-node PostgreSQL server in your formance-system namespace. It's useful for development and testing, but not recommended for production workloads.

The bundled instance uses the credentials defined in global.postgresql.auth:

YAML
global:
  postgresql:
    host: "postgresql"
    auth:
      username: formance
      password: formance
      database: formance

The bundled PostgreSQL does not include persistent storage by default. Do not rely on it for production data.

External PostgreSQL#

For production, use a managed PostgreSQL service and disable the bundled instance:

YAML
postgresql:
  enabled: false

global:
  postgresql:
    host: "my-postgres.example.com"
    additionalArgs: "sslmode=require"
    auth:
      username: "formance"
      password: "your-secure-password"
      database: "formance"
      existingSecret: ""  # or reference a Kubernetes secret
      secretKeys:
        adminPasswordKey: ""
        userPasswordKey: ""
    service:
      ports:
        postgresql: 5432

Use global.postgresql.auth.existingSecret to reference a Kubernetes Secret instead of storing passwords in your values file.

Configure PostgreSQL URI via Helm Values#

The Formance Operator uses Settings CRDs to configure database connections for each stack. You can create these Settings declaratively through Helm values using regions.settings:

YAML
regions:
  settings:
    postgres-uri:
      key: "postgres.*.uri"
      value: "postgresql://formance:formance@my-postgres.example.com:5432?disableSSLMode=true"

This creates a Settings resource that applies the PostgreSQL URI to all stacks and all modules (the * wildcard).

Scope to Specific Stacks#

To target a specific stack, add a stacks field:

YAML
regions:
  settings:
    postgres-uri:
      key: "postgres.*.uri"
      stacks:
        - "my-stack"
      value: "postgresql://formance:formance@my-postgres.example.com:5432?disableSSLMode=true"

Per-Module Configuration#

Use the module name instead of * to configure different PostgreSQL servers per module:

YAML
regions:
  settings:
    postgres-ledger:
      key: "postgres.ledger.uri"
      value: "postgresql://formance:formance@pg-ledger.example.com:5432?disableSSLMode=true"
    postgres-payments:
      key: "postgres.payments.uri"
      value: "postgresql://formance:formance@pg-payments.example.com:5432?disableSSLMode=true"

Create Database Settings Manually#

If you prefer to manage Settings CRDs directly with kubectl, you can create them manually.

Option 1: Use the same server for all modules#

Set up a PostgreSQL cluster for all modules of the formance-dev stack. Each module gets its own database following the format {stackName}-{module}.

The database is created following the format: {stackName}-{module}

YAML
apiVersion: formance.com/v1beta1
kind: Settings
metadata:
  name: formance-dev-postgres-uri
spec:
  key: postgres.*.uri
  stacks:
    - 'formance-dev'
  value: postgresql://formance:formance@postgresql.formance-system.svc:5432?disableSSLMode=true

Option 2: Use different servers for each module#

YAML
---
apiVersion: formance.com/v1beta1
kind: Settings
metadata:
  name: formance-dev-ledger-postgres-uri
spec:
  key: postgres.ledger.uri
  stacks:
    - 'formance-dev'
  value: postgresql://formance:formance@postgresql-ledger.formance-system.svc:5432?disableSSLMode=true
---
apiVersion: formance.com/v1beta1
kind: Settings
metadata:
  name: formance-dev-payments-postgres-uri
spec:
  key: postgres.payments.uri
  stacks:
    - 'formance-dev'
  value: postgresql://formance:formance@postgresql-payments.formance-system.svc:5432?disableSSLMode=true

Option 3: Use PostgreSQL on AWS RDS with an IAM role#

YAML
apiVersion: v1
kind: ServiceAccount
metadata:
  name: aws-rds-access-role
  namespace: formance-system
  labels:
    formance.com/stack: any
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::AWS_ACCOUNT_ID:role/AWS_ROLE_NAME
---
apiVersion: formance.com/v1beta1
kind: Settings
metadata:
  name: formance-dev-aws-service-account
spec:
  stacks:
    - formance-dev
  key: aws.service-account
  value: aws-rds-access-role
---
apiVersion: formance.com/v1beta1
kind: Settings
metadata:
  name: formance-dev-postgres-uri
spec:
  key: postgres.*.uri
  stacks:
    - 'formance-dev'
  value: postgresql://formance@postgresql.formance-system.svc:5432
Control Plane SetupMessage Broker
On This Page
  • Bundled PostgreSQL
  • External PostgreSQL
  • Configure PostgreSQL URI via Helm Values
  • Scope to Specific Stacks
  • Per-Module Configuration
  • Create Database Settings Manually
  • Option 1: Use the same server for all modules
  • Option 2: Use different servers for each module
  • Option 3: Use PostgreSQL on AWS RDS with an IAM role