# Coolify Database Architecture & Patterns

## Database Strategy

Coolify uses **PostgreSQL 15** as the primary database with **Redis 7** for caching and real-time features. The architecture supports managing multiple external databases across different servers.

## Primary Database (PostgreSQL)

### Core Tables & Models

#### User & Team Management
- **[User.php](mdc:app/Models/User.php)** - User authentication and profiles
- **[Team.php](mdc:app/Models/Team.php)** - Multi-tenant organization structure
- **[TeamInvitation.php](mdc:app/Models/TeamInvitation.php)** - Team collaboration invitations
- **[PersonalAccessToken.php](mdc:app/Models/PersonalAccessToken.php)** - API token management

#### Infrastructure Management
- **[Server.php](mdc:app/Models/Server.php)** - Physical/virtual server definitions (46KB, complex)
- **[PrivateKey.php](mdc:app/Models/PrivateKey.php)** - SSH key management
- **[ServerSetting.php](mdc:app/Models/ServerSetting.php)** - Server-specific configurations

#### Project Organization
- **[Project.php](mdc:app/Models/Project.php)** - Project containers for applications
- **[Environment.php](mdc:app/Models/Environment.php)** - Environment isolation (staging, production, etc.)
- **[ProjectSetting.php](mdc:app/Models/ProjectSetting.php)** - Project-specific settings

#### Application Deployment
- **[Application.php](mdc:app/Models/Application.php)** - Main application entity (74KB, highly complex)
- **[ApplicationSetting.php](mdc:app/Models/ApplicationSetting.php)** - Application configurations
- **[ApplicationDeploymentQueue.php](mdc:app/Models/ApplicationDeploymentQueue.php)** - Deployment orchestration
- **[ApplicationPreview.php](mdc:app/Models/ApplicationPreview.php)** - Preview environment management

#### Service Management
- **[Service.php](mdc:app/Models/Service.php)** - Service definitions (58KB, complex)
- **[ServiceApplication.php](mdc:app/Models/ServiceApplication.php)** - Service components
- **[ServiceDatabase.php](mdc:app/Models/ServiceDatabase.php)** - Service-attached databases

## Database Type Support

### Standalone Database Models
Each database type has its own dedicated model with specific configurations:

#### SQL Databases
- **[StandalonePostgresql.php](mdc:app/Models/StandalonePostgresql.php)** - PostgreSQL instances
- **[StandaloneMysql.php](mdc:app/Models/StandaloneMysql.php)** - MySQL instances  
- **[StandaloneMariadb.php](mdc:app/Models/StandaloneMariadb.php)** - MariaDB instances

#### NoSQL & Analytics
- **[StandaloneMongodb.php](mdc:app/Models/StandaloneMongodb.php)** - MongoDB instances
- **[StandaloneClickhouse.php](mdc:app/Models/StandaloneClickhouse.php)** - ClickHouse analytics

#### Caching & In-Memory
- **[StandaloneRedis.php](mdc:app/Models/StandaloneRedis.php)** - Redis instances
- **[StandaloneKeydb.php](mdc:app/Models/StandaloneKeydb.php)** - KeyDB instances
- **[StandaloneDragonfly.php](mdc:app/Models/StandaloneDragonfly.php)** - Dragonfly instances

## Configuration Management

### Environment Variables
- **[EnvironmentVariable.php](mdc:app/Models/EnvironmentVariable.php)** - Application-specific environment variables
- **[SharedEnvironmentVariable.php](mdc:app/Models/SharedEnvironmentVariable.php)** - Shared across applications

### Settings Hierarchy
- **[InstanceSettings.php](mdc:app/Models/InstanceSettings.php)** - Global Coolify instance settings
- **[ServerSetting.php](mdc:app/Models/ServerSetting.php)** - Server-specific settings
- **[ProjectSetting.php](mdc:app/Models/ProjectSetting.php)** - Project-level settings
- **[ApplicationSetting.php](mdc:app/Models/ApplicationSetting.php)** - Application settings

## Storage & Backup Systems

### Storage Management
- **[S3Storage.php](mdc:app/Models/S3Storage.php)** - S3-compatible storage configurations
- **[LocalFileVolume.php](mdc:app/Models/LocalFileVolume.php)** - Local filesystem volumes
- **[LocalPersistentVolume.php](mdc:app/Models/LocalPersistentVolume.php)** - Persistent volume management

