diff --git a/app/Livewire/Project/Application/Advanced.php b/app/Livewire/Project/Application/Advanced.php index cf7ef3e0b..bb1e58067 100644 --- a/app/Livewire/Project/Application/Advanced.php +++ b/app/Livewire/Project/Application/Advanced.php @@ -70,6 +70,9 @@ class Advanced extends Component #[Validate(['string', 'nullable'])] public ?string $customInternalName = null; + #[Validate(['string', 'nullable'])] + public ?string $customContainerNamePrefix = null; + #[Validate(['boolean'])] public bool $isGzipEnabled = true; @@ -111,6 +114,7 @@ class Advanced extends Component $this->application->settings->is_build_server_enabled = $this->isBuildServerEnabled; $this->application->settings->is_consistent_container_name_enabled = $this->isConsistentContainerNameEnabled; $this->application->settings->custom_internal_name = $this->customInternalName; + $this->application->settings->custom_container_name_prefix = $this->customContainerNamePrefix; $this->application->settings->is_gzip_enabled = $this->isGzipEnabled; $this->application->settings->is_stripprefix_enabled = $this->isStripprefixEnabled; $this->application->settings->is_raw_compose_deployment_enabled = $this->isRawComposeDeploymentEnabled; @@ -139,6 +143,7 @@ class Advanced extends Component $this->isBuildServerEnabled = $this->application->settings->is_build_server_enabled; $this->isConsistentContainerNameEnabled = $this->application->settings->is_consistent_container_name_enabled; $this->customInternalName = $this->application->settings->custom_internal_name; + $this->customContainerNamePrefix = $this->application->settings->custom_container_name_prefix; $this->isRawComposeDeploymentEnabled = $this->application->settings->is_raw_compose_deployment_enabled; $this->isConnectToDockerNetworkEnabled = $this->application->settings->connect_to_docker_network; $this->disableBuildCache = $this->application->settings->disable_build_cache; @@ -231,12 +236,19 @@ class Advanced extends Component return; } + + $this->customContainerNamePrefix = null; $customInternalName = $this->customInternalName; $server = $this->application->destination->server; $allApplications = $server->applications(); $foundSameInternalName = $allApplications->filter(function ($application) { - return $application->id !== $this->application->id && $application->settings->custom_internal_name === $this->customInternalName; + if ($application->id === $this->application->id) { + return false; + } + + return $application->settings->custom_internal_name === $this->customInternalName + || $application->settings->custom_container_name_prefix === $this->customInternalName; }); if ($foundSameInternalName->isNotEmpty()) { $this->dispatch('error', 'This custom container name is already in use by another application on this server.'); @@ -252,6 +264,50 @@ class Advanced extends Component } } + public function saveCustomNamePrefix() + { + try { + $this->authorize('update', $this->application); + + if (str($this->customContainerNamePrefix)->isNotEmpty()) { + $this->customContainerNamePrefix = str($this->customContainerNamePrefix)->slug()->value(); + } else { + $this->customContainerNamePrefix = null; + } + + if (is_null($this->customContainerNamePrefix)) { + $this->syncData(true); + $this->dispatch('success', 'Custom container name prefix saved.'); + + return; + } + + $this->customInternalName = null; + $server = $this->application->destination->server; + $allApplications = $server->applications(); + + $foundDuplicate = $allApplications->filter(function ($application) { + if ($application->id === $this->application->id) { + return false; + } + + return $application->settings->custom_container_name_prefix === $this->customContainerNamePrefix + || $application->settings->custom_internal_name === $this->customContainerNamePrefix; + }); + + if ($foundDuplicate->isNotEmpty()) { + $this->dispatch('error', 'This custom container name prefix is already in use by another application on this server.'); + + return; + } + + $this->syncData(true); + $this->dispatch('success', 'Custom container name prefix saved.'); + } catch (\Throwable $e) { + return handleError($e, $this); + } + } + public function render() { return view('livewire.project.application.advanced'); diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php index 7b74392cf..3372d5266 100644 --- a/bootstrap/helpers/docker.php +++ b/bootstrap/helpers/docker.php @@ -181,6 +181,7 @@ function generateApplicationContainerName(Application $application, $pull_reques // TODO: refactor generateApplicationContainerName, we do not need $application and $pull_request_id $consistent_container_name = $application->settings->is_consistent_container_name_enabled; + $custom_container_name_prefix = $application->settings->custom_container_name_prefix; $now = now()->format('Hisu'); if ($pull_request_id !== 0 && $pull_request_id !== null) { return $application->uuid.'-pr-'.$pull_request_id; @@ -189,7 +190,10 @@ function generateApplicationContainerName(Application $application, $pull_reques return $application->uuid; } - return $application->uuid.'-'.$now; + + $prefix = $custom_container_name_prefix ?? $application->uuid; + + return $prefix.'-'.$now; } } function get_port_from_dockerfile($dockerfile): ?int diff --git a/database/migrations/2026_02_02_000000_add_custom_container_name_prefix_to_application_settings.php b/database/migrations/2026_02_02_000000_add_custom_container_name_prefix_to_application_settings.php new file mode 100644 index 000000000..bbeb825e2 --- /dev/null +++ b/database/migrations/2026_02_02_000000_add_custom_container_name_prefix_to_application_settings.php @@ -0,0 +1,28 @@ +string('custom_container_name_prefix')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('application_settings', function (Blueprint $table) { + $table->dropColumn('custom_container_name_prefix'); + }); + } +}; diff --git a/resources/views/livewire/project/application/advanced.blade.php b/resources/views/livewire/project/application/advanced.blade.php index 907500dfa..2c7e4d743 100644 --- a/resources/views/livewire/project/application/advanced.blade.php +++ b/resources/views/livewire/project/application/advanced.blade.php @@ -63,10 +63,20 @@ @if ($isConsistentContainerNameEnabled === false)
+ @endif @if ($application->build_pack === 'dockercompose')