diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index aafda266e..3bb3cba2f 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -2,9 +2,8 @@ namespace App\Console; -use App\Jobs\CheckLogDrainContainerJob; +use App\Jobs\CheckForUpdatesJob; use App\Jobs\CleanupInstanceStuffsJob; -use App\Jobs\ContainerStatusJob; use App\Jobs\DatabaseBackupJob; use App\Jobs\DockerCleanupJob; use App\Jobs\PullCoolifyImageJob; @@ -13,9 +12,7 @@ use App\Jobs\PullSentinelImageJob; use App\Jobs\PullTemplatesFromCDN; use App\Jobs\ScheduledTaskJob; use App\Jobs\ServerCheckJob; -use App\Jobs\ServerStatusJob; use App\Jobs\UpdateCoolifyJob; -use App\Jobs\CheckForUpdatesJob; use App\Models\InstanceSettings; use App\Models\ScheduledDatabaseBackup; use App\Models\ScheduledTask; @@ -41,8 +38,6 @@ class Kernel extends ConsoleKernel // Server Jobs $this->check_scheduled_backups($schedule); $this->checkResourcesNew($schedule); - // $this->check_resources($schedule); - $this->check_scheduled_backups($schedule); $this->check_scheduled_tasks($schedule); $schedule->command('uploads:clear')->everyTwoMinutes(); } else { @@ -57,7 +52,6 @@ class Kernel extends ConsoleKernel // Server Jobs $this->check_scheduled_backups($schedule); $this->checkResourcesNew($schedule); - // $this->check_resources($schedule); $this->pull_images($schedule); $this->check_scheduled_tasks($schedule); @@ -106,44 +100,6 @@ class Kernel extends ConsoleKernel } } - private function checkResourcesNew($schedule) - { - if (isCloud()) { - $servers = $this->all_servers->whereNotNull('team.subscription')->where('team.subscription.stripe_trial_already_ended', false)->where('ip', '!=', '1.2.3.4'); - $own = Team::find(0)->servers; - $servers = $servers->merge($own); - } else { - $servers = $this->all_servers->where('ip', '!=', '1.2.3.4'); - } - foreach ($servers as $server) { - $schedule->job(new ServerCheckJob($server))->everyMinute()->onOneServer(); - $schedule->job(new DockerCleanupJob($server))->everyTenMinutes()->onOneServer(); - } - } - - private function check_resources($schedule) - { - if (isCloud()) { - $servers = $this->all_servers->whereNotNull('team.subscription')->where('team.subscription.stripe_trial_already_ended', false)->where('ip', '!=', '1.2.3.4'); - $own = Team::find(0)->servers; - $servers = $servers->merge($own); - $containerServers = $servers->where('settings.is_swarm_worker', false)->where('settings.is_build_server', false); - } else { - $servers = $this->all_servers->where('ip', '!=', '1.2.3.4'); - $containerServers = $servers->where('settings.is_swarm_worker', false)->where('settings.is_build_server', false); - } - foreach ($containerServers as $server) { - $schedule->job(new ContainerStatusJob($server))->everyMinute()->onOneServer(); - if ($server->isLogDrainEnabled()) { - $schedule->job(new CheckLogDrainContainerJob($server))->everyMinute()->onOneServer(); - } - } - foreach ($servers as $server) { - $schedule->job(new ServerStatusJob($server))->everyMinute()->onOneServer(); - $schedule->job(new DockerCleanupJob($server))->everyTenMinutes()->onOneServer(); - } - } - private function check_scheduled_backups($schedule) { $scheduled_backups = ScheduledDatabaseBackup::all(); @@ -214,4 +170,4 @@ class Kernel extends ConsoleKernel require base_path('routes/console.php'); } -} \ No newline at end of file +} diff --git a/app/Livewire/Settings/Configuration.php b/app/Livewire/Settings/Configuration.php deleted file mode 100644 index 60cd46907..000000000 --- a/app/Livewire/Settings/Configuration.php +++ /dev/null @@ -1,177 +0,0 @@ - 'nullable', - 'settings.resale_license' => 'nullable', - 'settings.public_port_min' => 'required', - 'settings.public_port_max' => 'required', - 'settings.custom_dns_servers' => 'nullable', - 'settings.instance_name' => 'nullable', - 'settings.allowed_ips' => 'nullable', - 'settings.is_auto_update_enabled' => 'boolean', - 'auto_update_frequency' => 'nullable|string', - 'update_check_frequency' => 'nullable|string', - ]; - - protected $validationAttributes = [ - 'settings.fqdn' => 'FQDN', - 'settings.resale_license' => 'Resale License', - 'settings.public_port_min' => 'Public port min', - 'settings.public_port_max' => 'Public port max', - 'settings.custom_dns_servers' => 'Custom DNS servers', - 'settings.allowed_ips' => 'Allowed IPs', - 'settings.is_auto_update_enabled' => 'Auto Update Enabled', - 'auto_update_frequency' => 'Auto Update Frequency', - 'update_check_frequency' => 'Update Check Frequency', - ]; - - public function mount() - { - $this->do_not_track = $this->settings->do_not_track; - $this->is_auto_update_enabled = $this->settings->is_auto_update_enabled; - $this->is_registration_enabled = $this->settings->is_registration_enabled; - $this->is_dns_validation_enabled = $this->settings->is_dns_validation_enabled; - $this->is_api_enabled = $this->settings->is_api_enabled; - $this->auto_update_frequency = $this->settings->auto_update_frequency; - $this->update_check_frequency = $this->settings->update_check_frequency; - } - - public function instantSave() - { - $this->settings->do_not_track = $this->do_not_track; - $this->settings->is_auto_update_enabled = $this->is_auto_update_enabled; - $this->settings->is_registration_enabled = $this->is_registration_enabled; - $this->settings->is_dns_validation_enabled = $this->is_dns_validation_enabled; - $this->settings->is_api_enabled = $this->is_api_enabled; - $this->settings->auto_update_frequency = $this->auto_update_frequency; - $this->settings->update_check_frequency = $this->update_check_frequency; - $this->settings->save(); - $this->dispatch('success', 'Settings updated!'); - } - - public function submit() - { - try { - $error_show = false; - $this->server = Server::findOrFail(0); - $this->resetErrorBag(); - if ($this->settings->public_port_min > $this->settings->public_port_max) { - $this->addError('settings.public_port_min', 'The minimum port must be lower than the maximum port.'); - - return; - } - $this->validate(); - - if ($this->is_auto_update_enabled && !$this->validateCronExpression($this->auto_update_frequency)) { - $this->dispatch('error', 'Invalid Cron / Human expression for Auto Update Frequency.'); - return; - } - - if (!$this->validateCronExpression($this->update_check_frequency)) { - $this->dispatch('error', 'Invalid Cron / Human expression for Update Check Frequency.'); - return; - } - - if ($this->settings->is_dns_validation_enabled && $this->settings->fqdn) { - if (! validate_dns_entry($this->settings->fqdn, $this->server)) { - $this->dispatch('error', "Validating DNS failed.

