From de4e74b4cd8aaaf323fcea5c102d3b1046ac0a18 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Fri, 7 Aug 2026 15:41:39 +0200 Subject: [PATCH] feat(server): fall back Sentinel URL to request host Use the current request scheme/host when no FQDN or public IP is set, skipping loopback hosts. Polish boarding/server create cards, optional listbox tooltips, and cover the layout and Sentinel URL behavior in tests. --- app/Models/ServerSetting.php | 27 +++++- .../views/components/forms/listbox.blade.php | 3 +- .../views/livewire/boarding/index.blade.php | 84 +++++++------------ .../views/livewire/server/create.blade.php | 23 +---- .../views/livewire/server/index.blade.php | 11 +-- .../server/new/by-digital-ocean.blade.php | 12 ++- .../views/livewire/server/new/by-ip.blade.php | 2 +- .../livewire/server/new/by-vultr.blade.php | 12 ++- tests/Feature/BoardingActionsLayoutTest.php | 58 +++++++++++++ tests/Feature/SentinelTokenValidationTest.php | 36 ++++++++ tests/Feature/ServerCreatePageLayoutTest.php | 10 +++ .../ServerCreationBuildRoleLayoutTest.php | 1 + tests/Feature/ServerIndexViewSwitcherTest.php | 10 +++ .../StartSentinelEndpointFallbackTest.php | 3 +- 14 files changed, 203 insertions(+), 89 deletions(-) diff --git a/app/Models/ServerSetting.php b/app/Models/ServerSetting.php index 3bd39aeb1..93f040e4a 100644 --- a/app/Models/ServerSetting.php +++ b/app/Models/ServerSetting.php @@ -228,7 +228,7 @@ class ServerSetting extends Model } if (blank($url)) { - throw new \RuntimeException('Set an instance FQDN or public IP before enabling Sentinel.'); + throw new \RuntimeException('Set an instance FQDN, public IP, or reachable Coolify URL before enabling Sentinel.'); } return $url; @@ -246,6 +246,8 @@ class ServerSetting extends Model $domain = 'http://'.$settings->public_ipv4.':8000'; } elseif ($settings->public_ipv6) { $domain = 'http://'.$settings->public_ipv6.':8000'; + } else { + $domain = $this->sentinelUrlFromCurrentRequest(); } $this->sentinel_custom_url = $domain; if ($save) { @@ -259,6 +261,29 @@ class ServerSetting extends Model return $domain; } + private function sentinelUrlFromCurrentRequest(): ?string + { + if (! app()->bound('request')) { + return null; + } + + $request = request(); + $host = strtolower($request->getHost()); + + if ( + $host === 'localhost' || + str_ends_with($host, '.localhost') || + $host === '::1' || + $host === '::' || + $host === '0.0.0.0' || + str_starts_with($host, '127.') + ) { + return null; + } + + return $request->getSchemeAndHttpHost(); + } + public function server() { return $this->belongsTo(Server::class); diff --git a/resources/views/components/forms/listbox.blade.php b/resources/views/components/forms/listbox.blade.php index eb32de577..050bea8b3 100644 --- a/resources/views/components/forms/listbox.blade.php +++ b/resources/views/components/forms/listbox.blade.php @@ -11,6 +11,7 @@ 'wire' => true, // false = purely client-side value (no Livewire binding) 'value' => null, // initial value when wire=false 'disabled' => false, + 'tooltip' => true, ])
@@ -53,7 +54,7 @@ @click.outside="open = false" @keydown.escape="open = false">
- -

- Group related resources (apps, databases, - services) - into logical projects. -

-

- Each project includes a production environment by - default. - Add staging, development, or custom environments as needed. -

-

- Projects inherit team permissions and can be managed - collaboratively. -

-
@elseif ($currentState === 'create-resource') diff --git a/resources/views/livewire/server/create.blade.php b/resources/views/livewire/server/create.blade.php index fea01333e..9b42400bd 100644 --- a/resources/views/livewire/server/create.blade.php +++ b/resources/views/livewire/server/create.blade.php @@ -3,7 +3,7 @@ New Server | Coolify -
+

New server

@if ($selectedType) @@ -11,27 +11,6 @@ Change method @endif - @if ($selectedType && $selectedType !== 'manual' && ! $selectedTokenUuid) - @php - $tokenProvider = $selectedType === 'digital-ocean' ? 'digitalocean' : $selectedType; - $tokenProviderName = $selectedType === 'digital-ocean' - ? 'DigitalOcean' - : str($selectedType)->headline(); - @endphp - @can('create', App\Models\CloudProviderToken::class) - - - - - - - @endcan - @endif
diff --git a/resources/views/livewire/server/index.blade.php b/resources/views/livewire/server/index.blade.php index d1dda5920..9faae18c5 100644 --- a/resources/views/livewire/server/index.blade.php +++ b/resources/views/livewire/server/index.blade.php @@ -24,7 +24,6 @@ 'uuid' => $server->uuid, 'name' => $server->name, 'description' => $server->description ?: 'No description', - 'address' => $server->ip, 'href' => route('server.show', ['server_uuid' => $server->uuid]), 'status' => $isReady ? 'Ready' : ($server->settings->force_disabled ? 'Disabled' : 'Validation required'), 'statusType' => $isReady ? 'success' : 'error', @@ -41,7 +40,7 @@ const query = this.search.trim().toLowerCase(); if (!query) return this.servers; return this.servers.filter(server => - [server.name, server.description, server.address, server.status] + [server.name, server.description, server.status] .some(value => String(value || '').toLowerCase().includes(query)) ); }, @@ -109,7 +108,7 @@

+ x-text="server.description">

@@ -126,14 +125,13 @@
+ class="grid min-w-[480px] grid-cols-[minmax(0,1fr)_9.5rem] border-b border-neutral-200 bg-neutral-50 px-4 py-2.5 text-[11px] font-medium text-neutral-500 dark:border-white/[0.08] dark:bg-white/[0.025] dark:text-fg-faint">
Server
-
Address
Status