Compare commits

...

38 Commits

Author SHA1 Message Date
Andras Bacsai
ad8653f54d Merge pull request #1564 from coollabsio/next
v4.0.0-beta.172
2023-12-21 10:35:40 +01:00
Andras Bacsai
8939d77051 fix 2023-12-21 10:28:02 +01:00
Andras Bacsai
37be4a1796 fix 2023-12-21 10:00:41 +01:00
Andras Bacsai
e4c923e358 fix 2023-12-21 09:57:39 +01:00
Andras Bacsai
62ca3ffaa5 fix 2023-12-21 09:55:16 +01:00
Andras Bacsai
9af3ce4be5 fail job instead of runtime exception 2023-12-21 09:49:18 +01:00
Andras Bacsai
fe143ef8a5 Merge pull request #1563 from coollabsio/next
v4.0.0-beta.171
2023-12-21 09:35:43 +01:00
Andras Bacsai
5fb5845e90 redirect false on some urls 2023-12-21 09:33:11 +01:00
Andras Bacsai
794cfbd8eb execute handle on containerstatusjob 2023-12-21 09:28:47 +01:00
Andras Bacsai
29ee9915f3 fix: check proxy after mount on server view
fix: change realtime console log
version++
2023-12-21 09:28:39 +01:00
Andras Bacsai
331d485213 Merge pull request #1562 from coollabsio/next
v4.0.0-beta.170
2023-12-21 08:49:22 +01:00
Andras Bacsai
665e3761c4 fix: stay tuned 2023-12-21 08:48:53 +01:00
Andras Bacsai
ac19f0e34f enable docker image swarms 2023-12-21 08:46:48 +01:00
Andras Bacsai
d7cfa0578f Comment out handle() method call in
ContainerStatusJob constructor
2023-12-20 20:01:45 +01:00
Andras Bacsai
694169bb84 fix: why?! 2023-12-20 18:09:01 +01:00
Andras Bacsai
ab853cac87 Merge pull request #1560 from coollabsio/next
v4.0.0-beta.169
2023-12-20 16:21:06 +01:00
Andras Bacsai
51db2f797d fix: storage error on dbs 2023-12-20 16:19:48 +01:00
Andras Bacsai
0c90d3d0a1 fix: docker compose apps env rewritten 2023-12-20 16:15:13 +01:00
Andras Bacsai
51efe23690 Merge pull request #1559 from coollabsio/next
disable db + service deployments swarm
2023-12-20 14:46:12 +01:00
Andras Bacsai
e3ee84105c disable db + service deployments swarm 2023-12-20 14:45:47 +01:00
Andras Bacsai
6cbd61ac6c Merge pull request #1558 from coollabsio/next
fix: get swarm service logs
2023-12-20 14:25:53 +01:00
Andras Bacsai
638d0c8c99 fix: get swarm service logs 2023-12-20 14:11:50 +01:00
Andras Bacsai
aecc81fe9d Merge pull request #1557 from coollabsio/next
v4.0.0-beta.166
2023-12-20 13:21:45 +01:00
Andras Bacsai
c9a1437870 Fix handle method in ServerStatusJob 2023-12-20 12:33:58 +01:00
Andras Bacsai
66b41b3d4c Update ServerStatusJob middleware and uniqueId()
method
2023-12-20 12:33:21 +01:00
Andras Bacsai
c41cfe2a2f Fix server status check and cleanup logic 2023-12-20 12:32:46 +01:00
Andras Bacsai
5f2ad56529 Update container and server status job 2023-12-20 12:25:14 +01:00
Andras Bacsai
cd842bc1b2 Update number of tries in ContainerStatusJob 2023-12-20 12:13:34 +01:00
Andras Bacsai
27b6aad53a fix 2023-12-20 11:59:53 +01:00
Andras Bacsai
64b58b7661 hm 2023-12-20 11:59:06 +01:00
Andras Bacsai
94960d96a9 add max horizon processes 2023-12-20 11:47:51 +01:00
Andras Bacsai
2549244f97 hm 2023-12-20 11:44:46 +01:00
Andras Bacsai
5bfffce33b hm 2023-12-20 11:37:04 +01:00
Andras Bacsai
3a4f19f368 version++ 2023-12-20 11:22:10 +01:00
Andras Bacsai
50e17ed932 fix: server ready 2023-12-20 11:21:17 +01:00
Andras Bacsai
a8fcd7aee4 Merge pull request #1556 from coollabsio/next
small UI fixes
2023-12-20 10:31:59 +01:00
Andras Bacsai
87036cc49b link 2023-12-20 10:27:39 +01:00
Andras Bacsai
e48842c6ec fix: swarm support ui 2023-12-20 10:19:21 +01:00
27 changed files with 138 additions and 82 deletions

