Skip to Content

PostgreSQL

The PostgreSQL service is different from most Veris services:

  • it provides a real PostgreSQL database
  • it applies your schema before seeding
  • it can expose a Supabase/PostgREST-compatible surface for apps that expect Supabase

Your agent can connect to it using standard PostgreSQL connection strings, or through a Supabase-style HTTP/RPC layer if your app uses Supabase clients.

Requirements

Most apps need to do all 3 steps:

  1. Enable the Postgres service in veris.yaml

  2. Provide one SQL schema artifact and point schema_path at it

  3. Configure your app to connect to the mock database

If your app expects specific tables, functions, or RPCs to exist before startup, those need to be present in the schema file too.

Enable the service

Add the service to veris.yaml:

.veris/veris.yaml
services: - name: postgres

That gives your simulation a real Postgres instance. If you do nothing else, the database starts empty.

Provide a schema file

Most real applications should provide a schema file. Without one, Veris starts an empty database with no application tables or functions.

How schema loading works

The current Postgres service startup path is driven by one concrete SQL file:

.veris/veris.yaml
services: - name: postgres config: schema_path: /agent/db/schema.sql

At startup, Veris reads schema_path, exports it as SCHEMA_PATH, and applies that SQL file before seeding.

If schema_path is missing, or the file does not exist in the image, the database starts without your tables and functions.

Put the schema file in your image

The simplest pattern is to copy one SQL file into the image at a stable path:

.veris/Dockerfile.sandbox
ARG GVISOR_BASE FROM ${GVISOR_BASE} COPY . /agent COPY db/schema.sql /agent/db/schema.sql WORKDIR /app

Then point schema_path at that file:

.veris/veris.yaml
services: - name: postgres config: schema_path: /agent/db/schema.sql

If your repo does not already include a single schema.sql, export a schema-only SQL file from the database tooling you already use and commit that file into the repo you upload to Veris. For most teams, this file is generated or exported rather than written by hand.

What if your app uses migrations instead of one schema file?

That is normal.

Many customers keep their database as:

  • a migrations directory
  • seed files
  • generated snapshots

rather than one hand-maintained schema.sql.

Veris does not currently apply an entire migrations directory automatically during Postgres startup. The recommended approach is:

  1. generate or export one SQL file during your build
  2. copy that file into the image
  3. point schema_path at it

In other words, the schema can still come from your existing app/database tooling, but Veris wants one concrete SQL file to execute at startup.

For many customers, this means taking an explicit export step, for example:

  • PostgreSQL: a schema-only dump such as pg_dump --schema-only
  • Supabase: a schema dump or generated snapshot from your Supabase tooling
  • ORM or migration stacks: a generated SQL artifact checked into the repo for Veris packaging

You do not need to hand-write this file. It is usually better to generate or export it from the source of truth your team already uses.

Connect your app

There are two common connection patterns:

  • raw PostgreSQL clients
  • Supabase clients

Raw PostgreSQL clients

If your app uses a normal PostgreSQL driver, point it at the mock database with a connection string such as:

.veris/veris.yaml
services: - name: postgres config: schema_path: /agent/db/schema.sql agent: environment: DATABASE_URL: postgresql://postgres:postgres@localhost:5432/veris

Supabase clients

If your app uses Supabase clients instead of a raw PostgreSQL connection, enable Supabase compatibility:

.veris/veris.yaml
services: - name: postgres config: schema_path: /agent/db/schema.sql supabase_auth: true

When supabase_auth: true is enabled, Veris auto-injects Supabase-style environment variables for the agent, including:

  • NEXT_PUBLIC_SUPABASE_URL
  • NEXT_PUBLIC_SUPABASE_ANON_KEY
  • SUPABASE_SERVICE_ROLE_KEY

This is useful for apps that use @supabase/supabase-js and call RPC functions such as /rpc/execute_sql.

What “auto-injects” means in practice:

  • you enable supabase_auth: true in veris.yaml
  • Veris generates the correct mock Supabase URL and JWT-style keys at runtime
  • Veris places those values into the agent process environment before your app starts

For the mock Postgres service path, the customer usually does not need to set NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, or SUPABASE_SERVICE_ROLE_KEY manually in veris.yaml or in the Console.

If you manually set those variables yourself, Veris will not replace them. That is useful when you intentionally want custom values, but it can also break the mock DB connection if the values point at the wrong host or use the wrong keys.

That means:

  • turn on supabase_auth: true
  • do not manually set the three Supabase vars unless you have a specific reason to override them
  • let the sandbox provide the mock-compatible values automatically

Troubleshooting

If Postgres logs:

No SCHEMA_PATH configured; database 'veris' is empty

then either:

  • schema_path was not set in veris.yaml, or
  • the file does not exist in the image at that path

If your app expects Supabase and logs that its database tool is unavailable, check:

  • supabase_auth: true is enabled on the postgres service
  • you are not overriding the injected Supabase env vars with incorrect values
  • your schema file actually defines the tables and RPC functions your app expects