Skip to content

Database Setup

The Postgres entity runs a real PostgreSQL instance in a Docker container. It handles image pulling, container lifecycle, readiness checks, and SQL initialization.

import { Postgres } from "sigil";
const db = env.add(new Postgres("my-db"));

This starts Postgres 16 on port 5432 with default credentials (postgres/postgres).

const db = env.add(
new Postgres("my-db", {
port: 5433, // host port (default: 5432)
database: "myapp", // database name (default: "postgres")
username: "admin", // (default: "postgres")
password: "secret", // (default: "postgres")
version: "15", // Postgres version (default: "16")
})
);

Pass a path to a SQL file that creates your tables:

const db = env.add(
new Postgres("my-db", {
database: "myapp",
initSql: path.join(root, "db/schema.sql"),
})
);

Example schema.sql:

CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
email TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE TABLE IF NOT EXISTS posts (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
title TEXT NOT NULL,
body TEXT,
created_at TIMESTAMP DEFAULT NOW()
);

Load test data after the schema is created:

const db = env.add(
new Postgres("my-db", {
database: "myapp",
initSql: path.join(root, "db/schema.sql"),
seedSql: path.join(root, "db/seed.sql"),
})
);

Example seed.sql:

INSERT INTO users (email, name) VALUES
('alice@example.com', 'Alice'),
('bob@example.com', 'Bob');
INSERT INTO posts (user_id, title, body) VALUES
(1, 'Hello World', 'My first post'),
(2, 'Getting Started', 'How I set up my project');

Execution order: initSql runs first, then seedSql.

The Postgres entity exposes a standard connection string:

const db = env.add(new Postgres("my-db", { port: 5433, database: "myapp" }));
console.log(db.connectionString);
// "postgresql://postgres:postgres@localhost:5433/myapp"

Pass this to other services:

env.add(
new Service("backend", {
command: ["node", "server.js"],
env: {
DATABASE_URL: db.connectionString,
},
})
);
  1. Image pull — On first run, Sigil pulls postgres:<version> from Docker Hub
  2. Container creation — Creates a container named sigil-<entity-name> with the specified port mapping and credentials
  3. Readiness check — Polls the database using psql -c 'SELECT 1' inside the container until it succeeds (not pg_isready, which can return true before the target database exists)
  4. SQL execution — Runs initSql then seedSql by piping the file contents into psql inside the container
  5. Cleanup — On stop(), the container is stopped and removed

Containers are named sigil-<entity-name>. If a container with that name already exists (from a previous crashed run), Sigil will handle it during startup.