From 62c38c98597709c2ec78ab680c37879177efc864 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 18 Dec 2023 14:01:25 +0100 Subject: [PATCH] wip: swarm --- app/Console/Kernel.php | 8 ++- app/Jobs/ApplicationDeploymentJob.php | 60 ++++++++++++------- app/Jobs/ContainerStatusJob.php | 10 ++-- app/Livewire/Project/Application/General.php | 2 +- app/Livewire/Project/Application/Heading.php | 4 ++ app/Livewire/Project/Application/Previews.php | 12 ++-- app/Livewire/Project/Application/Swarm.php | 51 ++++++++++++++++ app/Livewire/Project/New/Select.php | 38 ++++++++++-- app/Livewire/Project/Shared/Storages/Add.php | 38 ++++++++---- app/Livewire/Server/Form.php | 4 +- app/Livewire/Server/New/ByIp.php | 5 ++ app/Models/Server.php | 10 +++- bootstrap/helpers/proxy.php | 10 +++- ..._12_18_093514_add_swarm_related_things.php | 36 +++++++++++ .../components/applications/navbar.blade.php | 46 +++++++------- .../views/components/server/navbar.blade.php | 45 +++++++------- .../application/configuration.blade.php | 9 +++ .../project/application/general.blade.php | 16 +++-- .../project/application/swarm.blade.php | 24 ++++++++ .../livewire/project/new/select.blade.php | 8 +++ .../project/shared/storages/add.blade.php | 22 +++++-- .../views/livewire/server/form.blade.php | 24 ++++++-- .../views/livewire/server/new/by-ip.blade.php | 15 ++++- .../livewire/server/proxy/show.blade.php | 4 +- 24 files changed, 387 insertions(+), 114 deletions(-) create mode 100644 app/Livewire/Project/Application/Swarm.php create mode 100644 database/migrations/2023_12_18_093514_add_swarm_related_things.php create mode 100644 resources/views/livewire/project/application/swarm.blade.php diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index e24d657a9..2a8e857e2 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -56,16 +56,20 @@ private function check_resources($schedule) $servers = Server::all()->whereNotNull('team.subscription')->where('team.subscription.stripe_trial_already_ended', false)->where('ip', '!=', '1.2.3.4'); $own = Team::find(0)->servers; $servers = $servers->merge($own); + $containerServers = $servers->where('settings.is_swarm_worker', false); } else { $servers = Server::all()->where('ip', '!=', '1.2.3.4'); + $containerServers = $servers->where('settings.is_swarm_worker', false); } - foreach ($servers as $server) { - $schedule->job(new ServerStatusJob($server))->everyTenMinutes()->onOneServer(); + foreach ($containerServers as $server) { $schedule->job(new ContainerStatusJob($server))->everyMinute()->onOneServer(); if ($server->isLogDrainEnabled()) { $schedule->job(new CheckLogDrainContainerJob($server))->everyMinute()->onOneServer(); } } + foreach ($servers as $server) { + $schedule->job(new ServerStatusJob($server))->everyTenMinutes()->onOneServer(); + } } private function instance_auto_update($schedule) { diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index d684473ad..263eb35f6 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -217,19 +217,8 @@ public function handle(): void if ($this->server->isProxyShouldRun()) { dispatch(new ContainerStatusJob($this->server)); } - if ($this->application->docker_registry_image_name && $this->application->build_pack !== 'dockerimage') { + if ($this->application->docker_registry_image_name && $this->application->build_pack !== 'dockerimage' && !$this->application->destination->server->isSwarm()) { $this->push_to_docker_registry(); - if ($this->server->isSwarm()) { - $this->application_deployment_queue->addLogEntry("Creating / updating stack."); - $this->execute_remote_command( - [ - executeInDocker($this->deployment_uuid, "cd {$this->workdir} && docker stack deploy --with-registry-auth -c docker-compose.yml {$this->application->uuid}") - ], - [ - "echo 'Stack deployed. It may take a few minutes to fully available in your swarm.'" - ] - ); - } } $this->next(ApplicationDeploymentStatus::FINISHED->value); $this->application->isConfigurationChanged(true); @@ -301,6 +290,9 @@ private function push_to_docker_registry() "echo -n 'Image pushed to docker registry.'" ]); } catch (Exception $e) { + if ($this->application->destination->server->isSwarm()) { + throw $e; + } $this->execute_remote_command( ["echo -n 'Failed to push image to docker registry. Please check debug logs for more information.'"], ); @@ -604,7 +596,14 @@ private function deploy_static_buildpack() private function rolling_update() { if ($this->server->isSwarm()) { - // Skip this. + $this->push_to_docker_registry(); + $this->application_deployment_queue->addLogEntry("Rolling update started."); + $this->execute_remote_command( + [ + executeInDocker($this->deployment_uuid, "docker stack deploy --with-registry-auth -c {$this->workdir}{$this->docker_compose_location} {$this->application->uuid}") + ], + ); + $this->application_deployment_queue->addLogEntry("Rolling update completed."); } else { if (count($this->application->ports_mappings_array) > 0) { $this->execute_remote_command( @@ -703,10 +702,20 @@ private function deploy_pull_request() $this->add_build_env_variables_to_dockerfile(); $this->build_image(); $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], - ); + if ($this->application->destination->server->isSwarm()) { + ray("{$this->workdir}{$this->docker_compose_location}"); + $this->push_to_docker_registry(); + $this->execute_remote_command( + [ + 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->execute_remote_command( + ["echo -n 'Starting preview deployment.'"], + [executeInDocker($this->deployment_uuid, "docker compose --project-directory {$this->workdir} up -d"), "hidden" => true], + ); + } } private function create_workdir() { @@ -970,13 +979,8 @@ private function generate_compose_file() data_forget($docker_compose, 'services.' . $this->container_name . '.cpu_shares'); $docker_compose['services'][$this->container_name]['deploy'] = [ - 'placement' => [ - 'constraints' => [ - 'node.role == worker' - ] - ], 'mode' => 'replicated', - 'replicas' => 1, + 'replicas' => data_get($this->application, 'swarm_replicas', 1), 'update_config' => [ 'order' => 'start-first' ], @@ -995,6 +999,16 @@ private function generate_compose_file() ] ] ]; + if (data_get($this->application, 'settings.is_swarm_only_worker_nodes')) { + $docker_compose['services'][$this->container_name]['deploy']['placement'] = [ + 'constraints' => [ + 'node.role == worker' + ] + ]; + } + if ($this->pull_request_id !== 0) { + $docker_compose['services'][$this->container_name]['deploy']['replicas'] = 1; + } } else { $docker_compose['services'][$this->container_name]['labels'] = $labels; } diff --git a/app/Jobs/ContainerStatusJob.php b/app/Jobs/ContainerStatusJob.php index 9989ed8cb..c0d0e7ad9 100644 --- a/app/Jobs/ContainerStatusJob.php +++ b/app/Jobs/ContainerStatusJob.php @@ -46,7 +46,7 @@ public function handle() }; if ($this->server->isSwarm()) { $containers = instant_remote_process(["docker service inspect $(docker service ls -q) --format '{{json .}}'"], $this->server, false); - $containerReplicase = instant_remote_process(["docker service ls --format '{{json .}}'"], $this->server, false); + $containerReplicates = instant_remote_process(["docker service ls --format '{{json .}}'"], $this->server, false); } else { // Precheck for containers $containers = instant_remote_process(["docker container ls -q"], $this->server, false); @@ -54,15 +54,15 @@ public function handle() return; } $containers = instant_remote_process(["docker container inspect $(docker container ls -q) --format '{{json .}}'"], $this->server, false); - $containerReplicase = null; + $containerReplicates = null; } if (is_null($containers)) { return; } $containers = format_docker_command_output_to_json($containers); - if ($containerReplicase) { - $containerReplicase = format_docker_command_output_to_json($containerReplicase); - foreach ($containerReplicase as $containerReplica) { + if ($containerReplicates) { + $containerReplicates = format_docker_command_output_to_json($containerReplicates); + foreach ($containerReplicates as $containerReplica) { $name = data_get($containerReplica, 'Name'); $containers = $containers->map(function ($container) use ($name, $containerReplica) { if (data_get($container, 'Spec.Name') === $name) { diff --git a/app/Livewire/Project/Application/General.php b/app/Livewire/Project/Application/General.php index 996774e0b..39cb15b27 100644 --- a/app/Livewire/Project/Application/General.php +++ b/app/Livewire/Project/Application/General.php @@ -113,7 +113,7 @@ public function mount() $this->application->isConfigurationChanged(true); } $this->isConfigurationChanged = $this->application->isConfigurationChanged(); - $this->customLabels = $this->application->parseContainerLabels(); + $this->customLabels = $this->application->parseContainerLabels(); $this->initialDockerComposeLocation = $this->application->docker_compose_location; $this->checkLabelUpdates(); } diff --git a/app/Livewire/Project/Application/Heading.php b/app/Livewire/Project/Application/Heading.php index 3db5fc9c4..c8fbcca2b 100644 --- a/app/Livewire/Project/Application/Heading.php +++ b/app/Livewire/Project/Application/Heading.php @@ -73,6 +73,10 @@ public function deploy(bool $force_rebuild = false) $this->dispatch('error', 'Please load a Compose file first.'); return; } + if ($this->application->destination->server->isSwarm() && is_null($this->application->docker_registry_image_name)) { + $this->dispatch('error', 'Please set a Docker image name first.'); + return; + } $this->setDeploymentUuid(); queue_application_deployment( application_id: $this->application->id, diff --git a/app/Livewire/Project/Application/Previews.php b/app/Livewire/Project/Application/Previews.php index 0fc1acf5e..31707aa3d 100644 --- a/app/Livewire/Project/Application/Previews.php +++ b/app/Livewire/Project/Application/Previews.php @@ -72,10 +72,14 @@ protected function setDeploymentUuid() public function stop(int $pull_request_id) { try { - $containers = getCurrentApplicationContainerStatus($this->application->destination->server, $this->application->id, $pull_request_id); - foreach ($containers as $container) { - $name = str_replace('/', '', $container['Names']); - instant_remote_process(["docker rm -f $name"], $this->application->destination->server, throwError: false); + if ($this->application->destination->server->isSwarm()) { + instant_remote_process(["docker stack rm {$this->application->uuid}-{$pull_request_id}"], $this->application->destination->server); + } else { + $containers = getCurrentApplicationContainerStatus($this->application->destination->server, $this->application->id, $pull_request_id); + foreach ($containers as $container) { + $name = str_replace('/', '', $container['Names']); + instant_remote_process(["docker rm -f $name"], $this->application->destination->server, throwError: false); + } } ApplicationPreview::where('application_id', $this->application->id)->where('pull_request_id', $pull_request_id)->first()->delete(); $this->application->refresh(); diff --git a/app/Livewire/Project/Application/Swarm.php b/app/Livewire/Project/Application/Swarm.php new file mode 100644 index 000000000..5f89f4934 --- /dev/null +++ b/app/Livewire/Project/Application/Swarm.php @@ -0,0 +1,51 @@ + 'required', + 'application.swarm_placement_constraints' => 'nullable', + 'application.settings.is_swarm_only_worker_nodes' => 'required', + ]; + public function mount() { + if ($this->application->swarm_placement_constraints) { + $this->swarm_placement_constraints = base64_decode($this->application->swarm_placement_constraints); + } + } + public function instantSave() { + try { + $this->validate(); + $this->application->settings->save(); + $this->dispatch('success', 'Swarm settings updated.'); + } catch (\Throwable $e) { + return handleError($e, $this); + } + } + public function submit() { + try { + $this->validate(); + if ($this->swarm_placement_constraints) { + $this->application->swarm_placement_constraints = base64_encode($this->swarm_placement_constraints); + } else { + $this->application->swarm_placement_constraints = null; + } + $this->application->save(); + + $this->dispatch('success', 'Swarm settings updated.'); + } catch (\Throwable $e) { + return handleError($e, $this); + } + } + public function render() + { + return view('livewire.project.application.swarm'); + } +} diff --git a/app/Livewire/Project/New/Select.php b/app/Livewire/Project/New/Select.php index 635e0de51..b205467bf 100644 --- a/app/Livewire/Project/New/Select.php +++ b/app/Livewire/Project/New/Select.php @@ -15,12 +15,15 @@ class Select extends Component public string $type; public string $server_id; public string $destination_uuid; + public Countable|array|Server $allServers = []; public Countable|array|Server $servers = []; public Collection|array $standaloneDockers = []; public Collection|array $swarmDockers = []; public array $parameters; public Collection|array $services = []; public Collection|array $allServices = []; + public bool $isDatabase = false; + public bool $includeSwarm = true; public bool $loadingServices = true; public bool $loading = false; @@ -96,19 +99,43 @@ public function loadServices() $this->loadingServices = false; } } + public function instantSave() + { + if ($this->includeSwarm) { + $this->servers = $this->allServers; + } else { + $this->servers = $this->allServers->where('settings.is_swarm_worker', false)->where('settings.is_swarm_manager', false); + } + } public function setType(string $type) { - $this->type = $type; if ($this->loading) return; $this->loading = true; + $this->type = $type; + switch ($type) { + case 'postgresql': + case 'mysql': + case 'mariadb': + case 'redis': + case 'mongodb': + $this->isDatabase = true; + $this->includeSwarm = false; + $this->servers = $this->allServers->where('settings.is_swarm_worker', false)->where('settings.is_swarm_manager', false); + break; + } + if (str($type)->startsWith('one-click-service')) { + $this->isDatabase = true; + $this->includeSwarm = false; + $this->servers = $this->allServers->where('settings.is_swarm_worker', false)->where('settings.is_swarm_manager', false); + } if ($type === "existing-postgresql") { $this->current_step = $type; return; } - if (count($this->servers) === 1) { - $server = $this->servers->first(); - $this->setServer($server); - } + // if (count($this->servers) === 1) { + // $server = $this->servers->first(); + // $this->setServer($server); + // } if (!is_null($this->server)) { $foundServer = $this->servers->where('id', $this->server->id)->first(); if ($foundServer) { @@ -142,5 +169,6 @@ public function setDestination(string $destination_uuid) public function loadServers() { $this->servers = Server::isUsable()->get(); + $this->allServers = $this->servers; } } diff --git a/app/Livewire/Project/Shared/Storages/Add.php b/app/Livewire/Project/Shared/Storages/Add.php index b1f467b34..e2e84c358 100644 --- a/app/Livewire/Project/Shared/Storages/Add.php +++ b/app/Livewire/Project/Shared/Storages/Add.php @@ -2,22 +2,26 @@ namespace App\Livewire\Project\Shared\Storages; +use App\Models\Application; use Livewire\Component; class Add extends Component { public $uuid; public $parameters; + public $isSwarm = false; public string $name; public string $mount_path; - public string|null $host_path = null; + public ?string $host_path = null; - protected $listeners = ['clearAddStorage' => 'clear']; - protected $rules = [ + public $rules = [ 'name' => 'required|string', 'mount_path' => 'required|string', 'host_path' => 'string|nullable', ]; + + protected $listeners = ['clearAddStorage' => 'clear']; + protected $validationAttributes = [ 'name' => 'name', 'mount_path' => 'mount', @@ -27,17 +31,31 @@ class Add extends Component public function mount() { $this->parameters = get_route_parameters(); + $applicationUuid = $this->parameters['application_uuid']; + $application = Application::where('uuid', $applicationUuid)->first(); + if (!$application) { + abort(404); + } + if ($application->destination->server->isSwarm()) { + $this->isSwarm = true; + $this->rules['host_path'] = 'required|string'; + } } public function submit() { - $this->validate(); - $name = $this->uuid . '-' . $this->name; - $this->dispatch('addNewVolume', [ - 'name' => $name, - 'mount_path' => $this->mount_path, - 'host_path' => $this->host_path, - ]); + try { + $this->validate($this->rules); + $name = $this->uuid . '-' . $this->name; + $this->dispatch('addNewVolume', [ + 'name' => $name, + 'mount_path' => $this->mount_path, + 'host_path' => $this->host_path, + ]); + $this->dispatch('closeStorageModal'); + } catch (\Throwable $e) { + return handleError($e, $this); + } } public function clear() diff --git a/app/Livewire/Server/Form.php b/app/Livewire/Server/Form.php index 480028ede..943be4458 100644 --- a/app/Livewire/Server/Form.php +++ b/app/Livewire/Server/Form.php @@ -25,7 +25,7 @@ class Form extends Component 'server.settings.is_cloudflare_tunnel' => 'required|boolean', 'server.settings.is_reachable' => 'required', 'server.settings.is_swarm_manager' => 'required|boolean', - // 'server.settings.is_swarm_worker' => 'required|boolean', + 'server.settings.is_swarm_worker' => 'required|boolean', 'wildcard_domain' => 'nullable|url', ]; protected $validationAttributes = [ @@ -37,7 +37,7 @@ class Form extends Component 'server.settings.is_cloudflare_tunnel' => 'Cloudflare Tunnel', 'server.settings.is_reachable' => 'Is reachable', 'server.settings.is_swarm_manager' => 'Swarm Manager', - // 'server.settings.is_swarm_worker' => 'Swarm Worker', + 'server.settings.is_swarm_worker' => 'Swarm Worker', ]; public function mount() diff --git a/app/Livewire/Server/New/ByIp.php b/app/Livewire/Server/New/ByIp.php index 3470e27f8..98e7a99a7 100644 --- a/app/Livewire/Server/New/ByIp.php +++ b/app/Livewire/Server/New/ByIp.php @@ -22,6 +22,8 @@ class ByIp extends Component public string $user = 'root'; public int $port = 22; public bool $is_swarm_manager = false; + public bool $is_swarm_worker = false; + protected $rules = [ 'name' => 'required|string', @@ -30,6 +32,7 @@ class ByIp extends Component 'user' => 'required|string', 'port' => 'required|integer', 'is_swarm_manager' => 'required|boolean', + 'is_swarm_worker' => 'required|boolean', ]; protected $validationAttributes = [ 'name' => 'Name', @@ -38,6 +41,7 @@ class ByIp extends Component 'user' => 'User', 'port' => 'Port', 'is_swarm_manager' => 'Swarm Manager', + 'is_swarm_worker' => 'Swarm Worker', ]; public function mount() @@ -77,6 +81,7 @@ public function submit() ], ]); $server->settings->is_swarm_manager = $this->is_swarm_manager; + $server->settings->is_swarm_worker = $this->is_swarm_worker; $server->settings->save(); $server->addInitialNetwork(); return $this->redirectRoute('server.show', $server->uuid, navigate: true); diff --git a/app/Models/Server.php b/app/Models/Server.php index a5577f6c1..59046831f 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -72,7 +72,7 @@ static public function ownedByCurrentTeam(array $select = ['*']) static public function isUsable() { - return Server::ownedByCurrentTeam()->whereRelation('settings', 'is_reachable', true)->whereRelation('settings', 'is_usable', true); + return Server::ownedByCurrentTeam()->whereRelation('settings', 'is_reachable', true)->whereRelation('settings', 'is_usable', true)->whereRelation('settings', 'is_swarm_worker', false); } static public function destinationsByServer(string $server_id) @@ -380,6 +380,14 @@ public function isSwarm() { return data_get($this, 'settings.is_swarm_manager') || data_get($this, 'settings.is_swarm_worker'); } + public function isSwarmManager() + { + return data_get($this, 'settings.is_swarm_manager'); + } + public function isSwarmWorker() + { + return data_get($this, 'settings.is_swarm_worker'); + } public function validateConnection() { $server = Server::find($this->id); diff --git a/bootstrap/helpers/proxy.php b/bootstrap/helpers/proxy.php index b40edd1d2..0ff3d1344 100644 --- a/bootstrap/helpers/proxy.php +++ b/bootstrap/helpers/proxy.php @@ -80,14 +80,18 @@ function generate_default_proxy_configuration(Server $server) $networks = collect($server->swarmDockers)->map(function ($docker) { return $docker['network']; })->unique(); + if ($networks->count() === 0) { + $networks = collect(['coolify-overlay']); + } } else { $networks = collect($server->standaloneDockers)->map(function ($docker) { return $docker['network']; })->unique(); + if ($networks->count() === 0) { + $networks = collect(['coolify']); + } } - if ($networks->count() === 0) { - $networks = collect(['coolify']); - } + $array_of_networks = collect([]); $networks->map(function ($network) use ($array_of_networks) { $array_of_networks[$network] = [ diff --git a/database/migrations/2023_12_18_093514_add_swarm_related_things.php b/database/migrations/2023_12_18_093514_add_swarm_related_things.php new file mode 100644 index 000000000..0f44f35ec --- /dev/null +++ b/database/migrations/2023_12_18_093514_add_swarm_related_things.php @@ -0,0 +1,36 @@ +integer('swarm_replicas')->default(1); + $table->text('swarm_placement_constraints')->nullable(); + }); + Schema::table('application_settings', function (Blueprint $table) { + $table->boolean('is_swarm_only_worker_nodes')->default(true); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('applications', function (Blueprint $table) { + $table->dropColumn('swarm_replicas'); + $table->dropColumn('swarm_placement_constraints'); + }); + Schema::table('application_settings', function (Blueprint $table) { + $table->dropColumn('is_swarm_only_worker_nodes'); + }); + } +}; diff --git a/resources/views/components/applications/navbar.blade.php b/resources/views/components/applications/navbar.blade.php index 38bff68e2..a1b4af91d 100644 --- a/resources/views/components/applications/navbar.blade.php +++ b/resources/views/components/applications/navbar.blade.php @@ -19,24 +19,26 @@
@if ($application->build_pack === 'dockercompose' && is_null($application->docker_compose_raw))
Please load a Compose file.
- @elseif ($application->destination->server->isSwarm() && str($application->docker_registry_image_name)->isEmpty()) - Swarm Deployments requires a Docker Image in a Registry. @else - + @if (!$application->destination->server->isSwarm()) + + @endif @if ($application->status !== 'exited') - + @if (!$application->destination->server->isSwarm()) + + @endif @if ($application->build_pack !== 'dockercompose') - @if (isDev()) + {{-- @if (isDev()) - @endif + @endif --}} @endif - @if (isDev()) + {{-- @if (isDev()) - @endif + @endif --}} @endif @endif diff --git a/resources/views/components/server/navbar.blade.php b/resources/views/components/server/navbar.blade.php index f1e4715d1..b6e8d127f 100644 --- a/resources/views/components/server/navbar.blade.php +++ b/resources/views/components/server/navbar.blade.php @@ -2,7 +2,7 @@

Server

- @if ($server->proxyType() !== 'NONE') + @if ($server->proxyType() !== 'NONE' && $server->isFunctional() && !$server->isSwarmWorker()) @endif
@@ -20,25 +20,30 @@ ]) }}"> - - - - - - - - - + @if (!$server->isSwarmWorker()) + + + + + + + + + + @endif +
- + @if ($server->proxyType() !== 'NONE' && $server->isFunctional() && !$server->isSwarmWorker()) + + @endif diff --git a/resources/views/livewire/project/application/configuration.blade.php b/resources/views/livewire/project/application/configuration.blade.php index ecfb74779..5d2936649 100644 --- a/resources/views/livewire/project/application/configuration.blade.php +++ b/resources/views/livewire/project/application/configuration.blade.php @@ -5,6 +5,11 @@
General + @if ($application->destination->server->isSwarm()) + Swarm + Configuration + @endif Advanced @if ($application->build_pack !== 'static') @@ -13,6 +18,7 @@ href="#">Environment Variables @endif + @if ($application->git_based()) Source @@ -56,6 +62,9 @@
+
+ +
diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php index 963a30ca4..6c50dec1d 100644 --- a/resources/views/livewire/project/application/general.blade.php +++ b/resources/views/livewire/project/application/general.blade.php @@ -70,8 +70,11 @@ @if ($application->build_pack !== 'dockercompose')