### Backup Infrastructure
- **[ScheduledDatabaseBackup.php](mdc:app/Models/ScheduledDatabaseBackup.php)** - Automated backup scheduling
- **[ScheduledDatabaseBackupExecution.php](mdc:app/Models/ScheduledDatabaseBackupExecution.php)** - Backup execution tracking

### Task Scheduling
- **[ScheduledTask.php](mdc:app/Models/ScheduledTask.php)** - Cron job management
- **[ScheduledTaskExecution.php](mdc:app/Models/ScheduledTaskExecution.php)** - Task execution history

## Notification & Integration Models

### Notification Channels
- **[EmailNotificationSettings.php](mdc:app/Models/EmailNotificationSettings.php)** - Email notifications
- **[DiscordNotificationSettings.php](mdc:app/Models/DiscordNotificationSettings.php)** - Discord integration
- **[SlackNotificationSettings.php](mdc:app/Models/SlackNotificationSettings.php)** - Slack integration
- **[TelegramNotificationSettings.php](mdc:app/Models/TelegramNotificationSettings.php)** - Telegram bot
- **[PushoverNotificationSettings.php](mdc:app/Models/PushoverNotificationSettings.php)** - Pushover notifications

### Source Control Integration
- **[GithubApp.php](mdc:app/Models/GithubApp.php)** - GitHub App integration
- **[GitlabApp.php](mdc:app/Models/GitlabApp.php)** - GitLab integration

### OAuth & Authentication
- **[OauthSetting.php](mdc:app/Models/OauthSetting.php)** - OAuth provider configurations

## Docker & Container Management

### Container Orchestration
- **[StandaloneDocker.php](mdc:app/Models/StandaloneDocker.php)** - Standalone Docker containers
- **[SwarmDocker.php](mdc:app/Models/SwarmDocker.php)** - Docker Swarm management

### SSL & Security
- **[SslCertificate.php](mdc:app/Models/SslCertificate.php)** - SSL certificate management

## Database Migration Strategy

### Migration Location: [database/migrations/](mdc:database/migrations)

#### Migration Patterns
```php
// Typical Coolify migration structure
Schema::create('applications', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('fqdn')->nullable();
    $table->json('environment_variables')->nullable();
    $table->foreignId('destination_id');
    $table->foreignId('source_id');
    $table->timestamps();
});
```

### Schema Versioning
- **Incremental migrations** for database evolution
- **Data migrations** for complex transformations
- **Rollback support** for deployment safety

## Eloquent Model Patterns

### Base Model Structure
- **[BaseModel.php](mdc:app/Models/BaseModel.php)** - Common model functionality
- **UUID primary keys** for distributed systems
- **Soft deletes** for audit trails
- **Activity logging** with Spatie package

### **CRITICAL: Mass Assignment Protection**
**When adding new database columns, you MUST update the model's `$fillable` array.** Without this, Laravel will silently ignore mass assignment operations like `Model::create()` or `$model->update()`.

**Checklist for new columns:**
1. ✅ Create migration file
2. ✅ Run migration
3. ✅ **Add column to model's `$fillable` array**
4. ✅ Update any Livewire components that sync this property
5. ✅ Test that the column can be read and written

**Example:**
```php
class Server extends BaseModel
{
    protected $fillable = [
        'name',
        'ip',
        'port',
        'is_validating', // ← MUST add new columns here
    ];
}
```

### Relationship Patterns
```php
// Typical relationship structure in Application model
class Application extends Model
{
    public function server()
    {
        return $this->belongsTo(Server::class);
    }
    
    public function environment()
    {
        return $this->belongsTo(Environment::class);
    }
    
    public function deployments()
    {
        return $this->hasMany(ApplicationDeploymentQueue::class);
    }
    
    public function environmentVariables()
    {
        return $this->hasMany(EnvironmentVariable::class);
    }
}
```

### Model Traits
```php
// Common traits used across models
use SoftDeletes;
use LogsActivity;
use HasFactory;
use HasUuids;
```

## Caching Strategy (Redis)

### Cache Usage Patterns
- **Session storage** - User authentication sessions
- **Queue backend** - Background job processing
- **Model caching** - Expensive query results
- **Real-time data** - WebSocket state management

### Cache Keys Structure
```
coolify:session:{session_id}
coolify:server:{server_id}:status
coolify:deployment:{deployment_id}:logs
coolify:user:{user_id}:teams
```

## Query Optimization Patterns

