Skip to content

Commit 16278f3

Browse files
committed
fix: parse HEALTHCHECK from dockerfile
1 parent 05c6d67 commit 16278f3

File tree

7 files changed

+104
-25
lines changed

7 files changed

+104
-25
lines changed

app/Jobs/ApplicationDeploymentJob.php

+17-18
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
9595
private ?string $buildTarget = null;
9696
private Collection $saved_outputs;
9797
private ?string $full_healthcheck_url = null;
98-
private bool $custom_healthcheck_found = false;
9998

10099
private string $serverUser = 'root';
101100
private string $serverUserHomeDir = '/root';
@@ -903,10 +902,13 @@ private function health_check()
903902
if ($this->server->isSwarm()) {
904903
// Implement healthcheck for swarm
905904
} else {
906-
if ($this->application->isHealthcheckDisabled() && $this->custom_healthcheck_found === false) {
905+
if ($this->application->isHealthcheckDisabled() && $this->application->custom_healthcheck_found === false) {
907906
$this->newVersionIsHealthy = true;
908907
return;
909908
}
909+
if ($this->application->custom_healthcheck_found) {
910+
$this->application_deployment_queue->addLogEntry("Custom healthcheck found, skipping default healthcheck.");
911+
}
910912
// ray('New container name: ', $this->container_name);
911913
if ($this->container_name) {
912914
$counter = 1;
@@ -1272,16 +1274,14 @@ private function generate_compose_file()
12721274
return escapeDollarSign($value);
12731275
});
12741276
$labels = $labels->merge(defaultLabels($this->application->id, $this->application->uuid, $this->pull_request_id))->toArray();
1277+
12751278
// Check for custom HEALTHCHECK
1276-
$this->custom_healthcheck_found = false;
12771279
if ($this->application->build_pack === 'dockerfile' || $this->application->dockerfile) {
12781280
$this->execute_remote_command([
12791281
executeInDocker($this->deployment_uuid, "cat {$this->workdir}{$this->dockerfile_location}"), "hidden" => true, "save" => 'dockerfile_from_repo', "ignore_errors" => true
12801282
]);
12811283
$dockerfile = collect(Str::of($this->saved_outputs->get('dockerfile_from_repo'))->trim()->explode("\n"));
1282-
if (str($dockerfile)->contains('HEALTHCHECK')) {
1283-
$this->custom_healthcheck_found = true;
1284-
}
1284+
$this->application->parseHealthcheckFromDockerfile($dockerfile);
12851285
}
12861286
$docker_compose = [
12871287
'version' => '3.8',
@@ -1327,18 +1327,17 @@ private function generate_compose_file()
13271327
if (!is_null($this->env_filename)) {
13281328
$docker_compose['services'][$this->container_name]['env_file'] = [$this->env_filename];
13291329
}
1330-
if (!$this->custom_healthcheck_found) {
1331-
$docker_compose['services'][$this->container_name]['healthcheck'] = [
1332-
'test' => [
1333-
'CMD-SHELL',
1334-
$this->generate_healthcheck_commands()
1335-
],
1336-
'interval' => $this->application->health_check_interval . 's',
1337-
'timeout' => $this->application->health_check_timeout . 's',
1338-
'retries' => $this->application->health_check_retries,
1339-
'start_period' => $this->application->health_check_start_period . 's'
1340-
];
1341-
}
1330+
$docker_compose['services'][$this->container_name]['healthcheck'] = [
1331+
'test' => [
1332+
'CMD-SHELL',
1333+
$this->generate_healthcheck_commands()
1334+
],
1335+
'interval' => $this->application->health_check_interval . 's',
1336+
'timeout' => $this->application->health_check_timeout . 's',
1337+
'retries' => $this->application->health_check_retries,
1338+
'start_period' => $this->application->health_check_start_period . 's'
1339+
];
1340+
13421341
if (!is_null($this->application->limits_cpuset)) {
13431342
data_set($docker_compose, 'services.' . $this->container_name . '.cpuset', $this->application->limits_cpuset);
13441343
}

app/Livewire/Project/New/SimpleDockerfile.php

+2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ public function submit()
7070
'fqdn' => $fqdn
7171
]);
7272