Make sure you have added the DNS records correctly.

{$this->settings->fqdn}->{$this->server->ip}

Check this documentation for further help."); - $error_show = true; - } - } - if ($this->settings->fqdn) { - check_domain_usage(domain: $this->settings->fqdn); - } - $this->settings->custom_dns_servers = str($this->settings->custom_dns_servers)->replaceEnd(',', '')->trim(); - $this->settings->custom_dns_servers = str($this->settings->custom_dns_servers)->trim()->explode(',')->map(function ($dns) { - return str($dns)->trim()->lower(); - }); - $this->settings->custom_dns_servers = $this->settings->custom_dns_servers->unique(); - $this->settings->custom_dns_servers = $this->settings->custom_dns_servers->implode(','); - - $this->settings->allowed_ips = str($this->settings->allowed_ips)->replaceEnd(',', '')->trim(); - $this->settings->allowed_ips = str($this->settings->allowed_ips)->trim()->explode(',')->map(function ($ip) { - return str($ip)->trim(); - }); - $this->settings->allowed_ips = $this->settings->allowed_ips->unique(); - $this->settings->allowed_ips = $this->settings->allowed_ips->implode(','); - - $this->settings->do_not_track = $this->do_not_track; - $this->settings->is_auto_update_enabled = $this->is_auto_update_enabled; - $this->settings->is_registration_enabled = $this->is_registration_enabled; - $this->settings->is_dns_validation_enabled = $this->is_dns_validation_enabled; - $this->settings->is_api_enabled = $this->is_api_enabled; - $this->settings->auto_update_frequency = $this->auto_update_frequency; - $this->settings->update_check_frequency = $this->update_check_frequency; - $this->settings->save(); - $this->server->setupDynamicProxyConfiguration(); - if (! $error_show) { - $this->dispatch('success', 'Instance settings updated successfully!'); - } - } catch (\Exception $e) { - return handleError($e, $this); - } - } - - private function validateCronExpression($expression): bool - { - if (empty($expression)) { - return true; - } - $isValid = false; - try { - $cronExpression = new CronExpression($expression); - $isValid = $cronExpression->getNextRunDate() !== false; - } catch (\Exception $e) { - $isValid = false; - } - - if (isset(VALID_CRON_STRINGS[$expression])) { - $isValid = true; - } - - return $isValid; - } - - public function updatedAutoUpdateFrequency() - { - if (!$this->validateCronExpression($this->auto_update_frequency)) { - $this->dispatch('error', 'Invalid Cron / Human expression for Auto Update Frequency.'); - } - } - - public function updatedUpdateCheckFrequency() - { - if (!$this->validateCronExpression($this->update_check_frequency)) { - $this->dispatch('error', 'Invalid Cron / Human expression for Update Check Frequency.'); - } - } -} \ No newline at end of file diff --git a/app/Livewire/Settings/Index.php b/app/Livewire/Settings/Index.php index e71d2de00..18132c670 100644 --- a/app/Livewire/Settings/Index.php +++ b/app/Livewire/Settings/Index.php @@ -3,38 +3,185 @@ namespace App\Livewire\Settings; use App\Models\InstanceSettings; -use App\Models\S3Storage; -use App\Models\StandalonePostgresql; +use App\Models\Server; +use Cron\CronExpression; use Livewire\Component; class Index extends Component { public InstanceSettings $settings; - public StandalonePostgresql $database; + public bool $do_not_track; - public $s3s; + public bool $is_auto_update_enabled; + + public bool $is_registration_enabled; + + public bool $is_dns_validation_enabled; + + public bool $is_api_enabled; + + public string $auto_update_frequency; + + public string $update_check_frequency; + + protected string $dynamic_config_path = '/data/coolify/proxy/dynamic'; + + protected Server $server; + + protected $rules = [ + 'settings.fqdn' => 'nullable', + 'settings.resale_license' => 'nullable', + 'settings.public_port_min' => 'required', + 'settings.public_port_max' => 'required', + 'settings.custom_dns_servers' => 'nullable', + 'settings.instance_name' => 'nullable', + 'settings.allowed_ips' => 'nullable', + 'settings.is_auto_update_enabled' => 'boolean', + 'auto_update_frequency' => 'nullable|string', + 'update_check_frequency' => 'nullable|string', + ]; + + protected $validationAttributes = [ + 'settings.fqdn' => 'FQDN', + 'settings.resale_license' => 'Resale License', + 'settings.public_port_min' => 'Public port min', + 'settings.public_port_max' => 'Public port max', + 'settings.custom_dns_servers' => 'Custom DNS servers', + 'settings.allowed_ips' => 'Allowed IPs', + 'settings.is_auto_update_enabled' => 'Auto Update Enabled', + 'auto_update_frequency' => 'Auto Update Frequency', + 'update_check_frequency' => 'Update Check Frequency', + ]; public function mount() { if (isInstanceAdmin()) { - $settings = \App\Models\InstanceSettings::get(); - $database = StandalonePostgresql::whereName('coolify-db')->first(); - $s3s = S3Storage::whereTeamId(0)->get() ?? []; - if ($database) { - if ($database->status !== 'running') { - $database->status = 'running'; - $database->save(); - } - $this->database = $database; - } - $this->settings = $settings; - $this->s3s = $s3s; + $this->settings = InstanceSettings::get(); + $this->do_not_track = $this->settings->do_not_track; + $this->is_auto_update_enabled = $this->settings->is_auto_update_enabled; + $this->is_registration_enabled = $this->settings->is_registration_enabled; + $this->is_dns_validation_enabled = $this->settings->is_dns_validation_enabled; + $this->is_api_enabled = $this->settings->is_api_enabled; + $this->auto_update_frequency = $this->settings->auto_update_frequency; + $this->update_check_frequency = $this->settings->update_check_frequency; } else { return redirect()->route('dashboard'); } } + public function instantSave() + { + $this->settings->do_not_track = $this->do_not_track; + $this->settings->is_auto_update_enabled = $this->is_auto_update_enabled; + $this->settings->is_registration_enabled = $this->is_registration_enabled; + $this->settings->is_dns_validation_enabled = $this->is_dns_validation_enabled; + $this->settings->is_api_enabled = $this->is_api_enabled; + $this->settings->auto_update_frequency = $this->auto_update_frequency; + $this->settings->update_check_frequency = $this->update_check_frequency; + $this->settings->save(); + $this->dispatch('success', 'Settings updated!'); + } + + public function submit() + { + try { + $error_show = false; + $this->server = Server::findOrFail(0); + $this->resetErrorBag(); + if ($this->settings->public_port_min > $this->settings->public_port_max) { + $this->addError('settings.public_port_min', 'The minimum port must be lower than the maximum port.'); + + return; + } + $this->validate(); + + if ($this->is_auto_update_enabled && ! $this->validateCronExpression($this->auto_update_frequency)) { + $this->dispatch('error', 'Invalid Cron / Human expression for Auto Update Frequency.'); + + return; + } + + if (! $this->validateCronExpression($this->update_check_frequency)) { + $this->dispatch('error', 'Invalid Cron / Human expression for Update Check Frequency.'); + + return; + } + + if ($this->settings->is_dns_validation_enabled && $this->settings->fqdn) { + if (! validate_dns_entry($this->settings->fqdn, $this->server)) { + $this->dispatch('error', "Validating DNS failed.

