diff --git a/CHANGELOG.md b/CHANGELOG.md index 2df7cc9752..6290e382e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), - Save the update channel in **Settings > Updates** when you select **Preview** or **Nightly**. Before, the "Save changes" bar did not open for these channels, so the change was lost when you refreshed the page - Save the healthcheck **Check type** when it is the only change. Before, the "Save changes" bar did not open when you changed only the check type, for example from **Container command** back to **HTTP request** - Coolify Cloud: end a paid subscription that lost its link to Stripe when the customer cancels it. Before, it stayed active, and `cloud:sync-stripe-subscriptions` did not report it +- Keep the dashboard proxy configuration of a server with the IP `host.docker.internal` that is not the default localhost server. Before, Coolify did not see this server as localhost after it saved the server, for example after a proxy restart, and deleted `coolify.yaml`, so the dashboard was not reachable at its domain ([#12444](https://github.com/coollabsio/coolify/issues/12444)) ## [v4.6.0] - 2026-11-02 diff --git a/app/Models/Server.php b/app/Models/Server.php index c2e36b1fd6..9ce8903655 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -179,10 +179,10 @@ class Server extends BaseModel static::saving(function ($server) { $payload = []; if ($server->user) { - $payload['user'] = str($server->user)->trim(); + $payload['user'] = trim($server->user); } if ($server->ip) { - $payload['ip'] = str($server->ip)->trim(); + $payload['ip'] = trim($server->ip); // Update ip_previous when ip is being changed if ($server->isDirty('ip') && $server->getOriginal('ip')) { diff --git a/tests/Feature/Server/ServerSavingKeepsStringAttributesTest.php b/tests/Feature/Server/ServerSavingKeepsStringAttributesTest.php new file mode 100644 index 0000000000..ccea358156 --- /dev/null +++ b/tests/Feature/Server/ServerSavingKeepsStringAttributesTest.php @@ -0,0 +1,44 @@ + 0]); + $team = Team::factory()->create(); + $privateKey = PrivateKey::factory()->create(['team_id' => $team->id]); + $this->server = Server::factory()->create([ + 'team_id' => $team->id, + 'private_key_id' => $privateKey->id, + 'ip' => ' host.docker.internal ', + 'user' => ' root ', + ]); +}); + +it('keeps ip and user as trimmed strings on the same instance after save', function () { + expect($this->server->id)->not->toBe(0) + ->and($this->server->ip)->toBe('host.docker.internal') + ->and($this->server->user)->toBe('root') + ->and($this->server->isLocalhost())->toBeTrue(); + + $this->server->save(); + + expect($this->server->ip)->toBe('host.docker.internal') + ->and($this->server->user)->toBe('root') + ->and($this->server->isLocalhost())->toBeTrue(); +}); + +it('returns the normalized ip after save, not the raw input', function () { + $this->server->update(['ip' => ' 2A01:04F8::0001 ']); + + expect($this->server->ip)->toBe('2a01:4f8::1') + ->and($this->server->fresh()->ip)->toBe('2a01:4f8::1'); +});