Read Dokploy environments for composes
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2026-01-29 11:17:41 +01:00
parent 87f348462b
commit ce7da1ff66
3 changed files with 157 additions and 90 deletions

View File

@@ -72,10 +72,10 @@ class DokployPlatformHealth extends Widget
continue;
}
$applicationsPayload = Arr::get($project, 'applications', []);
$applications = $this->formatApplications(is_array($applicationsPayload) ? $applicationsPayload : [], $client);
$composes = $this->formatProjectComposes($project, $client);
$services = $this->formatProjectServices($project);
$environments = $this->extractEnvironments($project);
$applications = $this->formatEnvironmentApplications($environments, $client);
$composes = $this->formatEnvironmentComposes($environments, $client);
$services = $this->formatEnvironmentServices($environments);
$results[] = [
'label' => ucfirst((string) $label),
@@ -147,10 +147,116 @@ class DokployPlatformHealth extends Widget
return $results;
}
protected function formatApplications(array $applications, DokployClient $client): array
protected function extractEnvironments(array $project): array
{
$environments = Arr::get($project, 'environments', []);
if (is_array($environments) && ! empty($environments)) {
return $environments;
}
return [[
'name' => Arr::get($project, 'name'),
'applications' => Arr::get($project, 'applications', []),
'compose' => Arr::get($project, 'compose', []),
'mysql' => Arr::get($project, 'mysql', []),
'postgres' => Arr::get($project, 'postgres', []),
'mariadb' => Arr::get($project, 'mariadb', []),
'mongo' => Arr::get($project, 'mongo', []),
'redis' => Arr::get($project, 'redis', []),
]];
}
protected function formatEnvironmentApplications(array $environments, DokployClient $client): array
{
return collect($environments)
->flatMap(function (array $environment) use ($client) {
$applications = Arr::get($environment, 'applications', []);
$environmentName = Arr::get($environment, 'name');
return $this->formatApplications(is_array($applications) ? $applications : [], $client, $environmentName);
})
->values()
->all();
}
protected function formatEnvironmentComposes(array $environments, DokployClient $client): array
{
return collect($environments)
->flatMap(function (array $environment) use ($client) {
$composes = Arr::get($environment, 'compose', []);
$environmentName = Arr::get($environment, 'name');
return collect(is_array($composes) ? $composes : [])
->map(function (array $compose) use ($client, $environmentName) {
$composeId = Arr::get($compose, 'composeId') ?? Arr::get($compose, 'id');
$statusPayload = [];
$deployments = [];
if ($composeId) {
try {
$statusPayload = $client->composeStatus($composeId);
$deployments = $client->composeDeployments($composeId, 1);
} catch (\Throwable $exception) {
$statusPayload = [];
$deployments = [];
}
}
$composeDetails = Arr::get($statusPayload, 'compose', []);
return [
'id' => $composeId,
'name' => Arr::get($compose, 'name')
?? Arr::get($compose, 'appName')
?? Arr::get($composeDetails, 'name')
?? Arr::get($composeDetails, 'appName')
?? $composeId,
'status' => Arr::get($compose, 'composeStatus')
?? Arr::get($compose, 'status')
?? Arr::get($composeDetails, 'composeStatus')
?? Arr::get($composeDetails, 'status')
?? 'unknown',
'environment' => $environmentName,
'last_deploy' => Arr::get($deployments, '0.createdAt')
?? Arr::get($deployments, '0.created_at')
?? Arr::get($compose, 'updatedAt')
?? Arr::get($composeDetails, 'updatedAt'),
'services' => $this->formatServices(Arr::get($statusPayload, 'services', [])),
];
})
->filter(fn (array $compose) => filled($compose['name']))
->values()
->all();
})
->values()
->all();
}
protected function formatEnvironmentServices(array $environments): array
{
return collect($environments)
->flatMap(function (array $environment) {
$environmentName = Arr::get($environment, 'name');
return collect([
...$this->normalizeServiceList((array) Arr::get($environment, 'compose', []), 'compose', 'composeId', 'composeStatus', $environmentName),
...$this->normalizeServiceList((array) Arr::get($environment, 'mysql', []), 'mysql', 'mysqlId', 'applicationStatus', $environmentName),
...$this->normalizeServiceList((array) Arr::get($environment, 'postgres', []), 'postgres', 'postgresId', 'applicationStatus', $environmentName),
...$this->normalizeServiceList((array) Arr::get($environment, 'mariadb', []), 'mariadb', 'mariadbId', 'applicationStatus', $environmentName),
...$this->normalizeServiceList((array) Arr::get($environment, 'mongo', []), 'mongo', 'mongoId', 'applicationStatus', $environmentName),
...$this->normalizeServiceList((array) Arr::get($environment, 'redis', []), 'redis', 'redisId', 'applicationStatus', $environmentName),
]);
})
->filter(fn (array $service) => filled($service['name']))
->values()
->all();
}
protected function formatApplications(array $applications, DokployClient $client, ?string $environment = null): array
{
return collect($applications)
->map(function (array $application) use ($client) {
->map(function (array $application) use ($client, $environment) {
$applicationId = $this->extractApplicationId($application);
$statusPayload = [];
@@ -194,6 +300,7 @@ class DokployPlatformHealth extends Widget
'server' => Arr::get($application, 'serverName')
?? Arr::get($applicationDetails, 'serverName')
?? Arr::get($application, 'server'),
'environment' => $environment,
'last_deploy' => Arr::get($application, 'lastDeploymentAt')
?? Arr::get($applicationDetails, 'lastDeploymentAt')
?? Arr::get($application, 'updatedAt')
@@ -214,71 +321,10 @@ class DokployPlatformHealth extends Widget
?? Arr::get($application, 'id');
}
protected function formatProjectServices(array $project): array
{
return collect([
...$this->normalizeServiceList((array) Arr::get($project, 'compose', []), 'compose', 'composeId', 'composeStatus'),
...$this->normalizeServiceList((array) Arr::get($project, 'mysql', []), 'mysql', 'mysqlId', 'applicationStatus'),
...$this->normalizeServiceList((array) Arr::get($project, 'postgres', []), 'postgres', 'postgresId', 'applicationStatus'),
...$this->normalizeServiceList((array) Arr::get($project, 'mariadb', []), 'mariadb', 'mariadbId', 'applicationStatus'),
...$this->normalizeServiceList((array) Arr::get($project, 'mongo', []), 'mongo', 'mongoId', 'applicationStatus'),
...$this->normalizeServiceList((array) Arr::get($project, 'redis', []), 'redis', 'redisId', 'applicationStatus'),
])
->filter(fn (array $service) => filled($service['name']))
->values()
->all();
}
protected function formatProjectComposes(array $project, DokployClient $client): array
{
$composes = (array) Arr::get($project, 'compose', []);
return collect($composes)
->map(function (array $compose) use ($client) {
$composeId = Arr::get($compose, 'composeId') ?? Arr::get($compose, 'id');
$statusPayload = [];
$deployments = [];
if ($composeId) {
try {
$statusPayload = $client->composeStatus($composeId);
$deployments = $client->composeDeployments($composeId, 1);
} catch (\Throwable $exception) {
$statusPayload = [];
$deployments = [];
}
}
$composeDetails = Arr::get($statusPayload, 'compose', []);
return [
'id' => $composeId,
'name' => Arr::get($compose, 'name')
?? Arr::get($compose, 'appName')
?? Arr::get($composeDetails, 'name')
?? Arr::get($composeDetails, 'appName')
?? $composeId,
'status' => Arr::get($compose, 'composeStatus')
?? Arr::get($compose, 'status')
?? Arr::get($composeDetails, 'composeStatus')
?? Arr::get($composeDetails, 'status')
?? 'unknown',
'last_deploy' => Arr::get($deployments, '0.createdAt')
?? Arr::get($deployments, '0.created_at')
?? Arr::get($compose, 'updatedAt')
?? Arr::get($composeDetails, 'updatedAt'),
'services' => $this->formatServices(Arr::get($statusPayload, 'services', [])),
];
})
->filter(fn (array $compose) => filled($compose['name']))
->values()
->all();
}
protected function normalizeServiceList(array $services, string $type, string $idKey, string $statusKey): array
protected function normalizeServiceList(array $services, string $type, string $idKey, string $statusKey, ?string $environment = null): array
{
return collect($services)
->map(function (array $service) use ($type, $idKey, $statusKey) {
->map(function (array $service) use ($type, $idKey, $statusKey, $environment) {
return [
'type' => $type,
'id' => Arr::get($service, $idKey) ?? Arr::get($service, 'id'),
@@ -286,6 +332,7 @@ class DokployPlatformHealth extends Widget
'status' => Arr::get($service, $statusKey) ?? Arr::get($service, 'status') ?? Arr::get($service, 'composeStatus', 'unknown'),
'version' => Arr::get($service, 'dockerImage') ?? Arr::get($service, 'image'),
'external_port' => Arr::get($service, 'externalPort'),
'environment' => $environment,
];
})
->values()

View File

@@ -118,6 +118,11 @@
{{ $application['id'] }}
</x-filament::badge>
@endif
@if(!empty($application['environment']))
<x-filament::badge color="gray" :icon="Heroicon::RectangleStack">
Env: {{ $application['environment'] }}
</x-filament::badge>
@endif
@if(!empty($application['repository']))
<x-filament::badge color="gray" :icon="Heroicon::CodeBracket">
{{ $application['repository'] }}
@@ -184,6 +189,11 @@
{{ $compose['id'] }}
</x-filament::badge>
@endif
@if(!empty($compose['environment']))
<x-filament::badge color="gray" :icon="Heroicon::RectangleStack">
Env: {{ $compose['environment'] }}
</x-filament::badge>
@endif
<x-filament::badge color="gray" :icon="Heroicon::Clock">
Last deploy:
{{ $compose['last_deploy'] ? \Illuminate\Support\Carbon::parse($compose['last_deploy'])->diffForHumans() : '—' }}
@@ -235,6 +245,11 @@
{{ $service['id'] }}
</x-filament::badge>
@endif
@if(!empty($service['environment']))
<x-filament::badge color="gray" :icon="Heroicon::RectangleStack">
Env: {{ $service['environment'] }}
</x-filament::badge>
@endif
@if(!empty($service['version']))
<x-filament::badge color="gray" :icon="Heroicon::Cube">
{{ $service['version'] }}

View File

@@ -31,28 +31,33 @@ class DokployPlatformHealthWidgetTest extends TestCase
'name' => 'Core',
'description' => 'Main stack',
'updatedAt' => now()->toIso8601String(),
'applications' => [
'environments' => [
[
'applicationId' => 'app_1',
'name' => 'API',
'applicationStatus' => 'running',
'repository' => 'repo/api',
'branch' => 'main',
],
],
'compose' => [
[
'composeId' => 'cmp_1',
'name' => 'Main Compose',
'composeStatus' => 'done',
],
],
'redis' => [
[
'redisId' => 'redis_1',
'name' => 'Redis',
'applicationStatus' => 'done',
'externalPort' => 6379,
'name' => 'production',
'applications' => [
[
'applicationId' => 'app_1',
'name' => 'API',
'applicationStatus' => 'running',
'repository' => 'repo/api',
'branch' => 'main',
],
],
'compose' => [
[
'composeId' => 'cmp_1',
'name' => 'Main Compose',
'composeStatus' => 'done',
],
],
'redis' => [
[
'redisId' => 'redis_1',
'name' => 'Redis',
'applicationStatus' => 'done',
'externalPort' => 6379,
],
],
],
],
]);