diff --git a/app/Actions/Database/StartClickhouse.php b/app/Actions/Database/StartClickhouse.php
index 1e8616416..13667e829 100644
--- a/app/Actions/Database/StartClickhouse.php
+++ b/app/Actions/Database/StartClickhouse.php
@@ -99,8 +99,8 @@ class StartClickhouse
}
// Add custom docker run options
- $docker_run_options = convert_docker_run_to_compose($this->database->custom_docker_run_options);
- $docker_compose = generate_custom_docker_run_options_for_databases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
+ $docker_run_options = convertDockerRunToCompose($this->database->custom_docker_run_options);
+ $docker_compose = generateCustomDockerRunOptionsForDatabases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
$docker_compose = Yaml::dump($docker_compose, 10);
$docker_compose_base64 = base64_encode($docker_compose);
diff --git a/app/Actions/Database/StartDatabase.php b/app/Actions/Database/StartDatabase.php
index 73b2f9ac0..869a88521 100644
--- a/app/Actions/Database/StartDatabase.php
+++ b/app/Actions/Database/StartDatabase.php
@@ -49,7 +49,7 @@ class StartDatabase
break;
}
if ($database->is_public && $database->public_port) {
- StartDatabaseProxy::dispatch($database);
+ StartDatabaseProxy::dispatch($database)->onQueue('high');
}
return $activity;
diff --git a/app/Actions/Database/StartDragonfly.php b/app/Actions/Database/StartDragonfly.php
index 6274737a1..c72714e1c 100644
--- a/app/Actions/Database/StartDragonfly.php
+++ b/app/Actions/Database/StartDragonfly.php
@@ -96,8 +96,8 @@ class StartDragonfly
}
// Add custom docker run options
- $docker_run_options = convert_docker_run_to_compose($this->database->custom_docker_run_options);
- $docker_compose = generate_custom_docker_run_options_for_databases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
+ $docker_run_options = convertDockerRunToCompose($this->database->custom_docker_run_options);
+ $docker_compose = generateCustomDockerRunOptionsForDatabases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
$docker_compose = Yaml::dump($docker_compose, 10);
$docker_compose_base64 = base64_encode($docker_compose);
diff --git a/app/Actions/Database/StartKeydb.php b/app/Actions/Database/StartKeydb.php
index 734b28322..bd98258ab 100644
--- a/app/Actions/Database/StartKeydb.php
+++ b/app/Actions/Database/StartKeydb.php
@@ -107,8 +107,8 @@ class StartKeydb
}
// Add custom docker run options
- $docker_run_options = convert_docker_run_to_compose($this->database->custom_docker_run_options);
- $docker_compose = generate_custom_docker_run_options_for_databases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
+ $docker_run_options = convertDockerRunToCompose($this->database->custom_docker_run_options);
+ $docker_compose = generateCustomDockerRunOptionsForDatabases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
$docker_compose = Yaml::dump($docker_compose, 10);
$docker_compose_base64 = base64_encode($docker_compose);
$this->commands[] = "echo '{$docker_compose_base64}' | base64 -d | tee $this->configuration_dir/docker-compose.yml > /dev/null";
diff --git a/app/Actions/Database/StartMariadb.php b/app/Actions/Database/StartMariadb.php
index aa6b79126..696dd7ff4 100644
--- a/app/Actions/Database/StartMariadb.php
+++ b/app/Actions/Database/StartMariadb.php
@@ -101,8 +101,8 @@ class StartMariadb
}
// Add custom docker run options
- $docker_run_options = convert_docker_run_to_compose($this->database->custom_docker_run_options);
- $docker_compose = generate_custom_docker_run_options_for_databases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
+ $docker_run_options = convertDockerRunToCompose($this->database->custom_docker_run_options);
+ $docker_compose = generateCustomDockerRunOptionsForDatabases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
$docker_compose = Yaml::dump($docker_compose, 10);
$docker_compose_base64 = base64_encode($docker_compose);
diff --git a/app/Actions/Database/StartMongodb.php b/app/Actions/Database/StartMongodb.php
index 8d0a6b3ca..6d67bdde6 100644
--- a/app/Actions/Database/StartMongodb.php
+++ b/app/Actions/Database/StartMongodb.php
@@ -117,8 +117,8 @@ class StartMongodb
];
// Add custom docker run options
- $docker_run_options = convert_docker_run_to_compose($this->database->custom_docker_run_options);
- $docker_compose = generate_custom_docker_run_options_for_databases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
+ $docker_run_options = convertDockerRunToCompose($this->database->custom_docker_run_options);
+ $docker_compose = generateCustomDockerRunOptionsForDatabases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
$docker_compose = Yaml::dump($docker_compose, 10);
$docker_compose_base64 = base64_encode($docker_compose);
diff --git a/app/Actions/Database/StartMysql.php b/app/Actions/Database/StartMysql.php
index 0339501b0..a3694648f 100644
--- a/app/Actions/Database/StartMysql.php
+++ b/app/Actions/Database/StartMysql.php
@@ -101,8 +101,8 @@ class StartMysql
}
// Add custom docker run options
- $docker_run_options = convert_docker_run_to_compose($this->database->custom_docker_run_options);
- $docker_compose = generate_custom_docker_run_options_for_databases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
+ $docker_run_options = convertDockerRunToCompose($this->database->custom_docker_run_options);
+ $docker_compose = generateCustomDockerRunOptionsForDatabases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
$docker_compose = Yaml::dump($docker_compose, 10);
$docker_compose_base64 = base64_encode($docker_compose);
diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php
index 5c956acbc..f5e85087f 100644
--- a/app/Actions/Database/StartPostgresql.php
+++ b/app/Actions/Database/StartPostgresql.php
@@ -122,8 +122,8 @@ class StartPostgresql
];
}
// Add custom docker run options
- $docker_run_options = convert_docker_run_to_compose($this->database->custom_docker_run_options);
- $docker_compose = generate_custom_docker_run_options_for_databases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
+ $docker_run_options = convertDockerRunToCompose($this->database->custom_docker_run_options);
+ $docker_compose = generateCustomDockerRunOptionsForDatabases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
$docker_compose = Yaml::dump($docker_compose, 10);
$docker_compose_base64 = base64_encode($docker_compose);
diff --git a/app/Actions/Database/StartRedis.php b/app/Actions/Database/StartRedis.php
index e445a246e..7a2d2b34d 100644
--- a/app/Actions/Database/StartRedis.php
+++ b/app/Actions/Database/StartRedis.php
@@ -110,8 +110,8 @@ class StartRedis
}
// Add custom docker run options
- $docker_run_options = convert_docker_run_to_compose($this->database->custom_docker_run_options);
- $docker_compose = generate_custom_docker_run_options_for_databases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
+ $docker_run_options = convertDockerRunToCompose($this->database->custom_docker_run_options);
+ $docker_compose = generateCustomDockerRunOptionsForDatabases($docker_run_options, $docker_compose, $container_name, $this->database->destination->network);
$docker_compose = Yaml::dump($docker_compose, 10);
$docker_compose_base64 = base64_encode($docker_compose);
diff --git a/app/Actions/Server/InstallDocker.php b/app/Actions/Server/InstallDocker.php
index fd4dd150c..ba6c23ffc 100644
--- a/app/Actions/Server/InstallDocker.php
+++ b/app/Actions/Server/InstallDocker.php
@@ -12,11 +12,11 @@ class InstallDocker
public function handle(Server $server)
{
+ $dockerVersion = config('constants.docker_install_version');
$supported_os_type = $server->validateOS();
if (! $supported_os_type) {
throw new \Exception('Server OS type is not supported for automated installation. Please install Docker manually before continuing: documentation.');
}
- $dockerVersion = '26.0';
$config = base64_encode('{
"log-driver": "json-file",
"log-opts": {
diff --git a/app/Actions/Server/ServerCheck.php b/app/Actions/Server/ServerCheck.php
index f61422807..d9de1464e 100644
--- a/app/Actions/Server/ServerCheck.php
+++ b/app/Actions/Server/ServerCheck.php
@@ -130,10 +130,10 @@ class ServerCheck
if ($foundLogDrainContainer) {
$status = data_get($foundLogDrainContainer, 'State.Status');
if ($status !== 'running') {
- StartLogDrain::dispatch($this->server);
+ StartLogDrain::dispatch($this->server)->onQueue('high');
}
} else {
- StartLogDrain::dispatch($this->server);
+ StartLogDrain::dispatch($this->server)->onQueue('high');
}
}
diff --git a/app/Console/Commands/Init.php b/app/Console/Commands/Init.php
index 8d4f51d1c..c802fb116 100644
--- a/app/Console/Commands/Init.php
+++ b/app/Console/Commands/Init.php
@@ -39,7 +39,7 @@ class Init extends Command
}
// Backward compatibility
- $this->disable_metrics();
+ // $this->disable_metrics();
$this->replace_slash_in_environment_name();
$this->restore_coolify_db_backup();
$this->update_user_emails();
@@ -80,19 +80,19 @@ class Init extends Command
}
}
- private function disable_metrics()
- {
- if (version_compare('4.0.0-beta.312', config('version'), '<=')) {
- foreach ($this->servers as $server) {
- if ($server->settings->is_metrics_enabled === true) {
- $server->settings->update(['is_metrics_enabled' => false]);
- }
- if ($server->isFunctional()) {
- StopSentinel::dispatch($server);
- }
- }
- }
- }
+ // private function disable_metrics()
+ // {
+ // if (version_compare('4.0.0-beta.312', config('version'), '<=')) {
+ // foreach ($this->servers as $server) {
+ // if ($server->settings->is_metrics_enabled === true) {
+ // $server->settings->update(['is_metrics_enabled' => false]);
+ // }
+ // if ($server->isFunctional()) {
+ // StopSentinel::dispatch($server)->onQueue('high');
+ // }
+ // }
+ // }
+ // }
private function update_user_emails()
{
diff --git a/app/Console/Commands/ServicesDelete.php b/app/Console/Commands/ServicesDelete.php
index b5a74166a..1e5d5808c 100644
--- a/app/Console/Commands/ServicesDelete.php
+++ b/app/Console/Commands/ServicesDelete.php
@@ -96,7 +96,7 @@ class ServicesDelete extends Command
if (! $confirmed) {
break;
}
- DeleteResourceJob::dispatch($toDelete);
+ DeleteResourceJob::dispatch($toDelete)->onQueue('high');
}
}
}
@@ -122,7 +122,7 @@ class ServicesDelete extends Command
if (! $confirmed) {
return;
}
- DeleteResourceJob::dispatch($toDelete);
+ DeleteResourceJob::dispatch($toDelete)->onQueue('high');
}
}
}
@@ -148,7 +148,7 @@ class ServicesDelete extends Command
if (! $confirmed) {
return;
}
- DeleteResourceJob::dispatch($toDelete);
+ DeleteResourceJob::dispatch($toDelete)->onQueue('high');
}
}
}
diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index 8b60c694b..3e3ae0834 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -179,14 +179,11 @@ class Kernel extends ConsoleKernel
private function checkScheduledTasks($schedule): void
{
- $scheduled_tasks = ScheduledTask::all();
+ $scheduled_tasks = ScheduledTask::where('enabled', true)->get();
if ($scheduled_tasks->isEmpty()) {
return;
}
foreach ($scheduled_tasks as $scheduled_task) {
- if ($scheduled_task->enabled === false) {
- continue;
- }
$service = $scheduled_task->service;
$application = $scheduled_task->application;
diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php
index dee75578f..f0eeb56d8 100644
--- a/app/Http/Controllers/Api/ApplicationsController.php
+++ b/app/Http/Controllers/Api/ApplicationsController.php
@@ -1203,7 +1203,7 @@ class ApplicationsController extends Controller
$service->name = "service-$service->uuid";
$service->parse(isNew: true);
if ($instantDeploy) {
- StartService::dispatch($service);
+ StartService::dispatch($service)->onQueue('high');
}
return response()->json(serializeApiResponse([
@@ -1358,7 +1358,7 @@ class ApplicationsController extends Controller
deleteVolumes: $request->query->get('delete_volumes', true),
dockerCleanup: $request->query->get('docker_cleanup', true),
deleteConnectedNetworks: $request->query->get('delete_connected_networks', true)
- );
+ )->onQueue('high');
return response()->json([
'message' => 'Application deletion request queued.',
@@ -2482,7 +2482,7 @@ class ApplicationsController extends Controller
if (! $application) {
return response()->json(['message' => 'Application not found.'], 404);
}
- StopApplication::dispatch($application);
+ StopApplication::dispatch($application)->onQueue('high');
return response()->json(
[
diff --git a/app/Http/Controllers/Api/DatabasesController.php b/app/Http/Controllers/Api/DatabasesController.php
index ce658d2a2..eaa542a83 100644
--- a/app/Http/Controllers/Api/DatabasesController.php
+++ b/app/Http/Controllers/Api/DatabasesController.php
@@ -497,9 +497,9 @@ class DatabasesController extends Controller
$database->update($request->all());
if ($whatToDoWithDatabaseProxy === 'start') {
- StartDatabaseProxy::dispatch($database);
+ StartDatabaseProxy::dispatch($database)->onQueue('high');
} elseif ($whatToDoWithDatabaseProxy === 'stop') {
- StopDatabaseProxy::dispatch($database);
+ StopDatabaseProxy::dispatch($database)->onQueue('high');
}
return response()->json([
@@ -1151,7 +1151,7 @@ class DatabasesController extends Controller
}
$database = create_standalone_postgresql($environment->id, $destination->uuid, $request->all());
if ($instantDeploy) {
- StartDatabase::dispatch($database);
+ StartDatabase::dispatch($database)->onQueue('high');
}
$database->refresh();
$payload = [
@@ -1206,7 +1206,7 @@ class DatabasesController extends Controller
}
$database = create_standalone_mariadb($environment->id, $destination->uuid, $request->all());
if ($instantDeploy) {
- StartDatabase::dispatch($database);
+ StartDatabase::dispatch($database)->onQueue('high');
}
$database->refresh();
@@ -1264,7 +1264,7 @@ class DatabasesController extends Controller
}
$database = create_standalone_mysql($environment->id, $destination->uuid, $request->all());
if ($instantDeploy) {
- StartDatabase::dispatch($database);
+ StartDatabase::dispatch($database)->onQueue('high');
}
$database->refresh();
@@ -1320,7 +1320,7 @@ class DatabasesController extends Controller
}
$database = create_standalone_redis($environment->id, $destination->uuid, $request->all());
if ($instantDeploy) {
- StartDatabase::dispatch($database);
+ StartDatabase::dispatch($database)->onQueue('high');
}
$database->refresh();
@@ -1357,7 +1357,7 @@ class DatabasesController extends Controller
removeUnnecessaryFieldsFromRequest($request);
$database = create_standalone_dragonfly($environment->id, $destination->uuid, $request->all());
if ($instantDeploy) {
- StartDatabase::dispatch($database);
+ StartDatabase::dispatch($database)->onQueue('high');
}
return response()->json(serializeApiResponse([
@@ -1406,7 +1406,7 @@ class DatabasesController extends Controller
}
$database = create_standalone_keydb($environment->id, $destination->uuid, $request->all());
if ($instantDeploy) {
- StartDatabase::dispatch($database);
+ StartDatabase::dispatch($database)->onQueue('high');
}
$database->refresh();
@@ -1442,7 +1442,7 @@ class DatabasesController extends Controller
removeUnnecessaryFieldsFromRequest($request);
$database = create_standalone_clickhouse($environment->id, $destination->uuid, $request->all());
if ($instantDeploy) {
- StartDatabase::dispatch($database);
+ StartDatabase::dispatch($database)->onQueue('high');
}
$database->refresh();
@@ -1500,7 +1500,7 @@ class DatabasesController extends Controller
}
$database = create_standalone_mongodb($environment->id, $destination->uuid, $request->all());
if ($instantDeploy) {
- StartDatabase::dispatch($database);
+ StartDatabase::dispatch($database)->onQueue('high');
}
$database->refresh();
@@ -1593,7 +1593,7 @@ class DatabasesController extends Controller
deleteVolumes: $request->query->get('delete_volumes', true),
dockerCleanup: $request->query->get('docker_cleanup', true),
deleteConnectedNetworks: $request->query->get('delete_connected_networks', true)
- );
+ )->onQueue('high');
return response()->json([
'message' => 'Database deletion request queued.',
@@ -1666,7 +1666,7 @@ class DatabasesController extends Controller
if (str($database->status)->contains('running')) {
return response()->json(['message' => 'Database is already running.'], 400);
}
- StartDatabase::dispatch($database);
+ StartDatabase::dispatch($database)->onQueue('high');
return response()->json(
[
@@ -1742,7 +1742,7 @@ class DatabasesController extends Controller
if (str($database->status)->contains('stopped') || str($database->status)->contains('exited')) {
return response()->json(['message' => 'Database is already stopped.'], 400);
}
- StopDatabase::dispatch($database);
+ StopDatabase::dispatch($database)->onQueue('high');
return response()->json(
[
@@ -1815,7 +1815,7 @@ class DatabasesController extends Controller
if (! $database) {
return response()->json(['message' => 'Database not found.'], 404);
}
- RestartDatabase::dispatch($database);
+ RestartDatabase::dispatch($database)->onQueue('high');
return response()->json(
[
diff --git a/app/Http/Controllers/Api/DeployController.php b/app/Http/Controllers/Api/DeployController.php
index 666dc55a5..59b199d87 100644
--- a/app/Http/Controllers/Api/DeployController.php
+++ b/app/Http/Controllers/Api/DeployController.php
@@ -307,7 +307,7 @@ class DeployController extends Controller
break;
default:
// Database resource
- StartDatabase::dispatch($resource);
+ StartDatabase::dispatch($resource)->onQueue('high');
$resource->update([
'started_at' => now(),
]);
diff --git a/app/Http/Controllers/Api/ServersController.php b/app/Http/Controllers/Api/ServersController.php
index af4e008ef..024ef35fa 100644
--- a/app/Http/Controllers/Api/ServersController.php
+++ b/app/Http/Controllers/Api/ServersController.php
@@ -538,7 +538,7 @@ class ServersController extends Controller
'is_build_server' => $request->is_build_server,
]);
if ($request->instant_validate) {
- ValidateServer::dispatch($server);
+ ValidateServer::dispatch($server)->onQueue('high');
}
return response()->json([
@@ -651,7 +651,7 @@ class ServersController extends Controller
]);
}
if ($request->instant_validate) {
- ValidateServer::dispatch($server);
+ ValidateServer::dispatch($server)->onQueue('high');
}
return response()->json(serializeApiResponse($server))->setStatusCode(201);
@@ -787,7 +787,7 @@ class ServersController extends Controller
if (! $server) {
return response()->json(['message' => 'Server not found.'], 404);
}
- ValidateServer::dispatch($server);
+ ValidateServer::dispatch($server)->onQueue('high');
return response()->json(['message' => 'Validation started.']);
}
diff --git a/app/Http/Controllers/Api/ServicesController.php b/app/Http/Controllers/Api/ServicesController.php
index bf90322e2..bdb5612ad 100644
--- a/app/Http/Controllers/Api/ServicesController.php
+++ b/app/Http/Controllers/Api/ServicesController.php
@@ -342,7 +342,7 @@ class ServicesController extends Controller
}
$service->parse(isNew: true);
if ($instantDeploy) {
- StartService::dispatch($service);
+ StartService::dispatch($service)->onQueue('high');
}
$domains = $service->applications()->get()->pluck('fqdn')->sort();
$domains = $domains->map(function ($domain) {
@@ -487,7 +487,7 @@ class ServicesController extends Controller
deleteVolumes: $request->query->get('delete_volumes', true),
dockerCleanup: $request->query->get('docker_cleanup', true),
deleteConnectedNetworks: $request->query->get('delete_connected_networks', true)
- );
+ )->onQueue('high');
return response()->json([
'message' => 'Service deletion request queued.',
@@ -1076,7 +1076,7 @@ class ServicesController extends Controller
if (str($service->status())->contains('running')) {
return response()->json(['message' => 'Service is already running.'], 400);
}
- StartService::dispatch($service);
+ StartService::dispatch($service)->onQueue('high');
return response()->json(
[
@@ -1154,7 +1154,7 @@ class ServicesController extends Controller
if (str($service->status())->contains('stopped') || str($service->status())->contains('exited')) {
return response()->json(['message' => 'Service is already stopped.'], 400);
}
- StopService::dispatch($service);
+ StopService::dispatch($service)->onQueue('high');
return response()->json(
[
@@ -1229,7 +1229,7 @@ class ServicesController extends Controller
if (! $service) {
return response()->json(['message' => 'Service not found.'], 404);
}
- RestartService::dispatch($service);
+ RestartService::dispatch($service)->onQueue('high');
return response()->json(
[
diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php
index a0fdd0e97..5ceed332a 100644
--- a/app/Jobs/ApplicationDeploymentJob.php
+++ b/app/Jobs/ApplicationDeploymentJob.php
@@ -1836,7 +1836,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue
}
if ($this->pull_request_id === 0) {
- $custom_compose = convert_docker_run_to_compose($this->application->custom_docker_run_options);
+ $custom_compose = convertDockerRunToCompose($this->application->custom_docker_run_options);
if ((bool) $this->application->settings->is_consistent_container_name_enabled) {
if (! $this->application->settings->custom_internal_name) {
$docker_compose['services'][$this->application->uuid] = $docker_compose['services'][$this->container_name];
diff --git a/app/Jobs/PushServerUpdateJob.php b/app/Jobs/PushServerUpdateJob.php
index 24f8d1e6b..9822ca071 100644
--- a/app/Jobs/PushServerUpdateJob.php
+++ b/app/Jobs/PushServerUpdateJob.php
@@ -360,7 +360,7 @@ class PushServerUpdateJob implements ShouldBeEncrypted, ShouldQueue
private function checkLogDrainContainer()
{
if ($this->server->isLogDrainEnabled() && $this->foundLogDrainContainer === false) {
- StartLogDrain::dispatch($this->server);
+ StartLogDrain::dispatch($this->server)->onQueue('high');
}
}
}
diff --git a/app/Jobs/ServerCheckJob.php b/app/Jobs/ServerCheckJob.php
index 449a2da14..c584f493d 100644
--- a/app/Jobs/ServerCheckJob.php
+++ b/app/Jobs/ServerCheckJob.php
@@ -13,6 +13,7 @@ use Illuminate\Contracts\Queue\ShouldBeEncrypted;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
+use Illuminate\Queue\Middleware\WithoutOverlapping;
use Illuminate\Queue\SerializesModels;
class ServerCheckJob implements ShouldBeEncrypted, ShouldQueue
@@ -25,6 +26,11 @@ class ServerCheckJob implements ShouldBeEncrypted, ShouldQueue
public $containers;
+ public function middleware(): array
+ {
+ return [(new WithoutOverlapping($this->server->id))->dontRelease()];
+ }
+
public function __construct(public Server $server) {}
public function handle()
@@ -88,10 +94,10 @@ class ServerCheckJob implements ShouldBeEncrypted, ShouldQueue
if ($foundLogDrainContainer) {
$status = data_get($foundLogDrainContainer, 'State.Status');
if ($status !== 'running') {
- StartLogDrain::dispatch($this->server);
+ StartLogDrain::dispatch($this->server)->onQueue('high');
}
} else {
- StartLogDrain::dispatch($this->server);
+ StartLogDrain::dispatch($this->server)->onQueue('high');
}
}
}
diff --git a/app/Jobs/ServerLimitCheckJob.php b/app/Jobs/ServerLimitCheckJob.php
index 084b6bf81..aa82c6dad 100644
--- a/app/Jobs/ServerLimitCheckJob.php
+++ b/app/Jobs/ServerLimitCheckJob.php
@@ -30,8 +30,7 @@ class ServerLimitCheckJob implements ShouldBeEncrypted, ShouldQueue
try {
$servers = $this->team->servers;
$servers_count = $servers->count();
- $limit = data_get($this->team->limits, 'serverLimit', 2);
- $number_of_servers_to_disable = $servers_count - $limit;
+ $number_of_servers_to_disable = $servers_count - $this->team->limits;
if ($number_of_servers_to_disable > 0) {
$servers = $servers->sortbyDesc('created_at');
$servers_to_disable = $servers->take($number_of_servers_to_disable);
diff --git a/app/Livewire/Destination/New/Docker.php b/app/Livewire/Destination/New/Docker.php
index 1ef8761fa..8cf58ec41 100644
--- a/app/Livewire/Destination/New/Docker.php
+++ b/app/Livewire/Destination/New/Docker.php
@@ -6,7 +6,7 @@ use App\Models\Server;
use App\Models\StandaloneDocker;
use App\Models\SwarmDocker;
use Livewire\Attributes\Locked;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
use Visus\Cuid2\Cuid2;
@@ -18,16 +18,16 @@ class Docker extends Component
#[Locked]
public Server $selectedServer;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $name;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $network;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $serverId;
- #[Rule(['required', 'boolean'])]
+ #[Validate(['required', 'boolean'])]
public bool $isSwarm = false;
public function mount(?string $server_id = null)
diff --git a/app/Livewire/Destination/Show.php b/app/Livewire/Destination/Show.php
index f75749382..5c4d6c170 100644
--- a/app/Livewire/Destination/Show.php
+++ b/app/Livewire/Destination/Show.php
@@ -6,7 +6,7 @@ use App\Models\Server;
use App\Models\StandaloneDocker;
use App\Models\SwarmDocker;
use Livewire\Attributes\Locked;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class Show extends Component
@@ -14,13 +14,13 @@ class Show extends Component
#[Locked]
public $destination;
- #[Rule(['string', 'required'])]
+ #[Validate(['string', 'required'])]
public string $name;
- #[Rule(['string', 'required'])]
+ #[Validate(['string', 'required'])]
public string $network;
- #[Rule(['string', 'required'])]
+ #[Validate(['string', 'required'])]
public string $serverIp;
public function mount(string $destination_uuid)
diff --git a/app/Livewire/Help.php b/app/Livewire/Help.php
index b174b1429..f51527fbe 100644
--- a/app/Livewire/Help.php
+++ b/app/Livewire/Help.php
@@ -5,17 +5,17 @@ namespace App\Livewire;
use DanHarrin\LivewireRateLimiting\WithRateLimiting;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Support\Facades\Http;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class Help extends Component
{
use WithRateLimiting;
- #[Rule(['required', 'min:10', 'max:1000'])]
+ #[Validate(['required', 'min:10', 'max:1000'])]
public string $description;
- #[Rule(['required', 'min:3'])]
+ #[Validate(['required', 'min:3'])]
public string $subject;
public function submit()
diff --git a/app/Livewire/Notifications/Discord.php b/app/Livewire/Notifications/Discord.php
index df5489a24..7a177a227 100644
--- a/app/Livewire/Notifications/Discord.php
+++ b/app/Livewire/Notifications/Discord.php
@@ -4,35 +4,35 @@ namespace App\Livewire\Notifications;
use App\Models\Team;
use App\Notifications\Test;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class Discord extends Component
{
public Team $team;
- #[Rule(['boolean'])]
+ #[Validate(['boolean'])]
public bool $discordEnabled = false;
- #[Rule(['url', 'nullable'])]
+ #[Validate(['url', 'nullable'])]
public ?string $discordWebhookUrl = null;
- #[Rule(['boolean'])]
+ #[Validate(['boolean'])]
public bool $discordNotificationsTest = false;
- #[Rule(['boolean'])]
+ #[Validate(['boolean'])]
public bool $discordNotificationsDeployments = false;
- #[Rule(['boolean'])]
+ #[Validate(['boolean'])]
public bool $discordNotificationsStatusChanges = false;
- #[Rule(['boolean'])]
+ #[Validate(['boolean'])]
public bool $discordNotificationsDatabaseBackups = false;
- #[Rule(['boolean'])]
+ #[Validate(['boolean'])]
public bool $discordNotificationsScheduledTasks = false;
- #[Rule(['boolean'])]
+ #[Validate(['boolean'])]
public bool $discordNotificationsServerDiskUsage = false;
public function mount()
@@ -41,7 +41,7 @@ class Discord extends Component
$this->team = auth()->user()->currentTeam();
$this->syncData();
} catch (\Throwable $e) {
- handleError($e, $this);
+ return handleError($e, $this);
}
}
@@ -57,11 +57,8 @@ class Discord extends Component
$this->team->discord_notifications_database_backups = $this->discordNotificationsDatabaseBackups;
$this->team->discord_notifications_scheduled_tasks = $this->discordNotificationsScheduledTasks;
$this->team->discord_notifications_server_disk_usage = $this->discordNotificationsServerDiskUsage;
- try {
- $this->saveModel();
- } catch (\Throwable $e) {
- return handleError($e, $this);
- }
+ $this->team->save();
+ refreshSession();
} else {
$this->discordEnabled = $this->team->discord_enabled;
$this->discordWebhookUrl = $this->team->discord_webhook_url;
@@ -74,6 +71,22 @@ class Discord extends Component
}
}
+ public function instantSaveDiscordEnabled()
+ {
+ try {
+ $this->validate([
+ 'discordWebhookUrl' => 'required',
+ ], [
+ 'discordWebhookUrl.required' => 'Discord Webhook URL is required.',
+ ]);
+ $this->saveModel();
+ } catch (\Throwable $e) {
+ $this->discordEnabled = false;
+
+ return handleError($e, $this);
+ }
+ }
+
public function instantSave()
{
try {
@@ -96,7 +109,7 @@ class Discord extends Component
public function saveModel()
{
- $this->team->save();
+ $this->syncData(true);
refreshSession();
$this->dispatch('success', 'Settings saved.');
}
diff --git a/app/Livewire/Notifications/Email.php b/app/Livewire/Notifications/Email.php
index 08415731d..b49638b48 100644
--- a/app/Livewire/Notifications/Email.php
+++ b/app/Livewire/Notifications/Email.php
@@ -5,75 +5,133 @@ namespace App\Livewire\Notifications;
use App\Models\Team;
use App\Notifications\Test;
use Illuminate\Support\Facades\RateLimiter;
+use Livewire\Attributes\Locked;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class Email extends Component
{
public Team $team;
+ #[Locked]
public string $emails;
- public bool $sharedEmailEnabled = false;
+ #[Validate(['boolean'])]
+ public bool $smtpEnabled = false;
- protected $rules = [
- 'team.smtp_enabled' => 'nullable|boolean',
- 'team.smtp_from_address' => 'required|email',
- 'team.smtp_from_name' => 'required',
- 'team.smtp_recipients' => 'nullable',
- 'team.smtp_host' => 'required',
- 'team.smtp_port' => 'required',
- 'team.smtp_encryption' => 'nullable',
- 'team.smtp_username' => 'nullable',
- 'team.smtp_password' => 'nullable',
- 'team.smtp_timeout' => 'nullable',
- 'team.smtp_notifications_test' => 'nullable|boolean',
- 'team.smtp_notifications_deployments' => 'nullable|boolean',
- 'team.smtp_notifications_status_changes' => 'nullable|boolean',
- 'team.smtp_notifications_database_backups' => 'nullable|boolean',
- 'team.smtp_notifications_scheduled_tasks' => 'nullable|boolean',
- 'team.smtp_notifications_server_disk_usage' => 'nullable|boolean',
- 'team.use_instance_email_settings' => 'boolean',
- 'team.resend_enabled' => 'nullable|boolean',
- 'team.resend_api_key' => 'nullable',
- ];
+ #[Validate(['boolean'])]
+ public bool $useInstanceEmailSettings = false;
- protected $validationAttributes = [
- 'team.smtp_from_address' => 'From Address',
- 'team.smtp_from_name' => 'From Name',
- 'team.smtp_recipients' => 'Recipients',
- 'team.smtp_host' => 'Host',
- 'team.smtp_port' => 'Port',
- 'team.smtp_encryption' => 'Encryption',
- 'team.smtp_username' => 'Username',
- 'team.smtp_password' => 'Password',
- 'team.smtp_timeout' => 'Timeout',
- 'team.resend_enabled' => 'Resend Enabled',
- 'team.resend_api_key' => 'Resend API Key',
- ];
+ #[Validate(['nullable', 'email'])]
+ public ?string $smtpFromAddress = null;
+
+ #[Validate(['nullable', 'string'])]
+ public ?string $smtpFromName = null;
+
+ #[Validate(['nullable', 'string'])]
+ public ?string $smtpRecipients = null;
+
+ #[Validate(['nullable', 'string'])]
+ public ?string $smtpHost = null;
+
+ #[Validate(['nullable', 'numeric'])]
+ public ?int $smtpPort = null;
+
+ #[Validate(['nullable', 'string'])]
+ public ?string $smtpEncryption = null;
+
+ #[Validate(['nullable', 'string'])]
+ public ?string $smtpUsername = null;
+
+ #[Validate(['nullable', 'string'])]
+ public ?string $smtpPassword = null;
+
+ #[Validate(['nullable', 'numeric'])]
+ public ?int $smtpTimeout = null;
+
+ #[Validate(['boolean'])]
+ public bool $smtpNotificationsTest;
+
+ #[Validate(['boolean'])]
+ public bool $smtpNotificationsDeployments;
+
+ #[Validate(['boolean'])]
+ public bool $smtpNotificationsStatusChanges;
+
+ #[Validate(['boolean'])]
+ public bool $smtpNotificationsDatabaseBackups;
+
+ #[Validate(['boolean'])]
+ public bool $smtpNotificationsScheduledTasks;
+
+ #[Validate(['boolean'])]
+ public bool $smtpNotificationsServerDiskUsage;
+
+ #[Validate(['boolean'])]
+ public bool $resendEnabled;
+
+ #[Validate(['nullable', 'string'])]
+ public ?string $resendApiKey = null;
public function mount()
- {
- $this->team = auth()->user()->currentTeam();
- ['sharedEmailEnabled' => $this->sharedEmailEnabled] = $this->team->limits;
- $this->emails = auth()->user()->email;
- }
-
- public function submitFromFields()
{
try {
- $this->resetErrorBag();
- $this->validate([
- 'team.smtp_from_address' => 'required|email',
- 'team.smtp_from_name' => 'required',
- ]);
- $this->team->save();
- refreshSession();
- $this->dispatch('success', 'Settings saved.');
+ $this->team = auth()->user()->currentTeam();
+ $this->emails = auth()->user()->email;
+ $this->syncData();
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
+ public function syncData(bool $toModel = false)
+ {
+ if ($toModel) {
+ $this->validate();
+ $this->team->smtp_enabled = $this->smtpEnabled;
+ $this->team->smtp_from_address = $this->smtpFromAddress;
+ $this->team->smtp_from_name = $this->smtpFromName;
+ $this->team->smtp_host = $this->smtpHost;
+ $this->team->smtp_port = $this->smtpPort;
+ $this->team->smtp_encryption = $this->smtpEncryption;
+ $this->team->smtp_username = $this->smtpUsername;
+ $this->team->smtp_password = $this->smtpPassword;
+ $this->team->smtp_timeout = $this->smtpTimeout;
+ $this->team->smtp_recipients = $this->smtpRecipients;
+ $this->team->smtp_notifications_test = $this->smtpNotificationsTest;
+ $this->team->smtp_notifications_deployments = $this->smtpNotificationsDeployments;
+ $this->team->smtp_notifications_status_changes = $this->smtpNotificationsStatusChanges;
+ $this->team->smtp_notifications_database_backups = $this->smtpNotificationsDatabaseBackups;
+ $this->team->smtp_notifications_scheduled_tasks = $this->smtpNotificationsScheduledTasks;
+ $this->team->smtp_notifications_server_disk_usage = $this->smtpNotificationsServerDiskUsage;
+ $this->team->use_instance_email_settings = $this->useInstanceEmailSettings;
+ $this->team->resend_enabled = $this->resendEnabled;
+ $this->team->resend_api_key = $this->resendApiKey;
+ $this->team->save();
+ refreshSession();
+ } else {
+ $this->smtpEnabled = $this->team->smtp_enabled;
+ $this->smtpFromAddress = $this->team->smtp_from_address;
+ $this->smtpFromName = $this->team->smtp_from_name;
+ $this->smtpHost = $this->team->smtp_host;
+ $this->smtpPort = $this->team->smtp_port;
+ $this->smtpEncryption = $this->team->smtp_encryption;
+ $this->smtpUsername = $this->team->smtp_username;
+ $this->smtpPassword = $this->team->smtp_password;
+ $this->smtpTimeout = $this->team->smtp_timeout;
+ $this->smtpRecipients = $this->team->smtp_recipients;
+ $this->smtpNotificationsTest = $this->team->smtp_notifications_test;
+ $this->smtpNotificationsDeployments = $this->team->smtp_notifications_deployments;
+ $this->smtpNotificationsStatusChanges = $this->team->smtp_notifications_status_changes;
+ $this->smtpNotificationsDatabaseBackups = $this->team->smtp_notifications_database_backups;
+ $this->smtpNotificationsScheduledTasks = $this->team->smtp_notifications_scheduled_tasks;
+ $this->smtpNotificationsServerDiskUsage = $this->team->smtp_notifications_server_disk_usage;
+ $this->useInstanceEmailSettings = $this->team->use_instance_email_settings;
+ $this->resendEnabled = $this->team->resend_enabled;
+ $this->resendApiKey = $this->team->resend_api_key;
+ }
+ }
+
public function sendTestNotification()
{
try {
@@ -98,38 +156,44 @@ class Email extends Component
public function instantSaveInstance()
{
try {
- if (! $this->sharedEmailEnabled) {
- throw new \Exception('Not allowed to change settings. Please upgrade your subscription.');
- }
- $this->team->smtp_enabled = false;
- $this->team->resend_enabled = false;
- $this->team->save();
- refreshSession();
- $this->dispatch('success', 'Settings saved.');
+ $this->smtpEnabled = false;
+ $this->resendEnabled = false;
+ $this->saveModel();
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
+ public function instantSaveSmtpEnabled()
+ {
+ try {
+ $this->validate([
+ 'smtpHost' => 'required',
+ 'smtpPort' => 'required|numeric',
+ ], [
+ 'smtpHost.required' => 'SMTP Host is required.',
+ 'smtpPort.required' => 'SMTP Port is required.',
+ ]);
+ $this->resendEnabled = false;
+ $this->saveModel();
+ } catch (\Throwable $e) {
+ $this->smtpEnabled = false;
+
+ return handleError($e, $this);
+ }
+ }
+
public function instantSaveResend()
{
try {
- $this->team->smtp_enabled = false;
- $this->submitResend();
+ $this->validate([
+ ], [
+ 'resendApiKey.required' => 'Resend API Key is required.',
+ ]);
+ $this->smtpEnabled = false;
+ $this->saveModel();
} catch (\Throwable $e) {
- $this->team->smtp_enabled = false;
-
- return handleError($e, $this);
- }
- }
-
- public function instantSave()
- {
- try {
- $this->team->resend_enabled = false;
- $this->submit();
- } catch (\Throwable $e) {
- $this->team->smtp_enabled = false;
+ $this->resendEnabled = false;
return handleError($e, $this);
}
@@ -137,7 +201,7 @@ class Email extends Component
public function saveModel()
{
- $this->team->save();
+ $this->syncData(true);
refreshSession();
$this->dispatch('success', 'Settings saved.');
}
@@ -146,43 +210,8 @@ class Email extends Component
{
try {
$this->resetErrorBag();
- if (! $this->team->use_instance_email_settings) {
- $this->validate([
- 'team.smtp_from_address' => 'required|email',
- 'team.smtp_from_name' => 'required',
- 'team.smtp_host' => 'required',
- 'team.smtp_port' => 'required|numeric',
- 'team.smtp_encryption' => 'nullable',
- 'team.smtp_username' => 'nullable',
- 'team.smtp_password' => 'nullable',
- 'team.smtp_timeout' => 'nullable',
- ]);
- }
- $this->team->save();
- refreshSession();
- $this->dispatch('success', 'Settings saved.');
+ $this->saveModel();
} catch (\Throwable $e) {
- $this->team->smtp_enabled = false;
-
- return handleError($e, $this);
- }
- }
-
- public function submitResend()
- {
- try {
- $this->resetErrorBag();
- $this->validate([
- 'team.smtp_from_address' => 'required|email',
- 'team.smtp_from_name' => 'required',
- 'team.resend_api_key' => 'required',
- ]);
- $this->team->save();
- refreshSession();
- $this->dispatch('success', 'Settings saved.');
- } catch (\Throwable $e) {
- $this->team->resend_enabled = false;
-
return handleError($e, $this);
}
}
@@ -190,35 +219,28 @@ class Email extends Component
public function copyFromInstanceSettings()
{
$settings = instanceSettings();
+
if ($settings->smtp_enabled) {
- $team = currentTeam();
- $team->update([
- 'smtp_enabled' => $settings->smtp_enabled,
- 'smtp_from_address' => $settings->smtp_from_address,
- 'smtp_from_name' => $settings->smtp_from_name,
- 'smtp_recipients' => $settings->smtp_recipients,
- 'smtp_host' => $settings->smtp_host,
- 'smtp_port' => $settings->smtp_port,
- 'smtp_encryption' => $settings->smtp_encryption,
- 'smtp_username' => $settings->smtp_username,
- 'smtp_password' => $settings->smtp_password,
- 'smtp_timeout' => $settings->smtp_timeout,
- ]);
- refreshSession();
- $this->team = $team;
- $this->dispatch('success', 'Settings saved.');
+ $this->smtpEnabled = true;
+ $this->smtpFromAddress = $settings->smtp_from_address;
+ $this->smtpFromName = $settings->smtp_from_name;
+ $this->smtpRecipients = $settings->smtp_recipients;
+ $this->smtpHost = $settings->smtp_host;
+ $this->smtpPort = $settings->smtp_port;
+ $this->smtpEncryption = $settings->smtp_encryption;
+ $this->smtpUsername = $settings->smtp_username;
+ $this->smtpPassword = $settings->smtp_password;
+ $this->smtpTimeout = $settings->smtp_timeout;
+ $this->resendEnabled = false;
+ $this->saveModel();
return;
}
if ($settings->resend_enabled) {
- $team = currentTeam();
- $team->update([
- 'resend_enabled' => $settings->resend_enabled,
- 'resend_api_key' => $settings->resend_api_key,
- ]);
- refreshSession();
- $this->team = $team;
- $this->dispatch('success', 'Settings saved.');
+ $this->resendEnabled = true;
+ $this->resendApiKey = $settings->resend_api_key;
+ $this->smtpEnabled = false;
+ $this->saveModel();
return;
}
diff --git a/app/Livewire/Notifications/Telegram.php b/app/Livewire/Notifications/Telegram.php
index 862b9b3ea..15ec20577 100644
--- a/app/Livewire/Notifications/Telegram.php
+++ b/app/Livewire/Notifications/Telegram.php
@@ -4,67 +4,157 @@ namespace App\Livewire\Notifications;
use App\Models\Team;
use App\Notifications\Test;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class Telegram extends Component
{
public Team $team;
- protected $rules = [
- 'team.telegram_enabled' => 'nullable|boolean',
- 'team.telegram_token' => 'required|string',
- 'team.telegram_chat_id' => 'required|string',
- 'team.telegram_notifications_test' => 'nullable|boolean',
- 'team.telegram_notifications_deployments' => 'nullable|boolean',
- 'team.telegram_notifications_status_changes' => 'nullable|boolean',
- 'team.telegram_notifications_database_backups' => 'nullable|boolean',
- 'team.telegram_notifications_scheduled_tasks' => 'nullable|boolean',
- 'team.telegram_notifications_test_message_thread_id' => 'nullable|string',
- 'team.telegram_notifications_deployments_message_thread_id' => 'nullable|string',
- 'team.telegram_notifications_status_changes_message_thread_id' => 'nullable|string',
- 'team.telegram_notifications_database_backups_message_thread_id' => 'nullable|string',
- 'team.telegram_notifications_scheduled_tasks_thread_id' => 'nullable|string',
- 'team.telegram_notifications_server_disk_usage' => 'nullable|boolean',
- ];
+ #[Validate(['boolean'])]
+ public bool $telegramEnabled = false;
- protected $validationAttributes = [
- 'team.telegram_token' => 'Token',
- 'team.telegram_chat_id' => 'Chat ID',
- ];
+ #[Validate(['nullable', 'string'])]
+ public ?string $telegramToken = null;
+
+ #[Validate(['nullable', 'string'])]
+ public ?string $telegramChatId = null;
+
+ #[Validate(['boolean'])]
+ public bool $telegramNotificationsTest = false;
+
+ #[Validate(['boolean'])]
+ public bool $telegramNotificationsDeployments = false;
+
+ #[Validate(['boolean'])]
+ public bool $telegramNotificationsStatusChanges = false;
+
+ #[Validate(['boolean'])]
+ public bool $telegramNotificationsDatabaseBackups = false;
+
+ #[Validate(['boolean'])]
+ public bool $telegramNotificationsScheduledTasks = false;
+
+ #[Validate(['nullable', 'string'])]
+ public ?string $telegramNotificationsTestMessageThreadId = null;
+
+ #[Validate(['nullable', 'string'])]
+ public ?string $telegramNotificationsDeploymentsMessageThreadId = null;
+
+ #[Validate(['nullable', 'string'])]
+ public ?string $telegramNotificationsStatusChangesMessageThreadId = null;
+
+ #[Validate(['nullable', 'string'])]
+ public ?string $telegramNotificationsDatabaseBackupsMessageThreadId = null;
+
+ #[Validate(['nullable', 'string'])]
+ public ?string $telegramNotificationsScheduledTasksThreadId = null;
+
+ #[Validate(['boolean'])]
+ public bool $telegramNotificationsServerDiskUsage = false;
public function mount()
{
- $this->team = auth()->user()->currentTeam();
+ try {
+ $this->team = auth()->user()->currentTeam();
+ $this->syncData();
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ }
+ }
+
+ public function syncData(bool $toModel = false)
+ {
+ if ($toModel) {
+ $this->validate();
+ $this->team->telegram_enabled = $this->telegramEnabled;
+ $this->team->telegram_token = $this->telegramToken;
+ $this->team->telegram_chat_id = $this->telegramChatId;
+ $this->team->telegram_notifications_test = $this->telegramNotificationsTest;
+ $this->team->telegram_notifications_deployments = $this->telegramNotificationsDeployments;
+ $this->team->telegram_notifications_status_changes = $this->telegramNotificationsStatusChanges;
+ $this->team->telegram_notifications_database_backups = $this->telegramNotificationsDatabaseBackups;
+ $this->team->telegram_notifications_scheduled_tasks = $this->telegramNotificationsScheduledTasks;
+ $this->team->telegram_notifications_test_message_thread_id = $this->telegramNotificationsTestMessageThreadId;
+ $this->team->telegram_notifications_deployments_message_thread_id = $this->telegramNotificationsDeploymentsMessageThreadId;
+ $this->team->telegram_notifications_status_changes_message_thread_id = $this->telegramNotificationsStatusChangesMessageThreadId;
+ $this->team->telegram_notifications_database_backups_message_thread_id = $this->telegramNotificationsDatabaseBackupsMessageThreadId;
+ $this->team->telegram_notifications_scheduled_tasks_thread_id = $this->telegramNotificationsScheduledTasksThreadId;
+ $this->team->telegram_notifications_server_disk_usage = $this->telegramNotificationsServerDiskUsage;
+ $this->team->save();
+ refreshSession();
+ } else {
+ $this->telegramEnabled = $this->team->telegram_enabled;
+ $this->telegramToken = $this->team->telegram_token;
+ $this->telegramChatId = $this->team->telegram_chat_id;
+ $this->telegramNotificationsTest = $this->team->telegram_notifications_test;
+ $this->telegramNotificationsDeployments = $this->team->telegram_notifications_deployments;
+ $this->telegramNotificationsStatusChanges = $this->team->telegram_notifications_status_changes;
+ $this->telegramNotificationsDatabaseBackups = $this->team->telegram_notifications_database_backups;
+ $this->telegramNotificationsScheduledTasks = $this->team->telegram_notifications_scheduled_tasks;
+ $this->telegramNotificationsTestMessageThreadId = $this->team->telegram_notifications_test_message_thread_id;
+ $this->telegramNotificationsDeploymentsMessageThreadId = $this->team->telegram_notifications_deployments_message_thread_id;
+ $this->telegramNotificationsStatusChangesMessageThreadId = $this->team->telegram_notifications_status_changes_message_thread_id;
+ $this->telegramNotificationsDatabaseBackupsMessageThreadId = $this->team->telegram_notifications_database_backups_message_thread_id;
+ $this->telegramNotificationsScheduledTasksThreadId = $this->team->telegram_notifications_scheduled_tasks_thread_id;
+ $this->telegramNotificationsServerDiskUsage = $this->team->telegram_notifications_server_disk_usage;
+ }
+
}
public function instantSave()
{
try {
- $this->submit();
- } catch (\Throwable) {
- $this->team->telegram_enabled = false;
- $this->validate();
+ $this->syncData(true);
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
}
}
public function submit()
{
- $this->resetErrorBag();
- $this->validate();
- $this->saveModel();
+ try {
+ $this->resetErrorBag();
+ $this->syncData(true);
+ $this->saveModel();
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ }
+ }
+
+ public function instantSaveTelegramEnabled()
+ {
+ try {
+ $this->validate([
+ 'telegramToken' => 'required',
+ 'telegramChatId' => 'required',
+ ], [
+ 'telegramToken.required' => 'Telegram Token is required.',
+ 'telegramChatId.required' => 'Telegram Chat ID is required.',
+ ]);
+ $this->saveModel();
+ } catch (\Throwable $e) {
+ $this->telegramEnabled = false;
+
+ return handleError($e, $this);
+ }
}
public function saveModel()
{
- $this->team->save();
+ $this->syncData(true);
refreshSession();
$this->dispatch('success', 'Settings saved.');
}
public function sendTestNotification()
{
- $this->team?->notify(new Test);
- $this->dispatch('success', 'Test notification sent.');
+ try {
+ $this->team->notify(new Test);
+ $this->dispatch('success', 'Test notification sent.');
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ }
}
public function render()
diff --git a/app/Livewire/Project/AddEmpty.php b/app/Livewire/Project/AddEmpty.php
index c8c063960..fd976548a 100644
--- a/app/Livewire/Project/AddEmpty.php
+++ b/app/Livewire/Project/AddEmpty.php
@@ -3,15 +3,15 @@
namespace App\Livewire\Project;
use App\Models\Project;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class AddEmpty extends Component
{
- #[Rule(['required', 'string', 'min:3'])]
+ #[Validate(['required', 'string', 'min:3'])]
public string $name;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public string $description = '';
public function submit()
diff --git a/app/Livewire/Project/Application/Advanced.php b/app/Livewire/Project/Application/Advanced.php
index a3a688f7c..05ac25429 100644
--- a/app/Livewire/Project/Application/Advanced.php
+++ b/app/Livewire/Project/Application/Advanced.php
@@ -3,120 +3,200 @@
namespace App\Livewire\Project\Application;
use App\Models\Application;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class Advanced extends Component
{
public Application $application;
- public bool $is_force_https_enabled;
+ #[Validate(['boolean'])]
+ public bool $isForceHttpsEnabled = false;
- public bool $is_gzip_enabled;
+ #[Validate(['boolean'])]
+ public bool $isGitSubmodulesEnabled = false;
- public bool $is_stripprefix_enabled;
+ #[Validate(['boolean'])]
+ public bool $isGitLfsEnabled = false;
- 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',
- 'is_force_https_enabled' => 'boolean|required',
- 'application.settings.is_log_drain_enabled' => 'boolean|required',
- 'application.settings.is_gpu_enabled' => 'boolean|required',
- 'application.settings.is_build_server_enabled' => 'boolean|required',
- 'application.settings.is_consistent_container_name_enabled' => 'boolean|required',
- 'application.settings.custom_internal_name' => 'string|nullable',
- 'application.settings.is_gzip_enabled' => 'boolean|required',
- 'application.settings.is_stripprefix_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',
- 'application.settings.is_raw_compose_deployment_enabled' => 'boolean|required',
- 'application.settings.connect_to_docker_network' => 'boolean|required',
- ];
+ #[Validate(['boolean'])]
+ public bool $isPreviewDeploymentsEnabled = false;
+
+ #[Validate(['boolean'])]
+ public bool $isAutoDeployEnabled = true;
+
+ #[Validate(['boolean'])]
+ public bool $isLogDrainEnabled = false;
+
+ #[Validate(['boolean'])]
+ public bool $isGpuEnabled = false;
+
+ #[Validate(['string'])]
+ public string $gpuDriver = '';
+
+ #[Validate(['string', 'nullable'])]
+ public ?string $gpuCount = null;
+
+ #[Validate(['string', 'nullable'])]
+ public ?string $gpuDeviceIds = null;
+
+ #[Validate(['string', 'nullable'])]
+ public ?string $gpuOptions = null;
+
+ #[Validate(['boolean'])]
+ public bool $isBuildServerEnabled = false;
+
+ #[Validate(['boolean'])]
+ public bool $isConsistentContainerNameEnabled = false;
+
+ #[Validate(['string', 'nullable'])]
+ public ?string $customInternalName = null;
+
+ #[Validate(['boolean'])]
+ public bool $isGzipEnabled = true;
+
+ #[Validate(['boolean'])]
+ public bool $isStripprefixEnabled = true;
+
+ #[Validate(['boolean'])]
+ public bool $isRawComposeDeploymentEnabled = false;
+
+ #[Validate(['boolean'])]
+ public bool $isConnectToDockerNetworkEnabled = false;
public function mount()
{
- $this->is_force_https_enabled = $this->application->isForceHttpsEnabled();
- $this->is_gzip_enabled = $this->application->isGzipEnabled();
- $this->is_stripprefix_enabled = $this->application->isStripprefixEnabled();
+ try {
+ $this->syncData();
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ }
+ }
+
+ public function syncData(bool $toModel = false)
+ {
+ if ($toModel) {
+ $this->validate();
+ $this->application->settings->is_force_https_enabled = $this->isForceHttpsEnabled;
+ $this->application->settings->is_git_submodules_enabled = $this->isGitSubmodulesEnabled;
+ $this->application->settings->is_git_lfs_enabled = $this->isGitLfsEnabled;
+ $this->application->settings->is_preview_deployments_enabled = $this->isPreviewDeploymentsEnabled;
+ $this->application->settings->is_auto_deploy_enabled = $this->isAutoDeployEnabled;
+ $this->application->settings->is_log_drain_enabled = $this->isLogDrainEnabled;
+ $this->application->settings->is_gpu_enabled = $this->isGpuEnabled;
+ $this->application->settings->gpu_driver = $this->gpuDriver;
+ $this->application->settings->gpu_count = $this->gpuCount;
+ $this->application->settings->gpu_device_ids = $this->gpuDeviceIds;
+ $this->application->settings->gpu_options = $this->gpuOptions;
+ $this->application->settings->is_build_server_enabled = $this->isBuildServerEnabled;
+ $this->application->settings->is_consistent_container_name_enabled = $this->isConsistentContainerNameEnabled;
+ $this->application->settings->custom_internal_name = $this->customInternalName;
+ $this->application->settings->is_gzip_enabled = $this->isGzipEnabled;
+ $this->application->settings->is_stripprefix_enabled = $this->isStripprefixEnabled;
+ $this->application->settings->is_raw_compose_deployment_enabled = $this->isRawComposeDeploymentEnabled;
+ $this->application->settings->connect_to_docker_network = $this->isConnectToDockerNetworkEnabled;
+ $this->application->settings->save();
+ } else {
+ $this->isForceHttpsEnabled = $this->application->isForceHttpsEnabled();
+ $this->isGzipEnabled = $this->application->isGzipEnabled();
+ $this->isStripprefixEnabled = $this->application->isStripprefixEnabled();
+ $this->isLogDrainEnabled = $this->application->isLogDrainEnabled();
+
+ $this->isGitSubmodulesEnabled = $this->application->settings->is_git_submodules_enabled;
+ $this->isGitLfsEnabled = $this->application->settings->is_git_lfs_enabled;
+ $this->isPreviewDeploymentsEnabled = $this->application->settings->is_preview_deployments_enabled;
+ $this->isAutoDeployEnabled = $this->application->settings->is_auto_deploy_enabled;
+ $this->isGpuEnabled = $this->application->settings->is_gpu_enabled;
+ $this->gpuDriver = $this->application->settings->gpu_driver;
+ $this->gpuCount = $this->application->settings->gpu_count;
+ $this->gpuDeviceIds = $this->application->settings->gpu_device_ids;
+ $this->gpuOptions = $this->application->settings->gpu_options;
+ $this->isBuildServerEnabled = $this->application->settings->is_build_server_enabled;
+ $this->isConsistentContainerNameEnabled = $this->application->settings->is_consistent_container_name_enabled;
+ $this->customInternalName = $this->application->settings->custom_internal_name;
+ $this->isRawComposeDeploymentEnabled = $this->application->settings->is_raw_compose_deployment_enabled;
+ $this->isConnectToDockerNetworkEnabled = $this->application->settings->connect_to_docker_network;
+ }
}
public function instantSave()
{
- if ($this->application->isLogDrainEnabled()) {
- if (! $this->application->destination->server->isLogDrainEnabled()) {
- $this->application->settings->is_log_drain_enabled = false;
- $this->dispatch('error', 'Log drain is not enabled on this server.');
+ try {
+ if ($this->isLogDrainEnabled) {
+ if (! $this->application->destination->server->isLogDrainEnabled()) {
+ $this->isLogDrainEnabled = false;
+ $this->syncData(true);
+ $this->dispatch('error', 'Log drain is not enabled on this server.');
- return;
+ return;
+ }
}
+ if ($this->application->isForceHttpsEnabled() !== $this->isForceHttpsEnabled ||
+ $this->application->isGzipEnabled() !== $this->isGzipEnabled ||
+ $this->application->isStripprefixEnabled() !== $this->isStripprefixEnabled
+ ) {
+ $this->dispatch('resetDefaultLabels', false);
+ }
+
+ if ($this->application->settings->is_raw_compose_deployment_enabled) {
+ $this->application->oldRawParser();
+ } else {
+ $this->application->parse();
+ }
+ $this->syncData(true);
+ $this->dispatch('success', 'Settings saved.');
+ $this->dispatch('configurationChanged');
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
}
- if ($this->application->settings->is_force_https_enabled !== $this->is_force_https_enabled) {
- $this->application->settings->is_force_https_enabled = $this->is_force_https_enabled;
- $this->dispatch('resetDefaultLabels', false);
- }
- if ($this->application->settings->is_gzip_enabled !== $this->is_gzip_enabled) {
- $this->application->settings->is_gzip_enabled = $this->is_gzip_enabled;
- $this->dispatch('resetDefaultLabels', false);
- }
- if ($this->application->settings->is_stripprefix_enabled !== $this->is_stripprefix_enabled) {
- $this->application->settings->is_stripprefix_enabled = $this->is_stripprefix_enabled;
- $this->dispatch('resetDefaultLabels', false);
- }
- if ($this->application->settings->is_raw_compose_deployment_enabled) {
- $this->application->oldRawParser();
- } else {
- $this->application->parse();
- }
- $this->application->settings->save();
- $this->dispatch('success', 'Settings saved.');
- $this->dispatch('configurationChanged');
}
public function submit()
{
- if ($this->application->settings->gpu_count && $this->application->settings->gpu_device_ids) {
- $this->dispatch('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();
+ try {
+ if ($this->gpuCount && $this->gpuDeviceIds) {
+ $this->dispatch('error', 'You cannot set both GPU count and GPU device IDs.');
+ $this->gpuCount = null;
+ $this->gpuDeviceIds = null;
+ $this->syncData(true);
- return;
+ return;
+ }
+ $this->syncData(true);
+ $this->dispatch('success', 'Settings saved.');
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
}
- $this->application->settings->save();
- $this->dispatch('success', 'Settings saved.');
}
public function saveCustomName()
{
- if (str($this->application->settings->custom_internal_name)->isNotEmpty()) {
- $this->application->settings->custom_internal_name = str($this->application->settings->custom_internal_name)->slug()->value();
+ if (str($this->customInternalName)->isNotEmpty()) {
+ $this->customInternalName = str($this->customInternalName)->slug()->value();
} else {
- $this->application->settings->custom_internal_name = null;
+ $this->customInternalName = null;
}
- if (is_null($this->application->settings->custom_internal_name)) {
- $this->application->settings->save();
+ if (is_null($this->customInternalName)) {
+ $this->syncData(true);
$this->dispatch('success', 'Custom name saved.');
return;
}
- $customInternalName = $this->application->settings->custom_internal_name;
+ $customInternalName = $this->customInternalName;
$server = $this->application->destination->server;
$allApplications = $server->applications();
$foundSameInternalName = $allApplications->filter(function ($application) {
- return $application->id !== $this->application->id && $application->settings->custom_internal_name === $this->application->settings->custom_internal_name;
+ return $application->id !== $this->application->id && $application->settings->custom_internal_name === $this->customInternalName;
});
if ($foundSameInternalName->isNotEmpty()) {
$this->dispatch('error', 'This custom container name is already in use by another application on this server.');
- $this->application->settings->custom_internal_name = $customInternalName;
- $this->application->settings->refresh();
+ $this->customInternalName = $customInternalName;
+ $this->syncData(true);
return;
}
- $this->application->settings->save();
+ $this->syncData(true);
$this->dispatch('success', 'Custom name saved.');
}
diff --git a/app/Livewire/Project/Application/Preview/Form.php b/app/Livewire/Project/Application/Preview/Form.php
index 79b3276a1..c7b2e8184 100644
--- a/app/Livewire/Project/Application/Preview/Form.php
+++ b/app/Livewire/Project/Application/Preview/Form.php
@@ -3,7 +3,6 @@
namespace App\Livewire\Project\Application\Preview;
use App\Models\Application;
-use Livewire\Attributes\Rule;
use Livewire\Component;
use Spatie\Url\Url;
@@ -11,7 +10,7 @@ class Form extends Component
{
public Application $application;
- #[Rule('required')]
+ #[Validate('required')]
public string $previewUrlTemplate;
public function mount()
diff --git a/app/Livewire/Project/Application/Source.php b/app/Livewire/Project/Application/Source.php
index 2d75d91f2..ade297d50 100644
--- a/app/Livewire/Project/Application/Source.php
+++ b/app/Livewire/Project/Application/Source.php
@@ -5,7 +5,7 @@ namespace App\Livewire\Project\Application;
use App\Models\Application;
use App\Models\PrivateKey;
use Livewire\Attributes\Locked;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class Source extends Component
@@ -15,19 +15,19 @@ class Source extends Component
#[Locked]
public $privateKeys;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $privateKeyName = null;
- #[Rule(['nullable', 'integer'])]
+ #[Validate(['nullable', 'integer'])]
public ?int $privateKeyId = null;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $gitRepository;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $gitBranch;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $gitCommitSha = null;
public function mount()
diff --git a/app/Livewire/Project/Application/Swarm.php b/app/Livewire/Project/Application/Swarm.php
index c2cdcd667..197dc41ed 100644
--- a/app/Livewire/Project/Application/Swarm.php
+++ b/app/Livewire/Project/Application/Swarm.php
@@ -3,20 +3,20 @@
namespace App\Livewire\Project\Application;
use App\Models\Application;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class Swarm extends Component
{
public Application $application;
- #[Rule('required')]
+ #[Validate('required')]
public int $swarmReplicas;
- #[Rule(['nullable'])]
+ #[Validate(['nullable'])]
public ?string $swarmPlacementConstraints = null;
- #[Rule('required')]
+ #[Validate('required')]
public bool $isSwarmOnlyWorkerNodes;
public function mount()
diff --git a/app/Livewire/Project/Database/BackupEdit.php b/app/Livewire/Project/Database/BackupEdit.php
index 1e70eaba9..bcf2f959e 100644
--- a/app/Livewire/Project/Database/BackupEdit.php
+++ b/app/Livewire/Project/Database/BackupEdit.php
@@ -8,7 +8,7 @@ use Exception;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Livewire\Attributes\Locked;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
use Spatie\Url\Url;
@@ -22,37 +22,37 @@ class BackupEdit extends Component
#[Locked]
public $parameters;
- #[Rule(['required', 'boolean'])]
+ #[Validate(['required', 'boolean'])]
public bool $delete_associated_backups_locally = false;
- #[Rule(['required', 'boolean'])]
+ #[Validate(['required', 'boolean'])]
public bool $delete_associated_backups_s3 = false;
- #[Rule(['required', 'boolean'])]
+ #[Validate(['required', 'boolean'])]
public bool $delete_associated_backups_sftp = false;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $status = null;
- #[Rule(['required', 'boolean'])]
+ #[Validate(['required', 'boolean'])]
public bool $backupEnabled = false;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $frequency = '';
- #[Rule(['required', 'integer', 'min:1'])]
+ #[Validate(['required', 'integer', 'min:1'])]
public int $numberOfBackupsLocally = 1;
- #[Rule(['required', 'boolean'])]
+ #[Validate(['required', 'boolean'])]
public bool $saveS3 = false;
- #[Rule(['required', 'integer'])]
+ #[Validate(['required', 'integer'])]
public int $s3StorageId = 1;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $databasesToBackup = null;
- #[Rule(['required', 'boolean'])]
+ #[Validate(['required', 'boolean'])]
public bool $dumpAll = false;
public function mount()
diff --git a/app/Livewire/Project/Database/Clickhouse/General.php b/app/Livewire/Project/Database/Clickhouse/General.php
index 46688adca..2d39c5151 100644
--- a/app/Livewire/Project/Database/Clickhouse/General.php
+++ b/app/Livewire/Project/Database/Clickhouse/General.php
@@ -8,7 +8,7 @@ use App\Models\Server;
use App\Models\StandaloneClickhouse;
use Exception;
use Illuminate\Support\Facades\Auth;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class General extends Component
@@ -17,40 +17,40 @@ class General extends Component
public StandaloneClickhouse $database;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $name;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $description = null;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $clickhouseAdminUser;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $clickhouseAdminPassword;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $image;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $portsMappings = null;
- #[Rule(['nullable', 'boolean'])]
+ #[Validate(['nullable', 'boolean'])]
public ?bool $isPublic = null;
- #[Rule(['nullable', 'integer'])]
+ #[Validate(['nullable', 'integer'])]
public ?int $publicPort = null;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $customDockerRunOptions = null;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $dbUrl = null;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $dbUrlPublic = null;
- #[Rule(['nullable', 'boolean'])]
+ #[Validate(['nullable', 'boolean'])]
public bool $isLogDrainEnabled = false;
public function getListeners()
diff --git a/app/Livewire/Project/Database/CreateScheduledBackup.php b/app/Livewire/Project/Database/CreateScheduledBackup.php
index d26348f5f..0903efdfd 100644
--- a/app/Livewire/Project/Database/CreateScheduledBackup.php
+++ b/app/Livewire/Project/Database/CreateScheduledBackup.php
@@ -5,15 +5,15 @@ namespace App\Livewire\Project\Database;
use App\Models\ScheduledDatabaseBackup;
use Illuminate\Support\Collection;
use Livewire\Attributes\Locked;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class CreateScheduledBackup extends Component
{
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public $frequency;
- #[Rule(['required', 'boolean'])]
+ #[Validate(['required', 'boolean'])]
public bool $saveToS3 = false;
#[Locked]
@@ -21,7 +21,7 @@ class CreateScheduledBackup extends Component
public bool $enabled = true;
- #[Rule(['required', 'integer'])]
+ #[Validate(['required', 'integer'])]
public int $s3StorageId;
public Collection $definedS3s;
diff --git a/app/Livewire/Project/Database/Dragonfly/General.php b/app/Livewire/Project/Database/Dragonfly/General.php
index 5037f6283..ea6cd46b0 100644
--- a/app/Livewire/Project/Database/Dragonfly/General.php
+++ b/app/Livewire/Project/Database/Dragonfly/General.php
@@ -8,7 +8,7 @@ use App\Models\Server;
use App\Models\StandaloneDragonfly;
use Exception;
use Illuminate\Support\Facades\Auth;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class General extends Component
@@ -17,37 +17,37 @@ class General extends Component
public StandaloneDragonfly $database;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $name;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $description = null;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $dragonflyPassword;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $image;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $portsMappings = null;
- #[Rule(['nullable', 'boolean'])]
+ #[Validate(['nullable', 'boolean'])]
public ?bool $isPublic = null;
- #[Rule(['nullable', 'integer'])]
+ #[Validate(['nullable', 'integer'])]
public ?int $publicPort = null;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $customDockerRunOptions = null;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $dbUrl = null;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $dbUrlPublic = null;
- #[Rule(['nullable', 'boolean'])]
+ #[Validate(['nullable', 'boolean'])]
public bool $isLogDrainEnabled = false;
public function getListeners()
diff --git a/app/Livewire/Project/Database/InitScript.php b/app/Livewire/Project/Database/InitScript.php
index 6bc6904d7..e3baa1c8e 100644
--- a/app/Livewire/Project/Database/InitScript.php
+++ b/app/Livewire/Project/Database/InitScript.php
@@ -4,7 +4,7 @@ namespace App\Livewire\Project\Database;
use Exception;
use Livewire\Attributes\Locked;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class InitScript extends Component
@@ -15,10 +15,10 @@ class InitScript extends Component
#[Locked]
public int $index;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $filename = null;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $content = null;
public function mount()
diff --git a/app/Livewire/Project/Database/Keydb/General.php b/app/Livewire/Project/Database/Keydb/General.php
index f95173651..e768495eb 100644
--- a/app/Livewire/Project/Database/Keydb/General.php
+++ b/app/Livewire/Project/Database/Keydb/General.php
@@ -8,7 +8,7 @@ use App\Models\Server;
use App\Models\StandaloneKeydb;
use Exception;
use Illuminate\Support\Facades\Auth;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class General extends Component
@@ -17,40 +17,40 @@ class General extends Component
public StandaloneKeydb $database;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $name;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $description = null;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $keydbConf = null;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $keydbPassword;
- #[Rule(['required', 'string'])]
+ #[Validate(['required', 'string'])]
public string $image;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $portsMappings = null;
- #[Rule(['nullable', 'boolean'])]
+ #[Validate(['nullable', 'boolean'])]
public ?bool $isPublic = null;
- #[Rule(['nullable', 'integer'])]
+ #[Validate(['nullable', 'integer'])]
public ?int $publicPort = null;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $customDockerRunOptions = null;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $dbUrl = null;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $dbUrlPublic = null;
- #[Rule(['nullable', 'boolean'])]
+ #[Validate(['nullable', 'boolean'])]
public bool $isLogDrainEnabled = false;
public function getListeners()
diff --git a/app/Livewire/Project/Edit.php b/app/Livewire/Project/Edit.php
index 62c1bfc11..463febb10 100644
--- a/app/Livewire/Project/Edit.php
+++ b/app/Livewire/Project/Edit.php
@@ -3,17 +3,17 @@
namespace App\Livewire\Project;
use App\Models\Project;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class Edit extends Component
{
public Project $project;
- #[Rule(['required', 'string', 'min:3', 'max:255'])]
+ #[Validate(['required', 'string', 'min:3', 'max:255'])]
public string $name;
- #[Rule(['nullable', 'string', 'max:255'])]
+ #[Validate(['nullable', 'string', 'max:255'])]
public ?string $description = null;
public function mount(string $project_uuid)
diff --git a/app/Livewire/Project/EnvironmentEdit.php b/app/Livewire/Project/EnvironmentEdit.php
index fc33cf6b6..f48220b3d 100644
--- a/app/Livewire/Project/EnvironmentEdit.php
+++ b/app/Livewire/Project/EnvironmentEdit.php
@@ -5,7 +5,7 @@ namespace App\Livewire\Project;
use App\Models\Application;
use App\Models\Project;
use Livewire\Attributes\Locked;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class EnvironmentEdit extends Component
@@ -17,10 +17,10 @@ class EnvironmentEdit extends Component
#[Locked]
public $environment;
- #[Rule(['required', 'string', 'min:3', 'max:255'])]
+ #[Validate(['required', 'string', 'min:3', 'max:255'])]
public string $name;
- #[Rule(['nullable', 'string', 'max:255'])]
+ #[Validate(['nullable', 'string', 'max:255'])]
public ?string $description = null;
public function mount(string $project_uuid, string $environment_name)
diff --git a/app/Livewire/Project/Show.php b/app/Livewire/Project/Show.php
index 8374a98cc..2335519c7 100644
--- a/app/Livewire/Project/Show.php
+++ b/app/Livewire/Project/Show.php
@@ -4,17 +4,17 @@ namespace App\Livewire\Project;
use App\Models\Environment;
use App\Models\Project;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class Show extends Component
{
public Project $project;
- #[Rule(['required', 'string', 'min:3'])]
+ #[Validate(['required', 'string', 'min:3'])]
public string $name;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $description = null;
public function mount(string $project_uuid)
diff --git a/app/Livewire/Server/Advanced.php b/app/Livewire/Server/Advanced.php
index becae9f04..0852abebf 100644
--- a/app/Livewire/Server/Advanced.php
+++ b/app/Livewire/Server/Advanced.php
@@ -4,7 +4,7 @@ namespace App\Livewire\Server;
use App\Jobs\DockerCleanupJob;
use App\Models\Server;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class Advanced extends Component
@@ -13,28 +13,28 @@ class Advanced extends Component
public array $parameters = [];
- #[Rule(['integer', 'min:1'])]
+ #[Validate(['integer', 'min:1'])]
public int $concurrentBuilds = 1;
- #[Rule(['integer', 'min:1'])]
+ #[Validate(['integer', 'min:1'])]
public int $dynamicTimeout = 1;
- #[Rule('boolean')]
+ #[Validate('boolean')]
public bool $forceDockerCleanup = false;
- #[Rule('string')]
+ #[Validate('string')]
public string $dockerCleanupFrequency = '*/10 * * * *';
- #[Rule(['integer', 'min:1', 'max:99'])]
+ #[Validate(['integer', 'min:1', 'max:99'])]
public int $dockerCleanupThreshold = 10;
- #[Rule(['integer', 'min:1', 'max:99'])]
+ #[Validate(['integer', 'min:1', 'max:99'])]
public int $serverDiskUsageNotificationThreshold = 50;
- #[Rule('boolean')]
+ #[Validate('boolean')]
public bool $deleteUnusedVolumes = false;
- #[Rule('boolean')]
+ #[Validate('boolean')]
public bool $deleteUnusedNetworks = false;
public function mount(string $server_uuid)
diff --git a/app/Livewire/Server/CloudflareTunnels.php b/app/Livewire/Server/CloudflareTunnels.php
index f16962bca..311196473 100644
--- a/app/Livewire/Server/CloudflareTunnels.php
+++ b/app/Livewire/Server/CloudflareTunnels.php
@@ -3,14 +3,14 @@
namespace App\Livewire\Server;
use App\Models\Server;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class CloudflareTunnels extends Component
{
public Server $server;
- #[Rule(['required', 'boolean'])]
+ #[Validate(['required', 'boolean'])]
public bool $isCloudflareTunnelsEnabled;
public function mount(string $server_uuid)
diff --git a/app/Livewire/Server/Destinations.php b/app/Livewire/Server/Destinations.php
index c10958bd1..dbab6e03f 100644
--- a/app/Livewire/Server/Destinations.php
+++ b/app/Livewire/Server/Destinations.php
@@ -19,7 +19,6 @@ class Destinations extends Component
try {
$this->networks = collect();
$this->server = Server::ownedByCurrentTeam()->whereUuid($server_uuid)->firstOrFail();
- loggy($this->server);
} catch (\Throwable $e) {
return handleError($e, $this);
}
diff --git a/app/Livewire/Server/Form.php b/app/Livewire/Server/Form.php
deleted file mode 100644
index 740421373..000000000
--- a/app/Livewire/Server/Form.php
+++ /dev/null
@@ -1,281 +0,0 @@
-user()->currentTeam()->id;
-
- return [
- "echo-private:team.{$teamId},CloudflareTunnelConfigured" => 'cloudflareTunnelConfigured',
- 'refreshServerShow' => 'serverInstalled',
- 'revalidate' => '$refresh',
- ];
- }
-
- protected $rules = [
- 'server.name' => 'required',
- 'server.description' => 'nullable',
- 'server.ip' => 'required',
- 'server.user' => 'required',
- 'server.port' => 'required',
- 'wildcard_domain' => 'nullable|url',
- 'server.settings.is_reachable' => 'required',
- 'server.settings.is_swarm_manager' => 'required|boolean',
- 'server.settings.is_swarm_worker' => 'required|boolean',
- 'server.settings.is_build_server' => 'required|boolean',
- 'server.settings.is_metrics_enabled' => 'required|boolean',
- 'server.settings.sentinel_token' => 'required',
- 'server.settings.sentinel_metrics_refresh_rate_seconds' => 'required|integer|min:1',
- 'server.settings.sentinel_metrics_history_days' => 'required|integer|min:1',
- 'server.settings.sentinel_push_interval_seconds' => 'required|integer|min:10',
- 'server.settings.sentinel_custom_url' => 'nullable|url',
- 'server.settings.is_sentinel_enabled' => 'required|boolean',
- 'server.settings.is_sentinel_debug_enabled' => 'required|boolean',
- 'server.settings.server_timezone' => 'required|string|timezone',
- ];
-
- protected $validationAttributes = [
- 'server.name' => 'Name',
- 'server.description' => 'Description',
- 'server.ip' => 'IP address/Domain',
- 'server.user' => 'User',
- 'server.port' => 'Port',
- 'server.settings.is_reachable' => 'Is reachable',
- 'server.settings.is_swarm_manager' => 'Swarm Manager',
- 'server.settings.is_swarm_worker' => 'Swarm Worker',
- 'server.settings.is_build_server' => 'Build Server',
- 'server.settings.is_metrics_enabled' => 'Metrics',
- 'server.settings.sentinel_token' => 'Metrics Token',
- 'server.settings.sentinel_metrics_refresh_rate_seconds' => 'Metrics Interval',
- 'server.settings.sentinel_metrics_history_days' => 'Metrics History',
- 'server.settings.sentinel_push_interval_seconds' => 'Push Interval',
- 'server.settings.is_sentinel_enabled' => 'Server API',
- 'server.settings.is_sentinel_debug_enabled' => 'Debug',
- 'server.settings.sentinel_custom_url' => 'Coolify URL',
- 'server.settings.server_timezone' => 'Server Timezone',
- ];
-
- public function mount(Server $server)
- {
- $this->server = $server;
- $this->timezones = collect(timezone_identifiers_list())->sort()->values()->toArray();
- $this->wildcard_domain = $this->server->settings->wildcard_domain;
- }
-
- public function checkSyncStatus()
- {
- $this->server->refresh();
- $this->server->settings->refresh();
- }
-
- public function regenerateSentinelToken()
- {
- try {
- $this->server->settings->generateSentinelToken();
- $this->server->settings->refresh();
- // $this->restartSentinel(notification: false);
- $this->dispatch('success', 'Token regenerated & Sentinel restarted.');
- } catch (\Throwable $e) {
- return handleError($e, $this);
- }
- }
-
- public function updated($field)
- {
- if ($field === 'server.settings.docker_cleanup_frequency') {
- $frequency = $this->server->settings->docker_cleanup_frequency;
- if (! validate_cron_expression($frequency)) {
- $this->dispatch('error', 'Invalid Cron / Human expression for Docker Cleanup Frequency. Resetting to default 10 minutes.');
- $this->server->settings->docker_cleanup_frequency = '*/10 * * * *';
- }
- }
- }
-
- public function cloudflareTunnelConfigured()
- {
- $this->serverInstalled();
- $this->dispatch('success', 'Cloudflare Tunnels configured successfully.');
- }
-
- public function serverInstalled()
- {
- $this->server->refresh();
- $this->server->settings->refresh();
- }
-
- public function updatedServerSettingsIsBuildServer()
- {
- $this->dispatch('refreshServerShow');
- $this->dispatch('serverRefresh');
- $this->dispatch('proxyStatusUpdated');
- }
-
- public function updatedServerSettingsIsSentinelEnabled($value)
- {
- $this->validate([
- 'server.settings.sentinel_custom_url' => 'required|url',
- ]);
- if ($value === false) {
- StopSentinel::dispatch($this->server);
- $this->server->settings->is_metrics_enabled = false;
- $this->server->settings->save();
- $this->server->sentinelHeartbeat(isReset: true);
- } else {
- try {
- StartSentinel::run($this->server);
- } catch (\Throwable $e) {
- return handleError($e, $this);
- }
- }
- }
-
- public function updatedServerSettingsIsMetricsEnabled()
- {
- $this->restartSentinel();
- }
-
- public function updatedServerSettingsIsSentinelDebugEnabled()
- {
- $this->restartSentinel();
- }
-
- public function instantSave()
- {
- try {
- $this->validate();
- refresh_server_connection($this->server->privateKey);
- $this->validateServer(false);
-
- $this->server->settings->save();
- $this->server->save();
- $this->dispatch('success', 'Server updated.');
- $this->dispatch('refreshServerShow');
- } catch (\Throwable $e) {
- $this->server->settings->refresh();
-
- return handleError($e, $this);
- } finally {
- }
- }
-
- public function saveSentinel()
- {
- try {
- $this->validate();
- $this->server->settings->save();
- $this->dispatch('success', 'Sentinel updated.');
- } catch (\Throwable $e) {
- return handleError($e, $this);
- } finally {
- $this->checkSyncStatus();
- }
- }
-
- public function restartSentinel($notification = true)
- {
- try {
- $this->validate();
- $this->validate([
- 'server.settings.sentinel_custom_url' => 'required|url',
- ]);
- $this->server->settings->save();
- $this->server->restartSentinel(async: false);
- if ($notification) {
- $this->dispatch('success', 'Sentinel restarted.');
- }
- } catch (\Throwable $e) {
- return handleError($e, $this);
- }
- }
-
- public function revalidate()
- {
- $this->revalidate = true;
- }
-
- public function checkLocalhostConnection()
- {
- $this->submit();
- ['uptime' => $uptime, 'error' => $error] = $this->server->validateConnection();
- if ($uptime) {
- $this->dispatch('success', 'Server is reachable.');
- $this->server->settings->is_reachable = true;
- $this->server->settings->is_usable = true;
- $this->server->settings->save();
- $this->dispatch('proxyStatusUpdated');
- } else {
- $this->dispatch('error', 'Server is not reachable.', 'Please validate your configuration and connection.
Check this documentation for further help.
Error: '.$error);
-
- return;
- }
- }
-
- public function validateServer($install = true)
- {
- $this->server->update([
- 'validation_logs' => null,
- ]);
- $this->dispatch('init', $install);
- }
-
- public function submit()
- {
- try {
- if (isCloud() && ! isDev()) {
- $this->validate();
- $this->validate([
- 'server.ip' => 'required',
- ]);
- } else {
- $this->validate();
- }
- $uniqueIPs = Server::all()->reject(function (Server $server) {
- return $server->id === $this->server->id;
- })->pluck('ip')->toArray();
- if (in_array($this->server->ip, $uniqueIPs)) {
- $this->dispatch('error', 'IP address is already in use by another team.');
-
- return;
- }
- refresh_server_connection($this->server->privateKey);
- $this->server->settings->wildcard_domain = $this->wildcard_domain;
- $currentTimezone = $this->server->settings->getOriginal('server_timezone');
- $newTimezone = $this->server->settings->server_timezone;
- if ($currentTimezone !== $newTimezone || $currentTimezone === '') {
- $this->server->settings->server_timezone = $newTimezone;
- }
- $this->server->settings->save();
- $this->server->save();
-
- $this->dispatch('success', 'Server updated.');
- } catch (\Throwable $e) {
- return handleError($e, $this);
- }
- }
-}
diff --git a/app/Livewire/Server/LogDrains.php b/app/Livewire/Server/LogDrains.php
index 67a6962dc..6599149c4 100644
--- a/app/Livewire/Server/LogDrains.php
+++ b/app/Livewire/Server/LogDrains.php
@@ -5,38 +5,38 @@ namespace App\Livewire\Server;
use App\Actions\Server\StartLogDrain;
use App\Actions\Server\StopLogDrain;
use App\Models\Server;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class LogDrains extends Component
{
public Server $server;
- #[Rule(['boolean'])]
+ #[Validate(['boolean'])]
public bool $isLogDrainNewRelicEnabled = false;
- #[Rule(['boolean'])]
+ #[Validate(['boolean'])]
public bool $isLogDrainCustomEnabled = false;
- #[Rule(['boolean'])]
+ #[Validate(['boolean'])]
public bool $isLogDrainAxiomEnabled = false;
- #[Rule(['string', 'nullable'])]
+ #[Validate(['string', 'nullable'])]
public ?string $logDrainNewRelicLicenseKey = null;
- #[Rule(['url', 'nullable'])]
+ #[Validate(['url', 'nullable'])]
public ?string $logDrainNewRelicBaseUri = null;
- #[Rule(['string', 'nullable'])]
+ #[Validate(['string', 'nullable'])]
public ?string $logDrainAxiomDatasetName = null;
- #[Rule(['string', 'nullable'])]
+ #[Validate(['string', 'nullable'])]
public ?string $logDrainAxiomApiKey = null;
- #[Rule(['string', 'nullable'])]
+ #[Validate(['string', 'nullable'])]
public ?string $logDrainCustomConfig = null;
- #[Rule(['string', 'nullable'])]
+ #[Validate(['string', 'nullable'])]
public ?string $logDrainCustomConfigParser = null;
public function mount(string $server_uuid)
diff --git a/app/Livewire/Server/Show.php b/app/Livewire/Server/Show.php
index 2e4b67cc6..524e21908 100644
--- a/app/Livewire/Server/Show.php
+++ b/app/Livewire/Server/Show.php
@@ -5,77 +5,77 @@ namespace App\Livewire\Server;
use App\Actions\Server\StartSentinel;
use App\Actions\Server\StopSentinel;
use App\Models\Server;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class Show extends Component
{
public Server $server;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public string $name;
- #[Rule(['nullable'])]
+ #[Validate(['nullable'])]
public ?string $description;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public string $ip;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public string $user;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public string $port;
- #[Rule(['nullable'])]
+ #[Validate(['nullable'])]
public ?string $validationLogs = null;
- #[Rule(['nullable', 'url'])]
+ #[Validate(['nullable', 'url'])]
public ?string $wildcardDomain;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public bool $isReachable;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public bool $isUsable;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public bool $isSwarmManager;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public bool $isSwarmWorker;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public bool $isBuildServer;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public bool $isMetricsEnabled;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public string $sentinelToken;
- #[Rule(['nullable'])]
+ #[Validate(['nullable'])]
public ?string $sentinelUpdatedAt;
- #[Rule(['required', 'integer', 'min:1'])]
+ #[Validate(['required', 'integer', 'min:1'])]
public int $sentinelMetricsRefreshRateSeconds;
- #[Rule(['required', 'integer', 'min:1'])]
+ #[Validate(['required', 'integer', 'min:1'])]
public int $sentinelMetricsHistoryDays;
- #[Rule(['required', 'integer', 'min:10'])]
+ #[Validate(['required', 'integer', 'min:10'])]
public int $sentinelPushIntervalSeconds;
- #[Rule(['nullable', 'url'])]
+ #[Validate(['nullable', 'url'])]
public ?string $sentinelCustomUrl;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public bool $isSentinelEnabled;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public bool $isSentinelDebugEnabled;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public string $serverTimezone;
public array $timezones;
@@ -85,8 +85,8 @@ class Show extends Component
$teamId = auth()->user()->currentTeam()->id;
return [
- "echo-private:team.{$teamId},CloudflareTunnelConfigured" => '$refresh',
- 'refreshServerShow' => '$refresh',
+ "echo-private:team.{$teamId},CloudflareTunnelConfigured" => 'refresh',
+ 'refreshServerShow' => 'refresh',
];
}
@@ -151,6 +151,12 @@ class Show extends Component
}
}
+ public function refresh()
+ {
+ $this->syncData();
+ $this->dispatch('$refresh');
+ }
+
public function validateServer($install = true)
{
try {
diff --git a/app/Livewire/Settings/Index.php b/app/Livewire/Settings/Index.php
index 0a6c5bae6..2991b8ae8 100644
--- a/app/Livewire/Settings/Index.php
+++ b/app/Livewire/Settings/Index.php
@@ -8,7 +8,7 @@ use App\Models\Server;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Livewire\Attributes\Locked;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class Index extends Component
@@ -20,58 +20,58 @@ class Index extends Component
#[Locked]
public $timezones;
- #[Rule('boolean')]
+ #[Validate('boolean')]
public bool $is_auto_update_enabled;
- #[Rule('nullable|string|max:255')]
+ #[Validate('nullable|string|max:255')]
public ?string $fqdn = null;
- #[Rule('nullable|string|max:255')]
+ #[Validate('nullable|string|max:255')]
public ?string $resale_license = null;
- #[Rule('required|integer|min:1025|max:65535')]
+ #[Validate('required|integer|min:1025|max:65535')]
public int $public_port_min;
- #[Rule('required|integer|min:1025|max:65535')]
+ #[Validate('required|integer|min:1025|max:65535')]
public int $public_port_max;
- #[Rule('nullable|string')]
+ #[Validate('nullable|string')]
public ?string $custom_dns_servers = null;
- #[Rule('nullable|string|max:255')]
+ #[Validate('nullable|string|max:255')]
public ?string $instance_name = null;
- #[Rule('nullable|string')]
+ #[Validate('nullable|string')]
public ?string $allowed_ips = null;
- #[Rule('nullable|string')]
+ #[Validate('nullable|string')]
public ?string $public_ipv4 = null;
- #[Rule('nullable|string')]
+ #[Validate('nullable|string')]
public ?string $public_ipv6 = null;
- #[Rule('string')]
+ #[Validate('string')]
public string $auto_update_frequency;
- #[Rule('string')]
+ #[Validate('string')]
public string $update_check_frequency;
- #[Rule('required|string|timezone')]
+ #[Validate('required|string|timezone')]
public string $instance_timezone;
- #[Rule('boolean')]
+ #[Validate('boolean')]
public bool $do_not_track;
- #[Rule('boolean')]
+ #[Validate('boolean')]
public bool $is_registration_enabled;
- #[Rule('boolean')]
+ #[Validate('boolean')]
public bool $is_dns_validation_enabled;
- #[Rule('boolean')]
+ #[Validate('boolean')]
public bool $is_api_enabled;
- #[Rule('boolean')]
+ #[Validate('boolean')]
public bool $disable_two_step_confirmation;
public function render()
diff --git a/app/Livewire/SettingsBackup.php b/app/Livewire/SettingsBackup.php
index 38f7e548a..6dc5d6ab3 100644
--- a/app/Livewire/SettingsBackup.php
+++ b/app/Livewire/SettingsBackup.php
@@ -8,7 +8,7 @@ use App\Models\ScheduledDatabaseBackup;
use App\Models\Server;
use App\Models\StandalonePostgresql;
use Livewire\Attributes\Locked;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class SettingsBackup extends Component
@@ -25,19 +25,19 @@ class SettingsBackup extends Component
#[Locked]
public $executions = [];
- #[Rule(['required'])]
+ #[Validate(['required'])]
public string $uuid;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public string $name;
- #[Rule(['nullable'])]
+ #[Validate(['nullable'])]
public ?string $description = null;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public string $postgres_user;
- #[Rule(['required'])]
+ #[Validate(['required'])]
public string $postgres_password;
public function mount()
diff --git a/app/Livewire/SettingsEmail.php b/app/Livewire/SettingsEmail.php
index 2a017ed34..0ab5754f2 100644
--- a/app/Livewire/SettingsEmail.php
+++ b/app/Livewire/SettingsEmail.php
@@ -3,44 +3,44 @@
namespace App\Livewire;
use App\Models\InstanceSettings;
-use Livewire\Attributes\Rule;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class SettingsEmail extends Component
{
public InstanceSettings $settings;
- #[Rule(['boolean'])]
+ #[Validate(['boolean'])]
public bool $smtpEnabled = false;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $smtpHost = null;
- #[Rule(['nullable', 'numeric', 'min:1', 'max:65535'])]
+ #[Validate(['nullable', 'numeric', 'min:1', 'max:65535'])]
public ?int $smtpPort = null;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $smtpEncryption = null;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $smtpUsername = null;
- #[Rule(['nullable'])]
+ #[Validate(['nullable'])]
public ?string $smtpPassword = null;
- #[Rule(['nullable', 'numeric'])]
+ #[Validate(['nullable', 'numeric'])]
public ?int $smtpTimeout = null;
- #[Rule(['nullable', 'email'])]
+ #[Validate(['nullable', 'email'])]
public ?string $smtpFromAddress = null;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $smtpFromName = null;
- #[Rule(['boolean'])]
+ #[Validate(['boolean'])]
public bool $resendEnabled = false;
- #[Rule(['nullable', 'string'])]
+ #[Validate(['nullable', 'string'])]
public ?string $resendApiKey = null;
public function mount()
diff --git a/app/Livewire/Tags/Index.php b/app/Livewire/Tags/Index.php
deleted file mode 100644
index 116f19e4e..000000000
--- a/app/Livewire/Tags/Index.php
+++ /dev/null
@@ -1,82 +0,0 @@
- 'updateDeployments'];
-
- public function render()
- {
- return view('livewire.tags.index');
- }
-
- public function mount()
- {
- $this->tags = Tag::ownedByCurrentTeam()->get()->unique('name')->sortBy('name');
- if ($this->tag) {
- $this->tagUpdated();
- }
- }
-
- public function updateDeployments($deployments)
- {
- $this->deploymentsPerTagPerServer = $deployments;
- }
-
- public function tagUpdated()
- {
- if ($this->tag === '') {
- return;
- }
- $sanitizedTag = htmlspecialchars($this->tag, ENT_QUOTES, 'UTF-8');
- $tag = $this->tags->where('name', $sanitizedTag)->first();
- if (! $tag) {
- $this->dispatch('error', 'Tag ('.e($sanitizedTag).') not found.');
- $this->tag = '';
-
- return;
- }
- $this->webhook = generateTagDeployWebhook($tag->name);
- $this->applications = $tag->applications()->get();
- $this->services = $tag->services()->get();
- }
-
- public function redeployAll()
- {
- try {
- $this->applications->each(function ($resource) {
- $deploy = new DeployController;
- $deploy->deploy_resource($resource);
- });
- $this->services->each(function ($resource) {
- $deploy = new DeployController;
- $deploy->deploy_resource($resource);
- });
- $this->dispatch('success', 'Mass deployment started.');
- } catch (\Exception $e) {
- return handleError($e, $this);
- }
- }
-}
diff --git a/app/Livewire/Tags/Show.php b/app/Livewire/Tags/Show.php
index 0dffcce57..fc5b13374 100644
--- a/app/Livewire/Tags/Show.php
+++ b/app/Livewire/Tags/Show.php
@@ -5,43 +5,57 @@ namespace App\Livewire\Tags;
use App\Http\Controllers\Api\DeployController;
use App\Models\ApplicationDeploymentQueue;
use App\Models\Tag;
+use Illuminate\Support\Collection;
+use Livewire\Attributes\Locked;
use Livewire\Attributes\Title;
use Livewire\Component;
#[Title('Tags | Coolify')]
class Show extends Component
{
- public $tags;
+ #[Locked]
+ public ?string $tagName = null;
- public Tag $tag;
+ #[Locked]
+ public ?Collection $tags = null;
- public $applications;
+ #[Locked]
+ public ?Tag $tag = null;
- public $services;
+ #[Locked]
+ public ?Collection $applications = null;
- public $webhook = null;
+ #[Locked]
+ public ?Collection $services = null;
- public $deployments_per_tag_per_server = [];
+ #[Locked]
+ public ?string $webhook = null;
+
+ #[Locked]
+ public ?array $deploymentsPerTagPerServer = null;
public function mount()
{
- $this->tags = Tag::ownedByCurrentTeam()->get()->unique('name')->sortBy('name');
- $tag = $this->tags->where('name', request()->tag_name)->first();
- if (! $tag) {
- return redirect()->route('tags.index');
+ try {
+ $this->tags = Tag::ownedByCurrentTeam()->get()->unique('name')->sortBy('name');
+ if (str($this->tagName)->isNotEmpty()) {
+ $tag = $this->tags->where('name', $this->tagName)->first();
+ $this->webhook = generateTagDeployWebhook($tag->name);
+ $this->applications = $tag->applications()->get();
+ $this->services = $tag->services()->get();
+ $this->tag = $tag;
+ $this->getDeployments();
+ }
+ } catch (\Exception $e) {
+ return handleError($e, $this);
}
- $this->webhook = generateTagDeployWebhook($tag->name);
- $this->applications = $tag->applications()->get();
- $this->services = $tag->services()->get();
- $this->tag = $tag;
- $this->get_deployments();
}
- public function get_deployments()
+ public function getDeployments()
{
try {
$resource_ids = $this->applications->pluck('id');
- $this->deployments_per_tag_per_server = ApplicationDeploymentQueue::whereIn('status', ['in_progress', 'queued'])->whereIn('application_id', $resource_ids)->get([
+ $this->deploymentsPerTagPerServer = ApplicationDeploymentQueue::whereIn('status', ['in_progress', 'queued'])->whereIn('application_id', $resource_ids)->get([
'id',
'application_id',
'application_name',
@@ -56,7 +70,7 @@ class Show extends Component
}
}
- public function redeploy_all()
+ public function redeployAll()
{
try {
$message = collect([]);
diff --git a/app/Livewire/Team/Create.php b/app/Livewire/Team/Create.php
index 992833da5..f805d6122 100644
--- a/app/Livewire/Team/Create.php
+++ b/app/Livewire/Team/Create.php
@@ -3,28 +3,21 @@
namespace App\Livewire\Team;
use App\Models\Team;
+use Livewire\Attributes\Validate;
use Livewire\Component;
class Create extends Component
{
+ #[Validate(['required', 'min:3', 'max:255'])]
public string $name = '';
+ #[Validate(['nullable', 'min:3', 'max:255'])]
public ?string $description = null;
- protected $rules = [
- 'name' => 'required|min:3|max:255',
- 'description' => 'nullable|min:3|max:255',
- ];
-
- protected $validationAttributes = [
- 'name' => 'name',
- 'description' => 'description',
- ];
-
public function submit()
{
- $this->validate();
try {
+ $this->validate();
$team = Team::create([
'name' => $this->name,
'description' => $this->description,
diff --git a/app/Models/Server.php b/app/Models/Server.php
index e9b6fd929..0fcfd89ab 100644
--- a/app/Models/Server.php
+++ b/app/Models/Server.php
@@ -974,10 +974,10 @@ $schema://$host {
public function serverStatus(): bool
{
- if ($this->isFunctional() === false) {
+ if ($this->status() === false) {
return false;
}
- if ($this->status() === false) {
+ if ($this->isFunctional() === false) {
return false;
}
@@ -986,9 +986,6 @@ $schema://$host {
public function status(): bool
{
- if ($this->isFunctional() === false) {
- return false;
- }
['uptime' => $uptime] = $this->validateConnection(false);
if ($uptime === false) {
foreach ($this->applications() as $application) {
@@ -1232,7 +1229,7 @@ $schema://$host {
return str($this->ip)->contains(':');
}
- public function restartSentinel(bool $async = true): void
+ public function restartSentinel(bool $async = true)
{
try {
if ($async) {
@@ -1241,7 +1238,7 @@ $schema://$host {
StartSentinel::run($this, true);
}
} catch (\Throwable $e) {
- loggy('Error restarting Sentinel: '.$e->getMessage());
+ return handleError($e, $this);
}
}
diff --git a/app/Models/ServerSetting.php b/app/Models/ServerSetting.php
index bca16536e..e72c8c444 100644
--- a/app/Models/ServerSetting.php
+++ b/app/Models/ServerSetting.php
@@ -4,6 +4,7 @@ namespace App\Models;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Facades\Log;
use OpenApi\Attributes as OA;
#[OA\Schema(
@@ -69,7 +70,7 @@ class ServerSetting extends Model
$setting->generateSentinelUrl(save: false);
}
} catch (\Throwable $e) {
- loggy('Error creating server setting: '.$e->getMessage());
+ Log::error('Error creating server setting: '.$e->getMessage());
}
});
static::updated(function ($settings) {
diff --git a/app/Models/Team.php b/app/Models/Team.php
index 5b4a80cb1..db485054b 100644
--- a/app/Models/Team.php
+++ b/app/Models/Team.php
@@ -165,7 +165,7 @@ class Team extends Model implements SendsDiscord, SendsEmail
return 0;
}
- return data_get($team, 'limits.serverLimit', 0);
+ return data_get($team, 'limits', 0);
}
public function limits(): Attribute
@@ -187,9 +187,8 @@ class Team extends Model implements SendsDiscord, SendsEmail
} else {
$serverLimit = config('constants.limits.server')[strtolower($subscription)];
}
- $sharedEmailEnabled = config('constants.limits.email')[strtolower($subscription)];
- return ['serverLimit' => $serverLimit, 'sharedEmailEnabled' => $sharedEmailEnabled];
+ return $serverLimit ?? 2;
}
);
diff --git a/app/Notifications/Channels/DiscordChannel.php b/app/Notifications/Channels/DiscordChannel.php
index 3a33d8902..86276fec9 100644
--- a/app/Notifications/Channels/DiscordChannel.php
+++ b/app/Notifications/Channels/DiscordChannel.php
@@ -17,6 +17,6 @@ class DiscordChannel
if (! $webhookUrl) {
return;
}
- dispatch(new SendMessageToDiscordJob($message, $webhookUrl));
+ dispatch(new SendMessageToDiscordJob($message, $webhookUrl))->onQueue('high');
}
}
diff --git a/app/Notifications/Channels/TelegramChannel.php b/app/Notifications/Channels/TelegramChannel.php
index 4b1fa49dd..b3d4e384b 100644
--- a/app/Notifications/Channels/TelegramChannel.php
+++ b/app/Notifications/Channels/TelegramChannel.php
@@ -41,6 +41,6 @@ class TelegramChannel
if (! $telegramToken || ! $chatId || ! $message) {
return;
}
- dispatch(new SendMessageToTelegramJob($message, $buttons, $telegramToken, $chatId, $topicId));
+ dispatch(new SendMessageToTelegramJob($message, $buttons, $telegramToken, $chatId, $topicId))->onQueue('high');
}
}
diff --git a/bootstrap/helpers/applications.php b/bootstrap/helpers/applications.php
index b3e8011b9..eb331f8c2 100644
--- a/bootstrap/helpers/applications.php
+++ b/bootstrap/helpers/applications.php
@@ -91,7 +91,7 @@ function next_queuable(string $server_id, string $application_id): bool
$server = Server::find($server_id);
$concurrent_builds = $server->settings->concurrent_builds;
- ray("serverId:{$server->id}", "concurrentBuilds:{$concurrent_builds}", "deployments:{$deployments->count()}", "sameApplicationDeployments:{$same_application_deployments->count()}")->green();
+ // ray("serverId:{$server->id}", "concurrentBuilds:{$concurrent_builds}", "deployments:{$deployments->count()}", "sameApplicationDeployments:{$same_application_deployments->count()}")->green();
if ($deployments->count() > $concurrent_builds) {
return false;
diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php
index 52435703c..2e583b94d 100644
--- a/bootstrap/helpers/docker.php
+++ b/bootstrap/helpers/docker.php
@@ -654,7 +654,7 @@ function isDatabaseImage(?string $image = null)
return false;
}
-function convert_docker_run_to_compose(?string $custom_docker_run_options = null)
+function convertDockerRunToCompose(?string $custom_docker_run_options = null)
{
$options = [];
$compose_options = collect([]);
@@ -679,9 +679,17 @@ function convert_docker_run_to_compose(?string $custom_docker_run_options = null
'--privileged' => 'privileged',
'--ip' => 'ip',
'--shm-size' => 'shm_size',
+ '--gpus' => 'gpus',
]);
foreach ($matches as $match) {
$option = $match[1];
+ if ($option === '--gpus') {
+ $regexForParsingDeviceIds = '/device=([0-9A-Za-z-,]+)/';
+ preg_match($regexForParsingDeviceIds, $custom_docker_run_options, $device_matches);
+ $value = $device_matches[1] ?? 'all';
+ $options[$option][] = $value;
+ $options[$option] = array_unique($options[$option]);
+ }
if (isset($match[2]) && $match[2] !== '') {
$value = $match[2];
$options[$option][] = $value;
@@ -694,7 +702,6 @@ function convert_docker_run_to_compose(?string $custom_docker_run_options = null
$options = collect($options);
// Easily get mappings from https://github.com/composerize/composerize/blob/master/packages/composerize/src/mappings.js
foreach ($options as $option => $value) {
- // ray($option,$value);
if (! data_get($mapping, $option)) {
continue;
}
@@ -723,6 +730,28 @@ function convert_docker_run_to_compose(?string $custom_docker_run_options = null
if (! is_null($value) && is_array($value) && count($value) > 0) {
$compose_options->put($mapping[$option], $value[0]);
}
+ } elseif ($option === '--gpus') {
+ $payload = [
+ 'driver' => 'nvidia',
+ 'capabilities' => ['gpu'],
+ ];
+ if (! is_null($value) && is_array($value) && count($value) > 0) {
+ if (str($value[0]) != 'all') {
+ if (str($value[0])->contains(',')) {
+ $payload['device_ids'] = str($value[0])->explode(',')->toArray();
+ } else {
+ $payload['device_ids'] = [$value[0]];
+ }
+ }
+ }
+ ray($payload);
+ $compose_options->put('deploy', [
+ 'resources' => [
+ 'reservations' => [
+ 'devices' => [$payload],
+ ],
+ ],
+ ]);
} else {
if ($list_options->contains($option)) {
if ($compose_options->has($mapping[$option])) {
@@ -744,7 +773,7 @@ function convert_docker_run_to_compose(?string $custom_docker_run_options = null
return $compose_options->toArray();
}
-function generate_custom_docker_run_options_for_databases($docker_run_options, $docker_compose, $container_name, $network)
+function generateCustomDockerRunOptionsForDatabases($docker_run_options, $docker_compose, $container_name, $network)
{
$ipv4 = data_get($docker_run_options, 'ip.0');
$ipv6 = data_get($docker_run_options, 'ip6.0');
diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php
index ec13a1be2..77749a633 100644
--- a/bootstrap/helpers/shared.php
+++ b/bootstrap/helpers/shared.php
@@ -106,7 +106,7 @@ function currentTeam()
function showBoarding(): bool
{
- if (Auth::user()->isMember()) {
+ if (Auth::user()?->isMember()) {
return false;
}
diff --git a/config/constants.php b/config/constants.php
index 5792b358c..e979b2087 100644
--- a/config/constants.php
+++ b/config/constants.php
@@ -1,6 +1,7 @@
'26.0',
'docs' => [
'base_url' => 'https://coolify.io/docs',
'contact' => 'https://coolify.io/docs/contact',
diff --git a/database/migrations/2024_06_25_184323_update_db.php b/database/migrations/2024_06_25_184323_update_db.php
index 8f9405b86..d9cddb15f 100644
--- a/database/migrations/2024_06_25_184323_update_db.php
+++ b/database/migrations/2024_06_25_184323_update_db.php
@@ -5,6 +5,7 @@ use App\Models\Server;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
use Visus\Cuid2\Cuid2;
@@ -52,7 +53,7 @@ return new class extends Migration
DB::table('server_settings')->update(['metrics_history_days' => 7]);
} catch (\Exception $e) {
- loggy($e);
+ Log::error('Error updating db: '.$e->getMessage());
}
}
diff --git a/database/seeders/SentinelSeeder.php b/database/seeders/SentinelSeeder.php
index 117ba6782..d61c2f55d 100644
--- a/database/seeders/SentinelSeeder.php
+++ b/database/seeders/SentinelSeeder.php
@@ -4,6 +4,7 @@ namespace Database\Seeders;
use App\Models\Server;
use Illuminate\Database\Seeder;
+use Illuminate\Support\Facades\Log;
class SentinelSeeder extends Seeder
{
@@ -23,7 +24,7 @@ class SentinelSeeder extends Seeder
}
}
} catch (\Throwable $e) {
- loggy("Error: {$e->getMessage()}\n");
+ Log::error('Error seeding sentinel: '.$e->getMessage());
}
}
});
diff --git a/docker/prod/Dockerfile b/docker/prod/Dockerfile
index 22a5b143a..36ca5ebb3 100644
--- a/docker/prod/Dockerfile
+++ b/docker/prod/Dockerfile
@@ -45,6 +45,8 @@ RUN composer dump-autoload
COPY --from=static-assets --chown=9999:9999 /app/public/build ./public/build
COPY --chmod=755 docker/prod/etc/s6-overlay/ /etc/s6-overlay/
+RUN php artisan route:clear
+RUN php artisan view:clear
RUN php artisan route:cache
RUN php artisan view:cache
diff --git a/other/nightly/install.sh b/other/nightly/install.sh
index 04faf50ea..e005b7493 100755
--- a/other/nightly/install.sh
+++ b/other/nightly/install.sh
@@ -5,7 +5,7 @@ set -e # Exit immediately if a command exits with a non-zero status
## $1 could be empty, so we need to disable this check
#set -u # Treat unset variables as an error and exit
set -o pipefail # Cause a pipeline to return the status of the last command that exited with a non-zero status
-CDN="https://cdn.coollabs.io/coolify-nightly"
+CDN="https://cdn.coollabs.io/coolify"
DATE=$(date +"%Y%m%d-%H%M%S")
VERSION="1.6"
@@ -13,7 +13,7 @@ DOCKER_VERSION="26.0"
# TODO: Ask for a user
CURRENT_USER=$USER
-mkdir -p /data/coolify/{source,ssh,applications,databases,backups,services,proxy,webhooks-during-maintenance,metrics,logs}
+mkdir -p /data/coolify/{source,ssh,applications,databases,backups,services,proxy,webhooks-during-maintenance,sentinel}
mkdir -p /data/coolify/ssh/{keys,mux}
mkdir -p /data/coolify/proxy/dynamic
@@ -164,7 +164,6 @@ sles | opensuse-leap | opensuse-tumbleweed)
esac
-
echo -e "2. Check OpenSSH server configuration. "
# Detect OpenSSH server
@@ -262,9 +261,14 @@ if ! [ -x "$(command -v docker)" ]; then
fi
;;
*)
- curl -s https://releases.rancher.com/install-docker/${DOCKER_VERSION}.sh | sh >/dev/null 2>&1
+ if [ "$OS_TYPE" = "ubuntu" ] && [ "$OS_VERSION" = "24.10" ]; then
+ echo "Docker automated installation is not supported on Ubuntu 24.10 (non-LTS release)."
+ echo "Please install Docker manually."
+ exit 1
+ fi
+ curl -s https://releases.rancher.com/install-docker/${DOCKER_VERSION}.sh | sh 2>&1
if ! [ -x "$(command -v docker)" ]; then
- curl -s https://get.docker.com | sh -s -- --version ${DOCKER_VERSION} >/dev/null 2>&1
+ curl -s https://get.docker.com | sh -s -- --version ${DOCKER_VERSION} 2>&1
if ! [ -x "$(command -v docker)" ]; then
echo " - Docker installation failed."
echo " Maybe your OS is not supported?"
@@ -404,10 +408,10 @@ if [ ! -f ~/.ssh/authorized_keys ]; then
fi
set +e
-IF_COOLIFY_VOLUME_EXISTS=$(docker volume ls | grep coolify-db | wc -l)
+IS_COOLIFY_VOLUME_EXISTS=$(docker volume ls | grep coolify-db | wc -l)
set -e
-if [ "$IF_COOLIFY_VOLUME_EXISTS" -eq 0 ]; then
+if [ "$IS_COOLIFY_VOLUME_EXISTS" -eq 0 ]; then
echo " - Generating SSH key."
ssh-keygen -t ed25519 -a 100 -f /data/coolify/ssh/keys/id.$CURRENT_USER@host.docker.internal -q -N "" -C coolify
chown 9999 /data/coolify/ssh/keys/id.$CURRENT_USER@host.docker.internal
@@ -424,7 +428,7 @@ echo -e " - It could take a while based on your server's performance, network sp
echo -e " - Please wait."
getAJoke
-bash /data/coolify/source/upgrade.sh "${LATEST_VERSION:-latest}" "${LATEST_HELPER_VERSION:-latest}" >/dev/null 2>&1
+bash /data/coolify/source/upgrade.sh "${LATEST_VERSION:-latest}" "${LATEST_HELPER_VERSION:-latest}"
echo " - Coolify installed successfully."
rm -f $ENV_FILE-$DATE
diff --git a/resources/views/components/navbar.blade.php b/resources/views/components/navbar.blade.php
index ae98f85cb..8a2f4d5d6 100644
--- a/resources/views/components/navbar.blade.php
+++ b/resources/views/components/navbar.blade.php
@@ -215,7 +215,7 @@