Make sure you have added the DNS records correctly.

{$this->settings->fqdn}->{$this->server->ip}

Check this documentation for further help."); + $error_show = true; + } + } + if ($this->settings->fqdn) { + check_domain_usage(domain: $this->settings->fqdn); + } + $this->settings->custom_dns_servers = str($this->settings->custom_dns_servers)->replaceEnd(',', '')->trim(); + $this->settings->custom_dns_servers = str($this->settings->custom_dns_servers)->trim()->explode(',')->map(function ($dns) { + return str($dns)->trim()->lower(); + }); + $this->settings->custom_dns_servers = $this->settings->custom_dns_servers->unique(); + $this->settings->custom_dns_servers = $this->settings->custom_dns_servers->implode(','); + + $this->settings->allowed_ips = str($this->settings->allowed_ips)->replaceEnd(',', '')->trim(); + $this->settings->allowed_ips = str($this->settings->allowed_ips)->trim()->explode(',')->map(function ($ip) { + return str($ip)->trim(); + }); + $this->settings->allowed_ips = $this->settings->allowed_ips->unique(); + $this->settings->allowed_ips = $this->settings->allowed_ips->implode(','); + + $this->settings->do_not_track = $this->do_not_track; + $this->settings->is_auto_update_enabled = $this->is_auto_update_enabled; + $this->settings->is_registration_enabled = $this->is_registration_enabled; + $this->settings->is_dns_validation_enabled = $this->is_dns_validation_enabled; + $this->settings->is_api_enabled = $this->is_api_enabled; + $this->settings->auto_update_frequency = $this->auto_update_frequency; + $this->settings->update_check_frequency = $this->update_check_frequency; + $this->settings->save(); + $this->server->setupDynamicProxyConfiguration(); + if (! $error_show) { + $this->dispatch('success', 'Instance settings updated successfully!'); + } + } catch (\Exception $e) { + return handleError($e, $this); + } + } + + private function validateCronExpression($expression): bool + { + if (empty($expression)) { + return true; + } + $isValid = false; + try { + $cronExpression = new CronExpression($expression); + $isValid = $cronExpression->getNextRunDate() !== false; + } catch (\Exception $e) { + $isValid = false; + } + + if (isset(VALID_CRON_STRINGS[$expression])) { + $isValid = true; + } + + return $isValid; + } + + public function updatedAutoUpdateFrequency() + { + if (! $this->validateCronExpression($this->auto_update_frequency)) { + $this->dispatch('error', 'Invalid Cron / Human expression for Auto Update Frequency.'); + } + } + + public function updatedUpdateCheckFrequency() + { + if (! $this->validateCronExpression($this->update_check_frequency)) { + $this->dispatch('error', 'Invalid Cron / Human expression for Update Check Frequency.'); + } + } + public function render() { return view('livewire.settings.index'); diff --git a/app/Livewire/Settings/Backup.php b/app/Livewire/SettingsBackup.php similarity index 77% rename from app/Livewire/Settings/Backup.php rename to app/Livewire/SettingsBackup.php index 08ad04b2d..da3aee491 100644 --- a/app/Livewire/Settings/Backup.php +++ b/app/Livewire/SettingsBackup.php @@ -1,6 +1,6 @@ backup = $this->database?->scheduledBackups->first() ?? null; - $this->executions = $this->backup?->executions ?? []; + if (isInstanceAdmin()) { + $settings = InstanceSettings::get(); + $database = StandalonePostgresql::whereName('coolify-db')->first(); + $s3s = S3Storage::whereTeamId(0)->get() ?? []; + if ($database) { + if ($database->status !== 'running') { + $database->status = 'running'; + $database->save(); + } + $this->database = $database; + } + $this->settings = $settings; + $this->s3s = $s3s; + $this->backup = $this->database?->scheduledBackups?->first() ?? null; + $this->executions = $this->backup?->executions ?? []; + } else { + return redirect()->route('dashboard'); + } } public function add_coolify_database() diff --git a/app/Livewire/Settings/Email.php b/app/Livewire/SettingsEmail.php similarity index 93% rename from app/Livewire/Settings/Email.php rename to app/Livewire/SettingsEmail.php index bd7f8201e..3eb8ea646 100644 --- a/app/Livewire/Settings/Email.php +++ b/app/Livewire/SettingsEmail.php @@ -1,12 +1,12 @@ emails = auth()->user()->email; + if (isInstanceAdmin()) { + $this->settings = InstanceSettings::get(); + $this->emails = auth()->user()->email; + } else { + return redirect()->route('dashboard'); + } + } public function submitFromFields() diff --git a/app/Livewire/Settings/Auth.php b/app/Livewire/SettingsOauth.php similarity index 95% rename from app/Livewire/Settings/Auth.php rename to app/Livewire/SettingsOauth.php index 783b163e0..c3884589f 100644 --- a/app/Livewire/Settings/Auth.php +++ b/app/Livewire/SettingsOauth.php @@ -1,11 +1,11 @@ Resale License @endif + + + + + + + + +
diff --git a/resources/views/livewire/settings/backup.blade.php b/resources/views/livewire/settings-backup.blade.php similarity index 90% rename from resources/views/livewire/settings/backup.blade.php rename to resources/views/livewire/settings-backup.blade.php index d517b9516..bf29481cc 100644 --- a/resources/views/livewire/settings/backup.blade.php +++ b/resources/views/livewire/settings-backup.blade.php @@ -1,4 +1,8 @@
+ + Settings | Coolify + +

