Skip to content

Database Configuration

calServer v2 supports three database backends: PostgreSQL, MySQL, and Microsoft SQL Server. This page documents the Docker Compose and .env variables that control the database connections.

Connection Overview

┌─────────────────────────────────────────────────────────────┐
│                    Laravel 13 (API v2)                       │
│                                                             │
│  ┌─────────────┐  ┌──────────────┐  ┌───────────────────┐  │
│  │    pgsql     │  │ mysql_legacy │  │      sqlsrv       │  │
│  │  (default)   │  │ (V1 import)  │  │  (MET/TEAM etc.)  │  │
│  └──────┬──────┘  └──────┬───────┘  └────────┬──────────┘  │
└─────────┼────────────────┼───────────────────┼──────────────┘
          │                │                   │
          ▼                ▼                   ▼
  ┌──────────────┐ ┌──────────────┐  ┌─────────────────┐
  │ PostgreSQL 16│ │   MySQL 5.7  │  │  MS SQL Server   │
  │ (V2 own DB)  │ │  (former V1) │  │    2019+         │
  └──────────────┘ └──────────────┘  └─────────────────┘
Connection Name Driver Purpose Configured In
pgsql PostgreSQL V2 primary database (ADR-008), new tables DB_* variables
mysql_legacy MySQL V1 database, only for the data import DB_MYSQL_* variables
mysql MySQL Generic MySQL connection DB_* variables
sqlsrv SQL Server External systems (MET/TEAM, Fluke) DB_* variables
sqlite SQLite Local tests only (:memory:) DB_DATABASE

The default connection is set via DB_CONNECTION (default: pgsql).


Docker Compose Files

docker-compose.v2.yml — V2 Services

Together with docker-compose.v2-standalone.yml (reverse proxy, report-runner) this is the complete stack:

docker compose -f docker-compose.v2.yml -f docker-compose.v2-standalone.yml up -d
Service Image Port Purpose
calserver-postgres postgres:16-alpine 5432 V2 database (ADR-008)
calserver-api-v2 calhelp/calserver-api-v2 8081 Laravel API
calserver-frontend calhelp/calserver-frontend 3000 Nuxt 4 Frontend
redis redis:8-alpine 6379 Cache, Queue, Sessions

PostgreSQL variables (from docker/.env):

PG_DATABASE=calserver_v2        # Default: calserver_v2
PG_USERNAME=calserver           # Default: calserver
PG_PASSWORD=                    # REQUIRED — must be set

PG_PASSWORD is required

docker-compose.v2.yml enforces PG_PASSWORD via ${PG_PASSWORD:?PG_PASSWORD is required}. Without this value, the container will not start.


Environment Variables in Detail

V2 Primary Connection (PostgreSQL)

These variables control the default connection (DB_CONNECTION=pgsql):

Variable Default Description
DB_CONNECTION pgsql Active driver: pgsql, mysql, sqlsrv, sqlite
DB_HOST 127.0.0.1 Database server (Docker: calserver-postgres)
DB_PORT 5432 Port
DB_DATABASE calserver_v2 Database name
DB_USERNAME calserver User
DB_PASSWORD (empty) Password

V1 Database for the Data Import (MySQL)

Only needed when switching from v1. Variables with DB_MYSQL_ prefix for the mysql_legacy connection:

Variable Fallback Description
DB_MYSQL_HOST DB_HOST MySQL server (Docker: mysql_db)
DB_MYSQL_PORT 3306 Port
DB_MYSQL_DATABASE DB_DATABASE V1 database name
DB_MYSQL_USERNAME DB_USERNAME User
DB_MYSQL_PASSWORD DB_PASSWORD Password
DB_PREFIX (empty) Only for old installations with a table prefix

Fallback Behavior

If no DB_MYSQL_* variable is set, the mysql_legacy connection falls back to the generic DB_* values. This simplifies setups with only a single MySQL instance.

SQL Server (optional)

Variable Default Description
DB_HOST localhost SQL Server host
DB_PORT 1433 Port
DB_DATABASE laravel Database name
DB_USERNAME root User
DB_PASSWORD (empty) Password

SQL Server shares DB_* variables

SQL Server uses the same DB_* variables as PostgreSQL. When DB_CONNECTION=sqlsrv is set, Laravel interprets the generic variables for SQL Server.


Environment Profiles

Local Development (laravel/.env.example)

# V2 PostgreSQL (default)
DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=calserver_v2
DB_USERNAME=calserver
DB_PASSWORD=

# V1 MySQL (only for the data import)
DB_MYSQL_HOST=127.0.0.1
DB_MYSQL_PORT=3306
DB_MYSQL_DATABASE=calhelp
DB_MYSQL_USERNAME=calhelp
DB_MYSQL_PASSWORD=
DB_PREFIX=

Docker Production (docker-compose.v2.yml)

# PostgreSQL (via container network)
DB_CONNECTION=pgsql
DB_HOST=calserver-postgres
DB_PORT=5432
DB_DATABASE=${PG_DATABASE:-calserver_v2}
DB_USERNAME=${PG_USERNAME:-calserver}
DB_PASSWORD=${PG_PASSWORD}

Unit Tests (laravel/.env.testing)

DB_CONNECTION=sqlite
DB_DATABASE=:memory:

SQLite in-memory for fast, isolated tests. No external DB required.

CI/CD Tests (laravel/.env.ci)

DB_CONNECTION=pgsql
DB_HOST=127.0.0.1
DB_PORT=5432
DB_DATABASE=calserver_v2_test
DB_USERNAME=calserver
DB_PASSWORD=ci_test_password

PostgreSQL instance in the CI pipeline for realistic tests.


Connection Selection by Scenario

Scenario DB_CONNECTION Additional Connection
Standard deployment pgsql —
Switching from v1 (data import) pgsql mysql_legacy
Existing MySQL instance mysql —
Existing SQL Server sqlsrv —
MET/TEAM integration pgsql sqlsrv
Local tests sqlite —
CI pipeline pgsql —

Reference: config/database.php

The Laravel configuration defines all connections in laravel/config/database.php:

'default' => env('DB_CONNECTION', 'pgsql'),

'connections' => [
    'sqlite'       => [ /* ... */ ],
    'mysql'        => [ /* ... charset: utf8mb4 */ ],
    'mariadb'      => [ /* ... charset: utf8mb4 */ ],
    'pgsql'        => [ /* ... search_path: public, sslmode: prefer */ ],
    'mysql_legacy' => [ /* ... DB_MYSQL_* with fallback to DB_* */ ],
    'sqlsrv'       => [ /* ... charset: utf8 */ ],
],

Full file: laravel/config/database.php


Abstraction Rules

All database access must be DB-agnostic (see CLAUDE.md):

  1. Eloquent & Query Builder — no direct PDO
  2. DbDialect helper for unavoidable raw SQL (app/Support/DbDialect.php)
  3. Migrations only via Schema Builder, no raw DDL
  4. Repository pattern for driver-specific syntax (full-text search, JSON, CTEs)
  5. No DB-specific types in migrations (no ENUM, SERIAL, JSONB)
  6. Frontend makes no DB assumptions — the API is the only interface