diff --git a/app/Livewire/Server/New/ByHetzner.php b/app/Livewire/Server/New/ByHetzner.php
index 0d65bc603..047d84d93 100644
--- a/app/Livewire/Server/New/ByHetzner.php
+++ b/app/Livewire/Server/New/ByHetzner.php
@@ -58,6 +58,10 @@ class ByHetzner extends Component
public bool $loading_data = false;
+ public bool $enable_ipv4 = true;
+
+ public bool $enable_ipv6 = true;
+
public function mount()
{
$this->authorize('viewAny', CloudProviderToken::class);
@@ -129,6 +133,8 @@ class ByHetzner extends Component
'private_key_id' => 'required|integer|exists:private_keys,id,team_id,'.currentTeam()->id,
'selectedHetznerSshKeyIds' => 'nullable|array',
'selectedHetznerSshKeyIds.*' => 'integer',
+ 'enable_ipv4' => 'required|boolean',
+ 'enable_ipv6' => 'required|boolean',
]);
}
@@ -410,6 +416,10 @@ class ByHetzner extends Component
'location' => $this->selected_location,
'start_after_create' => true,
'ssh_keys' => $sshKeys,
+ 'public_net' => [
+ 'enable_ipv4' => $this->enable_ipv4,
+ 'enable_ipv6' => $this->enable_ipv6,
+ ],
];
ray('Server creation parameters', $params);
@@ -438,10 +448,22 @@ class ByHetzner extends Component
// Create server on Hetzner
$hetznerServer = $this->createHetznerServer($hetznerToken);
+ // Determine IP address to use (prefer IPv4, fallback to IPv6)
+ $ipAddress = null;
+ if ($this->enable_ipv4 && isset($hetznerServer['public_net']['ipv4']['ip'])) {
+ $ipAddress = $hetznerServer['public_net']['ipv4']['ip'];
+ } elseif ($this->enable_ipv6 && isset($hetznerServer['public_net']['ipv6']['ip'])) {
+ $ipAddress = $hetznerServer['public_net']['ipv6']['ip'];
+ }
+
+ if (! $ipAddress) {
+ throw new \Exception('No public IP address available. Enable at least one of IPv4 or IPv6.');
+ }
+
// Create server in Coolify database
$server = Server::create([
'name' => $this->server_name,
- 'ip' => $hetznerServer['public_net']['ipv4']['ip'],
+ 'ip' => $ipAddress,
'user' => 'root',
'port' => 22,
'team_id' => currentTeam()->id,
diff --git a/resources/views/livewire/server/new/by-hetzner.blade.php b/resources/views/livewire/server/new/by-hetzner.blade.php
index ea1934b68..d53286c53 100644
--- a/resources/views/livewire/server/new/by-hetzner.blade.php
+++ b/resources/views/livewire/server/new/by-hetzner.blade.php
@@ -145,6 +145,17 @@
@endforeach
+
+
+
+
+
+
+
+
+
Back
diff --git a/tests/Feature/HetznerServerCreationTest.php b/tests/Feature/HetznerServerCreationTest.php
index 815462ffa..c939c0041 100644
--- a/tests/Feature/HetznerServerCreationTest.php
+++ b/tests/Feature/HetznerServerCreationTest.php
@@ -1,7 +1,94 @@
$enableIpv4,
+ 'enable_ipv6' => $enableIpv6,
+ ];
+
+ expect($publicNet)->toBe([
+ 'enable_ipv4' => true,
+ 'enable_ipv6' => true,
+ ]);
+});
+
+it('validates public_net configuration with IPv4 only', function () {
+ $enableIpv4 = true;
+ $enableIpv6 = false;
+
+ $publicNet = [
+ 'enable_ipv4' => $enableIpv4,
+ 'enable_ipv6' => $enableIpv6,
+ ];
+
+ expect($publicNet)->toBe([
+ 'enable_ipv4' => true,
+ 'enable_ipv6' => false,
+ ]);
+});
+
+it('validates public_net configuration with IPv6 only', function () {
+ $enableIpv4 = false;
+ $enableIpv6 = true;
+
+ $publicNet = [
+ 'enable_ipv4' => $enableIpv4,
+ 'enable_ipv6' => $enableIpv6,
+ ];
+
+ expect($publicNet)->toBe([
+ 'enable_ipv4' => false,
+ 'enable_ipv6' => true,
+ ]);
+});
+
+it('validates IP address selection prefers IPv4 when both are enabled', function () {
+ $enableIpv4 = true;
+ $enableIpv6 = true;
+
+ $hetznerServer = [
+ 'public_net' => [
+ 'ipv4' => ['ip' => '1.2.3.4'],
+ 'ipv6' => ['ip' => '2001:db8::1'],
+ ],
+ ];
+
+ $ipAddress = null;
+ if ($enableIpv4 && isset($hetznerServer['public_net']['ipv4']['ip'])) {
+ $ipAddress = $hetznerServer['public_net']['ipv4']['ip'];
+ } elseif ($enableIpv6 && isset($hetznerServer['public_net']['ipv6']['ip'])) {
+ $ipAddress = $hetznerServer['public_net']['ipv6']['ip'];
+ }
+
+ expect($ipAddress)->toBe('1.2.3.4');
+});
+
+it('validates IP address selection uses IPv6 when only IPv6 is enabled', function () {
+ $enableIpv4 = false;
+ $enableIpv6 = true;
+
+ $hetznerServer = [
+ 'public_net' => [
+ 'ipv4' => ['ip' => '1.2.3.4'],
+ 'ipv6' => ['ip' => '2001:db8::1'],
+ ],
+ ];
+
+ $ipAddress = null;
+ if ($enableIpv4 && isset($hetznerServer['public_net']['ipv4']['ip'])) {
+ $ipAddress = $hetznerServer['public_net']['ipv4']['ip'];
+ } elseif ($enableIpv6 && isset($hetznerServer['public_net']['ipv6']['ip'])) {
+ $ipAddress = $hetznerServer['public_net']['ipv6']['ip'];
+ }
+
+ expect($ipAddress)->toBe('2001:db8::1');
+});
it('validates SSH key array merging logic with Coolify key', function () {
$coolifyKeyId = 123;