Merge pull request #2230 from coollabsio/next

v4.0.0-beta.281
This commit is contained in:
Andras Bacsai 2024-05-17 12:45:26 +02:00 committed by GitHub
commit 5de1246827
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
89 changed files with 507 additions and 324 deletions

View File

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

View File

@ -21,8 +21,10 @@
class Kernel extends ConsoleKernel
{
private $all_servers;
protected function schedule(Schedule $schedule): void
{
$this->all_servers = Server::all();
if (isDev()) {
// Instance Jobs
$schedule->command('horizon:snapshot')->everyMinute();
@ -56,7 +58,7 @@ protected function schedule(Schedule $schedule): void
}
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) {
if (config('coolify.is_sentinel_enabled')) {
$schedule->job(new PullSentinelImageJob($server))->everyFiveMinutes()->onOneServer();
@ -67,12 +69,12 @@ private function pull_helper_image($schedule)
private function check_resources($schedule)
{
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;
$servers = $servers->merge($own);
$containerServers = $servers->where('settings.is_swarm_worker', false)->where('settings.is_build_server', false);
} 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);
}
foreach ($containerServers as $server) {

View File

@ -713,10 +713,36 @@ private function check_image_locally_or_remotely()
private function save_environment_variables()
{
$envs = collect([]);
$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();
if ($this->pull_request_id !== 0) {
$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={$this->application->git_branch}");
}
foreach ($sorted_environment_variables_preview as $env) {
$real_value = $env->real_value;
if ($env->version === '4.0.0-beta.239') {
$real_value = $env->real_value;
@ -737,30 +763,27 @@ private function save_environment_variables()
if ($this->application->environment_variables_preview->where('key', 'HOST')->isEmpty()) {
$envs->push("HOST=0.0.0.0");
}
} else {
$this->env_filename = ".env";
// 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)) {
$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->where('key', 'COOLIFY_FQDN')->isEmpty()) {
$envs->push("COOLIFY_FQDN={$this->application->fqdn}");
}
if ($this->application->environment_variables_preview->where('key', 'COOLIFY_URL')->isEmpty()) {
$url = str($this->preview->fqdn)->replace('http://', '')->replace('https://', '');
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;
});
} else {
$this->env_filename = ".env";
foreach ($this->application->environment_variables as $env) {
foreach ($sorted_environment_variables as $env) {
$real_value = $env->real_value;
if ($env->version === '4.0.0-beta.239') {
$real_value = $env->real_value;
@ -781,27 +804,6 @@ private function save_environment_variables()
if ($this->application->environment_variables->where('key', 'HOST')->isEmpty()) {
$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()) {
@ -1272,6 +1274,7 @@ private function generate_nixpacks_env_variables()
private function generate_env_variables()
{
$this->env_args = collect([]);
$this->env_args->put('SOURCE_COMMIT', $this->commit);
if ($this->pull_request_id === 0) {
foreach ($this->application->build_environment_variables as $env) {
if (!is_null($env->real_value)) {
@ -1285,7 +1288,6 @@ private function generate_env_variables()
}
}
}
$this->env_args->put('SOURCE_COMMIT', $this->commit);
}
private function generate_compose_file()
@ -1603,12 +1605,12 @@ private function generate_healthcheck_commands()
if ($this->application->health_check_path) {
$this->full_healthcheck_url = "{$this->application->health_check_method}: {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}{$this->application->health_check_path}";
$generated_healthchecks_commands = [
"curl -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}{$this->application->health_check_path} > /dev/null || wget -q -O- {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}{$this->application->health_check_path} > /dev/null || exit 1"
"curl -o /dev/null -w \"%{http_code}\" -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}{$this->application->health_check_path} | grep -q \"{$this->application->health_check_return_code}\" || wget --save-headers -O - {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}{$this->application->health_check_path} 2>/dev/null |grep HTTP/ |grep -q \"{$this->application->health_check_return_code}\" || exit 1"
];
} else {
$this->full_healthcheck_url = "{$this->application->health_check_method}: {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}/";
$generated_healthchecks_commands = [
"curl -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}/ > /dev/null || wget -q -O- {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}/ > /dev/null || exit 1"
"curl -o /dev/null -w \"%{http_code}\" -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}/ | grep -q \"{$this->application->health_check_return_code}\" || wget --save-headers -O - {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}/ 2>/dev/null |grep HTTP/ |grep -q \"{$this->application->health_check_return_code}\" || exit 1"
];
}
return implode(' ', $generated_healthchecks_commands);
@ -1967,10 +1969,7 @@ private function next(string $status)
if (!$this->only_this_server) {
$this->deploy_to_additional_destinations();
}
if (!isCloud()) {
// TODO: turn off until we have a better solution
$this->application->environment->project->team?->notify(new DeploymentSuccess($this->application, $this->deployment_uuid, $this->preview));
}
$this->application->environment->project->team?->notify(new DeploymentSuccess($this->application, $this->deployment_uuid, $this->preview));
}
}

View File

@ -5,7 +5,7 @@
use App\Actions\Application\StopApplication;
use App\Actions\Docker\GetContainersStatus;
use App\Events\ApplicationStatusChanged;
use App\Jobs\ContainerStatusJob;
use App\Jobs\ContainerStatusJob;
use App\Jobs\ServerStatusJob;
use App\Models\Application;
use Livewire\Component;
@ -14,6 +14,8 @@
class Heading extends Component
{
public Application $application;
public ?string $lastDeploymentInfo = null;
public ?string $lastDeploymentLink = null;
public array $parameters;
protected string $deploymentUuid;
@ -28,6 +30,9 @@ public function getListeners()
public function mount()
{
$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)

View File

@ -5,11 +5,11 @@
use App\Models\EnvironmentVariable;
use Livewire\Component;
use Visus\Cuid2\Cuid2;
use Illuminate\Support\Str;
class All extends Component
{
public $resource;
public string $resourceClass;
public bool $showPreview = false;
public ?string $modalId = null;
public ?string $variables = null;
@ -19,17 +19,44 @@ class All extends Component
'refreshEnvs',
'saveKey' => 'submit',
];
protected $rules = [
'resource.settings.is_env_sorting_enabled' => 'required|boolean',
];
public function mount()
{
$resourceClass = get_class($this->resource);
$this->resourceClass = get_class($this->resource);
$resourceWithPreviews = ['App\Models\Application'];
$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->modalId = new Cuid2(7);
$this->sortMe();
$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()
{
$this->variables = $this->resource->environment_variables->map(function ($item) {
@ -40,7 +67,7 @@ public function getDevView()
return "$item->key=(multiline, edit in normal view)";
}
return "$item->key=$item->value";
})->sort()->join('
})->join('
');
if ($this->showPreview) {
$this->variablesPreview = $this->resource->environment_variables_preview->map(function ($item) {
@ -51,13 +78,18 @@ public function getDevView()
return "$item->key=(multiline, edit in normal view)";
}
return "$item->key=$item->value";
})->sort()->join('
})->join('
');
}
}
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)
{
@ -66,6 +98,7 @@ public function saveVariables($isPreview)
$this->resource->environment_variables_preview()->whereNotIn('key', array_keys($variables))->delete();
} else {
$variables = parseEnvFormatToArray($this->variables);
ray($variables, $this->variables);
$this->resource->environment_variables()->whereNotIn('key', array_keys($variables))->delete();
}
foreach ($variables as $key => $variable) {

View File

@ -13,7 +13,7 @@ class Configuration extends Component
public bool $is_auto_update_enabled;
public bool $is_registration_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 Server $server;
@ -37,7 +37,7 @@ public function mount()
$this->do_not_track = $this->settings->do_not_track;
$this->is_auto_update_enabled = $this->settings->is_auto_update_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;
}
@ -47,12 +47,12 @@ public function instantSave()
$this->settings->is_auto_update_enabled = $this->is_auto_update_enabled;
$this->settings->is_registration_enabled = $this->is_registration_enabled;
$this->settings->is_dns_validation_enabled = $this->is_dns_validation_enabled;
if ($this->next_channel) {
$this->settings->next_channel = false;
$this->next_channel = false;
} else {
$this->settings->next_channel = $this->next_channel;
}
// if ($this->next_channel) {
// $this->settings->next_channel = false;
// $this->next_channel = false;
// } else {
// $this->settings->next_channel = $this->next_channel;
// }
$this->settings->save();
$this->dispatch('success', 'Settings updated!');
}

View File

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

View File

@ -192,10 +192,16 @@ public function gitCommits(): Attribute
public function gitCommitLink($link): string
{
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}";
}
if (strpos($this->git_repository, 'git@') === 0) {
$git_repository = str_replace(['git@', ':', '.git'], ['', '/', ''], $this->git_repository);
if (str($this->source->html_url)->contains('bitbucket')) {
return "https://{$git_repository}/commits/{$link}";
}
return "https://{$git_repository}/commit/{$link}";
}
return $this->git_repository;
@ -454,6 +460,10 @@ public function isDeploymentInprogress()
}
return false;
}
public function get_last_successful_deployment()
{
return ApplicationDeploymentQueue::where('application_id', $this->id)->where('status', 'finished')->orderBy('created_at', 'desc')->first();
}
public function get_last_days_deployments()
{
return ApplicationDeploymentQueue::where('application_id', $this->id)->where('created_at', '>=', now()->subDays(7))->orderBy('created_at', 'desc')->get();
@ -989,7 +999,8 @@ public function getFilesFromServer(bool $isInit = false)
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)) {
$healthcheckCommand = null;
$lines = $dockerfile->toArray();

View File

@ -43,7 +43,12 @@ public function __construct(Application $application, string $deployment_uuid, A
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
{

View File

@ -14,20 +14,22 @@ public function send($notifiable, $notification): void
$buttons = data_get($data, 'buttons', []);
$telegramToken = data_get($telegramData, 'token');
$chatId = data_get($telegramData, 'chat_id');
$topicId = null;
$topicId = null;
$topicsInstance = get_class($notification);
switch ($topicsInstance) {
case 'App\Notifications\StatusChange':
$topicId = data_get($notifiable, 'telegram_notifications_status_changes_message_thread_id');
break;
case 'App\Notifications\Test':
$topicId = data_get($notifiable, 'telegram_notifications_test_message_thread_id');
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');
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');
break;
}

View File

@ -7,7 +7,7 @@
// The release version of your application
// 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.281',
// When left empty or `null` the Laravel environment will be used
'environment' => config('app.env'),

View File

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

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('destination*') ? 'menu-item-active menu-item' : 'menu-i
class="{{ request()->is('storages*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('storage.index') }}">
<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">
<path d="M4 6a8 3 0 1 0 16 0A8 3 0 1 0 4 6"/>
<path d="M4 6v6a8 3 0 0 0 16 0V6"/>
<path d="M4 12v6a8 3 0 0 0 16 0v-6"/>
<g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"
stroke-width="2">
<path d="M4 6a8 3 0 1 0 16 0A8 3 0 1 0 4 6" />
<path d="M4 6v6a8 3 0 0 0 16 0V6" />
<path d="M4 12v6a8 3 0 0 0 16 0v-6" />
</g>
</svg>
S3 Storages
@ -175,9 +176,11 @@ class="{{ request()->is('storages*') ? 'menu-item-active menu-item' : 'menu-item
class="{{ request()->is('shared-variables*') ? 'menu-item-active menu-item' : 'menu-item' }}"
href="{{ route('shared-variables.index') }}">
<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">
<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 fill="none" stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2">
<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>
</svg>
Shared Variables
@ -318,9 +321,7 @@ class="{{ request()->is('settings*') ? 'menu-item-active menu-item' : 'menu-item
<div class="flex-1"></div>
@if (isInstanceAdmin() && !isCloud())
<li>
@persist('upgrade')
<livewire:upgrade />
@endpersist
<livewire:upgrade />
</li>
@endif
<li>

View File

@ -1,5 +1,10 @@
@props([
'lastDeploymentInfo' => null,
'lastDeploymentLink' => null,
'resource' => null,
])
<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">
<div class="flex items-center">
<a wire:navigate class="text-xs truncate lg:text-sm"
@ -15,7 +20,6 @@
</li>
<li>
<div class="flex items-center">
<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>
<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')
<x-status.services :service="$resource" />
@else
<x-status.index :resource="$resource" />
<x-status.index :resource="$resource" :lastDeploymentInfo="$lastDeploymentInfo" :lastDeploymentLink="$lastDeploymentLink" />
@endif
</ol>
</nav>

View File

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

View File

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

View File

@ -1,12 +1,20 @@
@props([
'status' => 'Running',
'lastDeploymentInfo' => null,
'lastDeploymentLink' => null,
])
<div class="flex items-center">
<x-loading wire:loading.delay.longer />
<span wire:loading.remove.delay.longer class="flex items-center">
<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() }}
@endif
</div>
@if (!str($status)->startsWith('Proxy') && !str($status)->contains('('))
@if (str($status)->contains('unhealthy'))
@ -17,8 +25,6 @@
</svg>
</x-slot:icon>
</x-helper>
{{-- @else
<div class="text-xs dark:text-success">({{ str($status)->after(':') }})</div> --}}
@endif
@endif
</span>

View File

@ -98,47 +98,6 @@ function changePasswordFieldType(event) {
}
}
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) {
navigator?.clipboard?.writeText(text) && window.Livewire.dispatch('success', 'Copied to clipboard.');
}

