commit
a2c39fd07e
@ -3,7 +3,6 @@
|
|||||||
namespace App\Actions\Application;
|
namespace App\Actions\Application;
|
||||||
|
|
||||||
use App\Models\Application;
|
use App\Models\Application;
|
||||||
use App\Notifications\Application\StatusChanged;
|
|
||||||
use Lorisleiva\Actions\Concerns\AsAction;
|
use Lorisleiva\Actions\Concerns\AsAction;
|
||||||
|
|
||||||
class StopApplication
|
class StopApplication
|
||||||
@ -12,7 +11,7 @@ class StopApplication
|
|||||||
public function handle(Application $application)
|
public function handle(Application $application)
|
||||||
{
|
{
|
||||||
$server = $application->destination->server;
|
$server = $application->destination->server;
|
||||||
$containers = getCurrentApplicationContainerStatus($server, $application->id);
|
$containers = getCurrentApplicationContainerStatus($server, $application->id, 0);
|
||||||
if ($containers->count() > 0) {
|
if ($containers->count() > 0) {
|
||||||
foreach ($containers as $container) {
|
foreach ($containers as $container) {
|
||||||
$containerName = data_get($container, 'Names');
|
$containerName = data_get($container, 'Names');
|
||||||
|
@ -31,7 +31,7 @@ class Logs extends Component
|
|||||||
$this->resource = Application::where('uuid', $this->parameters['application_uuid'])->firstOrFail();
|
$this->resource = Application::where('uuid', $this->parameters['application_uuid'])->firstOrFail();
|
||||||
$this->status = $this->resource->status;
|
$this->status = $this->resource->status;
|
||||||
$this->server = $this->resource->destination->server;
|
$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) {
|
if ($containers->count() > 0) {
|
||||||
$this->container = data_get($containers[0], 'Names');
|
$this->container = data_get($containers[0], 'Names');
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
private GithubApp|GitlabApp|string $source = 'other';
|
private GithubApp|GitlabApp|string $source = 'other';
|
||||||
private StandaloneDocker|SwarmDocker $destination;
|
private StandaloneDocker|SwarmDocker $destination;
|
||||||
private Server $server;
|
private Server $server;
|
||||||
private ApplicationPreview|null $preview = null;
|
private ?ApplicationPreview $preview = null;
|
||||||
|
|
||||||
private string $container_name;
|
private string $container_name;
|
||||||
private ?string $currently_running_container_name = null;
|
private ?string $currently_running_container_name = null;
|
||||||
@ -139,21 +139,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
|
|
||||||
public function handle(): void
|
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([
|
$this->application_deployment_queue->update([
|
||||||
'status' => ApplicationDeploymentStatus::IN_PROGRESS->value,
|
'status' => ApplicationDeploymentStatus::IN_PROGRESS->value,
|
||||||
]);
|
]);
|
||||||
@ -502,6 +487,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
}
|
}
|
||||||
private function deploy_pull_request()
|
private function deploy_pull_request()
|
||||||
{
|
{
|
||||||
|
$this->newVersionIsHealthy = true;
|
||||||
$this->generate_image_names();
|
$this->generate_image_names();
|
||||||
$this->execute_remote_command([
|
$this->execute_remote_command([
|
||||||
"echo 'Starting pull request (#{$this->pull_request_id}) deployment of {$this->customRepository}:{$this->application->git_branch}.'",
|
"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->generate_build_env_variables();
|
||||||
// $this->add_build_env_variables_to_dockerfile();
|
// $this->add_build_env_variables_to_dockerfile();
|
||||||
$this->build_image();
|
$this->build_image();
|
||||||
if ($this->currently_running_container_name) {
|
$this->stop_running_container();
|
||||||
$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(
|
$this->execute_remote_command(
|
||||||
["echo -n 'Starting preview deployment.'"],
|
["echo -n 'Starting preview deployment.'"],
|
||||||
[executeInDocker($this->deployment_uuid, "docker compose --project-directory {$this->workdir} up -d"), "hidden" => true],
|
[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)
|
private function stop_running_container(bool $force = false)
|
||||||
{
|
{
|
||||||
if ($this->currently_running_container_name) {
|
$this->execute_remote_command(["echo -n 'Removing old version of your application.'"]);
|
||||||
if ($this->newVersionIsHealthy || $force) {
|
|
||||||
$this->execute_remote_command(
|
if ($this->newVersionIsHealthy || $force) {
|
||||||
["echo -n 'Removing old version of your application.'"],
|
$containers = getCurrentApplicationContainerStatus($this->server, $this->application->id, $this->pull_request_id);
|
||||||
[executeInDocker($this->deployment_uuid, "docker rm -f $this->currently_running_container_name >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true],
|
if ($this->pull_request_id !== 0) {
|
||||||
);
|
$containers = $containers->filter(function ($container) {
|
||||||
|
return data_get($container, 'Names') === $this->container_name;
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
$this->execute_remote_command(
|
$containers = $containers->filter(function ($container) {
|
||||||
["echo -n 'New version is not healthy, rolling back to the old version.'"],
|
return data_get($container, 'Names') !== $this->container_name;
|
||||||
[executeInDocker($this->deployment_uuid, "docker rm -f $this->container_name >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true],
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
$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(
|
$this->execute_remote_command(
|
||||||
["echo 'Oops something is not okay, are you okay? 😢'"],
|
["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);
|
$this->next(ApplicationDeploymentStatus::FAILED->value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,11 +84,14 @@ class DeploymentFailed extends Notification implements ShouldQueue
|
|||||||
} else {
|
} else {
|
||||||
$message = 'Coolify: Deployment failed of **' . $this->application_name . '** (' . $this->fqdn . '): ';
|
$message = 'Coolify: Deployment failed of **' . $this->application_name . '** (' . $this->fqdn . '): ';
|
||||||
}
|
}
|
||||||
|
$buttons[] = [
|
||||||
|
"text" => "Deployment logs",
|
||||||
|
"url" => $this->deployment_url
|
||||||
|
];
|
||||||
return [
|
return [
|
||||||
"message" => $message,
|
"message" => $message,
|
||||||
"buttons" => [
|
"buttons" => [
|
||||||
"text" => "View Deployment Logs",
|
...$buttons
|
||||||
"url" => $this->deployment_url
|
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -10,15 +10,24 @@ use Visus\Cuid2\Cuid2;
|
|||||||
|
|
||||||
function getCurrentApplicationContainerStatus(Server $server, int $id, ?int $pullRequestId = null): Collection
|
function getCurrentApplicationContainerStatus(Server $server, int $id, ?int $pullRequestId = null): Collection
|
||||||
{
|
{
|
||||||
if ($pullRequestId) {
|
ray($id, $pullRequestId);
|
||||||
$containers = instant_remote_process(["docker ps -a --filter='label=coolify.applicationId={$id}' --filter='label=coolify.pullRequestId={$pullRequestId}' --format '{{json .}}' "], $server);
|
$containers = collect([]);
|
||||||
} else {
|
$containers = instant_remote_process(["docker ps -a --filter='label=coolify.applicationId={$id}' --format '{{json .}}' "], $server);
|
||||||
$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) {
|
||||||
if (!$containers) {
|
$labels = data_get($container, 'Labels');
|
||||||
return collect([]);
|
if (!str($labels)->contains("coolify.pullRequestId=")) {
|
||||||
}
|
data_set($container, 'Labels', $labels . ",coolify.pullRequestId={$pullRequestId}");
|
||||||
return format_docker_command_output_to_json($containers);
|
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
|
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 . "Id=" . $id);
|
||||||
$labels->push("coolify.type=$type");
|
$labels->push("coolify.type=$type");
|
||||||
$labels->push('coolify.name=' . $name);
|
$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') {
|
if ($type === 'service') {
|
||||||
$labels->push('coolify.service.subId=' . $subId);
|
$labels->push('coolify.service.subId=' . $subId);
|
||||||
$labels->push('coolify.service.subType=' . $subType);
|
$labels->push('coolify.service.subType=' . $subType);
|
||||||
|
@ -7,7 +7,7 @@ return [
|
|||||||
|
|
||||||
// The release version of your application
|
// The release version of your application
|
||||||
// Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
|
// 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
|
// When left empty or `null` the Laravel environment will be used
|
||||||
'environment' => config('app.env'),
|
'environment' => config('app.env'),
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
return '4.0.0-beta.115';
|
return '4.0.0-beta.116';
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
@forelse ($deployments as $deployment)
|
@forelse ($deployments as $deployment)
|
||||||
<a @class([
|
<a @class([
|
||||||
'bg-coolgray-200 p-2 border-l border-dashed transition-colors hover:no-underline',
|
'bg-coolgray-200 p-2 border-l border-dashed transition-colors hover:no-underline',
|
||||||
'cursor-not-allowed hover:bg-coolgray-200' =>
|
'hover:bg-coolgray-200' =>
|
||||||
data_get($deployment, 'status') === 'queued' ||
|
data_get($deployment, 'status') === 'queued' ||
|
||||||
data_get($deployment, 'status') === 'cancelled by system',
|
data_get($deployment, 'status') === 'cancelled by system',
|
||||||
'border-warning hover:bg-warning hover:text-black' =>
|
'border-warning hover:bg-warning hover:text-black' =>
|
||||||
|
@ -50,9 +50,9 @@
|
|||||||
<h3>Build</h3>
|
<h3>Build</h3>
|
||||||
@if ($application->could_set_build_commands())
|
@if ($application->could_set_build_commands())
|
||||||
@if ($application->build_pack === 'nixpacks')
|
@if ($application->build_pack === 'nixpacks')
|
||||||
<div>Nixpacks will detect your package manager/configurations: <a class="underline"
|
<div>Nixpacks will detect the required configuration automatically.
|
||||||
href="https://nixpacks.com/docs/providers">Nixpacks documentation</a></div>
|
<a class="underline" href="https://coolify.io/docs/frameworks">Framework Specific Docs</a>
|
||||||
<div class="text-warning">You probably do not need to modify the commands below.</div>
|
</div>
|
||||||
<div class="flex flex-col gap-2 xl:flex-row">
|
<div class="flex flex-col gap-2 xl:flex-row">
|
||||||
<x-forms.input placeholder="If you modify this, you probably need to have a nixpacks.toml"
|
<x-forms.input placeholder="If you modify this, you probably need to have a nixpacks.toml"
|
||||||
id="application.install_command" label="Install Command" />
|
id="application.install_command" label="Install Command" />
|
||||||
@ -72,7 +72,8 @@
|
|||||||
<x-forms.input placeholder="/Dockerfile" id="application.dockerfile_location"
|
<x-forms.input placeholder="/Dockerfile" id="application.dockerfile_location"
|
||||||
label="Dockerfile Location"
|
label="Dockerfile Location"
|
||||||
helper="It is calculated together with the Base Directory: {{ Str::start($application->base_directory . $application->dockerfile_location, '/') }}" />
|
helper="It is calculated together with the Base Directory: {{ Str::start($application->base_directory . $application->dockerfile_location, '/') }}" />
|
||||||
<x-forms.input id="application.dockerfile_target_build" label="Docker Build Stage Target" helper="Useful if you have multi-staged dockerfile." />
|
<x-forms.input id="application.dockerfile_target_build" label="Docker Build Stage Target"
|
||||||
|
helper="Useful if you have multi-staged dockerfile." />
|
||||||
@endif
|
@endif
|
||||||
@if ($application->could_set_build_commands())
|
@if ($application->could_set_build_commands())
|
||||||
@if ($application->settings->is_static)
|
@if ($application->settings->is_static)
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
"version": "3.12.36"
|
"version": "3.12.36"
|
||||||
},
|
},
|
||||||
"v4": {
|
"v4": {
|
||||||
"version": "4.0.0-beta.115"
|
"version": "4.0.0-beta.116"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user