feat: gpu enabled containers
feat: move advanced settings to different view
This commit is contained in:
parent
8f963adbd4
commit
912b0a263e
54
app/Http/Livewire/Project/Application/Advanced.php
Normal file
54
app/Http/Livewire/Project/Application/Advanced.php
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Livewire\Project\Application;
|
||||||
|
|
||||||
|
use App\Models\Application;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class Advanced extends Component
|
||||||
|
{
|
||||||
|
public Application $application;
|
||||||
|
protected $rules = [
|
||||||
|
'application.settings.is_git_submodules_enabled' => 'boolean|required',
|
||||||
|
'application.settings.is_git_lfs_enabled' => 'boolean|required',
|
||||||
|
'application.settings.is_preview_deployments_enabled' => 'boolean|required',
|
||||||
|
'application.settings.is_auto_deploy_enabled' => 'boolean|required',
|
||||||
|
'application.settings.is_force_https_enabled' => 'boolean|required',
|
||||||
|
'application.settings.is_log_drain_enabled' => 'boolean|required',
|
||||||
|
'application.settings.is_gpu_enabled' => 'boolean|required',
|
||||||
|
'application.settings.gpu_driver' => 'string|required',
|
||||||
|
'application.settings.gpu_count' => 'string|required',
|
||||||
|
'application.settings.gpu_device_ids' => 'string|required',
|
||||||
|
'application.settings.gpu_options' => 'string|required',
|
||||||
|
];
|
||||||
|
public function instantSave()
|
||||||
|
{
|
||||||
|
if ($this->application->settings->is_log_drain_enabled) {
|
||||||
|
if (!$this->application->destination->server->isLogDrainEnabled()) {
|
||||||
|
$this->application->settings->is_log_drain_enabled = false;
|
||||||
|
$this->emit('error', 'Log drain is not enabled on this server.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($this->application->settings->is_force_https_enabled) {
|
||||||
|
$this->emit('resetDefaultLabels', false);
|
||||||
|
}
|
||||||
|
$this->application->settings->save();
|
||||||
|
$this->emit('success', 'Settings saved.');
|
||||||
|
}
|
||||||
|
public function submit() {
|
||||||
|
if ($this->application->settings->gpu_count && $this->application->settings->gpu_device_ids) {
|
||||||
|
$this->emit('error', 'You cannot set both GPU count and GPU device IDs.');
|
||||||
|
$this->application->settings->gpu_count = null;
|
||||||
|
$this->application->settings->gpu_device_ids = null;
|
||||||
|
$this->application->settings->save();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->application->settings->save();
|
||||||
|
$this->emit('success', 'Settings saved.');
|
||||||
|
}
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.project.application.advanced');
|
||||||
|
}
|
||||||
|
}
|
@ -26,14 +26,10 @@ class General extends Component
|
|||||||
public bool $isConfigurationChanged = false;
|
public bool $isConfigurationChanged = false;
|
||||||
|
|
||||||
public bool $is_static;
|
public bool $is_static;
|
||||||
public bool $is_git_submodules_enabled;
|
|
||||||
public bool $is_git_lfs_enabled;
|
|
||||||
public bool $is_debug_enabled;
|
|
||||||
public bool $is_preview_deployments_enabled;
|
|
||||||
public bool $is_auto_deploy_enabled;
|
|
||||||
public bool $is_force_https_enabled;
|
|
||||||
public bool $is_log_drain_enabled;
|
|
||||||
|
|
||||||
|
protected $listeners = [
|
||||||
|
'resetDefaultLabels'
|
||||||
|
];
|
||||||
protected $rules = [
|
protected $rules = [
|
||||||
'application.name' => 'required',
|
'application.name' => 'required',
|
||||||
'application.description' => 'nullable',
|
'application.description' => 'nullable',
|
||||||
@ -56,6 +52,7 @@ class General extends Component
|
|||||||
'application.dockerfile_location' => 'nullable',
|
'application.dockerfile_location' => 'nullable',
|
||||||
'application.custom_labels' => 'nullable',
|
'application.custom_labels' => 'nullable',
|
||||||
'application.dockerfile_target_build' => 'nullable',
|
'application.dockerfile_target_build' => 'nullable',
|
||||||
|
'application.settings.is_static' => 'boolean|required',
|
||||||
];
|
];
|
||||||
protected $validationAttributes = [
|
protected $validationAttributes = [
|
||||||
'application.name' => 'name',
|
'application.name' => 'name',
|
||||||
@ -79,6 +76,7 @@ class General extends Component
|
|||||||
'application.dockerfile_location' => 'Dockerfile location',
|
'application.dockerfile_location' => 'Dockerfile location',
|
||||||
'application.custom_labels' => 'Custom labels',
|
'application.custom_labels' => 'Custom labels',
|
||||||
'application.dockerfile_target_build' => 'Dockerfile target build',
|
'application.dockerfile_target_build' => 'Dockerfile target build',
|
||||||
|
'application.settings.is_static' => 'Is static',
|
||||||
];
|
];
|
||||||
|
|
||||||
public function mount()
|
public function mount()
|
||||||
@ -93,18 +91,13 @@ public function mount()
|
|||||||
} else {
|
} else {
|
||||||
$this->customLabels = str($this->application->custom_labels)->replace(',', "\n");
|
$this->customLabels = str($this->application->custom_labels)->replace(',', "\n");
|
||||||
}
|
}
|
||||||
if (data_get($this->application, 'settings')) {
|
|
||||||
$this->is_static = $this->application->settings->is_static;
|
|
||||||
$this->is_git_submodules_enabled = $this->application->settings->is_git_submodules_enabled;
|
|
||||||
$this->is_git_lfs_enabled = $this->application->settings->is_git_lfs_enabled;
|
|
||||||
$this->is_debug_enabled = $this->application->settings->is_debug_enabled;
|
|
||||||
$this->is_preview_deployments_enabled = $this->application->settings->is_preview_deployments_enabled;
|
|
||||||
$this->is_auto_deploy_enabled = $this->application->settings->is_auto_deploy_enabled;
|
|
||||||
$this->is_force_https_enabled = $this->application->settings->is_force_https_enabled;
|
|
||||||
$this->is_log_drain_enabled = $this->application->settings->is_log_drain_enabled;
|
|
||||||
}
|
|
||||||
$this->checkLabelUpdates();
|
$this->checkLabelUpdates();
|
||||||
}
|
}
|
||||||
|
public function instantSave()
|
||||||
|
{
|
||||||
|
$this->application->settings->save();
|
||||||
|
$this->emit('success', 'Settings saved.');
|
||||||
|
}
|
||||||
public function updatedApplicationBuildPack()
|
public function updatedApplicationBuildPack()
|
||||||
{
|
{
|
||||||
if ($this->application->build_pack !== 'nixpacks') {
|
if ($this->application->build_pack !== 'nixpacks') {
|
||||||
@ -121,40 +114,6 @@ public function checkLabelUpdates()
|
|||||||
$this->labelsChanged = false;
|
$this->labelsChanged = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public function instantSave()
|
|
||||||
{
|
|
||||||
// @TODO: find another way - if possible
|
|
||||||
$force_https = $this->application->settings->is_force_https_enabled;
|
|
||||||
$this->application->settings->is_static = $this->is_static;
|
|
||||||
if ($this->is_static) {
|
|
||||||
$this->application->ports_exposes = 80;
|
|
||||||
} else {
|
|
||||||
$this->application->ports_exposes = 3000;
|
|
||||||
}
|
|
||||||
$this->application->settings->is_git_submodules_enabled = $this->is_git_submodules_enabled;
|
|
||||||
$this->application->settings->is_git_lfs_enabled = $this->is_git_lfs_enabled;
|
|
||||||
$this->application->settings->is_debug_enabled = $this->is_debug_enabled;
|
|
||||||
$this->application->settings->is_preview_deployments_enabled = $this->is_preview_deployments_enabled;
|
|
||||||
$this->application->settings->is_auto_deploy_enabled = $this->is_auto_deploy_enabled;
|
|
||||||
$this->application->settings->is_force_https_enabled = $this->is_force_https_enabled;
|
|
||||||
$this->application->settings->is_log_drain_enabled = $this->is_log_drain_enabled;
|
|
||||||
if ($this->is_log_drain_enabled) {
|
|
||||||
if (!$this->application->destination->server->isLogDrainEnabled()) {
|
|
||||||
$this->application->settings->is_log_drain_enabled = $this->is_log_drain_enabled = false;
|
|
||||||
$this->emit('error', 'Log drain is not enabled on the server. Please enable it first.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->application->settings->save();
|
|
||||||
$this->application->save();
|
|
||||||
$this->application->refresh();
|
|
||||||
$this->emit('success', 'Application settings updated!');
|
|
||||||
$this->checkLabelUpdates();
|
|
||||||
$this->isConfigurationChanged = $this->application->isConfigurationChanged();
|
|
||||||
if ($force_https !== $this->is_force_https_enabled) {
|
|
||||||
$this->resetDefaultLabels(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getWildcardDomain()
|
public function getWildcardDomain()
|
||||||
{
|
{
|
||||||
|
@ -873,6 +873,27 @@ private function generate_compose_file()
|
|||||||
]
|
]
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
if ($this->application->settings->is_gpu_enabled) {
|
||||||
|
ray('asd');
|
||||||
|
$docker_compose['services'][$this->container_name]['deploy']['resources']['reservations']['devices'] = [
|
||||||
|
[
|
||||||
|
'driver' => data_get($this->application, 'settings.gpu_driver', 'nvidia'),
|
||||||
|
'capabilities' => ['gpu'],
|
||||||
|
'options' => data_get($this->application, 'settings.gpu_options', [])
|
||||||
|
]
|
||||||
|
];
|
||||||
|
if (data_get($this->application, 'settings.gpu_count')) {
|
||||||
|
$count = data_get($this->application, 'settings.gpu_count');
|
||||||
|
ray($count);
|
||||||
|
if ($count === 'all') {
|
||||||
|
$docker_compose['services'][$this->container_name]['deploy']['resources']['reservations']['devices'][0]['count'] = $count;
|
||||||
|
} else {
|
||||||
|
$docker_compose['services'][$this->container_name]['deploy']['resources']['reservations']['devices'][0]['count'] = (int) $count;
|
||||||
|
}
|
||||||
|
} else if (data_get($this->application, 'settings.gpu_device_ids')) {
|
||||||
|
$docker_compose['services'][$this->container_name]['deploy']['resources']['reservations']['devices'][0]['ids'] = data_get($this->application, 'settings.gpu_device_ids');
|
||||||
|
}
|
||||||
|
}
|
||||||
if ($this->application->isHealthcheckDisabled()) {
|
if ($this->application->isHealthcheckDisabled()) {
|
||||||
data_forget($docker_compose, 'services.' . $this->container_name . '.healthcheck');
|
data_forget($docker_compose, 'services.' . $this->container_name . '.healthcheck');
|
||||||
}
|
}
|
||||||
@ -891,6 +912,7 @@ private function generate_compose_file()
|
|||||||
// 'dockerfile' => $this->workdir . $this->dockerfile_location,
|
// 'dockerfile' => $this->workdir . $this->dockerfile_location,
|
||||||
// ];
|
// ];
|
||||||
// }
|
// }
|
||||||
|
ray($docker_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);
|
||||||
$this->execute_remote_command([executeInDocker($this->deployment_uuid, "echo '{$this->docker_compose_base64}' | base64 -d > {$this->workdir}/docker-compose.yml"), "hidden" => true]);
|
$this->execute_remote_command([executeInDocker($this->deployment_uuid, "echo '{$this->docker_compose_base64}' | base64 -d > {$this->workdir}/docker-compose.yml"), "hidden" => true]);
|
||||||
|
@ -38,7 +38,7 @@ public function render(): View|Closure|string
|
|||||||
if (is_null($this->id)) $this->id = new Cuid2(7);
|
if (is_null($this->id)) $this->id = new Cuid2(7);
|
||||||
if (is_null($this->name)) $this->name = $this->id;
|
if (is_null($this->name)) $this->name = $this->id;
|
||||||
|
|
||||||
$this->label = Str::title($this->label);
|
// $this->label = Str::title($this->label);
|
||||||
return view('components.forms.textarea');
|
return view('components.forms.textarea');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
database/migrations/2023_11_20_094628_add_gpu_settings.php
Normal file
36
database/migrations/2023_11_20_094628_add_gpu_settings.php
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('application_settings', function (Blueprint $table) {
|
||||||
|
$table->boolean('is_gpu_enabled')->default(false);
|
||||||
|
$table->string('gpu_driver')->default('nvidia');
|
||||||
|
$table->string('gpu_count')->nullable();
|
||||||
|
$table->string('gpu_device_ids')->nullable();
|
||||||
|
$table->longText('gpu_options')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('application_settings', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('is_gpu_enabled');
|
||||||
|
$table->dropColumn('gpu_driver');
|
||||||
|
$table->dropColumn('gpu_count');
|
||||||
|
$table->dropColumn('gpu_device_ids');
|
||||||
|
$table->dropColumn('gpu_options');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -1,4 +1,4 @@
|
|||||||
<div class="form-control min-w-fit">
|
<div class="px-2 form-control min-w-fit hover:bg-coolgray-100">
|
||||||
<label class="flex gap-4 px-0 cursor-pointer label">
|
<label class="flex gap-4 px-0 cursor-pointer label">
|
||||||
<span class="flex gap-2 label-text min-w-fit">
|
<span class="flex gap-2 label-text min-w-fit">
|
||||||
@if ($label)
|
@if ($label)
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
<div>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<h2>Advanced</h2>
|
||||||
|
</div>
|
||||||
|
<div>Advanced configuration for your application.</div>
|
||||||
|
<div class="flex flex-col w-full pt-4">
|
||||||
|
|
||||||
|
<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" />
|
||||||
|
<x-forms.checkbox
|
||||||
|
helper="Your application will be available only on https if your domain starts with https://..."
|
||||||
|
instantSave id="application.settings.is_force_https_enabled" label="Force Https" />
|
||||||
|
@if ($application->git_based())
|
||||||
|
<x-forms.checkbox helper="Automatically deploy new commits based on Git webhooks." instantSave
|
||||||
|
id="application.settings.is_auto_deploy_enabled" label="Auto Deploy" />
|
||||||
|
<x-forms.checkbox
|
||||||
|
helper="Allow to automatically deploy Preview Deployments for all opened PR's.<br><br>Closing a PR will delete Preview Deployments."
|
||||||
|
instantSave id="application.settings.is_preview_deployments_enabled" label="Preview Deployments" />
|
||||||
|
|
||||||
|
<x-forms.checkbox instantSave id="application.settings.is_git_submodules_enabled" label="Git Submodules"
|
||||||
|
helper="Allow Git Submodules during build process." />
|
||||||
|
<x-forms.checkbox instantSave id="application.settings.is_git_lfs_enabled" label="Git LFS"
|
||||||
|
helper="Allow Git LFS during build process." />
|
||||||
|
@endif
|
||||||
|
<form wire:submit.prevent="submit">
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<x-forms.checkbox helper="Enable GPU usage for this application." instantSave
|
||||||
|
id="application.settings.is_gpu_enabled" label="GPU Enabled Application" />
|
||||||
|
@if ($application->settings->is_gpu_enabled)
|
||||||
|
<x-forms.button type="submiot">Save</x-forms.button>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
@if ($application->settings->is_gpu_enabled)
|
||||||
|
<div class="flex flex-col w-full gap-2 p-2 xl:flex-row">
|
||||||
|
<x-forms.input label="GPU Driver" id="application.settings.gpu_driver"> </x-forms.input>
|
||||||
|
<x-forms.input label="GPU Count" placeholder="empty means use all GPUs"
|
||||||
|
id="application.settings.gpu_count"> </x-forms.input>
|
||||||
|
<x-forms.input label="GPU Device Ids" placeholder="0,2"
|
||||||
|
helper="Comma separated list of device ids. More info <a href='https://docs.docker.com/compose/gpu-support/' class='text-white underline' target='_blank'>here</a>."
|
||||||
|
id="application.settings.gpu_device_ids"> </x-forms.input>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<div class="px-2">
|
||||||
|
<x-forms.textarea label="GPU Options" id="application.settings.gpu_options">
|
||||||
|
</x-forms.textarea>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</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>
|
@ -40,7 +40,7 @@
|
|||||||
</div>
|
</div>
|
||||||
@if ($application->could_set_build_commands())
|
@if ($application->could_set_build_commands())
|
||||||
<div class="w-64">
|
<div class="w-64">
|
||||||
<x-forms.checkbox instantSave id="is_static" label="Is it a static site?"
|
<x-forms.checkbox instantSave id="application.settings.is_static" label="Is it a static site?"
|
||||||
helper="If your application is a static site or the final build assets should be served as a static site, enable this." />
|
helper="If your application is a static site or the final build assets should be served as a static site, enable this." />
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@ -112,29 +112,5 @@
|
|||||||
<x-forms.textarea label="Container Labels" rows="15" id="customLabels"></x-forms.textarea>
|
<x-forms.textarea label="Container Labels" rows="15" id="customLabels"></x-forms.textarea>
|
||||||
<x-forms.button wire:click="resetDefaultLabels">Reset to Coolify Generated Labels</x-forms.button>
|
<x-forms.button wire:click="resetDefaultLabels">Reset to Coolify Generated Labels</x-forms.button>
|
||||||
</div>
|
</div>
|
||||||
<h3>Advanced</h3>
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<x-forms.checkbox helper="Drain logs to your configured log drain endpoint in your Server settings." instantSave
|
|
||||||
id="is_log_drain_enabled" label="Drain Logs" />
|
|
||||||
<x-forms.checkbox
|
|
||||||
helper="Your application will be available only on https if your domain starts with https://..."
|
|
||||||
instantSave id="is_force_https_enabled" label="Force Https" />
|
|
||||||
@if ($application->git_based())
|
|
||||||
<x-forms.checkbox helper="Automatically deploy new commits based on Git webhooks." instantSave
|
|
||||||
id="is_auto_deploy_enabled" label="Auto Deploy" />
|
|
||||||
<x-forms.checkbox
|
|
||||||
helper="Allow to automatically deploy Preview Deployments for all opened PR's.<br><br>Closing a PR will delete Preview Deployments."
|
|
||||||
instantSave id="is_preview_deployments_enabled" label="Preview Deployments" />
|
|
||||||
|
|
||||||
<x-forms.checkbox instantSave id="is_git_submodules_enabled" label="Git Submodules"
|
|
||||||
helper="Allow Git Submodules during build process." />
|
|
||||||
<x-forms.checkbox instantSave id="is_git_lfs_enabled" label="Git LFS"
|
|
||||||
helper="Allow Git LFS during build process." />
|
|
||||||
@endif
|
|
||||||
|
|
||||||
{{-- <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>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
<div class="flex flex-col gap-4 min-w-fit">
|
<div class="flex flex-col gap-4 min-w-fit">
|
||||||
<a :class="activeTab === 'general' && 'text-white'"
|
<a :class="activeTab === 'general' && 'text-white'"
|
||||||
@click.prevent="activeTab = 'general'; window.location.hash = 'general'" href="#">General</a>
|
@click.prevent="activeTab = 'general'; window.location.hash = 'general'" href="#">General</a>
|
||||||
|
<a :class="activeTab === 'advanced' && 'text-white'"
|
||||||
|
@click.prevent="activeTab = 'advanced'; window.location.hash = 'advanced'" href="#">Advanced</a>
|
||||||
@if ($application->build_pack !== 'static')
|
@if ($application->build_pack !== 'static')
|
||||||
<a :class="activeTab === 'environment-variables' && 'text-white'"
|
<a :class="activeTab === 'environment-variables' && 'text-white'"
|
||||||
@click.prevent="activeTab = 'environment-variables'; window.location.hash = 'environment-variables'"
|
@click.prevent="activeTab = 'environment-variables'; window.location.hash = 'environment-variables'"
|
||||||
@ -52,6 +54,9 @@
|
|||||||
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
||||||
<livewire:project.application.general :application="$application" />
|
<livewire:project.application.general :application="$application" />
|
||||||
</div>
|
</div>
|
||||||
|
<div x-cloak x-show="activeTab === 'advanced'" class="h-full">
|
||||||
|
<livewire:project.application.advanced :application="$application" />
|
||||||
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'environment-variables'">
|
<div x-cloak x-show="activeTab === 'environment-variables'">
|
||||||
<livewire:project.shared.environment-variable.all :resource="$application" />
|
<livewire:project.shared.environment-variable.all :resource="$application" />
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user