View File

@@ -22,10 +22,10 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted
{ {
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $tries = 5; public $tries = 4;
public function backoff(): int public function backoff(): int
{ {
return isDev() ? 1 : 5; return isDev() ? 1 : 3;
} }
public function middleware(): array public function middleware(): array
{ {
@@ -39,13 +39,13 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted
public function __construct(public Server $server) public function __construct(public Server $server)
{ {
// $this->handle(); $this->handle();
} }
public function handle() public function handle()
{ {
if (!$this->server->isServerReady($this->tries)) { if (!$this->server->isServerReady($this->tries)) {
throw new \RuntimeException('Server is not reachable.'); return 'Server is not reachable.';
}; };
try { try {
if ($this->server->isSwarm()) { if ($this->server->isSwarm()) {

View File

@@ -17,22 +17,30 @@ class ServerStatusJob implements ShouldQueue, ShouldBeEncrypted
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public ?int $disk_usage = null; public ?int $disk_usage = null;
public $tries = 4;
public function backoff(): int
{
return isDev() ? 1 : 3;
}
public function __construct(public Server $server) public function __construct(public Server $server)
{ {
} }
public function middleware(): array public function middleware(): array
{ {
return [(new WithoutOverlapping($this->server->id))->dontRelease()]; return [(new WithoutOverlapping($this->server->uuid))];
} }
public function uniqueId(): int public function uniqueId(): int
{ {
return $this->server->id; return $this->server->uuid;
} }
public function handle(): void public function handle()
{ {
ray("checking server status for {$this->server->id}"); ray("checking server status for {$this->server->id}");
if (!$this->server->isServerReady(4)) {
throw new \RuntimeException('Server is not reachable.');
};
try { try {
if ($this->server->isFunctional()) { if ($this->server->isFunctional()) {
$this->cleanup(notify: false); $this->cleanup(notify: false);
@@ -40,7 +48,7 @@ class ServerStatusJob implements ShouldQueue, ShouldBeEncrypted
} catch (\Throwable $e) { } catch (\Throwable $e) {
send_internal_notification('ServerStatusJob failed with: ' . $e->getMessage()); send_internal_notification('ServerStatusJob failed with: ' . $e->getMessage());
ray($e->getMessage()); ray($e->getMessage());
handleError($e); return handleError($e);
} }
} }
public function cleanup(bool $notify = false): void public function cleanup(bool $notify = false): void

View File

@@ -68,7 +68,7 @@ class DockerImage extends Component
'application_uuid' => $application->uuid, 'application_uuid' => $application->uuid,
'environment_name' => $environment->name, 'environment_name' => $environment->name,
'project_uuid' => $project->uuid, 'project_uuid' => $project->uuid,
], navigate: true); ], navigate: false);
} }
public function render() public function render()
{ {

View File

@@ -13,6 +13,6 @@ class EmptyProject extends Component
'name' => generate_random_name(), 'name' => generate_random_name(),
'team_id' => currentTeam()->id, 'team_id' => currentTeam()->id,
]); ]);
return $this->redirectRoute('project.show', ['project_uuid' => $project->uuid, 'environment_name' => 'production'], navigate: true); return $this->redirectRoute('project.show', ['project_uuid' => $project->uuid, 'environment_name' => 'production'], navigate: false);
} }
} }

