How to Set Up Docker Deployment with PostgreSQL for Routa: A Complete Guide

Routa supports PostgreSQL in Docker by setting ROUTA_DB_DRIVER=postgres and providing a DATABASE_URL, enabling seamless switching from the default SQLite configuration through environment variables alone.

Routa is a production-ready Next.js application that abstracts database access through a driver-based architecture, allowing you to deploy with SQLite for development or PostgreSQL for production workloads. Setting up Docker deployment with PostgreSQL for Routa requires minimal configuration—just two environment variables and optionally leveraging the built-in Docker Compose profiles for automated database provisioning.

Understanding the Database Architecture

Routa's database selection happens at runtime in src/core/routa-system.ts, which implements a factory pattern that instantiates the appropriate storage driver based on the ROUTA_DB_DRIVER environment variable. By default, the Dockerfile sets ROUTA_DB_DRIVER=sqlite, but the system supports postgres as an alternative without rebuilding the container.

When ROUTA_DB_DRIVER=postgres is set, Routa uses the implementation in src/core/db/index.ts, which leverages drizzle-orm/postgres-js to manage database connections via the standard DATABASE_URL connection string.

Deploying with the PostgreSQL Docker Profile

The fastest way to run Routa with PostgreSQL is using the postgres profile defined in docker-compose.yml. This configuration spins up three coordinated services:

  • app: The Next.js application container that reads ROUTA_DB_DRIVER and DATABASE_URL at startup
  • migrate: A one-shot container that runs npm run db:push to apply schema migrations
  • postgres: A postgres:16-alpine container with credentials configurable via environment variables

The app service includes a depends_on condition with a healthcheck that ensures the database is ready before the application attempts to connect.

To deploy using the bundled PostgreSQL container:

docker compose --profile postgres up --detach

This command automatically generates the DATABASE_URL to point at the internal postgres service and sets ROUTA_DB_DRIVER=postgres.

Configuring Environment Variables

The switch between SQLite and PostgreSQL is controlled by two critical environment variables exposed in the Dockerfile:

  1. ROUTA_DB_DRIVER: Must be set to postgres to enable the PostgreSQL driver instead of the default SQLite implementation
  2. DATABASE_URL: A standard PostgreSQL connection string (e.g., postgresql://user:pass@host:5432/db)

These variables are consumed by the driver factory in src/core/routa-system.ts and the connection logic in src/core/db/index.ts. You can override these via a .env file or directly in your Docker Compose configuration.

Using an External PostgreSQL Server

If you prefer using an existing PostgreSQL instance rather than the bundled container, omit the postgres profile and provide your connection details:


# .env

ROUTA_DB_DRIVER=postgres
DATABASE_URL=postgresql://myuser:mypassword@mydb.example.com:5432/routa

docker compose up --detach

In this configuration, the app service still receives the environment variables but connects to your external database server instead of the containerized Postgres service.

Managing Database Migrations

When running with PostgreSQL, schema changes must be applied using the migrate service. After updating your schema or deploying a new version, run:

docker compose --profile postgres run --rm migrate

This executes npm run db:push against the configured DATABASE_URL, ensuring your database schema matches the application requirements before the app container restarts.

Default SQLite Deployment (No Database Required)

For development or lightweight deployments, Routa runs with SQLite by default, requiring no external database configuration:

docker compose up --detach

This uses the built-in file-based storage configured in src/core/routa-system.ts without requiring the postgres profile or additional environment variables.

Key Implementation Files

Understanding these source files helps troubleshoot deployment issues:

  • Dockerfile: Multi-stage build that sets ROUTA_DB_DRIVER=sqlite by default and exposes the DATABASE_URL environment variable
  • docker-compose.yml: Defines service orchestration, healthchecks, and the postgres profile that wires the three-service stack together
  • src/core/routa-system.ts: Central factory that selects between SQLite and PostgreSQL drivers based on environment variables
  • src/core/db/index.ts: Implements the PostgreSQL driver using drizzle-orm/postgres-js and handles connection pooling

Summary

  • Routa's src/core/routa-system.ts factory selects database drivers based on the ROUTA_DB_DRIVER environment variable
  • Set ROUTA_DB_DRIVER=postgres and provide a DATABASE_URL to switch from SQLite to PostgreSQL
  • Use docker compose --profile postgres up --detach to run the complete stack including a PostgreSQL 16 container
  • Run docker compose --profile postgres run --rm migrate to apply database schema changes
  • For external databases, omit the profile and set DATABASE_URL to point to your existing PostgreSQL server

Frequently Asked Questions

Does Routa require code changes to switch from SQLite to PostgreSQL?

No code changes are required. The application uses a factory pattern in src/core/routa-system.ts that selects the storage implementation at runtime based on the ROUTA_DB_DRIVER environment variable. Simply changing this value from sqlite to postgres and providing a valid DATABASE_URL switches the data layer transparently.

What PostgreSQL version does the Docker Compose profile use?

The postgres profile in docker-compose.yml uses the official postgres:16-alpine image. You can override this version by modifying the image tag in the Compose file or setting the POSTGRES_PASSWORD environment variable to customize credentials while keeping the default image.

How do I run database migrations in a Docker environment?

Routa provides a dedicated migrate service in docker-compose.yml that runs npm run db:push against your configured DATABASE_URL. Execute docker compose --profile postgres run --rm migrate to apply schema changes. This is particularly important when upgrading Routa versions or after modifying database schemas.

Can I use Routa with an external PostgreSQL database?

Yes. If you have an existing PostgreSQL server, set ROUTA_DB_DRIVER=postgres and provide the full connection string in DATABASE_URL via a .env file or environment configuration. Run docker compose up --detach without the postgres profile, and the application will connect to your external database instead of starting a containerized instance.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →