From 0df2620744fa148ed97853a0b94161f802cbe8cf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Nov 2025 14:37:48 +0000 Subject: [PATCH 1/5] chore(deps): bump symfony/http-foundation from 7.3.2 to 7.3.7 Bumps [symfony/http-foundation](https://github.com/symfony/http-foundation) from 7.3.2 to 7.3.7. - [Release notes](https://github.com/symfony/http-foundation/releases) - [Changelog](https://github.com/symfony/http-foundation/blob/7.3/CHANGELOG.md) - [Commits](https://github.com/symfony/http-foundation/compare/v7.3.2...v7.3.7) --- updated-dependencies: - dependency-name: symfony/http-foundation dependency-version: 7.3.7 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- composer.lock | 72 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 26 deletions(-) diff --git a/composer.lock b/composer.lock index 5ffeb7d39..b2923a240 100644 --- a/composer.lock +++ b/composer.lock @@ -9514,16 +9514,16 @@ }, { "name": "symfony/http-foundation", - "version": "v7.3.2", + "version": "v7.3.7", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "6877c122b3a6cc3695849622720054f6e6fa5fa6" + "reference": "db488a62f98f7a81d5746f05eea63a74e55bb7c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/6877c122b3a6cc3695849622720054f6e6fa5fa6", - "reference": "6877c122b3a6cc3695849622720054f6e6fa5fa6", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/db488a62f98f7a81d5746f05eea63a74e55bb7c4", + "reference": "db488a62f98f7a81d5746f05eea63a74e55bb7c4", "shasum": "" }, "require": { @@ -9573,7 +9573,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.3.2" + "source": "https://github.com/symfony/http-foundation/tree/v7.3.7" }, "funding": [ { @@ -9593,7 +9593,7 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:47:49+00:00" + "time": "2025-11-08T16:41:12+00:00" }, { "name": "symfony/http-kernel", @@ -9799,16 +9799,16 @@ }, { "name": "symfony/mime", - "version": "v7.3.2", + "version": "v7.3.4", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "e0a0f859148daf1edf6c60b398eb40bfc96697d1" + "reference": "b1b828f69cbaf887fa835a091869e55df91d0e35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/e0a0f859148daf1edf6c60b398eb40bfc96697d1", - "reference": "e0a0f859148daf1edf6c60b398eb40bfc96697d1", + "url": "https://api.github.com/repos/symfony/mime/zipball/b1b828f69cbaf887fa835a091869e55df91d0e35", + "reference": "b1b828f69cbaf887fa835a091869e55df91d0e35", "shasum": "" }, "require": { @@ -9863,7 +9863,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v7.3.2" + "source": "https://github.com/symfony/mime/tree/v7.3.4" }, "funding": [ { @@ -9883,7 +9883,7 @@ "type": "tidelift" } ], - "time": "2025-07-15T13:41:35+00:00" + "time": "2025-09-16T08:38:17+00:00" }, { "name": "symfony/options-resolver", @@ -10195,7 +10195,7 @@ }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.32.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", @@ -10258,7 +10258,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.32.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.33.0" }, "funding": [ { @@ -10269,6 +10269,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -10278,7 +10282,7 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.32.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", @@ -10339,7 +10343,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" }, "funding": [ { @@ -10350,6 +10354,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -10359,7 +10367,7 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.32.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", @@ -10420,7 +10428,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" }, "funding": [ { @@ -10431,6 +10439,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -10440,7 +10452,7 @@ }, { "name": "symfony/polyfill-php80", - "version": "v1.32.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", @@ -10500,7 +10512,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.32.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" }, "funding": [ { @@ -10511,6 +10523,10 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" @@ -10520,16 +10536,16 @@ }, { "name": "symfony/polyfill-php83", - "version": "v1.32.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" + "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", - "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/17f6f9a6b1735c0f163024d959f700cfbc5155e5", + "reference": "17f6f9a6b1735c0f163024d959f700cfbc5155e5", "shasum": "" }, "require": { @@ -10576,7 +10592,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.32.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.33.0" }, "funding": [ { @@ -10587,12 +10603,16 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-09-09T11:45:10+00:00" + "time": "2025-07-08T02:45:35+00:00" }, { "name": "symfony/polyfill-uuid", From 318cd18dde8c308621cef593701b8b9e31fa2811 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Fri, 14 Nov 2025 11:31:08 +0100 Subject: [PATCH 2/5] fix: remove PullHelperImageJob and mass server scheduling Stop dispatching PullHelperImageJob to thousands of servers when the helper image version changes. Instead, rely on Docker's automatic image pulling during actual deployments and backups. Inline the helper image pull in UpdateCoolify for the single use case. This eliminates queue flooding on cloud instances while maintaining all functionality through Docker's built-in image management. --- app/Actions/Server/UpdateCoolify.php | 5 +- app/Jobs/PullHelperImageJob.php | 30 ------- app/Models/InstanceSettings.php | 9 --- .../InstanceSettingsHelperVersionTest.php | 81 ------------------- 4 files changed, 3 insertions(+), 122 deletions(-) delete mode 100644 app/Jobs/PullHelperImageJob.php delete mode 100644 tests/Feature/InstanceSettingsHelperVersionTest.php diff --git a/app/Actions/Server/UpdateCoolify.php b/app/Actions/Server/UpdateCoolify.php index 2a06428e2..0bf763d78 100644 --- a/app/Actions/Server/UpdateCoolify.php +++ b/app/Actions/Server/UpdateCoolify.php @@ -2,7 +2,6 @@ namespace App\Actions\Server; -use App\Jobs\PullHelperImageJob; use App\Models\Server; use Illuminate\Support\Sleep; use Lorisleiva\Actions\Concerns\AsAction; @@ -50,7 +49,9 @@ public function handle($manual_update = false) private function update() { - PullHelperImageJob::dispatch($this->server); + $helperImage = config('constants.coolify.helper_image'); + $latest_version = getHelperVersion(); + instant_remote_process(["docker pull -q {$helperImage}:{$latest_version}"], $this->server, false); $image = config('constants.coolify.registry_url').'/coollabsio/coolify:'.$this->latestVersion; instant_remote_process(["docker pull -q $image"], $this->server, false); diff --git a/app/Jobs/PullHelperImageJob.php b/app/Jobs/PullHelperImageJob.php deleted file mode 100644 index 7cdf1b81a..000000000 --- a/app/Jobs/PullHelperImageJob.php +++ /dev/null @@ -1,30 +0,0 @@ -onQueue('high'); - } - - public function handle(): void - { - $helperImage = config('constants.coolify.helper_image'); - $latest_version = getHelperVersion(); - instant_remote_process(["docker pull -q {$helperImage}:{$latest_version}"], $this->server, false); - } -} diff --git a/app/Models/InstanceSettings.php b/app/Models/InstanceSettings.php index cd1c05de4..62b576012 100644 --- a/app/Models/InstanceSettings.php +++ b/app/Models/InstanceSettings.php @@ -2,7 +2,6 @@ namespace App\Models; -use App\Jobs\PullHelperImageJob; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Model; use Spatie\Url\Url; @@ -35,14 +34,6 @@ class InstanceSettings extends Model protected static function booted(): void { static::updated(function ($settings) { - if ($settings->wasChanged('helper_version')) { - Server::chunkById(100, function ($servers) { - foreach ($servers as $server) { - PullHelperImageJob::dispatch($server); - } - }); - } - // Clear trusted hosts cache when FQDN changes if ($settings->wasChanged('fqdn')) { \Cache::forget('instance_settings_fqdn_host'); diff --git a/tests/Feature/InstanceSettingsHelperVersionTest.php b/tests/Feature/InstanceSettingsHelperVersionTest.php deleted file mode 100644 index e731fa8b4..000000000 --- a/tests/Feature/InstanceSettingsHelperVersionTest.php +++ /dev/null @@ -1,81 +0,0 @@ -create(); - $team = $user->teams()->first(); - Server::factory()->count(3)->create(['team_id' => $team->id]); - - $settings = InstanceSettings::firstOrCreate([], ['helper_version' => 'v1.0.0']); - - // Change helper_version - $settings->helper_version = 'v1.2.3'; - $settings->save(); - - // Verify PullHelperImageJob was dispatched for all servers - Queue::assertPushed(PullHelperImageJob::class, 3); -}); - -it('does not dispatch PullHelperImageJob when helper_version is unchanged', function () { - Queue::fake(); - - // Create user and servers - $user = User::factory()->create(); - $team = $user->teams()->first(); - Server::factory()->count(3)->create(['team_id' => $team->id]); - - $settings = InstanceSettings::firstOrCreate([], ['helper_version' => 'v1.0.0']); - $currentVersion = $settings->helper_version; - - // Set to same value - $settings->helper_version = $currentVersion; - $settings->save(); - - // Verify no jobs were dispatched - Queue::assertNotPushed(PullHelperImageJob::class); -}); - -it('does not dispatch PullHelperImageJob when other fields change', function () { - Queue::fake(); - - // Create user and servers - $user = User::factory()->create(); - $team = $user->teams()->first(); - Server::factory()->count(3)->create(['team_id' => $team->id]); - - $settings = InstanceSettings::firstOrCreate([], ['helper_version' => 'v1.0.0']); - - // Change different field - $settings->is_auto_update_enabled = ! $settings->is_auto_update_enabled; - $settings->save(); - - // Verify no jobs were dispatched - Queue::assertNotPushed(PullHelperImageJob::class); -}); - -it('detects helper_version changes with wasChanged', function () { - $changeDetected = false; - - InstanceSettings::updated(function ($settings) use (&$changeDetected) { - if ($settings->wasChanged('helper_version')) { - $changeDetected = true; - } - }); - - $settings = InstanceSettings::firstOrCreate([], ['helper_version' => 'v1.0.0']); - $settings->helper_version = 'v2.0.0'; - $settings->save(); - - expect($changeDetected)->toBeTrue(); -}); From 60ef63de541a078c0da227957c53e5c30678612d Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 17 Nov 2025 14:26:42 +0100 Subject: [PATCH 3/5] fix: resolve duplicate migration timestamps and add idempotency guards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two migrations had identical timestamps (2025_10_10_120000), causing non-deterministic execution order and "table already exists" errors during instance startup. Renamed webhook_notification_settings migration to 120002 and added Schema::hasTable() guards to both migrations for idempotency. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- ...120000_create_cloud_init_scripts_table.php | 18 +++---- ...te_webhook_notification_settings_table.php | 46 ------------------ ...te_webhook_notification_settings_table.php | 48 +++++++++++++++++++ 3 files changed, 58 insertions(+), 54 deletions(-) delete mode 100644 database/migrations/2025_10_10_120000_create_webhook_notification_settings_table.php create mode 100644 database/migrations/2025_10_10_120002_create_webhook_notification_settings_table.php diff --git a/database/migrations/2025_10_10_120000_create_cloud_init_scripts_table.php b/database/migrations/2025_10_10_120000_create_cloud_init_scripts_table.php index fe216a57d..932c551d7 100644 --- a/database/migrations/2025_10_10_120000_create_cloud_init_scripts_table.php +++ b/database/migrations/2025_10_10_120000_create_cloud_init_scripts_table.php @@ -11,15 +11,17 @@ */ public function up(): void { - Schema::create('cloud_init_scripts', function (Blueprint $table) { - $table->id(); - $table->foreignId('team_id')->constrained()->onDelete('cascade'); - $table->string('name'); - $table->text('script'); // Encrypted in the model - $table->timestamps(); + if (!Schema::hasTable('cloud_init_scripts')) { + Schema::create('cloud_init_scripts', function (Blueprint $table) { + $table->id(); + $table->foreignId('team_id')->constrained()->onDelete('cascade'); + $table->string('name'); + $table->text('script'); // Encrypted in the model + $table->timestamps(); - $table->index('team_id'); - }); + $table->index('team_id'); + }); + } } /** diff --git a/database/migrations/2025_10_10_120000_create_webhook_notification_settings_table.php b/database/migrations/2025_10_10_120000_create_webhook_notification_settings_table.php deleted file mode 100644 index a3edacbf9..000000000 --- a/database/migrations/2025_10_10_120000_create_webhook_notification_settings_table.php +++ /dev/null @@ -1,46 +0,0 @@ -id(); - $table->foreignId('team_id')->constrained()->cascadeOnDelete(); - - $table->boolean('webhook_enabled')->default(false); - $table->text('webhook_url')->nullable(); - - $table->boolean('deployment_success_webhook_notifications')->default(false); - $table->boolean('deployment_failure_webhook_notifications')->default(true); - $table->boolean('status_change_webhook_notifications')->default(false); - $table->boolean('backup_success_webhook_notifications')->default(false); - $table->boolean('backup_failure_webhook_notifications')->default(true); - $table->boolean('scheduled_task_success_webhook_notifications')->default(false); - $table->boolean('scheduled_task_failure_webhook_notifications')->default(true); - $table->boolean('docker_cleanup_success_webhook_notifications')->default(false); - $table->boolean('docker_cleanup_failure_webhook_notifications')->default(true); - $table->boolean('server_disk_usage_webhook_notifications')->default(true); - $table->boolean('server_reachable_webhook_notifications')->default(false); - $table->boolean('server_unreachable_webhook_notifications')->default(true); - $table->boolean('server_patch_webhook_notifications')->default(false); - - $table->unique(['team_id']); - }); - } - - /** - * Reverse the migrations. - */ - public function down(): void - { - Schema::dropIfExists('webhook_notification_settings'); - } -}; diff --git a/database/migrations/2025_10_10_120002_create_webhook_notification_settings_table.php b/database/migrations/2025_10_10_120002_create_webhook_notification_settings_table.php new file mode 100644 index 000000000..1c2aeff88 --- /dev/null +++ b/database/migrations/2025_10_10_120002_create_webhook_notification_settings_table.php @@ -0,0 +1,48 @@ +id(); + $table->foreignId('team_id')->constrained()->cascadeOnDelete(); + + $table->boolean('webhook_enabled')->default(false); + $table->text('webhook_url')->nullable(); + + $table->boolean('deployment_success_webhook_notifications')->default(false); + $table->boolean('deployment_failure_webhook_notifications')->default(true); + $table->boolean('status_change_webhook_notifications')->default(false); + $table->boolean('backup_success_webhook_notifications')->default(false); + $table->boolean('backup_failure_webhook_notifications')->default(true); + $table->boolean('scheduled_task_success_webhook_notifications')->default(false); + $table->boolean('scheduled_task_failure_webhook_notifications')->default(true); + $table->boolean('docker_cleanup_success_webhook_notifications')->default(false); + $table->boolean('docker_cleanup_failure_webhook_notifications')->default(true); + $table->boolean('server_disk_usage_webhook_notifications')->default(true); + $table->boolean('server_reachable_webhook_notifications')->default(false); + $table->boolean('server_unreachable_webhook_notifications')->default(true); + $table->boolean('server_patch_webhook_notifications')->default(false); + + $table->unique(['team_id']); + }); + } + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::dropIfExists('webhook_notification_settings'); + } +}; From 8f7ae2670c41b6dc2aaa8bb3f8e9323c2c3d4178 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 17 Nov 2025 14:27:13 +0100 Subject: [PATCH 4/5] fix(versions): update coolify version to 4.0.0-beta.445 and nightly to 4.0.0-beta.446 --- config/constants.php | 2 +- other/nightly/versions.json | 4 ++-- versions.json | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/constants.php b/config/constants.php index d28f313ee..6ad70b31a 100644 --- a/config/constants.php +++ b/config/constants.php @@ -2,7 +2,7 @@ return [ 'coolify' => [ - 'version' => '4.0.0-beta.444', + 'version' => '4.0.0-beta.445', 'helper_version' => '1.0.12', 'realtime_version' => '1.0.10', 'self_hosted' => env('SELF_HOSTED', true), diff --git a/other/nightly/versions.json b/other/nightly/versions.json index 7d33719a0..bb9b51ab1 100644 --- a/other/nightly/versions.json +++ b/other/nightly/versions.json @@ -1,10 +1,10 @@ { "coolify": { "v4": { - "version": "4.0.0-beta.444" + "version": "4.0.0-beta.445" }, "nightly": { - "version": "4.0.0-beta.445" + "version": "4.0.0-beta.446" }, "helper": { "version": "1.0.12" diff --git a/versions.json b/versions.json index 7d33719a0..bb9b51ab1 100644 --- a/versions.json +++ b/versions.json @@ -1,10 +1,10 @@ { "coolify": { "v4": { - "version": "4.0.0-beta.444" + "version": "4.0.0-beta.445" }, "nightly": { - "version": "4.0.0-beta.445" + "version": "4.0.0-beta.446" }, "helper": { "version": "1.0.12" From 028e7cb35ee962b5f9ce5172e46948d9ea2db2ef Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 17 Nov 2025 14:28:28 +0100 Subject: [PATCH 5/5] fix: remove unnecessary table existence checks in migration files --- .../2025_10_10_120000_create_cloud_init_scripts_table.php | 2 -- ..._10_10_120002_create_webhook_notification_settings_table.php | 2 -- 2 files changed, 4 deletions(-) diff --git a/database/migrations/2025_10_10_120000_create_cloud_init_scripts_table.php b/database/migrations/2025_10_10_120000_create_cloud_init_scripts_table.php index 932c551d7..e0b2934f3 100644 --- a/database/migrations/2025_10_10_120000_create_cloud_init_scripts_table.php +++ b/database/migrations/2025_10_10_120000_create_cloud_init_scripts_table.php @@ -11,7 +11,6 @@ */ public function up(): void { - if (!Schema::hasTable('cloud_init_scripts')) { Schema::create('cloud_init_scripts', function (Blueprint $table) { $table->id(); $table->foreignId('team_id')->constrained()->onDelete('cascade'); @@ -21,7 +20,6 @@ public function up(): void $table->index('team_id'); }); - } } /** diff --git a/database/migrations/2025_10_10_120002_create_webhook_notification_settings_table.php b/database/migrations/2025_10_10_120002_create_webhook_notification_settings_table.php index 1c2aeff88..5ff8aa46d 100644 --- a/database/migrations/2025_10_10_120002_create_webhook_notification_settings_table.php +++ b/database/migrations/2025_10_10_120002_create_webhook_notification_settings_table.php @@ -11,7 +11,6 @@ */ public function up(): void { - if (!Schema::hasTable('webhook_notification_settings')) { Schema::create('webhook_notification_settings', function (Blueprint $table) { $table->id(); $table->foreignId('team_id')->constrained()->cascadeOnDelete(); @@ -35,7 +34,6 @@ public function up(): void $table->unique(['team_id']); }); - } } /**