Backup

@@ -8,7 +12,7 @@ @endif
-
Backup your Coolify instance settings
+
Backup configuration for Coolify instance.
@if (isset($database))
diff --git a/resources/views/livewire/settings/email.blade.php b/resources/views/livewire/settings-email.blade.php similarity index 97% rename from resources/views/livewire/settings/email.blade.php rename to resources/views/livewire/settings-email.blade.php index 106dd77d4..37d395cd8 100644 --- a/resources/views/livewire/settings/email.blade.php +++ b/resources/views/livewire/settings-email.blade.php @@ -1,4 +1,8 @@
+ + Settings | Coolify + +

Transactional Email

diff --git a/resources/views/livewire/settings/auth.blade.php b/resources/views/livewire/settings-oauth.blade.php similarity index 61% rename from resources/views/livewire/settings/auth.blade.php rename to resources/views/livewire/settings-oauth.blade.php index 46aa40fa5..9a94d3c2b 100644 --- a/resources/views/livewire/settings/auth.blade.php +++ b/resources/views/livewire/settings-oauth.blade.php @@ -1,4 +1,8 @@
+ + Settings | Coolify + +
@@ -7,20 +11,26 @@ Save
+
Custom authentication (OAuth) configurations.
@foreach ($oauth_settings_map as $oauth_setting)
-

