Compare commits

...

28 Commits

Author SHA1 Message Date
Andras Bacsai
56144482f1 Merge pull request #2244 from coollabsio/next
v4.0.0-beta.284
2024-05-19 20:56:17 +02:00
Andras Bacsai
59f681e6af revert: hc return code check 2024-05-19 20:54:16 +02:00
Andras Bacsai
d3296f5180 feat: add hc logs to healthchecks 2024-05-18 18:48:33 +02:00
Andras Bacsai
c6fff0aa13 Update version numbers to 4.0.0-beta.284 2024-05-17 18:54:21 +02:00
Andras Bacsai
41e0c42282 Remove warning message about only supporting root user login via SSH in the future 2024-05-17 18:54:11 +02:00
Andras Bacsai
ede2274816 Merge pull request #2234 from coollabsio/next
v4.0.0-beta.283
2024-05-17 15:34:00 +02:00
Andras Bacsai
ead672afb2 fix: PR deployments have good predefined envs 2024-05-17 15:30:27 +02:00
Andras Bacsai
73bc7b045e feat: Add pull_request_id filter to get_last_successful_deployment method in Application model 2024-05-17 15:28:54 +02:00
Andras Bacsai
3281502c25 feat: Update healthcheck test in StartMongodb action 2024-05-17 14:35:37 +02:00
Andras Bacsai
ca35e536db chore: Update version to 4.0.0-beta.283 2024-05-17 14:35:31 +02:00
Andras Bacsai
bb8e0eb7bf Merge pull request #2232 from coollabsio/next
quickfixes
2024-05-17 13:44:12 +02:00
Andras Bacsai
bb451ac3b5 Refactor BackupExecutions.php to use optional chaining for deleting failed backup executions 2024-05-17 13:43:36 +02:00
Andras Bacsai
b0b7842f9c Refactor BackupEdit component to handle null s3_storage_id 2024-05-17 13:43:21 +02:00
Andras Bacsai
aad661cb65 Merge pull request #2231 from coollabsio/next
v4.0.0-beta.282
2024-05-17 13:41:33 +02:00
Andras Bacsai
ed9b63520d Refactor gitCommitLink method in Application model 2024-05-17 13:40:28 +02:00
Andras Bacsai
5de1246827 Merge pull request #2230 from coollabsio/next
v4.0.0-beta.281
2024-05-17 12:45:26 +02:00
Andras Bacsai
edc3b014cd fix: telegram group chat notifications 2024-05-17 12:09:22 +02:00
Andras Bacsai
fec98f45ce feat: Improve sorting of environment variables in the All component 2024-05-17 11:40:32 +02:00
Andras Bacsai
94810d5066 fix: use rc in hc 2024-05-17 11:39:26 +02:00
Andras Bacsai
431cc796d8 feat: sort envs alphabetically and creation date 2024-05-17 11:10:57 +02:00
Andras Bacsai
e9d2dbcc92 Refactor Upgrade.php and add isDev condition for upgrade availability 2024-05-17 10:12:17 +02:00
Andras Bacsai
7a618ef89c feat: Add lastDeploymentInfo and lastDeploymentLink props to breadcrumbs and status components 2024-05-17 10:12:13 +02:00
Andras Bacsai
5b56249d12 Refactor gitCommitLink method in Application model 2024-05-17 10:12:05 +02:00
Andras Bacsai
e2ba5abe76 fix: hc from localhost to 127.0.0.1 2024-05-17 10:11:55 +02:00
Andras Bacsai
70a4b7c863 feat: new manual update process + remove next_channel 2024-05-17 09:52:19 +02:00
Andras Bacsai
10fde1b1ef feat: shows the latest deployment commit + message on status 2024-05-17 08:53:25 +02:00
Andras Bacsai
6131746180 Add all_servers property to Kernel class for better code organization 2024-05-16 21:36:01 +02:00
Andras Bacsai
bf953bf1b5 Update version numbers 2024-05-16 21:35:57 +02:00
93 changed files with 538 additions and 331 deletions

View File

