fix: correct status for services with all containers excluded from health checks

When all containers are excluded from health checks, display their actual status
with :excluded suffix instead of misleading hardcoded statuses. This prevents
broken UI state with incorrect action buttons and provides clarity that monitoring
is disabled.

🤖 Generated with Claude Code

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Andras BacsaiandClaude committed 2025-11-19 10:54:51 +01:00
1 parent f81640e316
commit 498b189286
7 files changed
+317 -31

No files matched your search

+5 -3
View File
@@ -98,11 +98,13 @@ class GetContainersStatus
$labels = data_get($container, 'Config.Labels');
}
$containerStatus = data_get($container, 'State.Status');
$containerHealth = data_get($container, 'State.Health.Status', 'unhealthy');
$containerHealth = data_get($container, 'State.Health.Status');
if ($containerStatus === 'restarting') {
$containerStatus = "restarting ($containerHealth)";
$healthSuffix = $containerHealth ?? 'unknown';
$containerStatus = "restarting ($healthSuffix)";
} else {
$containerStatus = "$containerStatus ($containerHealth)";
$healthSuffix = $containerHealth ?? 'unknown';
$containerStatus = "$containerStatus ($healthSuffix)";
}
$labels = Arr::undot(format_docker_labels_to_json($labels));
$applicationId = data_get($labels, 'coolify.applicationId');
+48 -3
View File
@@ -97,14 +97,14 @@ class ComplexStatusCheck
$relevantContainerCount++;
$containerStatus = data_get($container, 'State.Status');
$containerHealth = data_get($container, 'State.Health.Status', 'unhealthy');
$containerHealth = data_get($container, 'State.Health.Status');
if ($containerStatus === 'restarting') {
$hasRestarting = true;
$hasUnhealthy = true;
} elseif ($containerStatus === 'running') {
$hasRunning = true;
if ($containerHealth === 'unhealthy') {
if ($containerHealth && $containerHealth === 'unhealthy') {
$hasUnhealthy = true;
}
} elseif ($containerStatus === 'exited') {
@@ -113,8 +113,53 @@ class ComplexStatusCheck
}
}
// If all containers are excluded, calculate status from excluded containers
// but mark it with :excluded to indicate monitoring is disabled
if ($relevantContainerCount === 0) {
return 'exited:healthy';
$excludedHasRunning = false;
$excludedHasRestarting = false;
$excludedHasUnhealthy = false;
$excludedHasExited = false;
foreach ($containers as $container) {
$labels = data_get($container, 'Config.Labels', []);
$serviceName = data_get($labels, 'com.docker.compose.service');
// Only process excluded containers
if (! $serviceName || ! $excludedContainers->contains($serviceName)) {
continue;
}
$containerStatus = data_get($container, 'State.Status');
$containerHealth = data_get($container, 'State.Health.Status');
if ($containerStatus === 'restarting') {
$excludedHasRestarting = true;
$excludedHasUnhealthy = true;
} elseif ($containerStatus === 'running') {
$excludedHasRunning = true;
if ($containerHealth && $containerHealth === 'unhealthy') {
$excludedHasUnhealthy = true;
}
} elseif ($containerStatus === 'exited') {
$excludedHasExited = true;
$excludedHasUnhealthy = true;
}
}
if ($excludedHasRestarting) {
return 'degraded:excluded';
}
if ($excludedHasRunning && $excludedHasExited) {
return 'degraded:excluded';
}
if ($excludedHasRunning) {
return 'running:excluded';
}
return 'exited:excluded';
}
if ($hasRestarting) {
+75 -3
View File
@@ -184,11 +184,13 @@ class Service extends BaseModel
$complexStatus = null;
$complexHealth = null;
$hasNonExcluded = false;
foreach ($applications as $application) {
if ($application->exclude_from_status) {
continue;
}
$hasNonExcluded = true;
$status = str($application->status)->before('(')->trim();
$health = str($application->status)->between('(', ')')->trim();
if ($complexStatus === 'degraded') {
@@ -218,6 +220,7 @@ class Service extends BaseModel
if ($database->exclude_from_status) {
continue;
}
$hasNonExcluded = true;
$status = str($database->status)->before('(')->trim();
$health = str($database->status)->between('(', ')')->trim();
if ($complexStatus === 'degraded') {
@@ -244,9 +247,78 @@ class Service extends BaseModel
}
}
// If all services are excluded from status checks, return a default exited status
if ($complexStatus === null && $complexHealth === null) {
return 'exited:healthy';
// If all services are excluded from status checks, calculate status from excluded containers
// but mark it with :excluded to indicate monitoring is disabled
if (! $hasNonExcluded && ($complexStatus === null && $complexHealth === null)) {
$excludedStatus = null;
$excludedHealth = null;
// Calculate status from excluded containers
foreach ($applications as $application) {
$status = str($application->status)->before('(')->trim();
$health = str($application->status)->between('(', ')')->trim();
if ($excludedStatus === 'degraded') {
continue;
}
if ($status->startsWith('running')) {
if ($excludedStatus === 'exited') {
$excludedStatus = 'degraded';
} else {
$excludedStatus = 'running';
}
} elseif ($status->startsWith('restarting')) {
$excludedStatus = 'degraded';
} elseif ($status->startsWith('exited')) {
$excludedStatus = 'exited';
}
if ($health->value() === 'healthy') {
if ($excludedHealth === 'unhealthy') {
continue;
}
$excludedHealth = 'healthy';
} else {
$excludedHealth = 'unhealthy';
}
}
foreach ($databases as $database) {
$status = str($database->status)->before('(')->trim();
$health = str($database->status)->between('(', ')')->trim();
if ($excludedStatus === 'degraded') {
continue;
}
if ($status->startsWith('running')) {
if ($excludedStatus === 'exited') {
$excludedStatus = 'degraded';
} else {
$excludedStatus = 'running';
}
} elseif ($status->startsWith('restarting')) {
$excludedStatus = 'degraded';
} elseif ($status->startsWith('exited')) {
$excludedStatus = 'exited';
}
if ($health->value() === 'healthy') {
if ($excludedHealth === 'unhealthy') {
continue;
}
$excludedHealth = 'healthy';
} else {
$excludedHealth = 'unhealthy';
}
}
// Return status with :excluded suffix to indicate monitoring is disabled
if ($excludedStatus && $excludedHealth) {
return "{$excludedStatus}:excluded";
}
// If no status was calculated at all (no containers exist), return unknown
if ($excludedStatus === null && $excludedHealth === null) {
return 'unknown:excluded';
}
return 'exited:excluded';
}
return "{$complexStatus}:{$complexHealth}";