Add per-application Docker image retention for rollback capability

Implement a per-application setting (`docker_images_to_keep`) in `application_settings` table to control how many Docker images are preserved during cleanup. The cleanup process now:

- Respects per-application retention settings (default: 2 images)
- Preserves the N most recent images per application for easy rollback
- Always deletes PR images and keeps the currently running image
- Dynamically excludes application images from general Docker image prune
- Cleans up non-Coolify unused images to prevent disk bloat

Fixes issues where cleanup would delete all images needed for rollback.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Andras Bacsai
2025-12-05 11:02:07 +01:00
parent 558a885fdc
commit 4ed7a4238a
6 changed files with 390 additions and 11 deletions

View File

@@ -4,6 +4,7 @@ namespace App\Livewire\Project\Application;
use App\Models\Application;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Attributes\Validate;
use Livewire\Component;
use Visus\Cuid2\Cuid2;
@@ -19,9 +20,26 @@ class Rollback extends Component
public array $parameters;
#[Validate(['integer', 'min:0', 'max:100'])]
public int $dockerImagesToKeep = 2;
public function mount()
{
$this->parameters = get_route_parameters();
$this->dockerImagesToKeep = $this->application->settings->docker_images_to_keep ?? 2;
}
public function saveSettings()
{
try {
$this->authorize('update', $this->application);
$this->validate();
$this->application->settings->docker_images_to_keep = $this->dockerImagesToKeep;
$this->application->settings->save();
$this->dispatch('success', 'Settings saved.');
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function rollbackImage($commit)
@@ -66,14 +84,12 @@ class Rollback extends Component
return str($item)->contains($image);
})->map(function ($item) {
$item = str($item)->explode('#');
if ($item[1] === $this->current) {
// $is_current = true;
}
$is_current = $item[1] === $this->current;
return [
'tag' => $item[1],
'created_at' => $item[2],
'is_current' => $is_current ?? null,
'is_current' => $is_current,
];
})->toArray();
}