View File

@ -7,7 +7,7 @@
Save
</x-forms.button>
@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">
Send Test Notifications
</x-forms.button>
@ -18,40 +18,44 @@
</div>
<div class="flex gap-2">
<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" />
<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" />
</div>
@if (data_get($team, 'telegram_enabled'))
<h2 class="mt-4">Subscribe to events</h2>
<div class="w-96">
<div class="flex flex-col gap-4 w-96">
@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"
label="Test" />
label="Enabled" />
<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."
id="team.telegram_notifications_test_message_thread_id" label="Custom Topic ID" />
</div>
@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"
label="Container Status Changes" />
label="Enabled" />
<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."
id="team.telegram_notifications_status_changes_message_thread_id" label="Custom Topic ID" />
</div>
<div class="w-64">
<div class="flex flex-col">
<h4>Application Deployments</h4>
<x-forms.checkbox instantSave="saveModel" id="team.telegram_notifications_deployments"
label="Application Deployments" />
label="Enabled" />
<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."
id="team.telegram_notifications_deployments_message_thread_id" label="Custom Topic ID" />
</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"
label="Backup Status" />
label="Enabled" />
<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."
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">
<x-resources.breadcrumbs :resource="$application" :parameters="$parameters" />
<x-resources.breadcrumbs :resource="$application" :parameters="$parameters" :lastDeploymentInfo="$lastDeploymentInfo" :lastDeploymentLink="$lastDeploymentLink" />
<div class="navbar-main">
<nav class="flex items-center flex-shrink-0 gap-6 scrollbar min-h-10 whitespace-nowrap">
<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>
</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')
<div class="pt-4 dark:text-warning text-coollabs">Hardcoded variables are not shown here.</div>
@endif
</div>
@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 }}"
:env="$env" :type="$resource->type()" />
@empty
@ -27,7 +33,7 @@
<h3>Preview Deployments</h3>
<div>Environment (secrets) variables for Preview Deployments.</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 }}"
:env="$env" :type="$resource->type()" />
@endforeach