@@ -50,8 +50,9 @@ class StartMongodb
], ],
'healthcheck' => [ 'healthcheck' => [
'test' => [ 'test' => [
'CMD-SHELL', "CMD",
'mongosh --eval "printjson(db.runCommand(\"ping\"))"' "echo",
"ok"
], ],
'interval' => '5s', 'interval' => '5s',
'timeout' => '5s', 'timeout' => '5s',

View File

@@ -27,10 +27,10 @@ class UpdateCoolify
CleanupDocker::run($this->server, false); CleanupDocker::run($this->server, false);
$this->latestVersion = get_latest_version_of_coolify(); $this->latestVersion = get_latest_version_of_coolify();
$this->currentVersion = config('version'); $this->currentVersion = config('version');
if ($settings->next_channel) { // if ($settings->next_channel) {
ray('next channel enabled'); // ray('next channel enabled');
$this->latestVersion = 'next'; // $this->latestVersion = 'next';
} // }
if ($force) { if ($force) {
$this->update(); $this->update();
} else { } else {

View File

@@ -21,8 +21,10 @@ use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel class Kernel extends ConsoleKernel
{ {
private $all_servers;
protected function schedule(Schedule $schedule): void protected function schedule(Schedule $schedule): void
{ {
$this->all_servers = Server::all();
if (isDev()) { if (isDev()) {
// Instance Jobs // Instance Jobs
$schedule->command('horizon:snapshot')->everyMinute(); $schedule->command('horizon:snapshot')->everyMinute();
@@ -56,7 +58,7 @@ class Kernel extends ConsoleKernel
} }
private function pull_helper_image($schedule) private function pull_helper_image($schedule)
{ {
$servers = Server::all()->where('settings.is_usable', true)->where('settings.is_reachable', true)->where('ip', '!=', '1.2.3.4'); $servers = $this->all_servers->where('settings.is_usable', true)->where('settings.is_reachable', true)->where('ip', '!=', '1.2.3.4');
foreach ($servers as $server) { foreach ($servers as $server) {
if (config('coolify.is_sentinel_enabled')) { if (config('coolify.is_sentinel_enabled')) {
$schedule->job(new PullSentinelImageJob($server))->everyFiveMinutes()->onOneServer(); $schedule->job(new PullSentinelImageJob($server))->everyFiveMinutes()->onOneServer();
@@ -67,12 +69,12 @@ class Kernel extends ConsoleKernel
private function check_resources($schedule) private function check_resources($schedule)
{ {
if (isCloud()) { if (isCloud()) {
$servers = Server::all()->whereNotNull('team.subscription')->where('team.subscription.stripe_trial_already_ended', false)->where('ip', '!=', '1.2.3.4'); $servers = $this->all_servers->whereNotNull('team.subscription')->where('team.subscription.stripe_trial_already_ended', false)->where('ip', '!=', '1.2.3.4');
$own = Team::find(0)->servers; $own = Team::find(0)->servers;
$servers = $servers->merge($own); $servers = $servers->merge($own);
$containerServers = $servers->where('settings.is_swarm_worker', false)->where('settings.is_build_server', false); $containerServers = $servers->where('settings.is_swarm_worker', false)->where('settings.is_build_server', false);
} else { } else {
$servers = Server::all()->where('ip', '!=', '1.2.3.4'); $servers = $this->all_servers->where('ip', '!=', '1.2.3.4');
$containerServers = $servers->where('settings.is_swarm_worker', false)->where('settings.is_build_server', false); $containerServers = $servers->where('settings.is_swarm_worker', false)->where('settings.is_build_server', false);
} }
foreach ($containerServers as $server) { foreach ($containerServers as $server) {

View File

@@ -713,10 +713,40 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
private function save_environment_variables() private function save_environment_variables()
{ {
$envs = collect([]); $envs = collect([]);
$local_branch = $this->branch;
if ($this->pull_request_id !== 0) {
$local_branch = "pull/{$this->pull_request_id}/head";
}
$sort = $this->application->settings->is_env_sorting_enabled;
if ($sort) {
$sorted_environment_variables = $this->application->environment_variables->sortBy('key');
$sorted_environment_variables_preview = $this->application->environment_variables_preview->sortBy('key');
} else {
$sorted_environment_variables = $this->application->environment_variables->sortBy('id');
$sorted_environment_variables_preview = $this->application->environment_variables_preview->sortBy('id');
}
$ports = $this->application->main_port(); $ports = $this->application->main_port();
if ($this->pull_request_id !== 0) { if ($this->pull_request_id !== 0) {
$this->env_filename = ".env-pr-$this->pull_request_id"; $this->env_filename = ".env-pr-$this->pull_request_id";
foreach ($this->application->environment_variables_preview as $env) { // Add SOURCE_COMMIT if not exists
if ($this->application->environment_variables_preview->where('key', 'SOURCE_COMMIT')->isEmpty()) {
if (!is_null($this->commit)) {
$envs->push("SOURCE_COMMIT={$this->commit}");
} else {
$envs->push("SOURCE_COMMIT=unknown");
}
}
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_FQDN')->isEmpty()) {
$envs->push("COOLIFY_FQDN={$this->preview->fqdn}");
}
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_URL')->isEmpty()) {
$url = str($this->preview->fqdn)->replace('http://', '')->replace('https://', '');
$envs->push("COOLIFY_URL={$url}");
}
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_BRANCH')->isEmpty()) {
$envs->push("COOLIFY_BRANCH={$local_branch}");
}
foreach ($sorted_environment_variables_preview as $env) {
$real_value = $env->real_value; $real_value = $env->real_value;
if ($env->version === '4.0.0-beta.239') { if ($env->version === '4.0.0-beta.239') {
$real_value = $env->real_value; $real_value = $env->real_value;
@@ -737,30 +767,27 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
if ($this->application->environment_variables_preview->where('key', 'HOST')->isEmpty()) { if ($this->application->environment_variables_preview->where('key', 'HOST')->isEmpty()) {
$envs->push("HOST=0.0.0.0"); $envs->push("HOST=0.0.0.0");
} }
} else {
$this->env_filename = ".env";
// Add SOURCE_COMMIT if not exists // Add SOURCE_COMMIT if not exists
if ($this->application->environment_variables_preview->where('key', 'SOURCE_COMMIT')->isEmpty()) { if ($this->application->environment_variables->where('key', 'SOURCE_COMMIT')->isEmpty()) {
if (!is_null($this->commit)) { if (!is_null($this->commit)) {
$envs->push("SOURCE_COMMIT={$this->commit}"); $envs->push("SOURCE_COMMIT={$this->commit}");
} else { } else {
$envs->push("SOURCE_COMMIT=unknown"); $envs->push("SOURCE_COMMIT=unknown");
} }
} }
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_FQDN')->isEmpty()) { if ($this->application->environment_variables->where('key', 'COOLIFY_FQDN')->isEmpty()) {
$envs->push("COOLIFY_FQDN={$this->preview->fqdn}"); $envs->push("COOLIFY_FQDN={$this->application->fqdn}");
} }
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_URL')->isEmpty()) { if ($this->application->environment_variables->where('key', 'COOLIFY_URL')->isEmpty()) {
$url = str($this->preview->fqdn)->replace('http://', '')->replace('https://', ''); $url = str($this->application->fqdn)->replace('http://', '')->replace('https://', '');
$envs->push("COOLIFY_URL={$url}"); $envs->push("COOLIFY_URL={$url}");
} }
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_BRANCH')->isEmpty()) { if ($this->application->environment_variables_preview->where('key', 'COOLIFY_BRANCH')->isEmpty()) {
$envs->push("COOLIFY_BRANCH={$this->application->git_branch}"); $envs->push("COOLIFY_BRANCH={$local_branch}");
} }
$envs = $envs->sort(function ($a, $b) { foreach ($sorted_environment_variables as $env) {
return strpos($a, '$') === false ? -1 : 1;
});
} else {
$this->env_filename = ".env";
foreach ($this->application->environment_variables as $env) {
$real_value = $env->real_value; $real_value = $env->real_value;
if ($env->version === '4.0.0-beta.239') { if ($env->version === '4.0.0-beta.239') {
$real_value = $env->real_value; $real_value = $env->real_value;
@@ -781,27 +808,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
if ($this->application->environment_variables->where('key', 'HOST')->isEmpty()) { if ($this->application->environment_variables->where('key', 'HOST')->isEmpty()) {
$envs->push("HOST=0.0.0.0"); $envs->push("HOST=0.0.0.0");
} }
// Add SOURCE_COMMIT if not exists
if ($this->application->environment_variables->where('key', 'SOURCE_COMMIT')->isEmpty()) {
if (!is_null($this->commit)) {
$envs->push("SOURCE_COMMIT={$this->commit}");
} else {
$envs->push("SOURCE_COMMIT=unknown");
}
}
if ($this->application->environment_variables->where('key', 'COOLIFY_FQDN')->isEmpty()) {
$envs->push("COOLIFY_FQDN={$this->application->fqdn}");
}
if ($this->application->environment_variables->where('key', 'COOLIFY_URL')->isEmpty()) {
$url = str($this->application->fqdn)->replace('http://', '')->replace('https://', '');
$envs->push("COOLIFY_URL={$url}");
}
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_BRANCH')->isEmpty()) {
$envs->push("COOLIFY_BRANCH={$this->application->git_branch}");
}
$envs = $envs->sort(function ($a, $b) {
return strpos($a, '$') === false ? -1 : 1;
});
} }
if ($envs->isEmpty()) { if ($envs->isEmpty()) {
@@ -957,9 +963,23 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
"save" => "health_check", "save" => "health_check",
"append" => false "append" => false
], ],
[
"docker inspect --format='{{json .State.Health.Log}}' {$this->container_name}",
"hidden" => true,
"save" => "health_check_logs",
"append" => false
],
); );
$this->application_deployment_queue->addLogEntry("Attempt {$counter} of {$this->application->health_check_retries} | Healthcheck status: {$this->saved_outputs->get('health_check')}"); $this->application_deployment_queue->addLogEntry("Attempt {$counter} of {$this->application->health_check_retries} | Healthcheck status: {$this->saved_outputs->get('health_check')}");
$health_check_logs = data_get(collect(json_decode($this->saved_outputs->get('health_check_logs')))->last(), 'Output', '(no logs)');
if (empty($health_check_logs)) {
$health_check_logs = '(no logs)';
}
$health_check_return_code = data_get(collect(json_decode($this->saved_outputs->get('health_check_logs')))->last(), 'ExitCode', '(no return code)');
if ($health_check_logs !== '(no logs)' || $health_check_return_code !== '(no return code)') {
$this->application_deployment_queue->addLogEntry("Healthcheck logs: {$health_check_logs} | Return code: {$health_check_return_code}");
}
if (Str::of($this->saved_outputs->get('health_check'))->replace('"', '')->value() === 'healthy') { if (Str::of($this->saved_outputs->get('health_check'))->replace('"', '')->value() === 'healthy') {
$this->newVersionIsHealthy = true; $this->newVersionIsHealthy = true;
$this->application->update(['status' => 'running']); $this->application->update(['status' => 'running']);
@@ -993,6 +1013,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
$this->generate_image_names(); $this->generate_image_names();
$this->application_deployment_queue->addLogEntry("Starting pull request (#{$this->pull_request_id}) deployment of {$this->customRepository}:{$this->application->git_branch}."); $this->application_deployment_queue->addLogEntry("Starting pull request (#{$this->pull_request_id}) deployment of {$this->customRepository}:{$this->application->git_branch}.");
$this->prepare_builder_image(); $this->prepare_builder_image();
$this->check_git_if_build_needed();
$this->clone_repository(); $this->clone_repository();
$this->set_base_dir(); $this->set_base_dir();
$this->cleanup_git(); $this->cleanup_git();
@@ -1122,6 +1143,10 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
private function check_git_if_build_needed() private function check_git_if_build_needed()
{ {
$this->generate_git_import_commands(); $this->generate_git_import_commands();
$local_branch = $this->branch;
if ($this->pull_request_id !== 0) {
$local_branch = "pull/{$this->pull_request_id}/head";
}
$private_key = data_get($this->application, 'private_key.private_key'); $private_key = data_get($this->application, 'private_key.private_key');
if ($private_key) { if ($private_key) {
$private_key = base64_encode($private_key); $private_key = base64_encode($private_key);
@@ -1136,7 +1161,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
executeInDocker($this->deployment_uuid, "chmod 600 /root/.ssh/id_rsa") executeInDocker($this->deployment_uuid, "chmod 600 /root/.ssh/id_rsa")
], ],
[ [
executeInDocker($this->deployment_uuid, "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$this->customPort} -o Port={$this->customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git ls-remote {$this->fullRepoUrl} {$this->branch}"), executeInDocker($this->deployment_uuid, "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$this->customPort} -o Port={$this->customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -i /root/.ssh/id_rsa\" git ls-remote {$this->fullRepoUrl} {$local_branch}"),
"hidden" => true, "hidden" => true,
"save" => "git_commit_sha" "save" => "git_commit_sha"
], ],
@@ -1144,12 +1169,13 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
} else { } else {
$this->execute_remote_command( $this->execute_remote_command(
[ [
executeInDocker($this->deployment_uuid, "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$this->customPort} -o Port={$this->customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" git ls-remote {$this->fullRepoUrl} {$this->branch}"), executeInDocker($this->deployment_uuid, "GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$this->customPort} -o Port={$this->customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" git ls-remote {$this->fullRepoUrl} {$local_branch}"),
"hidden" => true, "hidden" => true,
"save" => "git_commit_sha" "save" => "git_commit_sha"
], ],
); );
} }
ray("GIT_SSH_COMMAND=\"ssh -o ConnectTimeout=30 -p {$this->customPort} -o Port={$this->customPort} -o LogLevel=ERROR -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null\" git ls-remote {$this->fullRepoUrl} {$local_branch}");
if ($this->saved_outputs->get('git_commit_sha') && !$this->rollback) { if ($this->saved_outputs->get('git_commit_sha') && !$this->rollback) {
$this->commit = $this->saved_outputs->get('git_commit_sha')->before("\t"); $this->commit = $this->saved_outputs->get('git_commit_sha')->before("\t");
$this->application_deployment_queue->commit = $this->commit; $this->application_deployment_queue->commit = $this->commit;
@@ -1165,6 +1191,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
if ($this->pull_request_id !== 0) { if ($this->pull_request_id !== 0) {
$this->application_deployment_queue->addLogEntry("Checking out tag pull/{$this->pull_request_id}/head."); $this->application_deployment_queue->addLogEntry("Checking out tag pull/{$this->pull_request_id}/head.");
} }
ray($importCommands);
$this->execute_remote_command( $this->execute_remote_command(
[ [
$importCommands, "hidden" => true $importCommands, "hidden" => true
@@ -1178,6 +1205,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
"save" => "commit_message" "save" => "commit_message"
] ]
); );
ray($this->saved_outputs->get('commit_message'));
raY($this->commit);
if ($this->saved_outputs->get('commit_message')) { if ($this->saved_outputs->get('commit_message')) {
$commit_message = str($this->saved_outputs->get('commit_message'))->limit(47); $commit_message = str($this->saved_outputs->get('commit_message'))->limit(47);
$this->application_deployment_queue->commit_message = $commit_message->value(); $this->application_deployment_queue->commit_message = $commit_message->value();
@@ -1272,6 +1301,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
private function generate_env_variables() private function generate_env_variables()
{ {
$this->env_args = collect([]); $this->env_args = collect([]);
$this->env_args->put('SOURCE_COMMIT', $this->commit);
if ($this->pull_request_id === 0) { if ($this->pull_request_id === 0) {
foreach ($this->application->build_environment_variables as $env) { foreach ($this->application->build_environment_variables as $env) {
if (!is_null($env->real_value)) { if (!is_null($env->real_value)) {
@@ -1285,7 +1315,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
} }
} }
} }
$this->env_args->put('SOURCE_COMMIT', $this->commit);
} }
private function generate_compose_file() private function generate_compose_file()
@@ -1967,10 +1996,7 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
if (!$this->only_this_server) { if (!$this->only_this_server) {
$this->deploy_to_additional_destinations(); $this->deploy_to_additional_destinations();
} }
if (!isCloud()) { $this->application->environment->project->team?->notify(new DeploymentSuccess($this->application, $this->deployment_uuid, $this->preview));
// TODO: turn off until we have a better solution
$this->application->environment->project->team?->notify(new DeploymentSuccess($this->application, $this->deployment_uuid, $this->preview));
}
} }
} }

View File

@@ -5,7 +5,7 @@ namespace App\Livewire\Project\Application;
use App\Actions\Application\StopApplication; use App\Actions\Application\StopApplication;
use App\Actions\Docker\GetContainersStatus; use App\Actions\Docker\GetContainersStatus;
use App\Events\ApplicationStatusChanged; use App\Events\ApplicationStatusChanged;
use App\Jobs\ContainerStatusJob; use App\Jobs\ContainerStatusJob;
use App\Jobs\ServerStatusJob; use App\Jobs\ServerStatusJob;
use App\Models\Application; use App\Models\Application;
use Livewire\Component; use Livewire\Component;
@@ -14,6 +14,8 @@ use Visus\Cuid2\Cuid2;
class Heading extends Component class Heading extends Component
{ {
public Application $application; public Application $application;
public ?string $lastDeploymentInfo = null;
public ?string $lastDeploymentLink = null;
public array $parameters; public array $parameters;
protected string $deploymentUuid; protected string $deploymentUuid;
@@ -28,6 +30,9 @@ class Heading extends Component
public function mount() public function mount()
{ {
$this->parameters = get_route_parameters(); $this->parameters = get_route_parameters();
$lastDeployment = $this->application->get_last_successful_deployment();
$this->lastDeploymentInfo = data_get_str($lastDeployment, 'commit')->limit(7) . ' ' . data_get($lastDeployment, 'commit_message');
$this->lastDeploymentLink = $this->application->gitCommitLink(data_get($lastDeployment, 'commit'));
} }
public function check_status($showNotification = false) public function check_status($showNotification = false)

View File

@@ -35,7 +35,7 @@ class BackupEdit extends Component
public function mount() public function mount()
{ {
$this->parameters = get_route_parameters(); $this->parameters = get_route_parameters();
if (is_null($this->backup->s3_storage_id)) { if (is_null(data_get($this->backup, 's3_storage_id'))) {
$this->backup->s3_storage_id = 'default'; $this->backup->s3_storage_id = 'default';
} }
} }

View File

@@ -20,7 +20,7 @@ class BackupExecutions extends Component
public function cleanupFailed() public function cleanupFailed()
{ {
$this->backup->executions()->where('status', 'failed')->delete(); $this->backup?->executions()->where('status', 'failed')->delete();
$this->refreshBackupExecutions(); $this->refreshBackupExecutions();
} }
public function deleteBackup($exeuctionId) public function deleteBackup($exeuctionId)

View File

@@ -5,11 +5,11 @@ namespace App\Livewire\Project\Shared\EnvironmentVariable;
use App\Models\EnvironmentVariable; use App\Models\EnvironmentVariable;
use Livewire\Component; use Livewire\Component;
use Visus\Cuid2\Cuid2; use Visus\Cuid2\Cuid2;
use Illuminate\Support\Str;
class All extends Component class All extends Component
{ {
public $resource; public $resource;
public string $resourceClass;
public bool $showPreview = false; public bool $showPreview = false;
public ?string $modalId = null; public ?string $modalId = null;
public ?string $variables = null; public ?string $variables = null;
@@ -19,17 +19,44 @@ class All extends Component
'refreshEnvs', 'refreshEnvs',
'saveKey' => 'submit', 'saveKey' => 'submit',
]; ];
protected $rules = [
'resource.settings.is_env_sorting_enabled' => 'required|boolean',
];
public function mount() public function mount()
{ {
$resourceClass = get_class($this->resource); $this->resourceClass = get_class($this->resource);
$resourceWithPreviews = ['App\Models\Application']; $resourceWithPreviews = ['App\Models\Application'];
$simpleDockerfile = !is_null(data_get($this->resource, 'dockerfile')); $simpleDockerfile = !is_null(data_get($this->resource, 'dockerfile'));
if (Str::of($resourceClass)->contains($resourceWithPreviews) && !$simpleDockerfile) { if (str($this->resourceClass)->contains($resourceWithPreviews) && !$simpleDockerfile) {
$this->showPreview = true; $this->showPreview = true;
} }
$this->modalId = new Cuid2(7); $this->modalId = new Cuid2(7);
$this->sortMe();
$this->getDevView(); $this->getDevView();
} }
public function sortMe()
{
if ($this->resourceClass === 'App\Models\Application' && data_get($this->resource, 'build_pack') !== 'dockercompose') {
if ($this->resource->settings->is_env_sorting_enabled) {
$this->resource->environment_variables = $this->resource->environment_variables->sortBy('key');
$this->resource->environment_variables_preview = $this->resource->environment_variables_preview->sortBy('key');
} else {
$this->resource->environment_variables = $this->resource->environment_variables->sortBy('id');
$this->resource->environment_variables_preview = $this->resource->environment_variables_preview->sortBy('id');
}
}
$this->getDevView();
}
public function instantSave()
{
if ($this->resourceClass === 'App\Models\Application' && data_get($this->resource, 'build_pack') !== 'dockercompose') {
$this->resource->settings->save();
$this->dispatch('success', 'Environment variable settings updated.');
$this->sortMe();
}
}
public function getDevView() public function getDevView()
{ {
$this->variables = $this->resource->environment_variables->map(function ($item) { $this->variables = $this->resource->environment_variables->map(function ($item) {
@@ -40,7 +67,7 @@ class All extends Component
return "$item->key=(multiline, edit in normal view)"; return "$item->key=(multiline, edit in normal view)";
} }
return "$item->key=$item->value"; return "$item->key=$item->value";
})->sort()->join(' })->join('
'); ');
if ($this->showPreview) { if ($this->showPreview) {
$this->variablesPreview = $this->resource->environment_variables_preview->map(function ($item) { $this->variablesPreview = $this->resource->environment_variables_preview->map(function ($item) {
@@ -51,13 +78,18 @@ class All extends Component
return "$item->key=(multiline, edit in normal view)"; return "$item->key=(multiline, edit in normal view)";
} }
return "$item->key=$item->value"; return "$item->key=$item->value";
})->sort()->join(' })->join('
'); ');
} }
} }
public function switch() public function switch()
{ {
$this->view = $this->view === 'normal' ? 'dev' : 'normal'; if ($this->view === 'normal') {
$this->view = 'dev';
} else {
$this->view = 'normal';
}
$this->sortMe();
} }
public function saveVariables($isPreview) public function saveVariables($isPreview)
{ {
@@ -66,6 +98,7 @@ class All extends Component
$this->resource->environment_variables_preview()->whereNotIn('key', array_keys($variables))->delete(); $this->resource->environment_variables_preview()->whereNotIn('key', array_keys($variables))->delete();
} else { } else {
$variables = parseEnvFormatToArray($this->variables); $variables = parseEnvFormatToArray($this->variables);
ray($variables, $this->variables);
$this->resource->environment_variables()->whereNotIn('key', array_keys($variables))->delete(); $this->resource->environment_variables()->whereNotIn('key', array_keys($variables))->delete();
} }
foreach ($variables as $key => $variable) { foreach ($variables as $key => $variable) {

View File

@@ -13,7 +13,7 @@ class Configuration extends Component
public bool $is_auto_update_enabled; public bool $is_auto_update_enabled;
public bool $is_registration_enabled; public bool $is_registration_enabled;
public bool $is_dns_validation_enabled; public bool $is_dns_validation_enabled;
public bool $next_channel; // public bool $next_channel;
protected string $dynamic_config_path = '/data/coolify/proxy/dynamic'; protected string $dynamic_config_path = '/data/coolify/proxy/dynamic';
protected Server $server; protected Server $server;
@@ -37,7 +37,7 @@ class Configuration extends Component
$this->do_not_track = $this->settings->do_not_track; $this->do_not_track = $this->settings->do_not_track;
$this->is_auto_update_enabled = $this->settings->is_auto_update_enabled; $this->is_auto_update_enabled = $this->settings->is_auto_update_enabled;
$this->is_registration_enabled = $this->settings->is_registration_enabled; $this->is_registration_enabled = $this->settings->is_registration_enabled;
$this->next_channel = $this->settings->next_channel; // $this->next_channel = $this->settings->next_channel;
$this->is_dns_validation_enabled = $this->settings->is_dns_validation_enabled; $this->is_dns_validation_enabled = $this->settings->is_dns_validation_enabled;
} }
@@ -47,12 +47,12 @@ class Configuration extends Component
$this->settings->is_auto_update_enabled = $this->is_auto_update_enabled; $this->settings->is_auto_update_enabled = $this->is_auto_update_enabled;
$this->settings->is_registration_enabled = $this->is_registration_enabled; $this->settings->is_registration_enabled = $this->is_registration_enabled;
$this->settings->is_dns_validation_enabled = $this->is_dns_validation_enabled; $this->settings->is_dns_validation_enabled = $this->is_dns_validation_enabled;
if ($this->next_channel) { // if ($this->next_channel) {
$this->settings->next_channel = false; // $this->settings->next_channel = false;
$this->next_channel = false; // $this->next_channel = false;
} else { // } else {
$this->settings->next_channel = $this->next_channel; // $this->settings->next_channel = $this->next_channel;
} // }
$this->settings->save(); $this->settings->save();
$this->dispatch('success', 'Settings updated!'); $this->dispatch('success', 'Settings updated!');
} }

View File

@@ -3,7 +3,7 @@
namespace App\Livewire; namespace App\Livewire;
use App\Actions\Server\UpdateCoolify; use App\Actions\Server\UpdateCoolify;
use App\Models\InstanceSettings;
use Livewire\Component; use Livewire\Component;
use DanHarrin\LivewireRateLimiting\WithRateLimiting; use DanHarrin\LivewireRateLimiting\WithRateLimiting;
@@ -11,6 +11,7 @@ class Upgrade extends Component
{ {
use WithRateLimiting; use WithRateLimiting;
public bool $showProgress = false; public bool $showProgress = false;
public bool $updateInProgress = false;
public bool $isUpgradeAvailable = false; public bool $isUpgradeAvailable = false;
public string $latestVersion = ''; public string $latestVersion = '';
@@ -22,23 +23,17 @@ class Upgrade extends Component
if (isDev()) { if (isDev()) {
$this->isUpgradeAvailable = true; $this->isUpgradeAvailable = true;
} }
$settings = InstanceSettings::get();
if ($settings->next_channel) {
$this->isUpgradeAvailable = true;
$this->latestVersion = 'next';
}
} }
public function upgrade() public function upgrade()
{ {
try { try {
if ($this->showProgress) { if ($this->updateInProgress) {
return; return;
} }
$this->rateLimit(1, 30); $this->rateLimit(1, 60);
$this->showProgress = true; $this->updateInProgress = true;
UpdateCoolify::run(force: true, async: true); UpdateCoolify::run(force: true, async: true);
$this->dispatch('success', "Updating Coolify to {$this->latestVersion} version...");
} catch (\Throwable $e) { } catch (\Throwable $e) {
return handleError($e, $this); return handleError($e, $this);
} }

View File

@@ -192,6 +192,9 @@ class Application extends BaseModel
public function gitCommitLink($link): string public function gitCommitLink($link): string
{ {
if (!is_null($this->source?->html_url) && !is_null($this->git_repository) && !is_null($this->git_branch)) { if (!is_null($this->source?->html_url) && !is_null($this->git_repository) && !is_null($this->git_branch)) {
if (str($this->source->html_url)->contains('bitbucket')) {
return "{$this->source->html_url}/{$this->git_repository}/commits/{$link}";
}
return "{$this->source->html_url}/{$this->git_repository}/commit/{$link}"; return "{$this->source->html_url}/{$this->git_repository}/commit/{$link}";
} }
if (strpos($this->git_repository, 'git@') === 0) { if (strpos($this->git_repository, 'git@') === 0) {
@@ -454,6 +457,10 @@ class Application extends BaseModel
} }
return false; return false;
} }
public function get_last_successful_deployment()
{
return ApplicationDeploymentQueue::where('application_id', $this->id)->where('status', 'finished')->where('pull_request_id', 0)->orderBy('created_at', 'desc')->first();
}
public function get_last_days_deployments() public function get_last_days_deployments()
{ {
return ApplicationDeploymentQueue::where('application_id', $this->id)->where('created_at', '>=', now()->subDays(7))->orderBy('created_at', 'desc')->get(); return ApplicationDeploymentQueue::where('application_id', $this->id)->where('created_at', '>=', now()->subDays(7))->orderBy('created_at', 'desc')->get();
@@ -989,7 +996,8 @@ class Application extends BaseModel
getFilesystemVolumesFromServer($this, $isInit); getFilesystemVolumesFromServer($this, $isInit);
} }
public function parseHealthcheckFromDockerfile($dockerfile, bool $isInit = false) { public function parseHealthcheckFromDockerfile($dockerfile, bool $isInit = false)
{
if (str($dockerfile)->contains('HEALTHCHECK') && ($this->isHealthcheckDisabled() || $isInit)) { if (str($dockerfile)->contains('HEALTHCHECK') && ($this->isHealthcheckDisabled() || $isInit)) {
$healthcheckCommand = null; $healthcheckCommand = null;
$lines = $dockerfile->toArray(); $lines = $dockerfile->toArray();

View File

@@ -43,7 +43,12 @@ class DeploymentSuccess extends Notification implements ShouldQueue
public function via(object $notifiable): array public function via(object $notifiable): array
{ {
return setNotificationChannels($notifiable, 'deployments'); $channels = setNotificationChannels($notifiable, 'deployments');
if (isCloud()) {
// TODO: Make batch notifications work with email
$channels = array_diff($channels, ['App\Notifications\Channels\EmailChannel']);
}
return $channels;
} }
public function toMail(): MailMessage public function toMail(): MailMessage
{ {

View File

@@ -14,20 +14,22 @@ class TelegramChannel
$buttons = data_get($data, 'buttons', []); $buttons = data_get($data, 'buttons', []);
$telegramToken = data_get($telegramData, 'token'); $telegramToken = data_get($telegramData, 'token');
$chatId = data_get($telegramData, 'chat_id'); $chatId = data_get($telegramData, 'chat_id');
$topicId = null; $topicId = null;
$topicsInstance = get_class($notification); $topicsInstance = get_class($notification);
switch ($topicsInstance) { switch ($topicsInstance) {
case 'App\Notifications\StatusChange':
$topicId = data_get($notifiable, 'telegram_notifications_status_changes_message_thread_id');
break;
case 'App\Notifications\Test': case 'App\Notifications\Test':
$topicId = data_get($notifiable, 'telegram_notifications_test_message_thread_id'); $topicId = data_get($notifiable, 'telegram_notifications_test_message_thread_id');
break; break;
case 'App\Notifications\Deployment': case 'App\Notifications\Application\StatusChanged':
$topicId = data_get($notifiable, 'telegram_notifications_status_changes_message_thread_id');
break;
case 'App\Notifications\Application\DeploymentSuccess':
case 'App\Notifications\Application\DeploymentFailed':
$topicId = data_get($notifiable, 'telegram_notifications_deployments_message_thread_id'); $topicId = data_get($notifiable, 'telegram_notifications_deployments_message_thread_id');
break; break;
case 'App\Notifications\DatabaseBackup': case 'App\Notifications\Database\BackupSuccess':
case 'App\Notifications\Database\BackupFailed':
$topicId = data_get($notifiable, 'telegram_notifications_database_backups_message_thread_id'); $topicId = data_get($notifiable, 'telegram_notifications_database_backups_message_thread_id');
break; break;
} }

View File

@@ -7,7 +7,7 @@ return [
// The release version of your application // The release version of your application
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
'release' => '4.0.0-beta.280', 'release' => '4.0.0-beta.284',
// When left empty or `null` the Laravel environment will be used // When left empty or `null` the Laravel environment will be used
'environment' => config('app.env'), 'environment' => config('app.env'),

View File

@@ -1,3 +1,3 @@
<?php <?php
return '4.0.0-beta.280'; return '4.0.0-beta.284';

View File

@@ -0,0 +1,28 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('application_settings', function (Blueprint $table) {
$table->boolean('is_env_sorting_enabled')->default(true);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('application_settings', function (Blueprint $table) {
$table->dropColumn('is_env_sorting_enabled');
});
}
};

View File

@@ -161,10 +161,11 @@
class="{{ request()->is('storages*') ? 'menu-item-active menu-item' : 'menu-item' }}" class="{{ request()->is('storages*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('storage.index') }}"> href="{{ route('storage.index') }}">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"> <g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
<path d="M4 6a8 3 0 1 0 16 0A8 3 0 1 0 4 6"/> stroke-width="2">
<path d="M4 6v6a8 3 0 0 0 16 0V6"/> <path d="M4 6a8 3 0 1 0 16 0A8 3 0 1 0 4 6" />
<path d="M4 12v6a8 3 0 0 0 16 0v-6"/> <path d="M4 6v6a8 3 0 0 0 16 0V6" />
<path d="M4 12v6a8 3 0 0 0 16 0v-6" />
</g> </g>
</svg> </svg>
S3 Storages S3 Storages
@@ -175,9 +176,11 @@
class="{{ request()->is('shared-variables*') ? 'menu-item-active menu-item' : 'menu-item' }}" class="{{ request()->is('shared-variables*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('shared-variables.index') }}"> href="{{ route('shared-variables.index') }}">
<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24"> <svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 24 24">
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"> <g fill="none" stroke="currentColor" stroke-linecap="round"
<path d="M5 4C2.5 9 2.5 14 5 20M19 4c2.5 5 2.5 10 0 16M9 9h1c1 0 1 1 2.016 3.527C13 15 13 16 14 16h1"/> stroke-linejoin="round" stroke-width="2">
<path d="M8 16c1.5 0 3-2 4-3.5S14.5 9 16 9"/> <path
d="M5 4C2.5 9 2.5 14 5 20M19 4c2.5 5 2.5 10 0 16M9 9h1c1 0 1 1 2.016 3.527C13 15 13 16 14 16h1" />
<path d="M8 16c1.5 0 3-2 4-3.5S14.5 9 16 9" />
</g> </g>
</svg> </svg>
Shared Variables Shared Variables
@@ -318,9 +321,7 @@
<div class="flex-1"></div> <div class="flex-1"></div>
@if (isInstanceAdmin() && !isCloud()) @if (isInstanceAdmin() && !isCloud())
<li> <li>
@persist('upgrade') <livewire:upgrade />
<livewire:upgrade />
@endpersist
</li> </li>
@endif @endif
<li> <li>

View File

@@ -1,5 +1,10 @@
@props([
'lastDeploymentInfo' => null,
'lastDeploymentLink' => null,
'resource' => null,
])
<nav class="flex pt-2 pb-10"> <nav class="flex pt-2 pb-10">
<ol class="flex items-center flex-wrap gap-y-1"> <ol class="flex flex-wrap items-center gap-y-1">
<li class="inline-flex items-center"> <li class="inline-flex items-center">
<div class="flex items-center"> <div class="flex items-center">
<a wire:navigate class="text-xs truncate lg:text-sm" <a wire:navigate class="text-xs truncate lg:text-sm"
@@ -15,7 +20,6 @@
</li> </li>
<li> <li>
<div class="flex items-center"> <div class="flex items-center">
<a class="text-xs truncate lg:text-sm" <a class="text-xs truncate lg:text-sm"
href="{{ route('project.resource.index', ['environment_name' => $this->parameters['environment_name'], 'project_uuid' => $this->parameters['project_uuid']]) }}">{{ $this->parameters['environment_name'] }}</a> href="{{ route('project.resource.index', ['environment_name' => $this->parameters['environment_name'], 'project_uuid' => $this->parameters['project_uuid']]) }}">{{ $this->parameters['environment_name'] }}</a>
<svg aria-hidden="true" class="w-4 h-4 mx-1 font-bold dark:text-warning" fill="currentColor" <svg aria-hidden="true" class="w-4 h-4 mx-1 font-bold dark:text-warning" fill="currentColor"
@@ -40,7 +44,7 @@
@if ($resource->getMorphClass() == 'App\Models\Service') @if ($resource->getMorphClass() == 'App\Models\Service')
<x-status.services :service="$resource" /> <x-status.services :service="$resource" />
@else @else
<x-status.index :resource="$resource" /> <x-status.index :resource="$resource" :lastDeploymentInfo="$lastDeploymentInfo" :lastDeploymentLink="$lastDeploymentLink" />
@endif @endif
</ol> </ol>
</nav> </nav>

View File

@@ -1,9 +1,14 @@
@props([
'lastDeploymentInfo' => null,
'lastDeploymentLink' => null,
'resource' => null,
])
@if (str($resource->status)->startsWith('running')) @if (str($resource->status)->startsWith('running'))
<x-status.running :status="$resource->status" /> <x-status.running :status="$resource->status" :lastDeploymentInfo="$lastDeploymentInfo" :lastDeploymentLink="$lastDeploymentLink" />
@elseif(str($resource->status)->startsWith('restarting') || @elseif(str($resource->status)->startsWith('restarting') ||
str($resource->status)->startsWith('starting') || str($resource->status)->startsWith('starting') ||
str($resource->status)->startsWith('degraded')) str($resource->status)->startsWith('degraded'))
<x-status.restarting :status="$resource->status" /> <x-status.restarting :status="$resource->status" :lastDeploymentInfo="$lastDeploymentInfo" :lastDeploymentLink="$lastDeploymentLink" />
@else @else
<x-status.stopped :status="$resource->status" /> <x-status.stopped :status="$resource->status" />
@endif @endif

View File

@@ -1,12 +1,20 @@
@props([ @props([
'status' => 'Restarting', 'status' => 'Restarting',
'lastDeploymentInfo' => null,
'lastDeploymentLink' => null,
]) ])
<div class="flex items-center"> <div class="flex items-center">
<x-loading wire:loading.delay.longer /> <x-loading wire:loading.delay.longer />
<span wire:loading.remove.delay.longer class="flex items-center"> <span wire:loading.remove.delay.longer class="flex items-center">
<div class="badge badge-warning "></div> <div class="badge badge-warning "></div>
<div class="pl-2 pr-1 text-xs font-bold tracking-wider dark:text-warning"> <div class="pl-2 pr-1 text-xs font-bold tracking-wider dark:text-warning" @if($lastDeploymentInfo) title="{{$lastDeploymentInfo}}" @endif>
{{ str($status)->before(':')->headline() }} @if ($lastDeploymentLink)
<a href="{{ $lastDeploymentLink }}" class="underline cursor-pointer">
{{ str($status)->before(':')->headline() }}
</a>
@else
{{ str($status)->before(':')->headline() }}
@endif
</div> </div>
@if (!str($status)->startsWith('Proxy') && !str($status)->contains('(')) @if (!str($status)->startsWith('Proxy') && !str($status)->contains('('))
<div class="text-xs dark:text-warning">({{ str($status)->after(':') }})</div> <div class="text-xs dark:text-warning">({{ str($status)->after(':') }})</div>

View File

@@ -1,12 +1,20 @@
@props([ @props([
'status' => 'Running', 'status' => 'Running',
'lastDeploymentInfo' => null,
'lastDeploymentLink' => null,
]) ])
<div class="flex items-center"> <div class="flex items-center">
<x-loading wire:loading.delay.longer /> <x-loading wire:loading.delay.longer />
<span wire:loading.remove.delay.longer class="flex items-center"> <span wire:loading.remove.delay.longer class="flex items-center">
<div class="badge badge-success "></div> <div class="badge badge-success "></div>
<div class="pl-2 pr-1 text-xs font-bold tracking-wider text-success"> <div class="pl-2 pr-1 text-xs font-bold tracking-wider text-success" @if($lastDeploymentInfo) title="{{$lastDeploymentInfo}}" @endif>
@if ($lastDeploymentLink)
<a href="{{ $lastDeploymentLink }}" class="underline cursor-pointer">
{{ str($status)->before(':')->headline() }}
</a>
@else
{{ str($status)->before(':')->headline() }} {{ str($status)->before(':')->headline() }}
@endif
</div> </div>
@if (!str($status)->startsWith('Proxy') && !str($status)->contains('(')) @if (!str($status)->startsWith('Proxy') && !str($status)->contains('('))
@if (str($status)->contains('unhealthy')) @if (str($status)->contains('unhealthy'))
@@ -17,8 +25,6 @@
</svg> </svg>
</x-slot:icon> </x-slot:icon>
</x-helper> </x-helper>
{{-- @else
<div class="text-xs dark:text-success">({{ str($status)->after(':') }})</div> --}}
@endif @endif
@endif @endif
</span> </span>

View File

@@ -98,47 +98,6 @@
} }
} }
function revive() {
if (checkHealthInterval) return true;
console.log('Checking server\'s health...')
checkHealthInterval = setInterval(() => {
fetch('/api/health')
.then(response => {
if (response.ok) {
window.toast('Coolify is back online. Reloading...', {
type: 'success',
})
if (checkHealthInterval) clearInterval(checkHealthInterval);
setTimeout(() => {
window.location.reload();
}, 5000)
} else {
console.log('Waiting for server to come back from dead...');
}
})
}, 2000);
}
function upgrade() {
if (checkIfIamDeadInterval) return true;
console.log('Update initiated.')
checkIfIamDeadInterval = setInterval(() => {
fetch('/api/health')
.then(response => {
if (response.ok) {
console.log('It\'s alive. Waiting for server to be dead...');
} else {
window.toast('Update done, restarting Coolify!', {
type: 'success',
})
console.log('It\'s dead. Reviving... Standby... Bzz... Bzz...')
if (checkIfIamDeadInterval) clearInterval(checkIfIamDeadInterval);
revive();
}
})
}, 2000);
}
function copyToClipboard(text) { function copyToClipboard(text) {
navigator?.clipboard?.writeText(text) && window.Livewire.dispatch('success', 'Copied to clipboard.'); navigator?.clipboard?.writeText(text) && window.Livewire.dispatch('success', 'Copied to clipboard.');
} }

View File

@@ -7,7 +7,7 @@
Save Save
</x-forms.button> </x-forms.button>
@if ($team->telegram_enabled) @if ($team->telegram_enabled)
<x-forms.button class="dark:text-white normal-case btn btn-xs no-animation btn-primary" <x-forms.button class="normal-case dark:text-white btn btn-xs no-animation btn-primary"
wire:click="sendTestNotification"> wire:click="sendTestNotification">
Send Test Notifications Send Test Notifications
</x-forms.button> </x-forms.button>
@@ -18,40 +18,44 @@
</div> </div>
<div class="flex gap-2"> <div class="flex gap-2">
<x-forms.input type="password" <x-forms.input type="password"
helper="Get it from the <a class='inline-block dark:text-white underline' href='https://t.me/botfather' target='_blank'>BotFather Bot</a> on Telegram." helper="Get it from the <a class='inline-block underline dark:text-white' href='https://t.me/botfather' target='_blank'>BotFather Bot</a> on Telegram."
required id="team.telegram_token" label="Token" /> required id="team.telegram_token" label="Token" />
<x-forms.input helper="Recommended to add your bot to a group chat and add its Chat ID here." required <x-forms.input helper="Recommended to add your bot to a group chat and add its Chat ID here." required
id="team.telegram_chat_id" label="Chat ID" /> id="team.telegram_chat_id" label="Chat ID" />
</div> </div>
@if (data_get($team, 'telegram_enabled')) @if (data_get($team, 'telegram_enabled'))
<h2 class="mt-4">Subscribe to events</h2> <h2 class="mt-4">Subscribe to events</h2>
<div class="w-96"> <div class="flex flex-col gap-4 w-96">
@if (isDev()) @if (isDev())
<div class="w-64"> <div class="flex flex-col">
<h4>Test Notification</h4>
<x-forms.checkbox instantSave="saveModel" id="team.telegram_notifications_test" <x-forms.checkbox instantSave="saveModel" id="team.telegram_notifications_test"
label="Test" /> label="Enabled" />
<x-forms.input <x-forms.input
helper="If you are using Group chat with Topics, you can specify the topics ID. If empty, General topic will be used." helper="If you are using Group chat with Topics, you can specify the topics ID. If empty, General topic will be used."
id="team.telegram_notifications_test_message_thread_id" label="Custom Topic ID" /> id="team.telegram_notifications_test_message_thread_id" label="Custom Topic ID" />
</div> </div>
@endif @endif
<div class="w-64"> <div class="flex flex-col">
<h4>Container Status Changes</h4>
<x-forms.checkbox instantSave="saveModel" id="team.telegram_notifications_status_changes" <x-forms.checkbox instantSave="saveModel" id="team.telegram_notifications_status_changes"
label="Container Status Changes" /> label="Enabled" />
<x-forms.input <x-forms.input
helper="If you are using Group chat with Topics, you can specify the topics ID. If empty, General topic will be used." helper="If you are using Group chat with Topics, you can specify the topics ID. If empty, General topic will be used."
id="team.telegram_notifications_status_changes_message_thread_id" label="Custom Topic ID" /> id="team.telegram_notifications_status_changes_message_thread_id" label="Custom Topic ID" />
</div> </div>
<div class="w-64"> <div class="flex flex-col">
<h4>Application Deployments</h4>
<x-forms.checkbox instantSave="saveModel" id="team.telegram_notifications_deployments" <x-forms.checkbox instantSave="saveModel" id="team.telegram_notifications_deployments"
label="Application Deployments" /> label="Enabled" />
<x-forms.input <x-forms.input
helper="If you are using Group chat with Topics, you can specify the topics ID. If empty, General topic will be used." helper="If you are using Group chat with Topics, you can specify the topics ID. If empty, General topic will be used."
id="team.telegram_notifications_deployments_message_thread_id" label="Custom Topic ID" /> id="team.telegram_notifications_deployments_message_thread_id" label="Custom Topic ID" />
</div> </div>
<div class="w-64"> <div class="flex flex-col">
<h4>Database Backup Status</h4>
<x-forms.checkbox instantSave="saveModel" id="team.telegram_notifications_database_backups" <x-forms.checkbox instantSave="saveModel" id="team.telegram_notifications_database_backups"
label="Backup Status" /> label="Enabled" />
<x-forms.input <x-forms.input
helper="If you are using Group chat with Topics, you can specify the topics ID. If empty, General topic will be used." helper="If you are using Group chat with Topics, you can specify the topics ID. If empty, General topic will be used."
id="team.telegram_notifications_database_backups_message_thread_id" label="Custom Topic ID" /> id="team.telegram_notifications_database_backups_message_thread_id" label="Custom Topic ID" />

View File

@@ -1,5 +1,5 @@
<nav wire:poll.5000ms="check_status"> <nav wire:poll.5000ms="check_status">
<x-resources.breadcrumbs :resource="$application" :parameters="$parameters" /> <x-resources.breadcrumbs :resource="$application" :parameters="$parameters" :lastDeploymentInfo="$lastDeploymentInfo" :lastDeploymentLink="$lastDeploymentLink" />
<div class="navbar-main"> <div class="navbar-main">
<nav class="flex items-center flex-shrink-0 gap-6 scrollbar min-h-10 whitespace-nowrap"> <nav class="flex items-center flex-shrink-0 gap-6 scrollbar min-h-10 whitespace-nowrap">
<a href="{{ route('project.application.configuration', $parameters) }}"> <a href="{{ route('project.application.configuration', $parameters) }}">

View File

@@ -11,12 +11,18 @@
wire:click='switch'>{{ $view === 'normal' ? 'Developer view' : 'Normal view' }}</x-forms.button> wire:click='switch'>{{ $view === 'normal' ? 'Developer view' : 'Normal view' }}</x-forms.button>
</div> </div>
<div>Environment variables (secrets) for this resource.</div> <div>Environment variables (secrets) for this resource.</div>
@if ($this->resourceClass === 'App\Models\Application' && data_get($this->resource, 'build_pack') !== 'dockercompose')
<div class="w-64 pt-2">
<x-forms.checkbox id="resource.settings.is_env_sorting_enabled" label="Sort alphabetically"
helper="Turn this off if one environment is dependent on an other. It will be sorted by creation order." instantSave></x-forms.checkbox>
</div>
@endif
@if ($resource->type() === 'service' || $resource?->build_pack === 'dockercompose') @if ($resource->type() === 'service' || $resource?->build_pack === 'dockercompose')
<div class="pt-4 dark:text-warning text-coollabs">Hardcoded variables are not shown here.</div> <div class="pt-4 dark:text-warning text-coollabs">Hardcoded variables are not shown here.</div>
@endif @endif
</div> </div>
@if ($view === 'normal') @if ($view === 'normal')
@forelse ($resource->environment_variables->sort()->sortBy('key') as $env) @forelse ($resource->environment_variables as $env)
<livewire:project.shared.environment-variable.show wire:key="environment-{{ $env->id }}" <livewire:project.shared.environment-variable.show wire:key="environment-{{ $env->id }}"
:env="$env" :type="$resource->type()" /> :env="$env" :type="$resource->type()" />
@empty @empty
@@ -27,7 +33,7 @@
<h3>Preview Deployments</h3> <h3>Preview Deployments</h3>
<div>Environment (secrets) variables for Preview Deployments.</div> <div>Environment (secrets) variables for Preview Deployments.</div>
</div> </div>
@foreach ($resource->environment_variables_preview->sort()->sortBy('key') as $env) @foreach ($resource->environment_variables_preview as $env)
<livewire:project.shared.environment-variable.show wire:key="environment-{{ $env->id }}" <livewire:project.shared.environment-variable.show wire:key="environment-{{ $env->id }}"
:env="$env" :type="$resource->type()" /> :env="$env" :type="$resource->type()" />
@endforeach @endforeach

View File

@@ -9,7 +9,7 @@
<div>General configuration for your Coolify instance.</div> <div>General configuration for your Coolify instance.</div>
<div class="flex flex-col gap-2 pt-4"> <div class="flex flex-col gap-2 pt-4">
<div class="flex items-end gap-2 flex-wrap"> <div class="flex flex-wrap items-end gap-2">
<x-forms.input id="settings.fqdn" label="Instance's Domain" placeholder="https://coolify.io" /> <x-forms.input id="settings.fqdn" label="Instance's Domain" placeholder="https://coolify.io" />
<x-forms.input id="settings.custom_dns_servers" label="DNS Servers" <x-forms.input id="settings.custom_dns_servers" label="DNS Servers"
helper="DNS servers for validation FQDNs againts. A comma separated list of DNS servers." helper="DNS servers for validation FQDNs againts. A comma separated list of DNS servers."
@@ -35,13 +35,13 @@
@endif @endif
<x-forms.checkbox instantSave id="is_registration_enabled" label="Registration Allowed" /> <x-forms.checkbox instantSave id="is_registration_enabled" label="Registration Allowed" />
<x-forms.checkbox instantSave id="do_not_track" label="Do Not Track" /> <x-forms.checkbox instantSave id="do_not_track" label="Do Not Track" />
@if ($next_channel) {{-- @if ($next_channel)
<x-forms.checkbox instantSave helper="Not recommended. Only if you like to live on the edge." <x-forms.checkbox instantSave helper="Not recommended. Only if you like to live on the edge."
id="next_channel" label="Enable pre-release (early) updates" /> id="next_channel" label="Enable pre-release (early) updates" />
@else @else
<x-forms.checkbox disabled instantSave <x-forms.checkbox disabled instantSave
helper="Currently disabled. Not recommended. Only if you like to live on the edge." id="next_channel" helper="Currently disabled. Not recommended. Only if you like to live on the edge." id="next_channel"
label="Enable pre-release (early) updates" /> label="Enable pre-release (early) updates" />
@endif @endif --}}
</div> </div>
</div> </div>

View File

@@ -1,29 +1,139 @@
<div @if ($isUpgradeAvailable) title="New version available" @else title="No upgrade available" @endif <div @if ($isUpgradeAvailable) title="New version available" @else title="No upgrade available" @endif
x-init="$wire.checkUpdate" x-data> x-init="$wire.checkUpdate" x-data="upgradeModal">
@if ($isUpgradeAvailable) @if ($isUpgradeAvailable)
<button wire:key="upgrade" wire:click='upgrade' class="menu-item" x-on:click="upgrade"> <div :class="{ 'z-40': modalOpen }" class="relative w-auto h-auto">
@if ($showProgress) <button class="menu-item" @click="modalOpen=true">
<svg xmlns="http://www.w3.org/2000/svg" @if ($showProgress)
class="w-6 h-6 text-pink-500 transition-colors hover:text-pink-300 lds-heart" viewBox="0 0 24 24" <svg xmlns="http://www.w3.org/2000/svg"
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" class="w-6 h-6 text-pink-500 transition-colors hover:text-pink-300 lds-heart" viewBox="0 0 24 24"
stroke-linejoin="round"> stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> stroke-linejoin="round">
<path d="M19.5 13.572l-7.5 7.428l-7.5 -7.428m0 0a5 5 0 1 1 7.5 -6.566a5 5 0 1 1 7.5 6.572" /> <path stroke="none" d="M0 0h24v24H0z" fill="none" />
</svg> <path d="M19.5 13.572l-7.5 7.428l-7.5 -7.428m0 0a5 5 0 1 1 7.5 -6.566a5 5 0 1 1 7.5 6.572" />
In progress </svg>
@else In progress
<svg xmlns="http://www.w3.org/2000/svg" @else
class="w-6 h-6 text-pink-500 transition-colors hover:text-pink-300" viewBox="0 0 24 24" <svg xmlns="http://www.w3.org/2000/svg"
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round" class="w-6 h-6 text-pink-500 transition-colors hover:text-pink-300" viewBox="0 0 24 24"
stroke-linejoin="round"> stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
<path stroke="none" d="M0 0h24v24H0z" fill="none" /> stroke-linejoin="round">
<path <path stroke="none" d="M0 0h24v24H0z" fill="none" />
d="M9 12h-3.586a1 1 0 0 1 -.707 -1.707l6.586 -6.586a1 1 0 0 1 1.414 0l6.586 6.586a1 1 0 0 1 -.707 1.707h-3.586v3h-6v-3z" /> <path
<path d="M9 21h6" /> d="M9 12h-3.586a1 1 0 0 1 -.707 -1.707l6.586 -6.586a1 1 0 0 1 1.414 0l6.586 6.586a1 1 0 0 1 -.707 1.707h-3.586v3h-6v-3z" />
<path d="M9 18h6" /> <path d="M9 21h6" />
</svg> <path d="M9 18h6" />
Upgrade </svg>
@endif Upgrade
</button> @endif
</button>
<template x-teleport="body">
<div x-show="modalOpen"
class="fixed top-0 lg:pt-10 left-0 z-[99] flex items-start justify-center w-screen h-screen"
x-cloak>
<div x-show="modalOpen" x-transition:enter="ease-out duration-100"
x-transition:enter-start="opacity-0" x-transition:enter-end="opacity-100"
x-transition:leave="ease-in duration-100" x-transition:leave-start="opacity-100"
x-transition:leave-end="opacity-0"
class="absolute inset-0 w-full h-full bg-black bg-opacity-20 backdrop-blur-sm"></div>
<div x-show="modalOpen" x-trap.inert.noscroll="modalOpen" x-transition:enter="ease-out duration-100"
x-transition:enter-start="opacity-0 -translate-y-2 sm:scale-95"
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
x-transition:leave="ease-in duration-100"
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
x-transition:leave-end="opacity-0 -translate-y-2 sm:scale-95"
class="relative w-full py-6 border rounded min-w-full lg:min-w-[36rem] max-w-fit bg-neutral-100 border-neutral-400 dark:bg-base px-7 dark:border-coolgray-300">
<div class="flex items-center justify-between pb-3">
<h3 class="text-lg font-semibold">Upgrade confirmation</h3>
@if (!$showProgress)
<button @click="modalOpen=false"
class="absolute top-0 right-0 flex items-center justify-center w-8 h-8 mt-5 mr-5 text-gray-600 rounded-full hover:text-gray-800 hover:bg-gray-50">
<svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" fill="none"
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
@endif
</div>
<div class="relative w-auto pb-8">
<p>Are you sure you would like to upgrade your instance to {{ $latestVersion }}?</p>
<br />
<p>You can review the changelogs <a class="font-bold underline"
href="https://github.com/coollabsio/coolify/releases" target="_blank">here</a>.</p>
@if ($showProgress)
<div class="flex flex-col pt-4">
<h4>Progress <x-loading /></h4>
<div x-html="currentStatus"></div>
</div>
@endif
</div>
<div class="flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2">
@if (!$showProgress)
<x-forms.button @click="modalOpen=false"
class="w-24 dark:bg-coolgray-200 dark:hover:bg-coolgray-300">Cancel
</x-forms.button>
<x-forms.button @click="confirmed" class="w-24" isHighlighted type="button">Continue
</x-forms.button>
@endif
</div>
</div>
</div>
</template>
</div>
@endif @endif
</div> </div>
<script>
document.addEventListener('alpine:init', () => {
Alpine.data('upgradeModal', () => ({
modalOpen: false,
showProgress: @js($showProgress),
currentStatus: '',
confirmed() {
this.$wire.$call('upgrade')
this.upgrade();
this.$wire.showProgress = true;
},
revive() {
if (checkHealthInterval) return true;
console.log('Checking server\'s health...')
checkHealthInterval = setInterval(() => {
fetch('/api/health')
.then(response => {
if (response.ok) {
this.currentStatus =
'Coolify is back online. Reloading this page (you can manually reload if its not done automatically)...';
if (checkHealthInterval) clearInterval(
checkHealthInterval);
setTimeout(() => {
window.location.reload();
}, 5000)
} else {
this.currentStatus =
"Waiting for Coolify to come back from dead..."
}
})
}, 2000);
},
upgrade() {
if (checkIfIamDeadInterval || this.$wire.showProgress) return true;
this.currentStatus = 'Pulling new images and updating Coolify.';
checkIfIamDeadInterval = setInterval(() => {
fetch('/api/health')
.then(response => {
if (response.ok) {
this.currentStatus = "Waiting for the update process..."
} else {
this.currentStatus =
"Update done, restarting Coolify & waiting until it is revived!"
if (checkIfIamDeadInterval) clearInterval(
checkIfIamDeadInterval);
this.revive();
}
})
}, 2000);
}
}))
})
</script>

View File

@@ -135,7 +135,6 @@ if [ "$SSH_PERMIT_ROOT_LOGIN" != "true" ]; then
echo "WARNING: PermitRootLogin is not enabled in /etc/ssh/sshd_config." echo "WARNING: PermitRootLogin is not enabled in /etc/ssh/sshd_config."
echo -e "It is set to $SSH_PERMIT_ROOT_LOGIN_CONFIG. Should be prohibit-password, yes or without-password.\n" echo -e "It is set to $SSH_PERMIT_ROOT_LOGIN_CONFIG. Should be prohibit-password, yes or without-password.\n"
echo -e "Please make sure it is set, otherwise Coolify cannot connect to the host system. \n" echo -e "Please make sure it is set, otherwise Coolify cannot connect to the host system. \n"
echo "(Currently we only support root user to login via SSH, this will be changed in the future.)"
echo "###############################################################################" echo "###############################################################################"
fi fi

View File

@@ -32,7 +32,7 @@ services:
redis: redis:
condition: service_started condition: service_started
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"] test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -16,7 +16,7 @@ services:
volumes: volumes:
- stacks-data:/appsmith-stacks - stacks-data:/appsmith-stacks
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"] test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -15,7 +15,7 @@ services:
volumes: volumes:
- babybuddy-config:/config - babybuddy-config:/config
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000"] test: ["CMD", "curl", "-f", "http://127.0.0.1:8000"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -13,7 +13,7 @@ services:
volumes: volumes:
- budge-config:/config - budge-config:/config
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"] test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -17,7 +17,7 @@ services:
depends_on: depends_on:
- mariadb - mariadb
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] test: ["CMD", "curl", "-f", "http://127.0.0.1"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 10 retries: 10

View File

@@ -17,7 +17,7 @@ services:
depends_on: depends_on:
- mysql - mysql
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] test: ["CMD", "curl", "-f", "http://127.0.0.1"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 10 retries: 10
@@ -31,7 +31,7 @@ services:
- MYSQL_USER=$SERVICE_USER_CLASSICPRESS - MYSQL_USER=$SERVICE_USER_CLASSICPRESS
- MYSQL_PASSWORD=$SERVICE_PASSWORD_CLASSICPRESS - MYSQL_PASSWORD=$SERVICE_PASSWORD_CLASSICPRESS
healthcheck: healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -11,7 +11,7 @@ services:
environment: environment:
- SERVICE_FQDN_CLASSICPRESS - SERVICE_FQDN_CLASSICPRESS
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] test: ["CMD", "curl", "-f", "http://127.0.0.1"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 10 retries: 10

View File

@@ -18,7 +18,7 @@ services:
volumes: volumes:
- code-server-config:/config - code-server-config:/config
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8443"] test: ["CMD", "curl", "-f", "http://127.0.0.1:8443"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -11,7 +11,7 @@ services:
volumes: volumes:
- dashboard-data:/app/data - dashboard-data:/app/data
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080"] test: ["CMD", "curl", "-f", "http://127.0.0.1:8080"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -26,7 +26,7 @@ services:
- REDIS_PORT=6379 - REDIS_PORT=6379
- WEBSOCKETS_ENABLED=true - WEBSOCKETS_ENABLED=true
healthcheck: healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8055/admin/login"] test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:8055/admin/login"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -22,7 +22,7 @@ services:
- WEBSOCKETS_ENABLED=true - WEBSOCKETS_ENABLED=true
healthcheck: healthcheck:
test: test:
["CMD", "wget", "-q", "--spider", "http://localhost:8055/admin/login"] ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:8055/admin/login"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -14,7 +14,7 @@ services:
volumes: volumes:
- dokuwiki-config:/config - dokuwiki-config:/config
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"] test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -16,7 +16,7 @@ services:
- duplicati-config:/config - duplicati-config:/config
- duplicati-backups:/backups - duplicati-backups:/backups
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8200"] test: ["CMD", "curl", "-f", "http://127.0.0.1:8200"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -17,7 +17,7 @@ services:
- emby-tvshows:/tvshows - emby-tvshows:/tvshows
- emby-movies:/movies - emby-movies:/movies
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8096"] test: ["CMD", "curl", "-f", "http://127.0.0.1:8096"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -14,7 +14,7 @@ services:
volumes: volumes:
- embystat-config:/config - embystat-config:/config
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:6555"] test: ["CMD", "curl", "-f", "http://127.0.0.1:6555"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -20,7 +20,7 @@ services:
read_only: true read_only: true
content: "{}" content: "{}"
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"] test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -21,7 +21,7 @@ services:
volumes: volumes:
- firefly-upload:/var/www/html/storage/upload - firefly-upload:/var/www/html/storage/upload
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080"] test: ["CMD", "curl", "-f", "http://127.0.0.1:8080"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10
@@ -42,7 +42,7 @@ services:
"mysqladmin", "mysqladmin",
"ping", "ping",
"-h", "-h",
"localhost", "127.0.0.1",
"-uroot", "-uroot",
"-p${SERVICE_PASSWORD_MYSQLROOT}", "-p${SERVICE_PASSWORD_MYSQLROOT}",
] ]

View File

@@ -42,7 +42,7 @@ services:
postgresql: postgresql:
condition: service_healthy condition: service_healthy
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"] test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -41,7 +41,7 @@ services:
- MYSQL_DATABASE=${MYSQL_DATABASE} - MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT} - MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT}
healthcheck: healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -25,7 +25,7 @@ services:
mariadb: mariadb:
condition: service_healthy condition: service_healthy
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"] test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -25,7 +25,7 @@ services:
mysql: mysql:
condition: service_healthy condition: service_healthy
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"] test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15
@@ -40,7 +40,7 @@ services:
- MYSQL_DATABASE=${MYSQL_DATABASE} - MYSQL_DATABASE=${MYSQL_DATABASE}
- MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT} - MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MYSQLROOT}
healthcheck: healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -25,7 +25,7 @@ services:
postgresql: postgresql:
condition: service_healthy condition: service_healthy
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"] test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -17,7 +17,7 @@ services:
- gitea-timezone:/etc/timezone:ro - gitea-timezone:/etc/timezone:ro
- gitea-localtime:/etc/localtime:ro - gitea-localtime:/etc/localtime:ro
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"] test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -20,7 +20,7 @@ services:
volumes: volumes:
- grafana-data:/var/lib/grafana - grafana-data:/var/lib/grafana
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"] test: ["CMD", "curl", "-f", "http://127.0.0.1:3000/api/health"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -15,7 +15,7 @@ services:
volumes: volumes:
- grafana-data:/var/lib/grafana - grafana-data:/var/lib/grafana
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"] test: ["CMD", "curl", "-f", "http://127.0.0.1:3000/api/health"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -14,7 +14,7 @@ services:
volumes: volumes:
- grocy-config:/config - grocy-config:/config
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"] test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -13,7 +13,7 @@ services:
volumes: volumes:
- heimdall-config:/config - heimdall-config:/config
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"] test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -23,7 +23,7 @@ services:
- DB_USERNAME=${SERVICE_USER_MYSQL} - DB_USERNAME=${SERVICE_USER_MYSQL}
- DB_PASSWORD=${SERVICE_PASSWORD_MYSQL} - DB_PASSWORD=${SERVICE_PASSWORD_MYSQL}
healthcheck: healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:9000'] test: ['CMD', 'curl', '-f', 'http://127.0.0.1:9000']
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10
@@ -94,7 +94,7 @@ services:
"mysqladmin", "mysqladmin",
"ping", "ping",
"-h", "-h",
"localhost", "127.0.0.1",
"-uroot", "-uroot",
"-p${SERVICE_PASSWORD_MYSQLROOT}", "-p${SERVICE_PASSWORD_MYSQLROOT}",
] ]

View File

@@ -18,7 +18,7 @@ services:
- jellyfin-tvshows:/data/tvshows - jellyfin-tvshows:/data/tvshows
- jellyfin-movies:/data/movies - jellyfin-movies:/data/movies
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8096"] test: ["CMD", "curl", "-f", "http://127.0.0.1:8096"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -18,7 +18,7 @@ services:
elasticsearch: elasticsearch:
image: kuzzleio/elasticsearch:7 image: kuzzleio/elasticsearch:7
healthcheck: healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:9200" ] test: [ "CMD", "curl", "-f", "http://127.0.0.1:9200" ]
interval: 2s interval: 2s
timeout: 2s timeout: 2s
retries: 10 retries: 10
@@ -51,7 +51,7 @@ services:
sysctls: sysctls:
- net.core.somaxconn=8192 - net.core.somaxconn=8192
healthcheck: healthcheck:
test: [ "CMD", "curl", "-f", "http://localhost:7512/_healthcheck" ] test: [ "CMD", "curl", "-f", "http://127.0.0.1:7512/_healthcheck" ]
timeout: 1s timeout: 1s
interval: 2s interval: 2s
retries: 30 retries: 30

View File

@@ -18,7 +18,7 @@ services:
- ENDPOINT=$LOGTO_ENDPOINT - ENDPOINT=$LOGTO_ENDPOINT
- ADMIN_ENDPOINT=$LOGTO_ADMIN_ENDPOINT - ADMIN_ENDPOINT=$LOGTO_ADMIN_ENDPOINT
healthcheck: healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:3002"] test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3002"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -15,7 +15,7 @@ services:
volumes: volumes:
- meilisearch-data:/meili_data - meilisearch-data:/meili_data
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:7700/health"] test: ["CMD", "curl", "-f", "http://127.0.0.1:7700/health"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -18,7 +18,7 @@ services:
- MB_DB_USER=$SERVICE_USER_POSTGRESQL - MB_DB_USER=$SERVICE_USER_POSTGRESQL
- MB_DB_PASS=$SERVICE_PASSWORD_POSTGRESQL - MB_DB_PASS=$SERVICE_PASSWORD_POSTGRESQL
healthcheck: healthcheck:
test: curl --fail -I http://localhost:3000/api/health || exit 1 test: curl --fail -I http://127.0.0.1:3000/api/health || exit 1
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -13,7 +13,7 @@ services:
volumes: volumes:
- metube-downloads:/downloads - metube-downloads:/downloads
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8081"] test: ["CMD", "curl", "-f", "http://127.0.0.1:8081"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -15,7 +15,7 @@ services:
volumes: volumes:
- minio-data:/data - minio-data:/data
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] test: ["CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -27,7 +27,7 @@ services:
postgresql: postgresql:
condition: service_healthy condition: service_healthy
healthcheck: healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:5678/"] test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:5678/"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -17,7 +17,7 @@ services:
volumes: volumes:
- n8n-data:/home/node/.n8n - n8n-data:/home/node/.n8n
healthcheck: healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:5678/"] test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:5678/"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -12,7 +12,7 @@ services:
- ALLOWED_REMOTE_DOMAINS=${ALLOWED_REMOTE_DOMAINS:-*} - ALLOWED_REMOTE_DOMAINS=${ALLOWED_REMOTE_DOMAINS:-*}
- IMGPROXY_URL=${IMGPROXY_URL:-http://imgproxy:8080} - IMGPROXY_URL=${IMGPROXY_URL:-http://imgproxy:8080}
healthcheck: healthcheck:
test: "wget -qO- http://localhost:3000/health || exit 1" test: "wget -qO- http://127.0.0.1:3000/health || exit 1"
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 5 retries: 5

View File

@@ -15,7 +15,7 @@ services:
- nextcloud-config:/config - nextcloud-config:/config
- nextcloud-data:/data - nextcloud-data:/data
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"] test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -12,7 +12,7 @@ services:
volumes: volumes:
- nocodb-data:/usr/app/data/ - nocodb-data:/usr/app/data/
healthcheck: healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080"] test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:8080"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -15,7 +15,7 @@ services:
volumes: volumes:
- odoo-web-data:/var/lib/odoo - odoo-web-data:/var/lib/odoo
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8069"] test: ["CMD", "curl", "-f", "http://127.0.0.1:8069"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 30 retries: 30

View File

@@ -15,7 +15,7 @@ services:
volumes: volumes:
- openblocks-data:/openblocks-stacks - openblocks-data:/openblocks-stacks
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"] test: ["CMD", "curl", "-f", "http://127.0.0.1:3000/health"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -13,7 +13,7 @@ services:
- TZ=Europe/Madrid - TZ=Europe/Madrid
- DEBUG_MODE=false - DEBUG_MODE=false
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"] test: ["CMD", "curl", "-f", "http://127.0.0.1:3000"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -14,7 +14,7 @@ services:
- SERVICE_FQDN_FRONTEND - SERVICE_FQDN_FRONTEND
- PENPOT_FLAGS=${PENPOT_FRONTEND_FLAGS:-enable-login-with-password} - PENPOT_FLAGS=${PENPOT_FRONTEND_FLAGS:-enable-login-with-password}
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"] test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15
@@ -48,7 +48,7 @@ services:
- PENPOT_SMTP_TLS=${PENPOT_SMTP_TLS:-false} - PENPOT_SMTP_TLS=${PENPOT_SMTP_TLS:-false}
- PENPOT_SMTP_SSL=${PENPOT_SMTP_SSL:-false} - PENPOT_SMTP_SSL=${PENPOT_SMTP_SSL:-false}
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:6060"] test: ["CMD", "curl", "-f", "http://127.0.0.1:6060"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -16,7 +16,7 @@ services:
volumes: volumes:
- phpmyadmin-config:/config - phpmyadmin-config:/config
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"] test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -51,7 +51,7 @@ services:
volumes: volumes:
- minio-data:/data - minio-data:/data
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] test: ["CMD", "curl", "-f", "http://127.0.0.1:9000/minio/health/live"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -14,7 +14,7 @@ services:
volumes: volumes:
- shlink-data:/etc/shlink/data - shlink-data:/etc/shlink/data
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/rest/v3/health"] test: ["CMD", "curl", "-f", "http://127.0.0.1:8080/rest/v3/health"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15
@@ -25,7 +25,7 @@ services:
- SHLINK_SERVER_API_KEY=${SERVICE_BASE64_SHLINKAPIKEY} - SHLINK_SERVER_API_KEY=${SERVICE_BASE64_SHLINKAPIKEY}
- SHLINK_SERVER_URL=${SERVICE_FQDN_SHLINK} - SHLINK_SERVER_URL=${SERVICE_FQDN_SHLINK}
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080"] test: ["CMD", "curl", "-f", "http://127.0.0.1:8080"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -11,7 +11,7 @@ services:
volumes: volumes:
- slash-data:/var/opt/slash - slash-data:/var/opt/slash
healthcheck: healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:5231"] test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:5231"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -13,7 +13,7 @@ services:
volumes: volumes:
- snapdrop-config:/config - snapdrop-config:/config
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"] test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -16,7 +16,7 @@ services:
- SERVICE_FQDN_SPDF_8080 - SERVICE_FQDN_SPDF_8080
- DOCKER_ENABLE_SECURITY=false - DOCKER_ENABLE_SECURITY=false
healthcheck: healthcheck:
test: 'curl --fail -I http://localhost:8080 || exit 1' test: 'curl --fail -I http://127.0.0.1:8080 || exit 1'
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -285,7 +285,7 @@ services:
"CMD", "CMD",
"node", "node",
"-e", "-e",
"require('http').get('http://localhost:3000/api/profile', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})", "require('http').get('http://127.0.0.1:3000/api/profile', (r) => {if (r.statusCode !== 200) throw new Error(r.statusCode)})",
] ]
timeout: 5s timeout: 5s
interval: 5s interval: 5s
@@ -316,7 +316,7 @@ services:
supabase-db: supabase-db:
image: supabase/postgres:15.1.1.41 image: supabase/postgres:15.1.1.41
healthcheck: healthcheck:
test: pg_isready -U postgres -h localhost test: pg_isready -U postgres -h 127.0.0.1
interval: 5s interval: 5s
timeout: 5s timeout: 5s
retries: 10 retries: 10
@@ -599,7 +599,7 @@ services:
supabase-analytics: supabase-analytics:
image: supabase/logflare:1.4.0 image: supabase/logflare:1.4.0
healthcheck: healthcheck:
test: ["CMD", "curl", "http://localhost:4000/health"] test: ["CMD", "curl", "http://127.0.0.1:4000/health"]
timeout: 5s timeout: 5s
interval: 5s interval: 5s
retries: 10 retries: 10
@@ -927,7 +927,7 @@ services:
"--no-verbose", "--no-verbose",
"--tries=1", "--tries=1",
"--spider", "--spider",
"http://localhost:9999/health", "http://127.0.0.1:9999/health",
] ]
timeout: 5s timeout: 5s
interval: 5s interval: 5s
@@ -1001,7 +1001,7 @@ services:
supabase-analytics: supabase-analytics:
condition: service_healthy condition: service_healthy
healthcheck: healthcheck:
test: ["CMD", "bash", "-c", "printf \\0 > /dev/tcp/localhost/4000"] test: ["CMD", "bash", "-c", "printf \\0 > /dev/tcp/127.0.0.1/4000"]
timeout: 5s timeout: 5s
interval: 5s interval: 5s
retries: 3 retries: 3
@@ -1075,7 +1075,7 @@ services:
"--no-verbose", "--no-verbose",
"--tries=1", "--tries=1",
"--spider", "--spider",
"http://localhost:5000/status", "http://127.0.0.1:5000/status",
] ]
timeout: 5s timeout: 5s
interval: 5s interval: 5s

View File

@@ -20,7 +20,7 @@ services:
volumes: volumes:
- tolgee-data:/data - tolgee-data:/data
healthcheck: healthcheck:
test: ["CMD", "wget", "-q", "--spider", "http://localhost:8080"] test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:8080"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -43,7 +43,7 @@ services:
postgres: postgres:
condition: service_healthy condition: service_healthy
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/healthz"] test: ["CMD", "curl", "-f", "http://127.0.0.1:3000/healthz"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -16,7 +16,7 @@ services:
postgresql: postgresql:
condition: service_healthy condition: service_healthy
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/api/heartbeat"] test: ["CMD", "curl", "-f", "http://127.0.0.1:3000/api/heartbeat"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -23,7 +23,7 @@ services:
- node - node
- index.js - index.js
healthcheck: healthcheck:
test: "wget --no-verbose --tries=1 --spider http://localhost:4242/health || exit 1" test: "wget --no-verbose --tries=1 --spider http://127.0.0.1:4242/health || exit 1"
interval: 1s interval: 1s
timeout: 1m timeout: 1m
retries: 5 retries: 5

View File

@@ -20,7 +20,7 @@ services:
- node - node
- index.js - index.js
healthcheck: healthcheck:
test: 'wget --no-verbose --tries=1 --spider http://localhost:4242/health || exit 1' test: 'wget --no-verbose --tries=1 --spider http://127.0.0.1:4242/health || exit 1'
interval: 1s interval: 1s
timeout: 1m timeout: 1m
retries: 5 retries: 5

View File

@@ -11,7 +11,7 @@ services:
volumes: volumes:
- vaultwarden-data:/data - vaultwarden-data:/data
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80"] test: ["CMD", "curl", "-f", "http://127.0.0.1:80"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -15,7 +15,7 @@ services:
volumes: volumes:
- vikunja-data:/app/vikunja/ - vikunja-data:/app/vikunja/
healthcheck: healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:3456"] test: ["CMD", "wget", "--spider", "http://127.0.0.1:3456"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -26,7 +26,7 @@ services:
- weblate-data:/app/data - weblate-data:/app/data
- weblate-cache:/app/cache - weblate-cache:/app/cache
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080"] test: ["CMD", "curl", "-f", "http://127.0.0.1:8080"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 30 retries: 30

View File

@@ -9,7 +9,7 @@ services:
environment: environment:
- SERVICE_FQDN_WHOOGLE_5000 - SERVICE_FQDN_WHOOGLE_5000
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000"] test: ["CMD", "curl", "-f", "http://127.0.0.1:5000"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 15 retries: 15

View File

@@ -17,7 +17,7 @@ services:
depends_on: depends_on:
- mariadb - mariadb
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] test: ["CMD", "curl", "-f", "http://127.0.0.1"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 10 retries: 10

View File

@@ -17,7 +17,7 @@ services:
depends_on: depends_on:
- mysql - mysql
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] test: ["CMD", "curl", "-f", "http://127.0.0.1"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 10 retries: 10
@@ -31,7 +31,7 @@ services:
- MYSQL_USER=$SERVICE_USER_WORDPRESS - MYSQL_USER=$SERVICE_USER_WORDPRESS
- MYSQL_PASSWORD=$SERVICE_PASSWORD_WORDPRESS - MYSQL_PASSWORD=$SERVICE_PASSWORD_WORDPRESS
healthcheck: healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"]
interval: 5s interval: 5s
timeout: 20s timeout: 20s
retries: 10 retries: 10

View File

@@ -11,7 +11,7 @@ services:
environment: environment:
- SERVICE_FQDN_WORDPRESS - SERVICE_FQDN_WORDPRESS
healthcheck: healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"] test: ["CMD", "curl", "-f", "http://127.0.0.1"]
interval: 2s interval: 2s
timeout: 10s timeout: 10s
retries: 10 retries: 10

File diff suppressed because one or more lines are too long

View File

@@ -1,7 +1,7 @@
{ {
"coolify": { "coolify": {
"v4": { "v4": {
"version": "4.0.0-beta.280" "version": "4.0.0-beta.284"
}, },
"sentinel": { "sentinel": {
"version": "0.0.4" "version": "0.0.4"