From ea1b701a9471d14f6ddfc8bb0bfe805440131e11 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 26 Oct 2026 13:24:36 +0100 Subject: [PATCH] fix(ports): skip the PORT mismatch warning when readonly labels are disabled Closes #10941 Co-Authored-By: Claude Opus 5.5 --- app/Jobs/ApplicationDeploymentJob.php | 5 +- app/Livewire/Project/Application/General.php | 5 ++ ...ationDeploymentControlVarFilteringTest.php | 21 ++++++ .../ApplicationPortMismatchWarningTest.php | 66 +++++++++++++++++++ 4 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 tests/Feature/ApplicationPortMismatchWarningTest.php diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 3a00704813..ea3ce9191c 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -1927,8 +1927,9 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue $envs->push($this->runtimeEnvironmentAssignment($env)); } - // Check for PORT environment variable mismatch with ports_exposes - if ($this->build_pack !== 'dockercompose') { + // Check for PORT environment variable mismatch with ports_exposes. + // With readonly labels disabled, custom labels control proxy routing, so skip the check. + if ($this->build_pack !== 'dockercompose' && $this->application->settings->is_container_label_readonly_enabled) { $detectedPort = $this->application->detectPortFromEnvironment(false); if ($detectedPort && ! empty($ports) && ! in_array($detectedPort, $ports)) { $this->application_deployment_queue->addLogEntry( diff --git a/app/Livewire/Project/Application/General.php b/app/Livewire/Project/Application/General.php index 09a634c681..a58d87f307 100644 --- a/app/Livewire/Project/Application/General.php +++ b/app/Livewire/Project/Application/General.php @@ -992,6 +992,11 @@ class General extends Component public function getDetectedPortInfoProperty(): ?array { + // With readonly labels disabled, Ports Exposes is read-only and custom labels control proxy routing. + if (! $this->application->settings->is_container_label_readonly_enabled) { + return null; + } + $detectedPort = $this->application->detectPortFromEnvironment(); if (! $detectedPort) { diff --git a/tests/Feature/ApplicationDeploymentControlVarFilteringTest.php b/tests/Feature/ApplicationDeploymentControlVarFilteringTest.php index d19a382e0e..caf92c69e4 100644 --- a/tests/Feature/ApplicationDeploymentControlVarFilteringTest.php +++ b/tests/Feature/ApplicationDeploymentControlVarFilteringTest.php @@ -2029,3 +2029,24 @@ it('keeps heredoc bodies unchanged when it adds build secrets to a Dockerfile', "RUN --mount=type=secret,id=API_URL,env=API_URL python -c 'print(1)'", ]); }); + +it('warns in the deployment log when PORT does not match ports_exposes', function () { + [$application, $server] = makeDeploymentControlVarFixture(['ports_exposes' => '80']); + createApplicationEnvironmentVariable($application, ['key' => 'PORT', 'value' => '3000']); + + [$job, $reflection] = makeControlVarFilteringJob($application, $server); + invokeDeploymentJobMethod($job, $reflection, 'generate_runtime_environment_variables'); + + expect(collect($job->recordedLogEntries)->contains(fn (string $entry) => str_contains($entry, 'PORT environment variable (3000)')))->toBeTrue(); +}); + +it('does not warn about a PORT mismatch when readonly labels are disabled', function () { + [$application, $server] = makeDeploymentControlVarFixture(['ports_exposes' => '80']); + $application->settings()->update(['is_container_label_readonly_enabled' => false]); + createApplicationEnvironmentVariable($application, ['key' => 'PORT', 'value' => '3000']); + + [$job, $reflection] = makeControlVarFilteringJob($application, $server); + invokeDeploymentJobMethod($job, $reflection, 'generate_runtime_environment_variables'); + + expect(collect($job->recordedLogEntries)->contains(fn (string $entry) => str_contains($entry, 'PORT environment variable')))->toBeFalse(); +}); diff --git a/tests/Feature/ApplicationPortMismatchWarningTest.php b/tests/Feature/ApplicationPortMismatchWarningTest.php new file mode 100644 index 0000000000..c47de2718b --- /dev/null +++ b/tests/Feature/ApplicationPortMismatchWarningTest.php @@ -0,0 +1,66 @@ +team = Team::factory()->create(); + $this->user = User::factory()->create(); + $this->team->members()->attach($this->user->id, ['role' => 'owner']); + + $this->actingAs($this->user); + session(['currentTeam' => $this->team]); + InstanceSettings::unguarded(function () { + InstanceSettings::updateOrCreate(['id' => 0], []); + }); + + $project = Project::factory()->create(['team_id' => $this->team->id]); + $environment = Environment::factory()->create(['project_id' => $project->id]); + $server = Server::factory()->create(['team_id' => $this->team->id]); + $destination = StandaloneDocker::where('server_id', $server->id)->first() + ?? StandaloneDocker::factory()->create(['server_id' => $server->id, 'network' => 'coolify-test']); + + $this->application = Application::factory()->create([ + 'environment_id' => $environment->id, + 'destination_id' => $destination->id, + 'destination_type' => StandaloneDocker::class, + 'build_pack' => 'dockerimage', + 'ports_exposes' => '80', + ]); + + EnvironmentVariable::create([ + 'key' => 'PORT', + 'value' => '3000', + 'resourceable_type' => Application::class, + 'resourceable_id' => $this->application->id, + 'is_preview' => false, + ]); +}); + +test('shows a PORT mismatch warning when readonly labels are enabled', function () { + Livewire::test(General::class, ['application' => $this->application->fresh()]) + ->assertSee('PORT mismatch detected'); +}); + +/** + * Regression for #10941: with readonly labels disabled, the Ports Exposes field is + * read-only and custom labels control proxy routing, so the warning cannot be acted on. + */ +test('does not show a PORT mismatch warning when readonly labels are disabled', function () { + $this->application->settings()->update(['is_container_label_readonly_enabled' => false]); + + Livewire::test(General::class, ['application' => $this->application->fresh()]) + ->assertDontSee('PORT mismatch detected'); +});