diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php
index 17ef4397c..cea419638 100644
--- a/app/Console/Kernel.php
+++ b/app/Console/Kernel.php
@@ -35,6 +35,7 @@ protected function schedule(Schedule $schedule): void
// Instance Jobs
$schedule->command('horizon:snapshot')->everyMinute();
$schedule->job(new CleanupInstanceStuffsJob)->everyMinute()->onOneServer();
+ $schedule->job(new PullCoolifyImageJob)->cron($settings->update_check_frequency)->timezone($settings->instance_timezone)->onOneServer();
// Server Jobs
$this->check_scheduled_backups($schedule);
$this->check_resources($schedule);
@@ -134,6 +135,7 @@ private function check_scheduled_backups($schedule)
if (is_null(data_get($scheduled_backup, 'database'))) {
ray('database not found');
$scheduled_backup->delete();
+
continue;
}
@@ -165,6 +167,7 @@ private function check_scheduled_tasks($schedule)
if (! $application && ! $service) {
ray('application/service attached to scheduled task does not exist');
$scheduled_task->delete();
+
continue;
}
if ($application) {
@@ -192,8 +195,8 @@ private function check_scheduled_tasks($schedule)
protected function commands(): void
{
- $this->load(__DIR__ . '/Commands');
+ $this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
-}
\ No newline at end of file
+}
diff --git a/app/Livewire/Server/Form.php b/app/Livewire/Server/Form.php
index 106d3d761..8a4efb21d 100644
--- a/app/Livewire/Server/Form.php
+++ b/app/Livewire/Server/Form.php
@@ -5,8 +5,7 @@
use App\Actions\Server\StartSentinel;
use App\Actions\Server\StopSentinel;
use App\Jobs\PullSentinelImageJob;
-use App\Models\Server;;
-
+use App\Models\Server;
use Livewire\Component;
class Form extends Component
@@ -23,6 +22,8 @@ class Form extends Component
public bool $revalidate = false;
+ public $timezones;
+
protected $listeners = ['serverInstalled', 'revalidate' => '$refresh'];
protected $rules = [
@@ -71,8 +72,6 @@ class Form extends Component
'server.settings.server_timezone' => 'Server Timezone',
];
- public $timezones;
-
public function mount(Server $server)
{
$this->server = $server;
@@ -174,7 +173,7 @@ public function checkLocalhostConnection()
$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);
+ $this->dispatch('error', 'Server is not reachable.', 'Please validate your configuration and connection.
Check this documentation for further help.
Error: '.$error);
return;
}
@@ -214,22 +213,12 @@ public function submit()
} else {
$this->server->settings->docker_cleanup_threshold = $this->server->settings->docker_cleanup_threshold;
}
- $currentTimezone = $this->server->settings->getOriginal('server_timezone');
- $newTimezone = $this->server->settings->server_timezone;
- if ($currentTimezone !== $newTimezone || $currentTimezone === '') {
- try {
- $timezoneUpdated = $this->updateServerTimezone($newTimezone);
- if ($timezoneUpdated) {
- $this->server->settings->server_timezone = $newTimezone;
- $this->server->settings->save();
- } else {
- return;
- }
- } catch (\Exception $e) {
- $this->dispatch('error', 'Failed to update server timezone: ' . $e->getMessage());
- return;
+ $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->settings->save();
$this->server->save();
@@ -239,89 +228,10 @@ public function submit()
}
}
- public function updatedServerTimezone($value)
+ public function updatedServerSettingsServerTimezone($value)
{
- if (!is_string($value) || !in_array($value, timezone_identifiers_list())) {
- $this->addError('server.settings.server_timezone', 'Invalid timezone.');
- return;
- }
$this->server->settings->server_timezone = $value;
- $this->updateServerTimezone($value);
- }
-
- private function updateServerTimezone($desired_timezone)
- {
- try {
- $commands = [
- "if command -v timedatectl > /dev/null 2>&1 && pidof systemd > /dev/null; then",
- " timedatectl set-timezone " . escapeshellarg($desired_timezone),
- "elif [ -f /etc/timezone ]; then",
- " echo " . escapeshellarg($desired_timezone) . " > /etc/timezone",
- " rm -f /etc/localtime",
- " ln -sf /usr/share/zoneinfo/" . escapeshellarg($desired_timezone) . " /etc/localtime",
- "elif [ -f /etc/localtime ]; then",
- " rm -f /etc/localtime",
- " ln -sf /usr/share/zoneinfo/" . escapeshellarg($desired_timezone) . " /etc/localtime",
- "else",
- " echo 'Unable to set timezone'",
- " exit 1",
- "fi",
- "if command -v dpkg-reconfigure > /dev/null 2>&1; then",
- " dpkg-reconfigure -f noninteractive tzdata",
- "elif command -v tzdata-update > /dev/null 2>&1; then",
- " tzdata-update",
- "elif [ -f /etc/sysconfig/clock ]; then",
- " sed -i 's/^ZONE=.*/ZONE=\"" . $desired_timezone . "\"/' /etc/sysconfig/clock",
- " source /etc/sysconfig/clock",
- "fi",
- "if command -v systemctl > /dev/null 2>&1 && pidof systemd > /dev/null; then",
- " systemctl try-restart systemd-timesyncd.service || true",
- "elif command -v service > /dev/null 2>&1; then",
- " service ntpd restart || service ntp restart || true",
- "fi",
- "echo \"Timezone updated to: $desired_timezone\"",
- "date"
- ];
-
- instant_remote_process($commands, $this->server);
-
- $verificationCommands = [
- "readlink /etc/localtime | sed 's#/usr/share/zoneinfo/##'",
- "date +'%Z %:z'"
- ];
- $verificationResult = instant_remote_process($verificationCommands, $this->server, false);
- $verificationLines = explode("\n", trim($verificationResult));
-
- if (count($verificationLines) !== 2) {
- $this->dispatch('error', 'Failed to verify timezone update. Unexpected server response.');
- return false;
- }
-
- $actualTimezone = trim($verificationLines[0]);
- [$abbreviation, $offset] = explode(' ', trim($verificationLines[1]));
-
- $desiredTz = new \DateTimeZone($desired_timezone);
- $desiredAbbr = (new \DateTime('now', $desiredTz))->format('T');
- $desiredOffset = $this->formatOffset($desiredTz->getOffset(new \DateTime('now', $desiredTz)));
-
- if ($actualTimezone === $desired_timezone && $abbreviation === $desiredAbbr && $offset === $desiredOffset) {
- $this->server->settings->server_timezone = $desired_timezone;
- $this->server->settings->save();
- return true;
- } else {
- $this->dispatch('error', 'Failed to update server timezone. The server reported a different timezone than requested.');
- return false;
- }
- } catch (\Exception $e) {
- $this->dispatch('error', 'Failed to update server timezone: ' . $e->getMessage());
- return false;
- }
- }
-
- private function formatOffset($offsetSeconds)
- {
- $hours = abs($offsetSeconds) / 3600;
- $minutes = (abs($offsetSeconds) % 3600) / 60;
- return sprintf('%s%02d:%02d', $offsetSeconds >= 0 ? '+' : '-', $hours, $minutes);
+ $this->server->settings->save();
+ $this->dispatch('success', 'Server timezone updated.');
}
}
diff --git a/app/Livewire/Settings/Index.php b/app/Livewire/Settings/Index.php
index eff09f0e5..c52970258 100644
--- a/app/Livewire/Settings/Index.php
+++ b/app/Livewire/Settings/Index.php
@@ -170,8 +170,15 @@ public function checkManually()
}
}
+ public function updatedSettingsInstanceTimezone($value)
+ {
+ $this->settings->instance_timezone = $value;
+ $this->settings->save();
+ $this->dispatch('success', 'Instance timezone updated.');
+ }
+
public function render()
{
return view('livewire.settings.index');
}
-}
\ No newline at end of file
+}
diff --git a/app/Models/InstanceSettings.php b/app/Models/InstanceSettings.php
index 5bd421956..27a181ee4 100644
--- a/app/Models/InstanceSettings.php
+++ b/app/Models/InstanceSettings.php
@@ -37,6 +37,30 @@ public function fqdn(): Attribute
);
}
+ public function updateCheckFrequency(): Attribute
+ {
+ return Attribute::make(
+ set: function ($value) {
+ return translate_cron_expression($value);
+ },
+ get: function ($value) {
+ return translate_cron_expression($value);
+ }
+ );
+ }
+
+ public function autoUpdateFrequency(): Attribute
+ {
+ return Attribute::make(
+ set: function ($value) {
+ return translate_cron_expression($value);
+ },
+ get: function ($value) {
+ return translate_cron_expression($value);
+ }
+ );
+ }
+
public static function get()
{
return InstanceSettings::findOrFail(0);
diff --git a/app/Models/ServerSetting.php b/app/Models/ServerSetting.php
index 6ef7f46ee..8f57d1e92 100644
--- a/app/Models/ServerSetting.php
+++ b/app/Models/ServerSetting.php
@@ -2,6 +2,7 @@
namespace App\Models;
+use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
use OpenApi\Attributes as OA;
@@ -58,4 +59,18 @@ public function server()
{
return $this->belongsTo(Server::class);
}
-}
\ No newline at end of file
+
+ public function dockerCleanupFrequency(): Attribute
+ {
+ return Attribute::make(
+ set: function ($value) {
+ ray($value);
+
+ return translate_cron_expression($value);
+ },
+ get: function ($value) {
+ return translate_cron_expression($value);
+ }
+ );
+ }
+}
diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php
index 47a02bb90..1ed92aff9 100644
--- a/bootstrap/helpers/shared.php
+++ b/bootstrap/helpers/shared.php
@@ -353,6 +353,14 @@ function isCloud(): bool
return ! config('coolify.self_hosted');
}
+function translate_cron_expression($expression_to_validate): string
+{
+ if (isset(VALID_CRON_STRINGS[$expression_to_validate])) {
+ return VALID_CRON_STRINGS[$expression_to_validate];
+ }
+
+ return $expression_to_validate;
+}
function validate_cron_expression($expression_to_validate): bool
{
$isValid = false;
diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php
index 736646ec6..b3fac350f 100644
--- a/database/seeders/DatabaseSeeder.php
+++ b/database/seeders/DatabaseSeeder.php
@@ -33,7 +33,6 @@ public function run(): void
ScheduledDatabaseBackupSeeder::class,
ScheduledDatabaseBackupExecutionSeeder::class,
OauthSettingSeeder::class,
- ServerTimezoneSeeder::class,
]);
}
}
diff --git a/database/seeders/ProductionSeeder.php b/database/seeders/ProductionSeeder.php
index a3bdab536..799dd0440 100644
--- a/database/seeders/ProductionSeeder.php
+++ b/database/seeders/ProductionSeeder.php
@@ -182,7 +182,5 @@ public function run(): void
$oauth_settings_seeder = new OauthSettingSeeder;
$oauth_settings_seeder->run();
- $server_timezone_seeder = new ServerTimezoneSeeder;
- $server_timezone_seeder->run();
}
}
diff --git a/database/seeders/ServerTimezoneSeeder.php b/database/seeders/ServerTimezoneSeeder.php
deleted file mode 100644
index 9dd6636f9..000000000
--- a/database/seeders/ServerTimezoneSeeder.php
+++ /dev/null
@@ -1,58 +0,0 @@
-whereNull('server_timezone')->orWhere('server_timezone', '');
- })->each(function ($server) use ($defaultTimezone) {
- DB::transaction(function () use ($server, $defaultTimezone) {
- $this->updateServerTimezone($server, $defaultTimezone);
- });
- });
- }
-
- private function updateServerTimezone($server, $desired_timezone)
- {
- $commands = [
- "if command -v timedatectl > /dev/null 2>&1 && pidof systemd > /dev/null; then",
- " timedatectl set-timezone " . escapeshellarg($desired_timezone),
- "elif [ -f /etc/timezone ]; then",
- " echo " . escapeshellarg($desired_timezone) . " > /etc/timezone",
- " rm -f /etc/localtime",
- " ln -sf /usr/share/zoneinfo/" . escapeshellarg($desired_timezone) . " /etc/localtime",
- "elif [ -f /etc/localtime ]; then",
- " rm -f /etc/localtime",
- " ln -sf /usr/share/zoneinfo/" . escapeshellarg($desired_timezone) . " /etc/localtime",
- "fi",
- "if command -v dpkg-reconfigure > /dev/null 2>&1; then",
- " dpkg-reconfigure -f noninteractive tzdata",
- "elif command -v tzdata-update > /dev/null 2>&1; then",
- " tzdata-update",
- "elif [ -f /etc/sysconfig/clock ]; then",
- " sed -i 's/^ZONE=.*/ZONE=\"" . $desired_timezone . "\"/' /etc/sysconfig/clock",
- " source /etc/sysconfig/clock",
- "fi",
- "if command -v systemctl > /dev/null 2>&1 && pidof systemd > /dev/null; then",
- " systemctl try-restart systemd-timesyncd.service || true",
- "elif command -v service > /dev/null 2>&1; then",
- " service ntpd restart || service ntp restart || true",
- "fi"
- ];
-
- instant_remote_process($commands, $server);
-
- $server->settings->server_timezone = $desired_timezone;
- $server->settings->save();
- }
-}
diff --git a/resources/views/livewire/project/database/backup-executions.blade.php b/resources/views/livewire/project/database/backup-executions.blade.php
index b1cc7fa66..6d177505c 100644
--- a/resources/views/livewire/project/database/backup-executions.blade.php
+++ b/resources/views/livewire/project/database/backup-executions.blade.php
@@ -1,66 +1,66 @@
{{ data_get($execution, 'message') }}-
{{ data_get($execution, 'message') }}+