Connect a Postgres database

Add a managed database to your app — Dockhold provisions it and wires it in for you.

Most apps need somewhere to keep data. On Dockhold you don't run or configure a database yourself: you turn one on for your app, and Dockhold provisions a private managed Postgres database and injects its connection string. Your code just reads it. This recipe is the whole path.

Want a running start? The postgres-starter template is a ready-made CRUD API on the managed database — click Use this template, then deploy it with the database add-on checked. For vector search, see deploy a vector database.

1. Enable the database

You can do this when you create the app or any time after:

  • New app: on the new-app page, check “Add a managed database.”
  • Existing app: open the app, go to Settings → Managed database, and click Add database.

Dockhold provisions a dedicated database in your app's isolated environment and injects its connection string as the DATABASE_URL environment variable, plus VECTOR_STORE_URL (the same database, ready for vector search — see below).

DATABASE_URL is managed by Dockhold — read it, never define or override it. The database persists across restarts and deploys; your app's own filesystem does not, so keep anything you need to keep in the database.

2. Read DATABASE_URL in your code

Connect using the injected variable — never a hardcoded host:

// Node (pg)
const { Pool } = require("pg");
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
# Python (psycopg)
import os, psycopg
conn = psycopg.connect(os.environ["DATABASE_URL"])

Most ORMs and query builders (Prisma, Drizzle, SQLAlchemy, and others) read DATABASE_URL directly — point them at it and you're done.

3. Create your tables

Run your migrations on startup or as part of your app's boot sequence. The database is empty when first provisioned; your app owns its schema. Don't rely on writing schema to local disk — only what's in the database survives a restart.

Vector search for AI apps (built in)

Every managed database ships with pgvector enabled, so you can store and query embeddings for RAG, semantic search, or AI memory without adding anything. Use DATABASE_URL as normal, or VECTOR_STORE_URL if a tool expects a dedicated vector-store variable — both point at the same database.

Troubleshooting

  • DATABASE_URL is undefined: the database isn't enabled for this app yet. Add it from the new-app page or Settings, then redeploy.
  • Connection refused / points at localhost: read process.env.DATABASE_URL (or your language's equivalent) — don't hardcode a host or port.
  • Data disappears after a deploy: it's being written to the container filesystem, not the database. Persist it in Postgres.

Next