{{ucfirst($oauth_setting->provider)}} Oauth

+

{{ ucfirst($oauth_setting->provider) }} Oauth

- +
- - - + + + @if ($oauth_setting->provider == 'azure') - + @endif
diff --git a/resources/views/livewire/settings/configuration.blade.php b/resources/views/livewire/settings/configuration.blade.php deleted file mode 100644 index 8a6a6e572..000000000 --- a/resources/views/livewire/settings/configuration.blade.php +++ /dev/null @@ -1,55 +0,0 @@ -
- -
-

Configuration

- - Save - -
-
General configuration for your Coolify instance.
- -
-
-

Instance Settings

- - -

DNS Validation

-
- -
- -
- - {{--
- - -
--}} - -
-

API

-
- -
- - - -

Advanced

-
- @if (!is_null(env('AUTOUPDATE', null))) - - @else - - @if($is_auto_update_enabled) - - @endif - - @endif - - -
-
diff --git a/resources/views/livewire/settings/index.blade.php b/resources/views/livewire/settings/index.blade.php index 327b8e4cc..df0d09963 100644 --- a/resources/views/livewire/settings/index.blade.php +++ b/resources/views/livewire/settings/index.blade.php @@ -3,32 +3,70 @@ Settings | Coolify -
-
- General - Instance Backup - Transactional - Email - Authentication - (OAuth) +
+
+

