feat: configurable unused images threshold with dashboard warning

- Add image_prune_threshold_mb setting (default 1024 MB)
- Add GET /api/docker/unused-images endpoint returning unused image count, size, and threshold status
- Dashboard shows amber warning banner when unused project images exceed threshold
- Banner links to settings page for pruning, shows count and human-readable size (MB/GB)
- Threshold configurable in Docker Image Cleanup section of settings
- DB migration + schema for image_prune_threshold_mb
This commit is contained in:
2026-04-05 14:34:48 +03:00
parent 0ddad87a9a
commit b0816502bf
12 changed files with 137 additions and 2 deletions
+13
View File
@@ -23,6 +23,7 @@
let baseVolumePath = $state('');
let notificationUrl = $state('');
let staleThresholdDays = $state('7');
let imagePruneThresholdMb = $state('1024');
// Proxy provider state.
@@ -128,6 +129,7 @@
baseVolumePath = settings.base_volume_path ?? '';
notificationUrl = settings.notification_url ?? '';
staleThresholdDays = String(settings.stale_threshold_days ?? 7);
imagePruneThresholdMb = String(settings.image_prune_threshold_mb ?? 1024);
proxyProvider = settings.proxy_provider ?? 'npm';
wildcardDns = settings.wildcard_dns ?? true;
dnsProvider = settings.dns_provider ?? '';
@@ -157,6 +159,7 @@
base_volume_path: baseVolumePath.trim(), notification_url: notificationUrl.trim(),
proxy_provider: proxyProvider,
stale_threshold_days: Math.max(1, parseInt(staleThresholdDays, 10) || 7),
image_prune_threshold_mb: Math.max(0, parseInt(String(imagePruneThresholdMb), 10) || 0),
wildcard_dns: wildcardDns,
dns_provider: wildcardDns ? '' : dnsProvider,
cloudflare_zone_id: cloudflareZoneId
@@ -363,6 +366,16 @@
<div class="mt-6 border-t border-[var(--border-primary)] pt-4">
<h3 class="mb-1 text-sm font-semibold text-[var(--text-primary)]">{$t('settings.dockerCleanup')}</h3>
<p class="mb-3 text-xs text-[var(--text-tertiary)]">{$t('settings.dockerCleanupHelp')}</p>
<div class="mb-3 max-w-xs">
<FormField
label={$t('settings.pruneThreshold')}
name="imagePruneThresholdMb"
type="number"
bind:value={imagePruneThresholdMb}
placeholder="1024"
helpText={$t('settings.pruneThresholdHelp')}
/>
</div>
<button
type="button"
onclick={() => { showPruneConfirm = true; }}