### Eager Loading
```php
// Optimized queries with relationships
$applications = Application::with([
    'server',
    'environment.project',
    'environmentVariables',
    'deployments' => function ($query) {
        $query->latest()->limit(5);
    }
])->get();
```

### Chunking for Large Datasets
```php
// Processing large datasets efficiently
Server::chunk(100, function ($servers) {
    foreach ($servers as $server) {
        // Process server monitoring
    }
});
```

### Database Indexes
- **Primary keys** on all tables
- **Foreign key indexes** for relationships
- **Composite indexes** for common queries
- **Unique constraints** for business rules

### Request-Level Caching with ownedByCurrentTeamCached()

Many models have both `ownedByCurrentTeam()` (returns query builder) and `ownedByCurrentTeamCached()` (returns cached collection). **Always prefer the cached version** to avoid duplicate database queries within the same request.

**Models with cached methods available:**
- `Server`, `PrivateKey`, `Project`
- `Application`
- `StandalonePostgresql`, `StandaloneMysql`, `StandaloneRedis`, `StandaloneMariadb`, `StandaloneMongodb`, `StandaloneKeydb`, `StandaloneDragonfly`, `StandaloneClickhouse`
- `Service`, `ServiceApplication`, `ServiceDatabase`

**Usage patterns:**
```php
// ✅ CORRECT - Uses request-level cache (via Laravel's once() helper)
$servers = Server::ownedByCurrentTeamCached();

// ❌ AVOID - Makes a new database query each time
$servers = Server::ownedByCurrentTeam()->get();

// ✅ CORRECT - Filter cached collection in memory
$activeServers = Server::ownedByCurrentTeamCached()->where('is_active', true);
$server = Server::ownedByCurrentTeamCached()->firstWhere('id', $serverId);
$serverIds = Server::ownedByCurrentTeamCached()->pluck('id');

// ❌ AVOID - Making filtered database queries when data is already cached
$activeServers = Server::ownedByCurrentTeam()->where('is_active', true)->get();
```

**When to use which:**
- `ownedByCurrentTeamCached()` - **Default choice** for reading team data
- `ownedByCurrentTeam()` - Only when you need to chain query builder methods that can't be done on collections (like `with()` for eager loading), or when you explicitly need a fresh database query

**Implementation pattern for new models:**
```php
/**
 * Get query builder for resources owned by current team.
 * If you need all resources without further query chaining, use ownedByCurrentTeamCached() instead.
 */
public static function ownedByCurrentTeam()
{
    return self::whereTeamId(currentTeam()->id);
}

/**
 * Get all resources owned by current team (cached for request duration).
 */
public static function ownedByCurrentTeamCached()
{
    return once(function () {
        return self::ownedByCurrentTeam()->get();
    });
}
```

## Data Consistency Patterns

### Database Transactions
```php
// Atomic operations for deployment
DB::transaction(function () {
    $application = Application::create($data);
    $application->environmentVariables()->createMany($envVars);
    $application->deployments()->create(['status' => 'queued']);
});
```

### Model Events
```php
// Automatic cleanup on model deletion
class Application extends Model
{
    protected static function booted()
    {
        static::deleting(function ($application) {
            $application->environmentVariables()->delete();
            $application->deployments()->delete();
        });
    }
}
```

## Backup & Recovery

### Database Backup Strategy
- **Automated PostgreSQL backups** via scheduled tasks
- **Point-in-time recovery** capability
- **Cross-region backup** replication
- **Backup verification** and testing

### Data Export/Import
- **Application configurations** export/import
- **Environment variable** bulk operations
- **Server configurations** backup and restore

## Performance Monitoring

### Query Performance
- **Laravel Telescope** for development debugging
- **Slow query logging** in production
- **Database connection** pooling
- **Read replica** support for scaling

### Metrics Collection
- **Database size** monitoring
- **Connection count** tracking
- **Query execution time** analysis
- **Cache hit rates** monitoring

## Multi-Tenancy Pattern

### Team-Based Isolation
```php
// Global scope for team-based filtering
class Application extends Model
{
    protected static function booted()
    {
        static::addGlobalScope('team', function (Builder $builder) {
            if (auth()->user()) {
                $builder->whereHas('environment.project', function ($query) {
                    $query->where('team_id', auth()->user()->currentTeam->id);
                });
            }
        });
    }
}
```

### Data Separation
- **Team-scoped queries** by default
- **Cross-team access** controls
- **Admin access** patterns
- **Data isolation** guarantees