Configuration

+ + Save +
-
-
- -
-
- -
-
- -
-
- +
General configuration for your Coolify instance.
+ +
+
+

Instance Settings

+ + +

DNS Validation

+
+ +
+
+ + {{--
+ + +
--}} +
+

API

+
+ +
+ + + +

Advanced

+ + +
Auto Update
+ @if (!is_null(env('AUTOUPDATE', null))) +
+ +
+ @else +
+ +
+
+ @if ($is_auto_update_enabled) + + @endif + +
+ @endif +
Others
+
+ +
+
diff --git a/routes/web.php b/routes/web.php index 7f41bb63d..e2ccfc704 100644 --- a/routes/web.php +++ b/routes/web.php @@ -45,6 +45,9 @@ use App\Livewire\Server\Resources as ResourcesShow; use App\Livewire\Server\Show as ServerShow; use App\Livewire\Settings\Index as SettingsIndex; use App\Livewire\Settings\License as SettingsLicense; +use App\Livewire\SettingsBackup; +use App\Livewire\SettingsEmail; +use App\Livewire\SettingsOauth; use App\Livewire\SharedVariables\Environment\Index as EnvironmentSharedVariablesIndex; use App\Livewire\SharedVariables\Environment\Show as EnvironmentSharedVariablesShow; use App\Livewire\SharedVariables\Index as SharedVariablesIndex; @@ -113,6 +116,9 @@ Route::middleware(['auth', 'verified'])->group(function () { Route::get('/subscription/new', SubscriptionIndex::class)->name('subscription.index'); Route::get('/settings', SettingsIndex::class)->name('settings.index'); + Route::get('/settings/backup', SettingsBackup::class)->name('settings.backup'); + Route::get('/settings/email', SettingsEmail::class)->name('settings.email'); + Route::get('/settings/oauth', SettingsOauth::class)->name('settings.oauth'); Route::get('/settings/license', SettingsLicense::class)->name('settings.license'); Route::get('/profile', ProfileIndex::class)->name('profile');