Skip to main content

Overview

Concordia uses PostgreSQL with Drizzle ORM for database management. This guide covers setting up your production database, running migrations, and managing data.

Database Configuration

Concordia uses separate Drizzle configurations for development and production environments.

Production Configuration

The production database is configured in drizzle-prod.config.ts:
drizzle-prod.config.ts

Development Configuration

For comparison, the development config uses DATABASE_URL_LOCAL:
drizzle-dev.config.ts

Environment Variables

Add these variables to your production .env file:
.env
When USE_PROD_DB=true, all database commands target your production database. Handle with care!

PostgreSQL Setup

Concordia works with any PostgreSQL provider. Popular options include:
  • Neon - Serverless PostgreSQL with branching
  • Supabase - PostgreSQL with built-in auth and storage
  • Railway - Simple PostgreSQL deployments
  • AWS RDS - Managed PostgreSQL service
  • Self-hosted - Traditional PostgreSQL instance

Connection String Format

Your production connection string should include SSL:
For Neon and similar providers, also add:

Running Migrations

Generate Migrations

Create migration files from your schema changes:
1

Generate migration

Run the generate command:
This creates SQL migration files in src/database/migrations/.
2

Review generated SQL

Check the generated .sql files to verify changes before applying.
3

Commit migrations

Add migration files to version control:

Apply Migrations

Run migrations against your production database:
Production Safety: The migrate script requires explicit confirmation when targeting production:
  • You’ll be prompted to type “oui” to confirm
  • Or set CONFIRM_PROD=oui to skip prompts (CI/CD)
  • Connection details are masked in logs for security

Migration Features

The migration script (scripts/db/db.migrate.ts) includes:
  • Safety confirmations for production databases
  • Automatic rollback on errors
  • Idempotent execution - safe to run multiple times
  • Migration tracking via __drizzle_migrations table
  • Reset option - --reset flag drops all tables (requires confirmation)

Reset Database (Destructive)

To drop all tables and start fresh:
The --reset flag is destructive and requires explicit confirmation, even in development.

Database Seeding

Populate your database with initial data:

Seed Data Location

Seed data files are stored in src/database/data/ with the naming convention:
The numeric prefix controls insertion order to handle foreign key dependencies.

Seed Features

  • Auto-matching: Automatically matches data files to schema tables
  • Conflict handling: Uses onConflictDoNothing() for safe re-runs
  • Production safety: Requires CONFIRM_PROD=oui for production
  • Reset option: --reset flag truncates all tables first

Seed with Reset

Database Synchronization

Sync data between development and production databases:
Dev-to-Prod sync is destructive! It truncates production tables and copies development data.Always:
  • Backup production first
  • Confirm when prompted
  • Use during initial setup, not ongoing operations

How Sync Works

The sync script (scripts/db/db.sync.ts):
  1. Connects to both databases
  2. Gets list of all tables
  3. For each table:
    • Reads all rows from source
    • Truncates destination table
    • Inserts all rows with proper column mapping
  4. Maintains referential integrity with CASCADE

Backup and Maintenance

Manual Backup

Use pg_dump for backups:

Restore from Backup

Database Comparison

Compare schemas between environments:

Connection Check

Verify database connectivity:

Production Checklist

1

Configure environment

Set DATABASE_URL_PROD with SSL-enabled connection string.
2

Run migrations

3

Seed initial data (optional)

4

Verify tables

Connect with psql or GUI tool to verify schema.
5

Set up backups

Configure automated backups with your PostgreSQL provider.

Troubleshooting

Migration Errors

If migrations fail:
  1. Check __drizzle_migrations table - see which migrations applied
  2. Review SQL syntax - some PostgreSQL features vary by version
  3. Check permissions - ensure user has CREATE/ALTER rights
  4. Manual rollback - migrations use transactions, so failures rollback automatically

Connection Issues

Schema Drift

If production schema differs from expected:

Next Steps

SMTP Configuration

Configure email delivery for authentication and notifications

Hosting

Deploy your application to production