Development Guide
This guide covers setting up a local development environment for contributing to Databasement.
Requirements
- PHP 8.4+
- Composer
- Node.js 20+ & npm
- Docker & Docker Compose
Quick Start
1. Clone and Setup
git clone https://github.com/David-Crty/databasement.git
cd databasement
make setup
This will:
- Install Composer dependencies
- Run database migrations
- Install npm dependencies
- Build frontend assets
You should be ready to go!
Open http://localhost:2226 in your browser to view the app.
2. Start Development Environment
make start
This starts all Docker services:
- php — FrankenPHP server on http://localhost:2226
- queue — Queue worker for async backup/restore jobs
- mysql — MySQL 8.0 on port 3306
- postgres — PostgreSQL 16 on port 5432
Test database credentials: admin / admin / testdb
Available Commands
All PHP commands run through Docker. Use the Makefile targets or docker compose exec app <command>.
Testing
make test # Run all tests
make test-filter FILTER=ServerTest # Run specific tests
make test-coverage # Run with coverage report
Code Quality
make lint-fix # Auto-fix code style with Laravel Pint
make lint-check # Check code style without fixing
make phpstan # Run PHPStan static analysis
Database
make migrate # Run pending migrations
make migrate-fresh # Drop all tables and re-migrate
make migrate-fresh-seed # Fresh migration with seeders
make db-seed # Run database seeders
Assets
npm run build # Build production assets
npm run dev # Start Vite dev server (HMR)
make build # Alternative: build via Makefile
Docker Services
make start # Start all services
docker compose logs -f # View logs from all services
docker compose logs -f queue # View queue worker logs
docker compose restart queue # Restart queue worker
docker compose down # Stop all services
OAuth / SSO Testing
Databasement includes a Dex OIDC server for local OAuth testing. The Dex service is commented out by default in docker-compose.yml.
1. Add Hosts Entry
The Dex server uses a custom hostname that must resolve both from your browser and from within Docker containers:
echo "127.0.0.1 dex-local" | sudo tee -a /etc/hosts
2. Enable Dex Service
Uncomment the dex service in docker-compose.yml:
3. Start Dex
docker compose up dex -d
4. Configure Environment
Add to your .env.local:
OAUTH_OIDC_ENABLED=true
OAUTH_OIDC_CLIENT_ID=databasement
OAUTH_OIDC_CLIENT_SECRET=databasement-secret
OAUTH_OIDC_BASE_URL=http://dex-local:5556/dex
OAUTH_OIDC_LABEL=SSO
Test User
| Password | |
|---|---|
user@databasement.com | databasement |
Testing Flow
- Ensure hosts entry is added (step 1)
- Start Dex:
docker compose up dex -d - Visit the login page at
http://localhost:2226/login - Click "Continue with SSO"
- Enter test credentials:
user@databasement.com/databasement - You'll be redirected back and logged in
OAuth Behavior Notes
- New users: Created automatically with the role defined by
OAUTH_DEFAULT_ROLE - Existing users: When an existing user logs in via OAuth (matching email), their account is linked and their password is cleared
- OAuth-only users: Cannot use password login — they must use the OAuth button
- Settings access: OAuth-only users don't see Password or Two-Factor settings (managed by the OAuth provider)
Git Hooks
Pre-commit hooks (via Husky) automatically run:
make lint-fix— Auto-format code with Laravel Pintmake test— Run all Pest tests
Ensure tests pass before committing.
Architecture Overview
Tech Stack
| Layer | Technology |
|---|---|
| Backend | Laravel 12, PHP 8.4+ |
| Frontend | Livewire, Mary UI, daisyUI, Tailwind CSS 4 |
| Testing | Pest PHP |
| Database | SQLite (dev), supports MySQL/PostgreSQL/MariaDB |
| Auth | Laravel Fortify with 2FA support |
Key Models
- DatabaseServer — Database connection configurations
- Volume — Storage destinations (local, S3)
- Backup — Backup configurations (schedule, retention, volume)
- Snapshot — Individual backup snapshots with metadata
- BackupJob — Tracks backup/restore job execution and logs
Key Services
- BackupTask — Executes database dumps, compression, and storage
- RestoreTask — Downloads, decompresses, and restores snapshots
- DatabaseProvider — Creates database handlers, tests connections, lists databases
- ShellProcessor — Executes shell commands with logging
Livewire Components
DatabaseServer/*— CRUD operations for database serversVolume/*— CRUD operations for storage volumesBackupJob/Index— Job listing with logs modalSnapshot/Index— Snapshot listing and managementSettings/*— User settings (Profile, Password, TwoFactor)RestoreModal— 3-step wizard for snapshot restoration
Backup & Restore Workflow
Backup Process:
- Connect to database server
- Execute database-specific dump (mysqldump/pg_dump)
- Compress with gzip
- Upload to configured volume (local/S3)
- Record snapshot metadata
Restore Process:
- Select source snapshot
- Download and decompress
- Validate compatibility (database types must match)
- Drop and recreate target database
- Restore SQL dump
Cross-Server Restore: Restore production snapshots to staging/preprod as long as database types match.
Configuration
Environment Variables
The .env file is committed to the repository and contains default development configuration. To override these values, create a .env.local file (which is gitignored).
Key development configuration:
# Application
APP_URL=http://localhost:2226
# Database (for application data)
DB_CONNECTION=sqlite
# Queue
QUEUE_CONNECTION=database
# AWS S3 (optional, for S3 volume testing)
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
Testing Strategy
We use Pest PHP for testing. Key principles:
- Test business logic and behaviors — Not framework internals
- Mock external services — AWS SDK, S3 client, etc.
- Don't mock models — Use real database interactions
What to Test
- Authorization (who can access what)
- Business logic (backup works, restore works, cleanup deletes correct snapshots)
- Integration points (external services, commands)
What NOT to Test
- Form validation rules (Laravel handles this)
- Eloquent relationships and cascades
- Session flash messages
- Framework behavior
Submitting Changes
- Create a feature branch from
main - Write tests for new functionality
- Ensure all tests pass:
make test - Run code quality checks:
make lint-fix && make phpstan - Submit a pull request with a clear description
For significant changes, open an issue first to discuss the approach.