fix: settings view

feat: add separate views for settings
This commit is contained in:
Andras Bacsai
2024-08-06 14:36:56 +02:00
parent c4436aadfa
commit b77171d2f2
13 changed files with 301 additions and 334 deletions

View File

@@ -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();

View File

@@ -1,177 +0,0 @@
<?php
namespace App\Livewire\Settings;
use App\Models\InstanceSettings as ModelsInstanceSettings;
use App\Models\Server;
use Livewire\Component;
use Cron\CronExpression;
class Configuration extends Component
{
public ModelsInstanceSettings $settings;
public bool $do_not_track;
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()
{
$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.<br><br>Make sure you have added the DNS records correctly.<br><br>{$this->settings->fqdn}->{$this->server->ip}<br><br>Check this <a target='_blank' class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/dns-configuration'>documentation</a> 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.');
}
}
}

View File

@@ -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.<br><br>Make sure you have added the DNS records correctly.<br><br>{$this->settings->fqdn}->{$this->server->ip}<br><br>Check this <a target='_blank' class='underline dark:text-white' href='https://coolify.io/docs/knowledge-base/dns-configuration'>documentation</a> 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');

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Livewire\Settings;
namespace App\Livewire;
use App\Jobs\DatabaseBackupJob;
use App\Models\InstanceSettings;
@@ -10,7 +10,7 @@ use App\Models\Server;
use App\Models\StandalonePostgresql;
use Livewire\Component;
class Backup extends Component
class SettingsBackup extends Component
{
public InstanceSettings $settings;
@@ -41,8 +41,24 @@ class Backup extends Component
public function mount()
{
$this->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()

View File

@@ -1,12 +1,12 @@
<?php
namespace App\Livewire\Settings;
namespace App\Livewire;
use App\Models\InstanceSettings;
use App\Notifications\TransactionalEmails\Test;
use Livewire\Component;
class Email extends Component
class SettingsEmail extends Component
{
public InstanceSettings $settings;
@@ -42,7 +42,13 @@ class Email extends Component
public function mount()
{
$this->emails = auth()->user()->email;
if (isInstanceAdmin()) {
$this->settings = InstanceSettings::get();
$this->emails = auth()->user()->email;
} else {
return redirect()->route('dashboard');
}
}
public function submitFromFields()

View File

@@ -1,11 +1,11 @@
<?php
namespace App\Livewire\Settings;
namespace App\Livewire;
use App\Models\OauthSetting;
use Livewire\Component;
class Auth extends Component
class SettingsOauth extends Component
{
public $oauth_settings_map;

View File

@@ -13,6 +13,18 @@
<button>Resale License</button>
</a>
@endif
<a class="{{ request()->routeIs('settings.backup') ? 'dark:text-white' : '' }}"
href="{{ route('settings.backup') }}">
<button>Backup</button>
</a>
<a class="{{ request()->routeIs('settings.email') ? 'dark:text-white' : '' }}"
href="{{ route('settings.email') }}">
<button>Transactional Email</button>
</a>
<a class="{{ request()->routeIs('settings.oauth') ? 'dark:text-white' : '' }}"
href="{{ route('settings.oauth') }}">
<button>OAuth</button>
</a>
<div class="flex-1"></div>
</nav>
</div>

View File

@@ -1,4 +1,8 @@
<div>
<x-slot:title>
Settings | Coolify
</x-slot>
<x-settings.navbar />
<div class="flex flex-col">
<div class="flex items-center gap-2">
<h2>Backup</h2>
@@ -8,7 +12,7 @@
</x-forms.button>
@endif
</div>
<div class="pb-4">Backup your Coolify instance settings</div>
<div class="pb-4">Backup configuration for Coolify instance.</div>
<div>
@if (isset($database))
<div class="flex flex-col gap-3 pb-4">

View File

@@ -1,4 +1,8 @@
<div>
<x-slot:title>
Settings | Coolify
</x-slot>
<x-settings.navbar />
<div class="flex items-center gap-2">
<h2>Transactional Email</h2>
</div>

View File

@@ -1,4 +1,8 @@
<div>
<x-slot:title>
Settings | Coolify
</x-slot>
<x-settings.navbar />
<form wire:submit='submit' class="flex flex-col">
<div class="flex flex-col">
<div class="flex items-center gap-2">
@@ -7,20 +11,26 @@
Save
</x-forms.button>
</div>
<div class="pb-4 ">Custom authentication (OAuth) configurations.</div>
</div>
<div class="flex flex-col gap-2 pt-4">
@foreach ($oauth_settings_map as $oauth_setting)
<div class="p-4 border dark:border-coolgray-300">
<h3>{{ucfirst($oauth_setting->provider)}} Oauth</h3>
<h3>{{ ucfirst($oauth_setting->provider) }} Oauth</h3>
<div class="w-32">
<x-forms.checkbox instantSave id="oauth_settings_map.{{$oauth_setting->provider}}.enabled" label="Enabled" />
<x-forms.checkbox instantSave id="oauth_settings_map.{{ $oauth_setting->provider }}.enabled"
label="Enabled" />
</div>
<div class="flex flex-col w-full gap-2 xl:flex-row">
<x-forms.input id="oauth_settings_map.{{$oauth_setting->provider}}.client_id" label="Client ID" />
<x-forms.input id="oauth_settings_map.{{$oauth_setting->provider}}.client_secret" type="password" label="Client Secret" />
<x-forms.input id="oauth_settings_map.{{$oauth_setting->provider}}.redirect_uri" label="Redirect URI" />
<x-forms.input id="oauth_settings_map.{{ $oauth_setting->provider }}.client_id"
label="Client ID" />
<x-forms.input id="oauth_settings_map.{{ $oauth_setting->provider }}.client_secret"
type="password" label="Client Secret" />
<x-forms.input id="oauth_settings_map.{{ $oauth_setting->provider }}.redirect_uri"
label="Redirect URI" />
@if ($oauth_setting->provider == 'azure')
<x-forms.input id="oauth_settings_map.{{$oauth_setting->provider}}.tenant" label="Tenant" />
<x-forms.input id="oauth_settings_map.{{ $oauth_setting->provider }}.tenant"
label="Tenant" />
@endif
</div>
</div>

View File

@@ -1,55 +0,0 @@
<div>
<form wire:submit='submit' class="flex flex-col">
<div class="flex items-center gap-2">
<h2>Configuration</h2>
<x-forms.button type="submit">
Save
</x-forms.button>
</div>
<div>General configuration for your Coolify instance.</div>
<div class="flex flex-col gap-2 pt-4">
<div class="flex flex-wrap items-end gap-2">
<h3 class="pt-6">Instance Settings</h3>
<x-forms.input id="settings.fqdn" label="Instance's Domain" placeholder="https://coolify.io" />
<x-forms.input id="settings.instance_name" label="Instance's Name" placeholder="Coolify" />
<h3 class="pt-6 w-full">DNS Validation</h3>
<div class="flex flex-wrap items-end gap-2 md:w-96">
<x-forms.checkbox instantSave id="is_dns_validation_enabled" label="Enable DNS validation" />
</div>
<x-forms.input id="settings.custom_dns_servers" label="DNS Servers"
helper="DNS servers for validation FQDNs againts. A comma separated list of DNS servers."
placeholder="1.1.1.1,8.8.8.8" />
</div>
{{-- <div class="flex gap-2 ">
<x-forms.input type="number" id="settings.public_port_min" label="Public Port Min" />
<x-forms.input type="number" id="settings.public_port_max" label="Public Port Max" />
</div> --}}
</div>
<h3 class="pt-6">API</h3>
<div class="md:w-96">
<x-forms.checkbox instantSave id="is_api_enabled" label="Enabled" />
</div>
<x-forms.input id="settings.allowed_ips" label="Allowed IPs"
helper="Allowed IP lists for the API. A comma separated list of IPs. Empty means you allow from everywhere."
placeholder="1.1.1.1,8.8.8.8" />
</form>
<h2 class="pt-6">Advanced</h2>
<div class="text-right md:w-96">
@if (!is_null(env('AUTOUPDATE', null)))
<x-forms.checkbox instantSave helper="AUTOUPDATE is set in .env file, you need to modify it there." disabled
id="is_auto_update_enabled" label="Auto Update Coolify" />
@else
<x-forms.checkbox instantSave id="is_auto_update_enabled" label="Auto Update Coolify" />
@if($is_auto_update_enabled)
<x-forms.input id="auto_update_frequency" label="Auto Update Frequency" placeholder="0 0 * * *" helper="Cron expression for auto update frequency (automatically update coolify). Default is every day at 00:00" />
@endif
<x-forms.input id="update_check_frequency" label="Update Check Frequency" placeholder="0 */11 * * *" helper="Cron expression for update check frequency (check for new Coolify versions and pull new Service Templates from CDN). Default is every 12 hours at 11:00 and 23:00" />
@endif
<x-forms.checkbox instantSave id="is_registration_enabled" label="Registration Allowed" />
<x-forms.checkbox instantSave id="do_not_track" label="Do Not Track" />
</div>
</div>

View File

@@ -3,32 +3,70 @@
Settings | Coolify
</x-slot>
<x-settings.navbar />
<div x-data="{ activeTab: window.location.hash ? window.location.hash.substring(1) : 'general' }" class="flex flex-col h-full gap-8 pt-1 sm:flex-row">
<div class="flex gap-6 overflow-x-scroll sm:gap-2 sm:overflow-x-hidden scrollbar sm:flex-col whitespace-nowrap">
<a class="menu-item" :class="activeTab === 'general' && 'menu-item-active'"
@click.prevent="activeTab = 'general'; window.location.hash = 'general'" href="#">General</a>
<a class="menu-item" :class="activeTab === 'backup' && 'menu-item-active'"
@click.prevent="activeTab = 'backup'; window.location.hash = 'backup'" href="#">Instance Backup</a>
<a class="menu-item" :class="activeTab === 'smtp' && 'menu-item-active'"
@click.prevent="activeTab = 'smtp'; window.location.hash = 'smtp'" href="#">Transactional
Email</a>
<a class="menu-item" :class="activeTab === 'auth' && 'menu-item-active'"
@click.prevent="activeTab = 'auth'; window.location.hash = 'auth'" href="#">Authentication
(OAuth)</a>
<form wire:submit='submit' class="flex flex-col">
<div class="flex items-center gap-2">
<h2>Configuration</h2>
<x-forms.button type="submit">
Save
</x-forms.button>
</div>
<div class="w-full">
<div x-cloak x-show="activeTab === 'general'" class="h-full">
<livewire:settings.configuration :settings="$settings" />
</div>
<div x-cloak x-show="activeTab === 'backup'" class="h-full">
<livewire:settings.backup :settings="$settings" :database="$database" :s3s="$s3s" />
</div>
<div x-cloak x-show="activeTab === 'smtp'" class="h-full">
<livewire:settings.email :settings="$settings" />
</div>
<div x-cloak x-show="activeTab === 'auth'" class="h-full">
<livewire:settings.auth />
<div>General configuration for your Coolify instance.</div>
<div class="flex flex-col gap-2">
<div class="flex flex-wrap items-end gap-2">
<h4 class="pt-6">Instance Settings</h4>
<x-forms.input id="settings.fqdn" label="Instance's Domain" placeholder="https://coolify.io" />
<x-forms.input id="settings.instance_name" label="Instance's Name" placeholder="Coolify" />
<h4 class="w-full pt-6">DNS Validation</h4>
<div class="flex flex-wrap items-end gap-2 md:w-96">
<x-forms.checkbox instantSave id="is_dns_validation_enabled" label="Enable DNS validation" />
</div>
<x-forms.input id="settings.custom_dns_servers" label="DNS Servers"
helper="DNS servers for validation FQDNs againts. A comma separated list of DNS servers."
placeholder="1.1.1.1,8.8.8.8" />
</div>
{{-- <div class="flex gap-2 ">
<x-forms.input type="number" id="settings.public_port_min" label="Public Port Min" />
<x-forms.input type="number" id="settings.public_port_max" label="Public Port Max" />
</div> --}}
</div>
<h4 class="pt-6">API</h4>
<div class="md:w-96">
<x-forms.checkbox instantSave id="is_api_enabled" label="Enabled" />
</div>
<x-forms.input id="settings.allowed_ips" label="Allowed IPs"
helper="Allowed IP lists for the API. A comma separated list of IPs. Empty means you allow from everywhere."
placeholder="1.1.1.1,8.8.8.8" />
</form>
<h4 class="pt-6">Advanced</h4>
<h5 class="pt-4 font-bold text-white">Auto Update</h5>
@if (!is_null(env('AUTOUPDATE', null)))
<div class="text-right md:w-96">
<x-forms.checkbox instantSave helper="AUTOUPDATE is set in .env file, you need to modify it there." disabled
id="is_auto_update_enabled" label="Enabled" />
</div>
@else
<div class="text-right md:w-96">
<x-forms.checkbox instantSave id="is_auto_update_enabled" label="Enabled" />
</div>
<div class="flex gap-2 ">
@if ($is_auto_update_enabled)
<x-forms.input id="auto_update_frequency" label="Auto Update Frequency" placeholder="0 0 * * *"
helper="Cron expression for auto update frequency (automatically update coolify). Default is every day at 00:00" />
@endif
<x-forms.input id="update_check_frequency" label="Update Check Frequency" placeholder="0 */11 * * *"
helper="Cron expression for update check frequency (check for new Coolify versions and pull new Service Templates from CDN). Default is every 12 hours at 11:00 and 23:00" />
</div>
@endif
<h5 class="pt-4 font-bold text-white">Others</h5>
<div class="text-right md:w-96">
<x-forms.checkbox instantSave id="is_registration_enabled" label="Registration Allowed" />
<x-forms.checkbox instantSave id="do_not_track" label="Do Not Track" />
</div>
</div>
</div>

View File

@@ -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');