View File

@ -9,7 +9,7 @@
<div>General configuration for your Coolify instance.</div>
<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.custom_dns_servers" label="DNS Servers"
helper="DNS servers for validation FQDNs againts. A comma separated list of DNS servers."
@ -35,13 +35,13 @@
@endif
<x-forms.checkbox instantSave id="is_registration_enabled" label="Registration Allowed" />
<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."
id="next_channel" label="Enable pre-release (early) updates" />
@else
<x-forms.checkbox disabled instantSave
helper="Currently disabled. Not recommended. Only if you like to live on the edge." id="next_channel"
label="Enable pre-release (early) updates" />
@endif
@endif --}}
</div>
</div>

View File

@ -1,29 +1,139 @@
<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)
<button wire:key="upgrade" wire:click='upgrade' class="menu-item" x-on:click="upgrade">
@if ($showProgress)
<svg xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6 text-pink-500 transition-colors hover:text-pink-300 lds-heart" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<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" />
</svg>
In progress
@else
<svg xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6 text-pink-500 transition-colors hover:text-pink-300" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path
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 21h6" />
<path d="M9 18h6" />
</svg>
Upgrade
@endif
</button>
<div :class="{ 'z-40': modalOpen }" class="relative w-auto h-auto">
<button class="menu-item" @click="modalOpen=true">
@if ($showProgress)
<svg xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6 text-pink-500 transition-colors hover:text-pink-300 lds-heart" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<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" />
</svg>
In progress
@else
<svg xmlns="http://www.w3.org/2000/svg"
class="w-6 h-6 text-pink-500 transition-colors hover:text-pink-300" viewBox="0 0 24 24"
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
stroke-linejoin="round">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path
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 21h6" />
<path d="M9 18h6" />
</svg>
Upgrade
@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
</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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -26,7 +26,7 @@ services:
- REDIS_PORT=6379
- WEBSOCKETS_ENABLED=true
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
timeout: 20s
retries: 10

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,7 +18,7 @@ services:
- MB_DB_USER=$SERVICE_USER_POSTGRESQL
- MB_DB_PASS=$SERVICE_PASSWORD_POSTGRESQL
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
timeout: 20s
retries: 10

