diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index efa906388..da66671f3 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -869,7 +869,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted $this->write_deployment_configurations(); $this->server = $this->original_server; } - if (count($this->application->ports_mappings_array) > 0 || (bool) $this->application->settings->is_consistent_container_name_enabled || $this->pull_request_id !== 0 || str($this->application->custom_docker_run_options)->contains('--ip') || str($this->application->custom_docker_run_options)->contains('--ip6')) { + if (count($this->application->ports_mappings_array) > 0 || (bool) $this->application->settings->is_consistent_container_name_enabled || isset($this->application->settings->custom_internal_name) || $this->pull_request_id !== 0 || str($this->application->custom_docker_run_options)->contains('--ip') || str($this->application->custom_docker_run_options)->contains('--ip6')) { $this->application_deployment_queue->addLogEntry("----------------------------------------"); if (count($this->application->ports_mappings_array) > 0) { $this->application_deployment_queue->addLogEntry("Application has ports mapped to the host system, rolling update is not supported."); @@ -877,6 +877,9 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted if ((bool) $this->application->settings->is_consistent_container_name_enabled) { $this->application_deployment_queue->addLogEntry("Consistent container name feature enabled, rolling update is not supported."); } + if (isset($this->application->settings->custom_internal_name)) { + $this->application_deployment_queue->addLogEntry("Custom internal name is set, rolling update is not supported."); + } if ($this->pull_request_id !== 0) { $this->application->settings->is_consistent_container_name_enabled = true; $this->application_deployment_queue->addLogEntry("Pull request deployment, rolling update is not supported."); @@ -1292,7 +1295,9 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted 'restart' => RESTART_MODE, 'expose' => $ports, 'networks' => [ - $this->destination->network, + $this->destination->network => [ + 'aliases' => [] + ] ], 'mem_limit' => $this->application->limits_memory, 'memswap_limit' => $this->application->limits_memory_swap, @@ -1310,6 +1315,9 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted ] ] ]; + if (isset($this->application->settings->custom_internal_name)) { + $docker_compose['services'][$this->container_name]['networks'][$this->destination->network]['aliases'][] = $this->application->settings->custom_internal_name; + } // if (str($this->saved_outputs->get('dotenv'))->isNotEmpty()) { // if (data_get($docker_compose, "services.{$this->container_name}.env_file")) { // $docker_compose['services'][$this->container_name]['env_file'][] = '.env'; @@ -1519,95 +1527,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted return $local_persistent_volumes_names; } - /*private function generate_environment_variables($ports) - { - $environment_variables = collect(); - if ($this->pull_request_id === 0) { - foreach ($this->application->runtime_environment_variables as $env) { - // This is necessary because we have to escape the value of the environment variable - // but only if the environment variable is created after 4.0.0-beta.240 - // when I implemented the escaping feature. - - // Old environment variables are not escaped, because it could break the application - // as the application could expect the unescaped value. - if ($env->version === '4.0.0-beta.239') { - $real_value = $env->real_value; - } else { - $real_value = escapeEnvVariables($env->real_value); - } - if ($env->is_literal) { - $real_value = escapeDollarSign($real_value); - $environment_variables->push("$env->key='$real_value'"); - } else { - $environment_variables->push("$env->key=$real_value"); - } - } - foreach ($this->application->nixpacks_environment_variables as $env) { - if ($env->version === '4.0.0-beta.239') { - $real_value = $env->real_value; - } else { - $real_value = escapeEnvVariables($env->real_value); - } - if ($env->is_literal) { - $real_value = escapeDollarSign($real_value); - $environment_variables->push("$env->key='$real_value'"); - } else { - $environment_variables->push("$env->key=$real_value"); - } - } - } else { - foreach ($this->application->runtime_environment_variables_preview as $env) { - if ($env->version === '4.0.0-beta.239') { - $real_value = $env->real_value; - } else { - $real_value = escapeEnvVariables($env->real_value); - } - if ($env->is_literal) { - $real_value = escapeDollarSign($real_value); - $environment_variables->push("$env->key='$real_value'"); - } else { - $environment_variables->push("$env->key=$real_value"); - } - } - foreach ($this->application->nixpacks_environment_variables_preview as $env) { - if ($env->version === '4.0.0-beta.239') { - $real_value = $env->real_value; - } else { - $real_value = escapeEnvVariables($env->real_value); - } - if ($env->is_literal) { - $real_value = escapeDollarSign($real_value); - $environment_variables->push("$env->key='$real_value'"); - } else { - $environment_variables->push("$env->key=$real_value"); - } - } - } - // Add PORT if not exists, use the first port as default - if ($environment_variables->filter(fn ($env) => Str::of($env)->startsWith('PORT'))->isEmpty()) { - $environment_variables->push("PORT={$ports[0]}"); - } - // Add HOST if not exists - if ($environment_variables->filter(fn ($env) => Str::of($env)->startsWith('HOST'))->isEmpty()) { - $environment_variables->push("HOST=0.0.0.0"); - } - if ($environment_variables->filter(fn ($env) => Str::of($env)->startsWith('SOURCE_COMMIT'))->isEmpty()) { - if (!is_null($this->commit)) { - $environment_variables->push("SOURCE_COMMIT={$this->commit}"); - } else { - $environment_variables->push("SOURCE_COMMIT=unknown"); - } - } - ray($environment_variables->all()); - return $environment_variables->all(); - }*/ - private function generate_healthcheck_commands() { - // if ($this->application->dockerfile || $this->application->build_pack === 'dockerfile' || $this->application->build_pack === 'dockerimage') { - // // TODO: disabled HC because there are several ways to hc a simple docker image, hard to figure out a good way. Like some docker images (pocketbase) does not have curl. - // return 'exit 0'; - // } if (!$this->application->health_check_port) { $health_check_port = $this->application->ports_exposes_array[0]; } else { @@ -1619,12 +1540,12 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted if ($this->application->health_check_path) { $this->full_healthcheck_url = "{$this->application->health_check_method}: {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}{$this->application->health_check_path}"; $generated_healthchecks_commands = [ - "curl -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}{$this->application->health_check_path} > /dev/null" + "curl -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}{$this->application->health_check_path} > /dev/null || wget -q -O- {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}{$this->application->health_check_path} > /dev/null || exit 1" ]; } else { $this->full_healthcheck_url = "{$this->application->health_check_method}: {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}/"; $generated_healthchecks_commands = [ - "curl -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}/" + "curl -s -X {$this->application->health_check_method} -f {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}/ > /dev/null || wget -q -O- {$this->application->health_check_scheme}://{$this->application->health_check_host}:{$health_check_port}/ > /dev/null || exit 1" ]; } return implode(' ', $generated_healthchecks_commands); @@ -1813,12 +1734,17 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf"); ["docker rm -f $containerName >/dev/null 2>&1", "hidden" => true, "ignore_errors" => true], ); }); - if ($this->application->settings->is_consistent_container_name_enabled) { + if ($this->application->settings->is_consistent_container_name_enabled || isset($this->application->settings->custom_internal_name)) { $this->execute_remote_command( ["docker rm -f $this->container_name >/dev/null 2>&1", "hidden" => true, "ignore_errors" => true], ); } } else { + if ($this->application->dockerfile || $this->application->build_pack === 'dockerfile' || $this->application->build_pack === 'dockerimage') { + $this->application_deployment_queue->addLogEntry("----------------------------------------"); + $this->application_deployment_queue->addLogEntry("WARNING: Dockerfile or Docker Image based deployment detected. The healthcheck needs a curl or wget command to check the health of the application. Please make sure that it is available in the image or turn off healthcheck on Coolify's UI."); + $this->application_deployment_queue->addLogEntry("----------------------------------------"); + } $this->application_deployment_queue->addLogEntry("New container is not healthy, rolling back to the old container."); $this->application_deployment_queue->update([ 'status' => ApplicationDeploymentStatus::FAILED->value, diff --git a/app/Livewire/Project/Application/Advanced.php b/app/Livewire/Project/Application/Advanced.php index d35867e8f..45cb57ee3 100644 --- a/app/Livewire/Project/Application/Advanced.php +++ b/app/Livewire/Project/Application/Advanced.php @@ -21,6 +21,7 @@ class Advanced extends Component 'application.settings.is_gpu_enabled' => 'boolean|required', 'application.settings.is_build_server_enabled' => 'boolean|required', 'application.settings.is_consistent_container_name_enabled' => 'boolean|required', + 'application.settings.custom_internal_name' => 'string|nullable', 'application.settings.is_gzip_enabled' => 'boolean|required', 'application.settings.is_stripprefix_enabled' => 'boolean|required', 'application.settings.gpu_driver' => 'string|required', @@ -30,7 +31,8 @@ class Advanced extends Component 'application.settings.is_raw_compose_deployment_enabled' => 'boolean|required', 'application.settings.connect_to_docker_network' => 'boolean|required', ]; - public function mount() { + public function mount() + { $this->is_force_https_enabled = $this->application->isForceHttpsEnabled(); $this->is_gzip_enabled = $this->application->isGzipEnabled(); $this->is_stripprefix_enabled = $this->application->isStripprefixEnabled(); @@ -65,7 +67,8 @@ class Advanced extends Component $this->dispatch('success', 'Settings saved.'); $this->dispatch('configurationChanged'); } - public function submit() { + public function submit() + { if ($this->application->settings->gpu_count && $this->application->settings->gpu_device_ids) { $this->dispatch('error', 'You cannot set both GPU count and GPU device IDs.'); $this->application->settings->gpu_count = null; @@ -76,6 +79,16 @@ class Advanced extends Component $this->application->settings->save(); $this->dispatch('success', 'Settings saved.'); } + public function saveCustomName() + { + if (isset($this->application->settings->custom_internal_name)) { + $this->application->settings->custom_internal_name = str($this->application->settings->custom_internal_name)->slug()->value(); + } else { + $this->application->settings->custom_internal_name = null; + } + $this->application->settings->save(); + $this->dispatch('success', 'Custom name saved.'); + } public function render() { return view('livewire.project.application.advanced'); diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 6c5ec2319..f11a9e416 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -1920,7 +1920,6 @@ function check_domain_usage(ServiceApplication|Application|null $resource = null $naked_domain = str($domain)->value(); if ($domains->contains($naked_domain)) { if (data_get($resource, 'uuid')) { - ray($resource->uuid, $app->uuid); if ($resource->uuid !== $app->uuid) { throw new \RuntimeException("Domain $naked_domain is already in use by another resource called:

{$app->name}."); } diff --git a/database/migrations/2024_05_06_093236_add_custom_name_to_application_settings.php b/database/migrations/2024_05_06_093236_add_custom_name_to_application_settings.php new file mode 100644 index 000000000..e2d68d240 --- /dev/null +++ b/database/migrations/2024_05_06_093236_add_custom_name_to_application_settings.php @@ -0,0 +1,28 @@ +string('custom_internal_name')->nullable(); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('application_settings', function (Blueprint $table) { + $table->dropColumn('custom_internal_name'); + }); + } +}; diff --git a/resources/views/components/popup-small.blade.php b/resources/views/components/popup-small.blade.php index 97ed025fe..ba6839bab 100644 --- a/resources/views/components/popup-small.blade.php +++ b/resources/views/components/popup-small.blade.php @@ -8,7 +8,7 @@ x-transition:leave-end="translate-y-full" x-init="setTimeout(() => { bannerVisible = true }, bannerVisibleAfter);" class="fixed bottom-0 right-0 h-auto duration-300 ease-out px-5 pb-5 max-w-[46rem] z-[999]" x-cloak>
+ class="flex flex-col items-center justify-between w-full h-full max-w-4xl p-6 mx-auto bg-white border shadow-lg lg:border-t dark:border-coolgray-300 dark:bg-coolgray-100 hover:dark:bg-coolgray-100 lg:p-8 lg:flex-row sm:rounded">
@if (isset($icon)) diff --git a/resources/views/livewire/project/application/advanced.blade.php b/resources/views/livewire/project/application/advanced.blade.php index 5d2922a7e..a2aab3fbc 100644 --- a/resources/views/livewire/project/application/advanced.blade.php +++ b/resources/views/livewire/project/application/advanced.blade.php @@ -16,10 +16,6 @@ - @@ -30,6 +26,17 @@ label="Raw Compose Deployment" helper="WARNING: Advanced use cases only. Your docker compose file will be deployed as-is. Nothing is modified by Coolify. You need to configure the proxy parts. More info in the documentation." /> @endif +

Container Names

+ +
+ + Save + @if ($application->build_pack === 'dockercompose')

Network