Summary

Enables database detection and backup support for Docker Compose deployments via GitHub App (dockercompose buildpack). Previously, database services in these deployments were not detected and ServiceDatabase records were not created, meaning automated backups were unavailable.

Issue

Resolves https://github.com/coollabsio/coolify/issues/7528

/claim #7528

Category

  • Bug fix
  • New Feature

Technical Details

Root Cause

parseDockerComposeFile() in bootstrap/helpers/shared.php has two code paths:

Path Model Calls isDatabaseImage() Creates ServiceDatabase Backups
Service model (lines ~1263-2025) Service
Application model (lines ~2026+) Application ✅ (already) missing

The Application path already called isDatabaseImage() and set is_database, but never created ServiceDatabase records because the existing FK (service_id) only pointed to the services table.

Database Changes

New migration: Adds nullable application_id FK (constrained to applications, cascade on delete) to service_databases table. Makes service_id nullable so Application-owned databases do not need it.

Model Changes

ServiceDatabase:

  • Added application() relationship (belongsTo Application)
  • Added helper methods for owner-agnostic resolution:
    • isApplicationOwned() — checks if owned by Application vs Service
    • getOwner() — returns the owning Service or Application
    • getOwnerUuid() — UUID of the owner
    • getServer() — resolves server through either ownership path
    • getNetwork() — resolves network through either ownership path
  • Updated restart(), getServiceDatabaseUrl(), team(), workdir() to use helpers
  • Updated ownedByCurrentTeam() and ownedByCurrentTeamAPI() to query both ownership paths

Application:

  • Added composeDatabases() HasMany relationship
  • Cleanup of compose databases when switching away from dockercompose build pack
  • Cleanup on forceDeleting

Parser Changes (shared.php)

  • In the Application model path of parseDockerComposeFile(), after isDatabaseImage() detection, creates/updates ServiceDatabase records with application_id (skips preview deployments)
  • Cleans up stale ServiceDatabase records when services are removed from the compose file
  • Updated getResourceByUuid team ownership check to handle Application-owned ServiceDatabases

Updated Code Paths

All locations that previously used hardcoded ->service->server, ->service->uuid, ->service->destination->network chains now use the new getServer(), getOwnerUuid(), getNetwork() helpers:

  • DatabaseBackupJob: Server resolution, container naming, network for S3 upload
  • StartDatabaseProxy / StopDatabaseProxy: Network, server, container name resolution
  • BackupExecutions: Server resolution for backup deletion and download
  • BackupEdit: Server resolution, redirect for Application-owned databases
  • ScheduledDatabaseBackup: Server resolution
  • Import: Server, container name, network resolution
  • LocalFileVolume: Server/workdir resolution for file storage operations
  • databases.php helper: Server resolution for backup cleanup
  • web.php download route: Server resolution for backup file downloads

UI Changes

  • Added “Backups” tab to Application configuration sidebar (only for dockercompose build pack when databases are detected)
  • Created ComposeBackups Livewire component with database selector and backup management
  • Reuses existing ScheduledBackups and CreateScheduledBackup components

Steps to Test

  1. Create a new Application using the dockercompose buildpack via GitHub App
  2. Use a repo with a docker-compose.yml containing a database service (e.g., postgres:16-alpine) and at least one non-database service
  3. Deploy the Application
  4. Navigate to Project > Environment > Application > Configuration > Backups
  5. Verify the database service is listed and you can create a scheduled backup
  6. Run a backup and confirm a new execution entry is created
  7. Verify that removing the database from the compose file and redeploying cleans up the ServiceDatabase record

AI Usage

  • AI is used in the process of creating this PR

Contributor Agreement

[!IMPORTANT]

  • I have read and understood the contributor guidelines. If I have failed to follow any guideline, I understand that this PR may be closed without review.
  • I have tested the changes thoroughly and am confident that they will work as expected without issues when the maintainer tests them

Claim

Total prize pool $100
Total paid $0
Status Pending
Submitted February 18, 2026
Last updated February 18, 2026

Contributors

CR

Cristol

@manas-io-ai

100%

Sponsors

IL

Ilias Ism

@me

$100