73+
$application->parseHealthcheckFromDockerfile(dockerfile: collect(str($this->dockerfile)->trim()->explode("\n")), isInit: true);
74+
7375
return redirect()->route('project.application.configuration', [
7476
'application_uuid' => $application->uuid,
7577
'environment_name' => $environment->name,

app/Livewire/Project/Shared/HealthChecks.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,13 @@ class HealthChecks extends Component
2121
'resource.health_check_timeout' => 'integer|min:1',
2222
'resource.health_check_retries' => 'integer|min:1',
2323
'resource.health_check_start_period' => 'integer',
24+
'resource.custom_healthcheck_found' => 'boolean',
2425

2526
];
2627
public function instantSave()
2728
{
2829
$this->resource->save();
2930
$this->dispatch('success', 'Health check updated.');
30-
31-
3231
}
3332
public function submit()
3433
{

app/Models/Application.php

+47
Original file line numberDiff line numberDiff line change
@@ -963,4 +963,51 @@ public function getFilesFromServer(bool $isInit = false)
963963
{
964964
getFilesystemVolumesFromServer($this, $isInit);
965965
}
966+
967+
public function parseHealthcheckFromDockerfile($dockerfile, bool $isInit = false) {
968+
if (str($dockerfile)->contains('HEALTHCHECK') && ($this->isHealthcheckDisabled() || $isInit)) {
969+
$healthcheckCommand = null;
970+
$lines = $dockerfile->toArray();
971+
foreach ($lines as $line) {
972+
$trimmedLine = trim($line);
973+
if (str_starts_with($trimmedLine, 'HEALTHCHECK')) {
974+
$healthcheckCommand .= trim($trimmedLine, '\\ ');
975+
continue;
976+
}
977+
if (isset($healthcheckCommand) && str_contains($trimmedLine, '\\')) {
978+
$healthcheckCommand .= ' ' . trim($trimmedLine, '\\ ');
979+
}
980+
if (isset($healthcheckCommand) && !str_contains($trimmedLine, '\\') && !empty($healthcheckCommand)) {
981+
$healthcheckCommand .= ' ' . $trimmedLine;
982+
break;
983+
}
984+
}
985+
if (str($healthcheckCommand)->isNotEmpty()) {
986+
$interval = str($healthcheckCommand)->match('/--interval=(\d+)/');
987+
$timeout = str($healthcheckCommand)->match('/--timeout=(\d+)/');
988+
$start_period = str($healthcheckCommand)->match('/--start-period=(\d+)/');
989+
$start_interval = str($healthcheckCommand)->match('/--start-interval=(\d+)/');
990+
$retries = str($healthcheckCommand)->match('/--retries=(\d+)/');
991+
if ($interval->isNotEmpty()) {
992+
$this->health_check_interval = $interval->toInteger();
993+
}
994+
if ($timeout->isNotEmpty()) {
995+
$this->health_check_timeout = $timeout->toInteger();
996+
}
997+
if ($start_period->isNotEmpty()) {
998+
$this->health_check_start_period = $start_period->toInteger();
999+
}
1000+
// if ($start_interval) {
1001+
// $this->health_check_start_interval = $start_interval->value();
1002+
// }
1003+
if ($retries->isNotEmpty()) {
1004+
$this->health_check_retries = $retries->toInteger();
1005+
}
1006+
if ($interval || $timeout || $start_period || $start_interval || $retries) {
1007+
$this->custom_healthcheck_found = true;
1008+
$this->save();
1009+
}
1010+
}
1011+
}
1012+
}
9661013
}

app/Notifications/Application/DeploymentFailed.php

+4-4
Original file line numberDiff line numberDiff line change
@@ -69,20 +69,20 @@ public function toMail(): MailMessage
6969
public function toDiscord(): string
7070
{
7171
if ($this->preview) {
72-
$message = 'Coolify: Pull request #' . $this->preview->pull_request_id . ' of **' . $this->application_name . '** (' . $this->preview->fqdn . ') deployment failed: ';
72+
$message = 'Coolify: Pull request #' . $this->preview->pull_request_id . ' of ' . $this->application_name . ' (' . $this->preview->fqdn . ') deployment failed: ';
7373
$message .= '[View Deployment Logs](' . $this->deployment_url . ')';
7474
} else {
75-
$message = 'Coolify: Deployment failed of **' . $this->application_name . '** (' . $this->fqdn . '): ';
75+
$message = 'Coolify: Deployment failed of ' . $this->application_name . ' (' . $this->fqdn . '): ';
7676
$message .= '[View Deployment Logs](' . $this->deployment_url . ')';
7777
}
7878
return $message;
7979
}
8080
public function toTelegram(): array
8181
{
8282
if ($this->preview) {
83-
$message = 'Coolify: Pull request #' . $this->preview->pull_request_id . ' of **' . $this->application_name . '** (' . $this->preview->fqdn . ') deployment failed: ';
83+
$message = 'Coolify: Pull request #' . $this->preview->pull_request_id . ' of ' . $this->application_name . ' (' . $this->preview->fqdn . ') deployment failed: ';
8484
} else {
85-
$message = 'Coolify: Deployment failed of **' . $this->application_name . '** (' . $this->fqdn . '): ';
85+
$message = 'Coolify: Deployment failed of ' . $this->application_name . ' (' . $this->fqdn . '): ';
8686
}
8787
$buttons[] = [
8888
"text" => "Deployment logs",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*/
12+
public function up(): void
13+
{
14+
Schema::table('applications', function (Blueprint $table) {
15+
$table->boolean('custom_healthcheck_found')->default(false);
16+
});
17+
}
18+
19+
/**
20+
* Reverse the migrations.
21+
*/
22+
public function down(): void
23+
{
24+
Schema::table('applications', function (Blueprint $table) {
25+
$table->dropColumn('custom_healthcheck_found');
26+
});
27+
}
28+
};

resources/views/livewire/project/shared/health-checks.blade.php

+5-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
</div>
66
<div class="pb-4">Define how your resource's health should be checked.</div>
77
<div class="flex flex-col gap-4">
8+
@if ($resource->custom_healthcheck_found)
9+
<div class="text-warning">A custom health check has been found and will be used until you enable this.</div>
10+
@endif
811
<div class="w-32">
912
<x-forms.checkbox instantSave id="resource.health_check_enabled" label="Enabled" />
1013
</div>
@@ -17,7 +20,8 @@
1720
<x-forms.input id="resource.health_check_path" placeholder="/health" label="Path" required />
1821
</div>
1922
<div class="flex gap-2">
20-
<x-forms.input type="number" id="resource.health_check_return_code" placeholder="200" label="Return Code" required />
23+
<x-forms.input type="number" id="resource.health_check_return_code" placeholder="200" label="Return Code"
24+
required />
2125
<x-forms.input id="resource.health_check_response_text" placeholder="OK" label="Response Text" />
2226
</div>
2327
<div class="flex gap-2">

0 commit comments

Comments
 (0)