Skip to content

PostgreSQL

Holden can provision a PostgreSQL database container for your app with automatic credential generation.

Add postgres to your needs block:

services:
web:
image: myapp:latest
domain: myapp.example.com
env:
DATABASE_URL: ${needs.postgres.url}
needs:
postgres:
VariableDescriptionExample
${needs.postgres.url}Full connection URLpostgresql://myapp:abc123@needs-postgres:5432/myapp
${needs.postgres.host}Container hostnameneeds-postgres
${needs.postgres.port}Port number5432
${needs.postgres.user}Database usermyapp
${needs.postgres.password}Generated passwordabc123...
${needs.postgres.database}Database namemyapp

Holden defaults to PostgreSQL 18 (Alpine). To use a different version:

needs:
postgres:
version: "16" # → postgres:16-alpine

To use a custom image entirely, like PostGIS:

needs:
postgres:
image: "postgis/postgis:18-3.5"

When image is set, version is ignored.

  • Image: postgres:18-alpine (default)
  • Network: Your app’s private network (holden-{app-id})
  • Container name: {app-id}-needs-postgres
  • Volume: [@base_data_dir]/{app-id}/postgres/var/lib/postgresql

Holden waits for PostgreSQL to be ready before starting your app services.

Command: pg_isready -U <user> -d <database>

  • Start period: 10 seconds
  • Timeout: 5 seconds per attempt
  • Retries: 10 attempts with 3-second intervals