View File

@@ -155,7 +155,7 @@ class GithubPrivateRepository extends Component
'application_uuid' => $application->uuid, 'application_uuid' => $application->uuid,
'environment_name' => $environment->name, 'environment_name' => $environment->name,
'project_uuid' => $project->uuid, 'project_uuid' => $project->uuid,
], navigate: true); ], navigate: false);
} catch (\Throwable $e) { } catch (\Throwable $e) {
return handleError($e, $this); return handleError($e, $this);
} }

View File

@@ -136,7 +136,7 @@ class GithubPrivateRepositoryDeployKey extends Component
'application_uuid' => $application->uuid, 'application_uuid' => $application->uuid,
'environment_name' => $environment->name, 'environment_name' => $environment->name,
'project_uuid' => $project->uuid, 'project_uuid' => $project->uuid,
], navigate: true); ], navigate: false);
} catch (\Throwable $e) { } catch (\Throwable $e) {
return handleError($e, $this); return handleError($e, $this);
} }

View File

@@ -188,7 +188,7 @@ class PublicGitRepository extends Component
'application_uuid' => $application->uuid, 'application_uuid' => $application->uuid,
'environment_name' => $environment->name, 'environment_name' => $environment->name,
'project_uuid' => $project->uuid, 'project_uuid' => $project->uuid,
], navigate: true); ], navigate: false);
} catch (\Throwable $e) { } catch (\Throwable $e) {
return handleError($e, $this); return handleError($e, $this);
} }

View File

@@ -123,7 +123,7 @@ class Select extends Component
$this->servers = $this->allServers->where('settings.is_swarm_worker', false)->where('settings.is_swarm_manager', false); $this->servers = $this->allServers->where('settings.is_swarm_worker', false)->where('settings.is_swarm_manager', false);
break; break;
} }
if (str($type)->startsWith('one-click-service') || str($type)->startsWith('docker-compose-empty') || str($type)->startsWith('docker-image')) { if (str($type)->startsWith('one-click-service') || str($type)->startsWith('docker-compose-empty')) {
$this->isDatabase = true; $this->isDatabase = true;
$this->includeSwarm = false; $this->includeSwarm = false;
$this->servers = $this->allServers->where('settings.is_swarm_worker', false)->where('settings.is_swarm_manager', false); $this->servers = $this->allServers->where('settings.is_swarm_worker', false)->where('settings.is_swarm_manager', false);

View File

@@ -74,6 +74,6 @@ CMD ["nginx", "-g", "daemon off;"]
'application_uuid' => $application->uuid, 'application_uuid' => $application->uuid,
'environment_name' => $environment->name, 'environment_name' => $environment->name,
'project_uuid' => $project->uuid, 'project_uuid' => $project->uuid,
], navigate: true); ], navigate: false);
} }
} }

View File

@@ -65,7 +65,11 @@ class Show extends Component
public function delete() public function delete()
{ {
$this->env->delete(); try {
$this->dispatch('refreshEnvs'); $this->env->delete();
$this->dispatch('refreshEnvs');
} catch (\Exception $e) {
return handleError($e);
}
} }
} }

View File

