fix: pull request deployments + build servers
This commit is contained in:
parent
860c537f81
commit
6fe791c1f1
@ -218,12 +218,12 @@ public function handle(): void
|
|||||||
$teamId = data_get($this->application, 'environment.project.team.id');
|
$teamId = data_get($this->application, 'environment.project.team.id');
|
||||||
$buildServers = Server::buildServers($teamId)->get();
|
$buildServers = Server::buildServers($teamId)->get();
|
||||||
if ($buildServers->count() === 0) {
|
if ($buildServers->count() === 0) {
|
||||||
$this->application_deployment_queue->addLogEntry("Build server feature activated, but no suitable build server found. Using the deployment server.");
|
$this->application_deployment_queue->addLogEntry("No suitable build server found. Using the deployment server.");
|
||||||
$this->build_server = $this->server;
|
$this->build_server = $this->server;
|
||||||
$this->original_server = $this->server;
|
$this->original_server = $this->server;
|
||||||
} else {
|
} else {
|
||||||
$this->application_deployment_queue->addLogEntry("Build server feature activated and found a suitable build server. Using it to build your application - if needed.");
|
|
||||||
$this->build_server = $buildServers->random();
|
$this->build_server = $buildServers->random();
|
||||||
|
$this->application_deployment_queue->addLogEntry("Found a suitable build server ({$this->build_server->name}).");
|
||||||
$this->original_server = $this->server;
|
$this->original_server = $this->server;
|
||||||
$this->use_build_server = true;
|
$this->use_build_server = true;
|
||||||
}
|
}
|
||||||
@ -427,13 +427,13 @@ private function deploy_docker_compose_buildpack()
|
|||||||
}
|
}
|
||||||
private function deploy_dockerfile_buildpack()
|
private function deploy_dockerfile_buildpack()
|
||||||
{
|
{
|
||||||
|
$this->application_deployment_queue->addLogEntry("Starting deployment of {$this->customRepository}:{$this->application->git_branch} to {$this->server->name}.");
|
||||||
if ($this->use_build_server) {
|
if ($this->use_build_server) {
|
||||||
$this->server = $this->build_server;
|
$this->server = $this->build_server;
|
||||||
}
|
}
|
||||||
if (data_get($this->application, 'dockerfile_location')) {
|
if (data_get($this->application, 'dockerfile_location')) {
|
||||||
$this->dockerfile_location = $this->application->dockerfile_location;
|
$this->dockerfile_location = $this->application->dockerfile_location;
|
||||||
}
|
}
|
||||||
$this->application_deployment_queue->addLogEntry("Starting deployment of {$this->customRepository}:{$this->application->git_branch} to {$this->server->name}.");
|
|
||||||
$this->prepare_builder_image();
|
$this->prepare_builder_image();
|
||||||
$this->check_git_if_build_needed();
|
$this->check_git_if_build_needed();
|
||||||
$this->set_base_dir();
|
$this->set_base_dir();
|
||||||
@ -528,9 +528,11 @@ private function write_deployment_configurations()
|
|||||||
$this->server = $this->original_server;
|
$this->server = $this->original_server;
|
||||||
}
|
}
|
||||||
$readme = generate_readme_file($this->application->name, $this->application_deployment_queue->updated_at);
|
$readme = generate_readme_file($this->application->name, $this->application_deployment_queue->updated_at);
|
||||||
|
if ($this->pull_request_id === 0) {
|
||||||
$composeFileName = "$this->configuration_dir/docker-compose.yml";
|
$composeFileName = "$this->configuration_dir/docker-compose.yml";
|
||||||
if ($this->pull_request_id !== 0) {
|
} else {
|
||||||
$composeFileName = "$this->configuration_dir/docker-compose-pr-{$this->pull_request_id}.yml";
|
$composeFileName = "$this->configuration_dir/docker-compose-pr-{$this->pull_request_id}.yml";
|
||||||
|
$this->docker_compose_location = "/docker-compose-pr-{$this->pull_request_id}.yml";
|
||||||
}
|
}
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[
|
[
|
||||||
@ -725,7 +727,7 @@ private function rolling_update()
|
|||||||
$this->write_deployment_configurations();
|
$this->write_deployment_configurations();
|
||||||
$this->server = $this->original_server;
|
$this->server = $this->original_server;
|
||||||
}
|
}
|
||||||
if (count($this->application->ports_mappings_array) > 0 || (bool) $this->application->settings->is_consistent_container_name_enabled) {
|
if (count($this->application->ports_mappings_array) > 0 || (bool) $this->application->settings->is_consistent_container_name_enabled || $this->application->pull_request_id !== 0) {
|
||||||
$this->application_deployment_queue->addLogEntry("----------------------------------------");
|
$this->application_deployment_queue->addLogEntry("----------------------------------------");
|
||||||
if (count($this->application->ports_mappings_array) > 0) {
|
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.");
|
$this->application_deployment_queue->addLogEntry("Application has ports mapped to the host system, rolling update is not supported.");
|
||||||
@ -733,6 +735,10 @@ private function rolling_update()
|
|||||||
if ((bool) $this->application->settings->is_consistent_container_name_enabled) {
|
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.");
|
$this->application_deployment_queue->addLogEntry("Consistent container name feature enabled, rolling update is not supported.");
|
||||||
}
|
}
|
||||||
|
if ($this->application->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.");
|
||||||
|
}
|
||||||
$this->stop_running_container(force: true);
|
$this->stop_running_container(force: true);
|
||||||
$this->start_by_compose_file();
|
$this->start_by_compose_file();
|
||||||
} else {
|
} else {
|
||||||
@ -810,26 +816,9 @@ private function deploy_pull_request()
|
|||||||
$this->add_build_env_variables_to_dockerfile();
|
$this->add_build_env_variables_to_dockerfile();
|
||||||
}
|
}
|
||||||
$this->build_image();
|
$this->build_image();
|
||||||
$this->stop_running_container();
|
|
||||||
if ($this->application->destination->server->isSwarm()) {
|
|
||||||
$this->push_to_docker_registry();
|
$this->push_to_docker_registry();
|
||||||
$this->execute_remote_command(
|
// $this->stop_running_container();
|
||||||
[
|
$this->rolling_update();
|
||||||
executeInDocker($this->deployment_uuid, "docker stack deploy --with-registry-auth -c {$this->workdir}{$this->docker_compose_location} {$this->application->uuid}-{$this->pull_request_id}")
|
|
||||||
],
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$this->application_deployment_queue->addLogEntry("Starting preview deployment.");
|
|
||||||
if ($this->use_build_server) {
|
|
||||||
$this->execute_remote_command(
|
|
||||||
["SOURCE_COMMIT={$this->commit} docker compose --project-directory {$this->configuration_dir} -f {$this->configuration_dir}{$this->docker_compose_location} up --build -d", "hidden" => true],
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
$this->execute_remote_command(
|
|
||||||
[executeInDocker($this->deployment_uuid, "SOURCE_COMMIT={$this->commit} docker compose --project-directory {$this->workdir} -f {$this->workdir}{$this->docker_compose_location} up --build -d"), "hidden" => true],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
private function create_workdir()
|
private function create_workdir()
|
||||||
{
|
{
|
||||||
@ -1226,6 +1215,7 @@ private function generate_compose_file()
|
|||||||
// ];
|
// ];
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
if ($this->application->pull_request_id === 0) {
|
||||||
if ((bool)$this->application->settings->is_consistent_container_name_enabled) {
|
if ((bool)$this->application->settings->is_consistent_container_name_enabled) {
|
||||||
$custom_compose = convert_docker_run_to_compose($this->application->custom_docker_run_options);
|
$custom_compose = convert_docker_run_to_compose($this->application->custom_docker_run_options);
|
||||||
if (count($custom_compose) > 0) {
|
if (count($custom_compose) > 0) {
|
||||||
@ -1234,13 +1224,13 @@ private function generate_compose_file()
|
|||||||
data_forget($custom_compose, 'ip');
|
data_forget($custom_compose, 'ip');
|
||||||
data_forget($custom_compose, 'ip6');
|
data_forget($custom_compose, 'ip6');
|
||||||
if ($ipv4 || $ipv6) {
|
if ($ipv4 || $ipv6) {
|
||||||
data_forget($docker_compose['services'][$this->application->uuid], 'networks');
|
data_forget($docker_compose['services'][$this->container_name], 'networks');
|
||||||
}
|
}
|
||||||
if ($ipv4) {
|
if ($ipv4) {
|
||||||
$docker_compose['services'][$this->application->uuid]['networks'][$this->destination->network]['ipv4_address'] = $ipv4;
|
$docker_compose['services'][$this->container_name]['networks'][$this->destination->network]['ipv4_address'] = $ipv4;
|
||||||
}
|
}
|
||||||
if ($ipv6) {
|
if ($ipv6) {
|
||||||
$docker_compose['services'][$this->application->uuid]['networks'][$this->destination->network]['ipv6_address'] = $ipv6;
|
$docker_compose['services'][$this->container_name]['networks'][$this->destination->network]['ipv6_address'] = $ipv6;
|
||||||
}
|
}
|
||||||
$docker_compose['services'][$this->container_name] = array_merge_recursive($docker_compose['services'][$this->container_name], $custom_compose);
|
$docker_compose['services'][$this->container_name] = array_merge_recursive($docker_compose['services'][$this->container_name], $custom_compose);
|
||||||
}
|
}
|
||||||
@ -1265,6 +1255,7 @@ private function generate_compose_file()
|
|||||||
$docker_compose['services'][$this->application->uuid] = array_merge_recursive($docker_compose['services'][$this->application->uuid], $custom_compose);
|
$docker_compose['services'][$this->application->uuid] = array_merge_recursive($docker_compose['services'][$this->application->uuid], $custom_compose);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->docker_compose = Yaml::dump($docker_compose, 10);
|
$this->docker_compose = Yaml::dump($docker_compose, 10);
|
||||||
$this->docker_compose_base64 = base64_encode($this->docker_compose);
|
$this->docker_compose_base64 = base64_encode($this->docker_compose);
|
||||||
@ -1539,18 +1530,18 @@ private function stop_running_container(bool $force = false)
|
|||||||
$containers = getCurrentApplicationContainerStatus($this->server, $this->application->id, $this->pull_request_id);
|
$containers = getCurrentApplicationContainerStatus($this->server, $this->application->id, $this->pull_request_id);
|
||||||
if ($this->pull_request_id === 0) {
|
if ($this->pull_request_id === 0) {
|
||||||
$containers = $containers->filter(function ($container) {
|
$containers = $containers->filter(function ($container) {
|
||||||
return data_get($container, 'Names') !== $this->container_name;
|
return data_get($container, 'Names') !== $this->container_name && data_get($container, 'Names') !== $this->container_name . '-pr-' . $this->pull_request_id;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
$containers->each(function ($container) {
|
$containers->each(function ($container) {
|
||||||
$containerName = data_get($container, 'Names');
|
$containerName = data_get($container, 'Names');
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[executeInDocker($this->deployment_uuid, "docker rm -f $containerName >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true],
|
["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) {
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[executeInDocker($this->deployment_uuid, "docker rm -f $this->container_name >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true],
|
["docker rm -f $this->container_name >/dev/null 2>&1", "hidden" => true, "ignore_errors" => true],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1559,7 +1550,7 @@ private function stop_running_container(bool $force = false)
|
|||||||
'status' => ApplicationDeploymentStatus::FAILED->value,
|
'status' => ApplicationDeploymentStatus::FAILED->value,
|
||||||
]);
|
]);
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[executeInDocker($this->deployment_uuid, "docker rm -f $this->container_name >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true],
|
["docker rm -f $this->container_name >/dev/null 2>&1", "hidden" => true, "ignore_errors" => true],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1680,7 +1671,7 @@ public function failed(Throwable $exception): void
|
|||||||
// 69420 means failed to push the image to the registry, so we don't need to remove the new version as it is the currently running one
|
// 69420 means failed to push the image to the registry, so we don't need to remove the new version as it is the currently running one
|
||||||
$this->application_deployment_queue->addLogEntry("Deployment failed. Removing the new version of your application.", 'stderr');
|
$this->application_deployment_queue->addLogEntry("Deployment failed. Removing the new version of your application.", 'stderr');
|
||||||
$this->execute_remote_command(
|
$this->execute_remote_command(
|
||||||
[executeInDocker($this->deployment_uuid, "docker rm -f $this->container_name >/dev/null 2>&1"), "hidden" => true, "ignore_errors" => true]
|
["docker rm -f $this->container_name >/dev/null 2>&1", "hidden" => true, "ignore_errors" => true]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
<h2>Advanced</h2>
|
<h2>Advanced</h2>
|
||||||
</div>
|
</div>
|
||||||
<div>Advanced configuration for your application.</div>
|
<div>Advanced configuration for your application.</div>
|
||||||
<div class="flex flex-col pt-4 ">
|
<div class="flex flex-col pt-4 w-96">
|
||||||
<h4>General</h4>
|
<h3>General</h3>
|
||||||
@if ($application->git_based())
|
@if ($application->git_based())
|
||||||
<x-forms.checkbox helper="Automatically deploy new commits based on Git webhooks." instantSave
|
<x-forms.checkbox helper="Automatically deploy new commits based on Git webhooks." instantSave
|
||||||
id="application.settings.is_auto_deploy_enabled" label="Auto Deploy" />
|
id="application.settings.is_auto_deploy_enabled" label="Auto Deploy" />
|
||||||
@ -20,28 +20,34 @@
|
|||||||
helper="The deployed container will have the same name ({{ $application->uuid }}). <span class='font-bold text-warning'>You will lose the rolling update feature!</span>"
|
helper="The deployed container will have the same name ({{ $application->uuid }}). <span class='font-bold text-warning'>You will lose the rolling update feature!</span>"
|
||||||
instantSave id="application.settings.is_consistent_container_name_enabled"
|
instantSave id="application.settings.is_consistent_container_name_enabled"
|
||||||
label="Consistent Container Names" />
|
label="Consistent Container Names" />
|
||||||
<h4>Logs</h4>
|
<h3>Logs</h3>
|
||||||
@if (!$application->settings->is_raw_compose_deployment_enabled)
|
@if (!$application->settings->is_raw_compose_deployment_enabled)
|
||||||
<x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings."
|
<x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings."
|
||||||
instantSave id="application.settings.is_log_drain_enabled" label="Drain Logs" />
|
instantSave id="application.settings.is_log_drain_enabled" label="Drain Logs" />
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($application->git_based())
|
@if ($application->git_based())
|
||||||
<h4>Git</h4>
|
<h3>Git</h3>
|
||||||
<x-forms.checkbox instantSave id="application.settings.is_git_submodules_enabled" label="Git Submodules"
|
<x-forms.checkbox instantSave id="application.settings.is_git_submodules_enabled" label="Submodules"
|
||||||
helper="Allow Git Submodules during build process." />
|
helper="Allow Git Submodules during build process." />
|
||||||
<x-forms.checkbox instantSave id="application.settings.is_git_lfs_enabled" label="Git LFS"
|
<x-forms.checkbox instantSave id="application.settings.is_git_lfs_enabled" label="LFS"
|
||||||
helper="Allow Git LFS during build process." />
|
helper="Allow Git LFS during build process." />
|
||||||
@endif
|
@endif
|
||||||
<h4>GPU</h4>
|
{{-- <x-forms.checkbox disabled instantSave id="is_dual_cert" label="Dual Certs?" />
|
||||||
|
<x-forms.checkbox disabled instantSave id="is_custom_ssl" label="Is Custom SSL?" />
|
||||||
|
<x-forms.checkbox disabled instantSave id="is_http2" label="Is Http2?" /> --}}
|
||||||
|
</div>
|
||||||
|
<h3>GPU</h3>
|
||||||
<form wire:submit="submit">
|
<form wire:submit="submit">
|
||||||
@if ($application->build_pack !== 'dockercompose')
|
@if ($application->build_pack !== 'dockercompose')
|
||||||
<div class="flex gap-2">
|
<div class="w-96">
|
||||||
<x-forms.checkbox
|
<x-forms.checkbox
|
||||||
helper="Enable GPU usage for this application. More info <a href='https://docs.docker.com/compose/gpu-support/' class='text-white underline' target='_blank'>here</a>."
|
helper="Enable GPU usage for this application. More info <a href='https://docs.docker.com/compose/gpu-support/' class='text-white underline' target='_blank'>here</a>."
|
||||||
instantSave id="application.settings.is_gpu_enabled" label="Attach GPU" />
|
instantSave id="application.settings.is_gpu_enabled" label="Attach GPU" />
|
||||||
@if ($application->settings->is_gpu_enabled)
|
@if ($application->settings->is_gpu_enabled)
|
||||||
<x-forms.button type="submiot">Save</x-forms.button>
|
<h5>GPU Settings</h5>
|
||||||
|
|
||||||
|
<x-forms.button type="submit">Save</x-forms.button>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@ -61,9 +67,5 @@
|
|||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</form>
|
</form>
|
||||||
{{-- <x-forms.checkbox disabled instantSave id="is_dual_cert" label="Dual Certs?" />
|
|
||||||
<x-forms.checkbox disabled instantSave id="is_custom_ssl" label="Is Custom SSL?" />
|
|
||||||
<x-forms.checkbox disabled instantSave id="is_http2" label="Is Http2?" /> --}}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
@if ($isConfigurationChanged && !is_null($application->config_hash) && !$application->isExited())
|
@if ($isConfigurationChanged && !is_null($application->config_hash) && !$application->isExited())
|
||||||
<div title="Configuration not applied to the running application. You need to redeploy.">
|
<div title="Configuration not applied to the running application. You need to redeploy.">
|
||||||
<svg class="w-6 h-6 text-warning" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
<svg class="w-6 h-6 text-warning" viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||||
<path fill="currentColor" d="M240.26 186.1L152.81 34.23a28.74 28.74 0 0 0-49.62 0L15.74 186.1a27.45 27.45 0 0 0 0 27.71A28.31 28.31 0 0 0 40.55 228h174.9a28.31 28.31 0 0 0 24.79-14.19a27.45 27.45 0 0 0 .02-27.71m-20.8 15.7a4.46 4.46 0 0 1-4 2.2H40.55a4.46 4.46 0 0 1-4-2.2a3.56 3.56 0 0 1 0-3.73L124 46.2a4.77 4.77 0 0 1 8 0l87.44 151.87a3.56 3.56 0 0 1 .02 3.73M116 136v-32a12 12 0 0 1 24 0v32a12 12 0 0 1-24 0m28 40a16 16 0 1 1-16-16a16 16 0 0 1 16 16"/>
|
<path fill="currentColor"
|
||||||
|
d="M240.26 186.1L152.81 34.23a28.74 28.74 0 0 0-49.62 0L15.74 186.1a27.45 27.45 0 0 0 0 27.71A28.31 28.31 0 0 0 40.55 228h174.9a28.31 28.31 0 0 0 24.79-14.19a27.45 27.45 0 0 0 .02-27.71m-20.8 15.7a4.46 4.46 0 0 1-4 2.2H40.55a4.46 4.46 0 0 1-4-2.2a3.56 3.56 0 0 1 0-3.73L124 46.2a4.77 4.77 0 0 1 8 0l87.44 151.87a3.56 3.56 0 0 1 .02 3.73M116 136v-32a12 12 0 0 1 24 0v32a12 12 0 0 1-24 0m28 40a16 16 0 1 1-16-16a16 16 0 0 1 16 16" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@ -100,11 +101,15 @@ class="underline" href="https://coolify.io/docs/docker/registry"
|
|||||||
<x-forms.input id="application.docker_registry_image_tag" label="Docker Image Tag" />
|
<x-forms.input id="application.docker_registry_image_tag" label="Docker Image Tag" />
|
||||||
@endif
|
@endif
|
||||||
@else
|
@else
|
||||||
@if ($application->destination->server->isSwarm() || $application->additional_servers->count() > 0)
|
@if (
|
||||||
<x-forms.input id="application.docker_registry_image_name" required label="Docker Image" />
|
$application->destination->server->isSwarm() ||
|
||||||
|
$application->additional_servers->count() > 0 ||
|
||||||
|
$application->settings->is_build_server_enabled)
|
||||||
|
<x-forms.input id="application.docker_registry_image_name" required label="Docker Image"
|
||||||
|
placeholder="Required!" />
|
||||||
<x-forms.input id="application.docker_registry_image_tag"
|
<x-forms.input id="application.docker_registry_image_tag"
|
||||||
helper="If set, it will tag the built image with this tag too. <br><br>Example: If you set it to 'latest', it will push the image with the commit sha tag + with the latest tag."
|
helper="If set, it will tag the built image with this tag too. <br><br>Example: If you set it to 'latest', it will push the image with the commit sha tag + with the latest tag."
|
||||||
label="Docker Image Tag" />
|
placeholder="Empty means latest will be used." label="Docker Image Tag" />
|
||||||
@else
|
@else
|
||||||
<x-forms.input id="application.docker_registry_image_name"
|
<x-forms.input id="application.docker_registry_image_name"
|
||||||
helper="Empty means it won't push the image to a docker registry."
|
helper="Empty means it won't push the image to a docker registry."
|
||||||
|
Loading…
Reference in New Issue
Block a user