View File

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

View File

@ -15,7 +15,7 @@ services:
volumes:
- minio-data:/data
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
timeout: 20s
retries: 10

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -51,7 +51,7 @@ services:
volumes:
- minio-data:/data
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
timeout: 20s
retries: 10

View File

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

View File

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

View File

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

View File

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

View File

@ -285,7 +285,7 @@ services:
"CMD",
"node",
"-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
interval: 5s
@ -316,7 +316,7 @@ services:
supabase-db:
image: supabase/postgres:15.1.1.41
healthcheck:
test: pg_isready -U postgres -h localhost
test: pg_isready -U postgres -h 127.0.0.1
interval: 5s
timeout: 5s
retries: 10
@ -599,7 +599,7 @@ services:
supabase-analytics:
image: supabase/logflare:1.4.0
healthcheck:
test: ["CMD", "curl", "http://localhost:4000/health"]
test: ["CMD", "curl", "http://127.0.0.1:4000/health"]
timeout: 5s
interval: 5s
retries: 10
@ -927,7 +927,7 @@ services:
"--no-verbose",
"--tries=1",
"--spider",
"http://localhost:9999/health",
"http://127.0.0.1:9999/health",
]
timeout: 5s
interval: 5s
@ -1001,7 +1001,7 @@ services:
supabase-analytics:
condition: service_healthy
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
interval: 5s
retries: 3
@ -1075,7 +1075,7 @@ services:
"--no-verbose",
"--tries=1",
"--spider",
"http://localhost:5000/status",
"http://127.0.0.1:5000/status",
]
timeout: 5s
interval: 5s

View File

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

View File

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

View File

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

View File

@ -23,7 +23,7 @@ services:
- node
- index.js
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
timeout: 1m
retries: 5

View File

@ -20,7 +20,7 @@ services:
- node
- index.js
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
timeout: 1m
retries: 5

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because one or more lines are too long

View File

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