@@ -73,9 +73,17 @@ class GetLogs extends Component
if (!$refresh && $this->resource?->getMorphClass() === 'App\Models\Service') return; if (!$refresh && $this->resource?->getMorphClass() === 'App\Models\Service') return;
if ($this->container) { if ($this->container) {
if ($this->showTimeStamps) { if ($this->showTimeStamps) {
$sshCommand = generateSshCommand($this->server, "docker logs -n {$this->numberOfLines} -t {$this->container}"); if ($this->server->isSwarm()) {
$sshCommand = generateSshCommand($this->server, "docker service logs -n {$this->numberOfLines} -t {$this->container}");
} else {
$sshCommand = generateSshCommand($this->server, "docker logs -n {$this->numberOfLines} -t {$this->container}");
}
} else { } else {
$sshCommand = generateSshCommand($this->server, "docker logs -n {$this->numberOfLines} {$this->container}"); if ($this->server->isSwarm()) {
$sshCommand = generateSshCommand($this->server, "docker service logs -n {$this->numberOfLines} {$this->container}");
} else {
$sshCommand = generateSshCommand($this->server, "docker logs -n {$this->numberOfLines} {$this->container}");
}
} }
if ($refresh) { if ($refresh) {
$this->outputs = ''; $this->outputs = '';

View File

@@ -34,7 +34,15 @@ 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, 0); if ($this->server->isSwarm()) {
$containers = collect([
[
'Names' => $this->resource->uuid . '_' . $this->resource->uuid,
]
]);
} else {
$containers = getCurrentApplicationContainerStatus($this->server, $this->resource->id, 0);
}
if ($containers->count() > 0) { if ($containers->count() > 0) {
$containers->each(function ($container) { $containers->each(function ($container) {
$this->containers->push(str_replace('/', '', $container['Names'])); $this->containers->push(str_replace('/', '', $container['Names']));
@@ -62,7 +70,7 @@ class Logs extends Component
$this->status = $this->resource->status; $this->status = $this->resource->status;
$this->server = $this->resource->destination->server; $this->server = $this->resource->destination->server;
$this->container = $this->resource->uuid; $this->container = $this->resource->uuid;
if (str(data_get($this,'resource.status'))->startsWith('running')) { if (str(data_get($this, 'resource.status'))->startsWith('running')) {
$this->containers->push($this->container); $this->containers->push($this->container);
} }
} else if (data_get($this->parameters, 'service_uuid')) { } else if (data_get($this->parameters, 'service_uuid')) {

View File

@@ -31,14 +31,16 @@ class Add extends Component
public function mount() public function mount()
{ {
$this->parameters = get_route_parameters(); $this->parameters = get_route_parameters();
$applicationUuid = $this->parameters['application_uuid']; if (data_get($this->parameters, 'application_uuid')) {
$application = Application::where('uuid', $applicationUuid)->first(); $applicationUuid = $this->parameters['application_uuid'];
if (!$application) { $application = Application::where('uuid', $applicationUuid)->first();
abort(404); if (!$application) {
} abort(404);
if ($application->destination->server->isSwarm()) { }
$this->isSwarm = true; if ($application->destination->server->isSwarm()) {
$this->rules['host_path'] = 'required|string'; $this->isSwarm = true;
$this->rules['host_path'] = 'required|string';
}
} }
} }

View File

@@ -93,7 +93,7 @@ class ByIp extends Component
$server->settings->is_swarm_worker = $this->is_swarm_worker; $server->settings->is_swarm_worker = $this->is_swarm_worker;
$server->settings->save(); $server->settings->save();
$server->addInitialNetwork(); $server->addInitialNetwork();
return $this->redirectRoute('server.show', $server->uuid, navigate: true); return $this->redirectRoute('server.show', $server->uuid);
} catch (\Throwable $e) { } catch (\Throwable $e) {
return handleError($e, $this); return handleError($e, $this);
} }

View File

@@ -15,7 +15,6 @@ class Status extends Component
protected $listeners = ['proxyStatusUpdated', 'startProxyPolling']; protected $listeners = ['proxyStatusUpdated', 'startProxyPolling'];
public function mount() { public function mount() {
$this->checkProxy();
} }
public function startProxyPolling() public function startProxyPolling()
{ {

View File

@@ -151,12 +151,22 @@ class Server extends BaseModel
} }
public function isServerReady(int $tries = 3) public function isServerReady(int $tries = 3)
{ {
$serverUptimeCheckNumber = $this->unreachable_count + 1; if ($this->skipServer()) {
return false;
}
$serverUptimeCheckNumber = $this->unreachable_count;
if ($this->unreachable_count < $tries) {
$serverUptimeCheckNumber = $this->unreachable_count + 1;
}
if ($this->unreachable_count > $tries) {
$serverUptimeCheckNumber = $tries;
}
$serverUptimeCheckNumberMax = $tries; $serverUptimeCheckNumberMax = $tries;
ray('server: ' . $this->name); // ray('server: ' . $this->name);
ray('serverUptimeCheckNumber: ' . $serverUptimeCheckNumber); // ray('serverUptimeCheckNumber: ' . $serverUptimeCheckNumber);
ray('serverUptimeCheckNumberMax: ' . $serverUptimeCheckNumberMax); // ray('serverUptimeCheckNumberMax: ' . $serverUptimeCheckNumberMax);
$result = $this->validateConnection(); $result = $this->validateConnection();
if ($result) { if ($result) {

View File

@@ -14,20 +14,23 @@ use Visus\Cuid2\Cuid2;
function getCurrentApplicationContainerStatus(Server $server, int $id, ?int $pullRequestId = null): Collection function getCurrentApplicationContainerStatus(Server $server, int $id, ?int $pullRequestId = null): Collection
{ {
$containers = collect([]); $containers = collect([]);
$containers = instant_remote_process(["docker ps -a --filter='label=coolify.applicationId={$id}' --format '{{json .}}' "], $server); if (!$server->isSwarm()) {
$containers = format_docker_command_output_to_json($containers); $containers = instant_remote_process(["docker ps -a --filter='label=coolify.applicationId={$id}' --format '{{json .}}' "], $server);
$containers = $containers->map(function ($container) use ($pullRequestId) { $containers = format_docker_command_output_to_json($containers);
$labels = data_get($container, 'Labels'); $containers = $containers->map(function ($container) use ($pullRequestId) {
if (!str($labels)->contains("coolify.pullRequestId=")) { $labels = data_get($container, 'Labels');
data_set($container, 'Labels', $labels . ",coolify.pullRequestId={$pullRequestId}"); if (!str($labels)->contains("coolify.pullRequestId=")) {
return $container; data_set($container, 'Labels', $labels . ",coolify.pullRequestId={$pullRequestId}");
} return $container;
if (str($labels)->contains("coolify.pullRequestId=$pullRequestId")) { }
return $container; if (str($labels)->contains("coolify.pullRequestId=$pullRequestId")) {
} return $container;
return null; }
}); return null;
$containers = $containers->filter(); });
$containers = $containers->filter();
return $containers;
}
return $containers; return $containers;
} }

View File

@@ -1330,7 +1330,8 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
if ($value?->startsWith('$')) { if ($value?->startsWith('$')) {
$foundEnv = EnvironmentVariable::where([ $foundEnv = EnvironmentVariable::where([
'key' => $key, 'key' => $key,
'service_id' => $resource->id, 'application_id' => $resource->id,
'is_preview' => false,
])->first(); ])->first();
$value = Str::of(replaceVariables($value)); $value = Str::of(replaceVariables($value));
$key = $value; $key = $value;
@@ -1397,14 +1398,22 @@ function parseDockerComposeFile(Service|Application $resource, bool $isNew = fal
$defaultValue = data_get($foundEnv, 'value'); $defaultValue = data_get($foundEnv, 'value');
} }
$isBuildTime = data_get($foundEnv, 'is_build_time', false); $isBuildTime = data_get($foundEnv, 'is_build_time', false);
EnvironmentVariable::updateOrCreate([ if ($foundEnv) {
'key' => $key->value(), $foundEnv->update([
'application_id' => $resource->id, 'key' => $key,
], [ 'application_id' => $resource->id,
'value' => $defaultValue, 'is_build_time' => $isBuildTime,
'is_build_time' => $isBuildTime, 'value' => $defaultValue,
'application_id' => $resource->id, ]);
]); } else {
EnvironmentVariable::create([
'key' => $key,
'value' => $defaultValue,
'is_build_time' => $isBuildTime,
'application_id' => $resource->id,
'is_preview' => false,
]);
}
} }
} }
} }

View File

@@ -216,7 +216,7 @@ return [
], ],
'long-running' => [ 'long-running' => [
'autoScalingStrategy' => 'size', 'autoScalingStrategy' => 'size',
'maxProcesses' => env('HORIZON_MAX_PROCESSES', 2), 'maxProcesses' => env('HORIZON_MAX_PROCESSES', 6),
'balanceMaxShift' => env('HORIZON_BALANCE_MAX_SHIFT', 1), 'balanceMaxShift' => env('HORIZON_BALANCE_MAX_SHIFT', 1),
'balanceCooldown' => env('HORIZON_BALANCE_COOLDOWN', 1), 'balanceCooldown' => env('HORIZON_BALANCE_COOLDOWN', 1),
], ],
@@ -231,7 +231,7 @@ return [
], ],
'long-running' => [ 'long-running' => [
'autoScalingStrategy' => 'size', 'autoScalingStrategy' => 'size',
'maxProcesses' => env('HORIZON_MAX_PROCESSES', 2), 'maxProcesses' => env('HORIZON_MAX_PROCESSES', 6),
'balanceMaxShift' => env('HORIZON_BALANCE_MAX_SHIFT', 1), 'balanceMaxShift' => env('HORIZON_BALANCE_MAX_SHIFT', 1),
'balanceCooldown' => env('HORIZON_BALANCE_COOLDOWN', 1), 'balanceCooldown' => env('HORIZON_BALANCE_COOLDOWN', 1),
], ],

View File

@@ -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.165', 'release' => '4.0.0-beta.172',
// 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'),

View File

@@ -1,3 +1,3 @@
<?php <?php
return '4.0.0-beta.165'; return '4.0.0-beta.172';

View File

@@ -3,10 +3,12 @@
href="{{ route('project.application.configuration', $parameters) }}"> href="{{ route('project.application.configuration', $parameters) }}">
<button>Configuration</button> <button>Configuration</button>
</a> </a>
@if(!$application->destination->server->isSwarm())
<a wire:navigate class="{{ request()->routeIs('project.application.command') ? 'text-white' : '' }}" <a wire:navigate class="{{ request()->routeIs('project.application.command') ? 'text-white' : '' }}"
href="{{ route('project.application.command', $parameters) }}"> href="{{ route('project.application.command', $parameters) }}">
<button>Execute Command</button> <button>Execute Command</button>
</a> </a>
@endif
<a wire:navigate class="{{ request()->routeIs('project.application.logs') ? 'text-white' : '' }}" <a wire:navigate class="{{ request()->routeIs('project.application.logs') ? 'text-white' : '' }}"
href="{{ route('project.application.logs', $parameters) }}"> href="{{ route('project.application.logs', $parameters) }}">
<button>Logs</button> <button>Logs</button>

View File

@@ -203,13 +203,17 @@
<li class="step">Select a Destination</li> <li class="step">Select a Destination</li>
</ul> </ul>
@if ($isDatabase) @if ($isDatabase)
<div class="text-center">Swarm clusters are excluded from this type of resource at the moment. It will
be activated soon. Stay tuned.</div>
@endif
{{-- @if ($isDatabase)
<div class="flex items-center justify-center pt-4"> <div class="flex items-center justify-center pt-4">
<x-forms.checkbox instantSave wire:model="includeSwarm" <x-forms.checkbox instantSave wire:model="includeSwarm"
helper="Swarm clusters are excluded from this list by default. For database, services or complex compose deployments with databases to work with Swarm, helper="Swarm clusters are excluded from this list by default. For database, services or complex compose deployments with databases to work with Swarm,
you need to set a few things on the server. Read more <a class='text-white underline' href='https://coolify.io/docs/swarm#database-requirements' target='_blank'>here</a>." you need to set a few things on the server. Read more <a class='text-white underline' href='https://coolify.io/docs/swarm#database-requirements' target='_blank'>here</a>."
label="Include Swarm Clusters" /> label="Include Swarm Clusters" />
</div> </div>
@endif @endif --}}
<div class="flex flex-col justify-center gap-2 text-left xl:flex-row xl:flex-wrap"> <div class="flex flex-col justify-center gap-2 text-left xl:flex-row xl:flex-wrap">
@forelse($servers as $server) @forelse($servers as $server)
<div class="box group" wire:click="setServer({{ $server }})"> <div class="box group" wire:click="setServer({{ $server }})">

View File

@@ -18,7 +18,7 @@
clearInterval(checkPusherInterval); clearInterval(checkPusherInterval);
} }
} else { } else {
console.log('Coolify is now connected to the new realtime service introduced in beta.154.'); console.log('Coolify Realtime Service is connected!');
clearInterval(checkPusherInterval); clearInterval(checkPusherInterval);
} }
} else { } else {

View File

@@ -25,8 +25,8 @@
@endif @endif
@endforeach @endforeach
</x-forms.select> </x-forms.select>
<div class="w-72"> <div class="w-96">
<div class="pt-6"> Swarm support is in alpha version. </div> <div class="pt-6"> Swarm support is in alpha version. Read the docs <a class='text-white' href='https://coolify.io/docs/swarm#deploy-with-persistent-storage' target='_blank'>here</a>.</div>
@if ($is_swarm_worker) @if ($is_swarm_worker)
<x-forms.checkbox disabled instantSave type="checkbox" id="is_swarm_manager" <x-forms.checkbox disabled instantSave type="checkbox" id="is_swarm_manager"
helper="For more information, please read the documentation <a class='text-white' href='https://coolify.io/docs/swarm' target='_blank'>here</a>." helper="For more information, please read the documentation <a class='text-white' href='https://coolify.io/docs/swarm' target='_blank'>here</a>."
@@ -45,24 +45,23 @@
helper="For more information, please read the documentation <a class='text-white' href='https://coolify.io/docs/swarm' target='_blank'>here</a>." helper="For more information, please read the documentation <a class='text-white' href='https://coolify.io/docs/swarm' target='_blank'>here</a>."
label="Is it a Swarm Worker?" /> label="Is it a Swarm Worker?" />
@endif @endif
@if ($is_swarm_worker) @if ($is_swarm_worker && count($swarm_managers) > 0)
<div class="py-4"> <div class="py-4">
<x-forms.select label="Select a Swarm Cluster" id="selected_swarm_cluster" required> <x-forms.select label="Select a Swarm Cluster" id="selected_swarm_cluster" required>
@foreach ($swarm_managers as $server) @foreach ($swarm_managers as $server)
@if ($loop->first) @if ($loop->first)
<option selected value="{{ $server->id }}">{{ $server->name }}</option> <option selected value="{{ $server->id }}">{{ $server->name }}</option>
@else @else
<option value="{{ $server->id }}">{{ $server->name }}</option> <option value="{{ $server->id }}">{{ $server->name }}</option>
@endif @endif
@endforeach @endforeach
</x-forms.select> </x-forms.select>
</div> </div>
@endif @endif
</div> </div>
<x-forms.button type="submit"> <x-forms.button type="submit">
Save New Server Save Server
</x-forms.button> </x-forms.button>
</form> </form>
@endif @endif
</div> </div>

View File

@@ -1,4 +1,4 @@
<div> <div x-init="$wire.checkProxy()">
@if ($server->isFunctional()) @if ($server->isFunctional())
<div class="flex gap-2"> <div class="flex gap-2">
@if (data_get($server, 'proxy.status') === 'running') @if (data_get($server, 'proxy.status') === 'running')

View File

@@ -4,7 +4,7 @@
"version": "3.12.36" "version": "3.12.36"
}, },
"v4": { "v4": {
"version": "4.0.0-beta.165" "version": "4.0.0-beta.172"
} }
} }
} }