Docker Registry

@if ($application->destination->server->isSwarm()) -
Docker Swarm requires the image to be available in a registry. More info here.
+ @if ($application->build_pack !== 'dockerimage') +
Docker Swarm requires the image to be available in a registry. More info here.
+ @endif @else @if ($application->build_pack !== 'dockerimage')
Push the built image to a docker registry. More info
-
The following commands are for advanced use cases. Only modify them if you know what are +
The following commands are for advanced use cases. Only modify them if you + know what are you doing.
@endif - + @if (!$application->destination->server->isSwarm()) + + @endif
Reset to Coolify Generated Labels diff --git a/resources/views/livewire/project/application/swarm.blade.php b/resources/views/livewire/project/application/swarm.blade.php new file mode 100644 index 000000000..2954c9e68 --- /dev/null +++ b/resources/views/livewire/project/application/swarm.blade.php @@ -0,0 +1,24 @@ +
+
+
+

Swarm Configuration

+ + Save + +
+ {{--
Advanced Swarm Configuration
--}} +
+
+ + +
+ +
+
+ +
diff --git a/resources/views/livewire/project/new/select.blade.php b/resources/views/livewire/project/new/select.blade.php index e176cd379..ae638b8ee 100644 --- a/resources/views/livewire/project/new/select.blade.php +++ b/resources/views/livewire/project/new/select.blade.php @@ -202,6 +202,14 @@ class="w-full text-white rounded input input-sm bg-coolgray-200 disabled:bg-cool
  • Select a Server
  • Select a Destination
  • + @if ($isDatabase) +
    + +
    + @endif
    @forelse($servers as $server)
    diff --git a/resources/views/livewire/project/shared/storages/add.blade.php b/resources/views/livewire/project/shared/storages/add.blade.php index 3c46e43fb..f1d927e02 100644 --- a/resources/views/livewire/project/shared/storages/add.blade.php +++ b/resources/views/livewire/project/shared/storages/add.blade.php @@ -1,14 +1,28 @@ diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index 049b1735f..e9f2d3d38 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -35,8 +35,10 @@
    - + @if (!$server->settings->is_swarm_worker) + + @endif
    @@ -53,10 +55,20 @@ helper="If you are using Cloudflare Tunnels, enable this. It will proxy all ssh requests to your server through Cloudflare.Coolify does not install/setup Cloudflare (cloudflared) on your server." id="server.settings.is_cloudflare_tunnel" label="Cloudflare Tunnel" /> @endif - - {{-- --}} + @if ($server->settings->is_swarm_worker) + + @else + + @endif + @if ($server->settings->is_swarm_manager) + + @else + + @endif
    diff --git a/resources/views/livewire/server/new/by-ip.blade.php b/resources/views/livewire/server/new/by-ip.blade.php index 787270aee..23bc9f983 100644 --- a/resources/views/livewire/server/new/by-ip.blade.php +++ b/resources/views/livewire/server/new/by-ip.blade.php @@ -26,8 +26,19 @@ @endforeach
    - + @if ($is_swarm_worker) + + @else + + @endif + @if ($is_swarm_manager) + + @else + + @endif
    Save New Server diff --git a/resources/views/livewire/server/proxy/show.blade.php b/resources/views/livewire/server/proxy/show.blade.php index 33b30448e..a10113754 100644 --- a/resources/views/livewire/server/proxy/show.blade.php +++ b/resources/views/livewire/server/proxy/show.blade.php @@ -3,7 +3,9 @@
    - + @if ($server->proxyType() !== 'NONE' && $server->isFunctional()) + + @endif