diff --git a/app/Actions/Application/StopApplication.php b/app/Actions/Application/StopApplication.php index 8ecebeda3..a98384f45 100644 --- a/app/Actions/Application/StopApplication.php +++ b/app/Actions/Application/StopApplication.php @@ -3,7 +3,6 @@ namespace App\Actions\Application; use App\Models\Application; -use App\Notifications\Application\StatusChanged; use Lorisleiva\Actions\Concerns\AsAction; class StopApplication @@ -12,7 +11,7 @@ class StopApplication public function handle(Application $application) { $server = $application->destination->server; - $containers = getCurrentApplicationContainerStatus($server, $application->id); + $containers = getCurrentApplicationContainerStatus($server, $application->id, 0); if ($containers->count() > 0) { foreach ($containers as $container) { $containerName = data_get($container, 'Names'); diff --git a/app/Http/Livewire/Project/Shared/Logs.php b/app/Http/Livewire/Project/Shared/Logs.php index 2b0561800..f58ec672a 100644 --- a/app/Http/Livewire/Project/Shared/Logs.php +++ b/app/Http/Livewire/Project/Shared/Logs.php @@ -31,7 +31,7 @@ class Logs extends Component $this->resource = Application::where('uuid', $this->parameters['application_uuid'])->firstOrFail(); $this->status = $this->resource->status; $this->server = $this->resource->destination->server; - $containers = getCurrentApplicationContainerStatus($this->server, $this->resource->id); + $containers = getCurrentApplicationContainerStatus($this->server, $this->resource->id, 0); if ($containers->count() > 0) { $this->container = data_get($containers[0], 'Names'); } diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 798c46b2b..1b7f4d492 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -52,7 +52,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted private GithubApp|GitlabApp|string $source = 'other'; private StandaloneDocker|SwarmDocker $destination; private Server $server; - private ApplicationPreview|null $preview = null; + private ?ApplicationPreview $preview = null; private string $container_name; private ?string $currently_running_container_name = null; @@ -139,21 +139,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted public function handle(): void { - // ray()->measure(); - $containers = getCurrentApplicationContainerStatus($this->server, $this->application->id, $this->pull_request_id); - if ($containers->count() === 1) { - $this->currently_running_container_name = data_get($containers[0], 'Names'); - } else { - $foundContainer = $containers->filter(function ($container) { - return !str(data_get($container, 'Names'))->startsWith("{$this->application->uuid}-pr-"); - })->first(); - if ($foundContainer) { - $this->currently_running_container_name = data_get($foundContainer, 'Names'); - } - } - if ($this->pull_request_id !== 0 && $this->pull_request_id !== null) { - $this->currently_running_container_name = $this->container_name; - } $this->application_deployment_queue->update([ 'status' => ApplicationDeploymentStatus::IN_PROGRESS->value, ]); @@ -502,6 +487,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted } private function deploy_pull_request() { + $this->newVersionIsHealthy = true; $this->generate_image_names(); $this->execute_remote_command([ "echo 'Starting pull request (#{$this->pull_request_id}) deployment of {$this->customRepository}:{$this->application->git_branch}.'", @@ -518,12 +504,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted // $this->generate_build_env_variables(); // $this->add_build_env_variables_to_dockerfile(); $this->build_image(); - if ($this->currently_running_container_name) { - $this->execute_remote_command( - ["echo -n 'Removing old version of your application.'"], - [executeInDocker($this->deployment_uuid, "docker rm -f $this->currently_running_container_name >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true], - ); - } + $this->stop_running_container(); $this->execute_remote_command( ["echo -n 'Starting preview deployment.'"], [executeInDocker($this->deployment_uuid, "docker compose --project-directory {$this->workdir} up -d"), "hidden" => true], @@ -980,18 +961,30 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf"); private function stop_running_container(bool $force = false) { - if ($this->currently_running_container_name) { - if ($this->newVersionIsHealthy || $force) { - $this->execute_remote_command( - ["echo -n 'Removing old version of your application.'"], - [executeInDocker($this->deployment_uuid, "docker rm -f $this->currently_running_container_name >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true], - ); + $this->execute_remote_command(["echo -n 'Removing old version of your application.'"]); + + if ($this->newVersionIsHealthy || $force) { + $containers = getCurrentApplicationContainerStatus($this->server, $this->application->id, $this->pull_request_id); + if ($this->pull_request_id !== 0) { + $containers = $containers->filter(function ($container) { + return data_get($container, 'Names') === $this->container_name; + }); } else { - $this->execute_remote_command( - ["echo -n 'New version is not healthy, rolling back to the old version.'"], - [executeInDocker($this->deployment_uuid, "docker rm -f $this->container_name >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true], - ); + $containers = $containers->filter(function ($container) { + return data_get($container, 'Names') !== $this->container_name; + }); } + $containers->each(function ($container) { + $containerName = data_get($container, 'Names'); + $this->execute_remote_command( + [executeInDocker($this->deployment_uuid, "docker rm -f $containerName >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true], + ); + }); + } else { + $this->execute_remote_command( + ["echo -n 'New version is not healthy, rolling back to the old version.'"], + [executeInDocker($this->deployment_uuid, "docker rm -f $this->container_name >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true], + ); } } @@ -1057,8 +1050,11 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf"); { $this->execute_remote_command( ["echo 'Oops something is not okay, are you okay? 😢'"], - ["echo '{$exception->getMessage()}'"] + ["echo '{$exception->getMessage()}'"], + ["echo -n 'Deployment failed. Removing the new version of your application.'"], + [executeInDocker($this->deployment_uuid, "docker rm -f $this->container_name >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true] ); + $this->next(ApplicationDeploymentStatus::FAILED->value); } } diff --git a/app/Notifications/Application/DeploymentFailed.php b/app/Notifications/Application/DeploymentFailed.php index a379cd46f..2d8ae381a 100644 --- a/app/Notifications/Application/DeploymentFailed.php +++ b/app/Notifications/Application/DeploymentFailed.php @@ -84,11 +84,14 @@ class DeploymentFailed extends Notification implements ShouldQueue } else { $message = 'Coolify: Deployment failed of **' . $this->application_name . '** (' . $this->fqdn . '): '; } + $buttons[] = [ + "text" => "Deployment logs", + "url" => $this->deployment_url + ]; return [ "message" => $message, "buttons" => [ - "text" => "View Deployment Logs", - "url" => $this->deployment_url + ...$buttons ], ]; } diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php index 874b01ebd..90c4179a7 100644 --- a/bootstrap/helpers/docker.php +++ b/bootstrap/helpers/docker.php @@ -10,15 +10,24 @@ use Visus\Cuid2\Cuid2; function getCurrentApplicationContainerStatus(Server $server, int $id, ?int $pullRequestId = null): Collection { - if ($pullRequestId) { - $containers = instant_remote_process(["docker ps -a --filter='label=coolify.applicationId={$id}' --filter='label=coolify.pullRequestId={$pullRequestId}' --format '{{json .}}' "], $server); - } else { - $containers = instant_remote_process(["docker ps -a --filter='label=coolify.applicationId={$id}' --format '{{json .}}'"], $server); - } - if (!$containers) { - return collect([]); - } - return format_docker_command_output_to_json($containers); + ray($id, $pullRequestId); + $containers = collect([]); + $containers = instant_remote_process(["docker ps -a --filter='label=coolify.applicationId={$id}' --format '{{json .}}' "], $server); + $containers = format_docker_command_output_to_json($containers); + $containers = $containers->map(function ($container) use ($pullRequestId) { + $labels = data_get($container, 'Labels'); + if (!str($labels)->contains("coolify.pullRequestId=")) { + data_set($container, 'Labels', $labels . ",coolify.pullRequestId={$pullRequestId}"); + return $container; + } + if (str($labels)->contains("coolify.pullRequestId=$pullRequestId")) { + return $container; + } + return null; + }); + $containers = $containers->filter(); + ray($containers); + return $containers; } function format_docker_command_output_to_json($rawOutput): Collection @@ -128,9 +137,7 @@ function defaultLabels($id, $name, $pull_request_id = 0, string $type = 'applica $labels->push("coolify." . $type . "Id=" . $id); $labels->push("coolify.type=$type"); $labels->push('coolify.name=' . $name); - if ($pull_request_id !== 0) { - $labels->push('coolify.pullRequestId=' . $pull_request_id); - } + $labels->push('coolify.pullRequestId=' . $pull_request_id); if ($type === 'service') { $labels->push('coolify.service.subId=' . $subId); $labels->push('coolify.service.subType=' . $subType); diff --git a/config/sentry.php b/config/sentry.php index b499fe319..833a0deca 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.115', + 'release' => '4.0.0-beta.116', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index 4c86b6ee4..7cbe50d82 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ + 'hover:bg-coolgray-200' => data_get($deployment, 'status') === 'queued' || data_get($deployment, 'status') === 'cancelled by system', 'border-warning hover:bg-warning hover:text-black' => diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php index 475763e41..31f0e1cdc 100644 --- a/resources/views/livewire/project/application/general.blade.php +++ b/resources/views/livewire/project/application/general.blade.php @@ -50,9 +50,9 @@

Build

@if ($application->could_set_build_commands()) @if ($application->build_pack === 'nixpacks') -
Nixpacks will detect your package manager/configurations: Nixpacks documentation
-
You probably do not need to modify the commands below.
+
Nixpacks will detect the required configuration automatically. + Framework Specific Docs +
@@ -72,7 +72,8 @@ - + @endif @if ($application->could_set_build_commands()) @if ($application->settings->is_static) diff --git a/versions.json b/versions.json index aeca3f8a1..7923441d3 100644 --- a/versions.json +++ b/versions.json @@ -4,7 +4,7 @@ "version": "3.12.36" }, "v4": { - "version": "4.0.0-beta.115" + "version": "4.0.0-beta.116" } } }