PRJ2 Database Infrastructure
Date: 2026-01-09 Status: Accepted Context: PRJ2 student team database provisioning and initialization
Decision
Deploy a shared PostgreSQL instance serving all teams, with platform-controlled database initialization.
Architecture
┌────────────────────────────────────────────────────────┐
│ prj2-system namespace │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ PostgreSQL (Bitnami Helm chart) │ │
│ │ │ │
│ │ Databases: │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ team_a │ │ team_b │ │ team_c │ ... │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └─────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ pgAdmin (web UI) │ │
│ │ https://pgadmin.prod.fontysvenlo.dev │ │
│ └─────────────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────┐
│ team-a namespace │
│ │
│ ┌────────────────┐ │
│ │ init-db │ (init container) │
│ │ 1. DROP DB │ - Platform-controlled image │
│ │ 2. CREATE DB │ - Reads team's init.sql │
│ │ 3. RUN init.sql│ │
│ └───────┬────────┘ │
│ │ success │
│ ▼ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ Backend │ │ Frontend │ │
│ └────────────────┘ └────────────────┘ │
│ │
└────────────────────────────────────────────────────────┘
Components
| Component | Location | Purpose |
|---|---|---|
| PostgreSQL | prj2-system namespace |
Shared database server (Bitnami Helm) |
| pgAdmin | prj2-system namespace |
Web UI for student database access |
| db-init image | harbor.../platform/db-init |
Platform-controlled init container |
| Team credentials | Central Secret in prj2-system |
One secret with all team passwords |
Database Initialization Modes
The platform db-init image supports two modes, auto-detected based on folder structure:
| Mode | Trigger | Behavior | Use Case |
|---|---|---|---|
| Reset (default) | db/init.sql exists |
DROP → CREATE → run init.sql | Learning, rapid iteration |
| Migrate (opt-in) | db/migrations/ exists |
CREATE IF NOT EXISTS → Flyway migrate | Data preservation, industry patterns |
Student folder structure:
db/
├── init.sql ← Reset mode (simple path)
└── migrations/ ← Migration mode (advanced path)
├── V1__create_schema.sql
└── V2__add_products.sql
If both exist, migrations/ takes precedence.
Credential Distribution
Instructor provides credentials via Canvas:
- Provisioning script generates team database users + passwords
- Script outputs a credential table
- Instructor posts in Canvas (per-team assignment notes)
- Students use for pgAdmin and backend configuration
Security Boundaries
| Actor | Can Access | Cannot Access |
|---|---|---|
| Platform admin | All databases, admin credentials | - |
| Student team | Their database via pgAdmin/app | Other team databases, admin creds |
| Init container | Admin creds (at runtime only) | Other team init.sql |
| Backend app | Team database credentials | Admin credentials |
Rationale
Why shared PostgreSQL?
- Resource efficiency: One instance serves all teams
- Simplified management: Single point of administration
- Course isolation: Separate instance per course (
prj2-system,prj3-system)
Why platform-controlled init container?
- Security: Students can't modify the init logic
- Isolation: Teams can only affect their own database
- Predictability: Platform guarantees clean state behavior
Why dual-mode (reset vs migrate)?
- Default (reset): Simple, predictable, ideal for learning
- Opt-in (migrate): Teaches industry-standard patterns (Flyway)
- Detection-based: No config needed—just add
migrations/folder to switch - Security maintained: Platform still controls execution
Why Canvas for credentials?
- Simple: Works with existing infrastructure
- Secure enough: Per-team credentials, no shared secrets
- Future path: Can add self-service portal or SSO later
Alternatives Considered
Per-team PostgreSQL instances
- ❌ Resource waste for educational scale
- ❌ Complex management overhead
Student-controlled init scripts in Dockerfile
- ❌ Security risk: students could affect other teams
- ❌ No guaranteed clean state
Self-service credential portal
- ❌ Additional infrastructure to build
- ✓ May add later as enhancement
Implementation
See prj2-database-infrastructure.md for detailed implementation plan and tasks.