Merge branch 'next' into feat-db-ssl
This commit is contained in:
@@ -6,14 +6,12 @@ use App\Jobs\CheckAndStartSentinelJob;
|
||||
use App\Jobs\CheckForUpdatesJob;
|
||||
use App\Jobs\CheckHelperImageJob;
|
||||
use App\Jobs\CleanupInstanceStuffsJob;
|
||||
use App\Jobs\CleanupStaleMultiplexedConnections;
|
||||
use App\Jobs\DatabaseBackupJob;
|
||||
use App\Jobs\DockerCleanupJob;
|
||||
use App\Jobs\PullTemplatesFromCDN;
|
||||
use App\Jobs\RegenerateSslCertJob;
|
||||
use App\Jobs\ScheduledTaskJob;
|
||||
use App\Jobs\ServerCheckJob;
|
||||
use App\Jobs\ServerCleanupMux;
|
||||
use App\Jobs\ServerStorageCheckJob;
|
||||
use App\Jobs\UpdateCoolifyJob;
|
||||
use App\Models\InstanceSettings;
|
||||
@@ -24,6 +22,7 @@ use App\Models\Team;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class Kernel extends ConsoleKernel
|
||||
{
|
||||
@@ -102,10 +101,14 @@ class Kernel extends ConsoleKernel
|
||||
$servers = $this->allServers->whereRelation('settings', 'is_usable', true)->whereRelation('settings', 'is_reachable', true)->get();
|
||||
}
|
||||
foreach ($servers as $server) {
|
||||
if ($server->isSentinelEnabled()) {
|
||||
$this->scheduleInstance->job(function () use ($server) {
|
||||
CheckAndStartSentinelJob::dispatch($server);
|
||||
})->cron($this->updateCheckFrequency)->timezone($this->instanceTimezone)->onOneServer();
|
||||
try {
|
||||
if ($server->isSentinelEnabled()) {
|
||||
$this->scheduleInstance->job(function () use ($server) {
|
||||
CheckAndStartSentinelJob::dispatch($server);
|
||||
})->cron($this->updateCheckFrequency)->timezone($this->instanceTimezone)->onOneServer();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error pulling images: '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
$this->scheduleInstance->job(new CheckHelperImageJob)
|
||||
@@ -141,35 +144,47 @@ class Kernel extends ConsoleKernel
|
||||
}
|
||||
|
||||
foreach ($servers as $server) {
|
||||
$serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone);
|
||||
if (validate_timezone($serverTimezone) === false) {
|
||||
$serverTimezone = config('app.timezone');
|
||||
}
|
||||
|
||||
// Sentinel check
|
||||
$lastSentinelUpdate = $server->sentinel_updated_at;
|
||||
if (Carbon::parse($lastSentinelUpdate)->isBefore(now()->subSeconds($server->waitBeforeDoingSshCheck()))) {
|
||||
// Check container status every minute if Sentinel does not activated
|
||||
if (isCloud()) {
|
||||
$this->scheduleInstance->job(new ServerCheckJob($server))->timezone($serverTimezone)->everyFiveMinutes()->onOneServer();
|
||||
} else {
|
||||
$this->scheduleInstance->job(new ServerCheckJob($server))->timezone($serverTimezone)->everyMinute()->onOneServer();
|
||||
try {
|
||||
$serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone);
|
||||
if (validate_timezone($serverTimezone) === false) {
|
||||
$serverTimezone = config('app.timezone');
|
||||
}
|
||||
// $this->scheduleInstance->job(new \App\Jobs\ServerCheckNewJob($server))->everyFiveMinutes()->onOneServer();
|
||||
|
||||
$this->scheduleInstance->job(new ServerStorageCheckJob($server))->cron($server->settings->server_disk_usage_check_frequency)->timezone($serverTimezone)->onOneServer();
|
||||
}
|
||||
// Sentinel check
|
||||
$lastSentinelUpdate = $server->sentinel_updated_at;
|
||||
if (Carbon::parse($lastSentinelUpdate)->isBefore(now()->subSeconds($server->waitBeforeDoingSshCheck()))) {
|
||||
// Check container status every minute if Sentinel does not activated
|
||||
if (isCloud()) {
|
||||
$this->scheduleInstance->job(new ServerCheckJob($server))->timezone($serverTimezone)->everyFiveMinutes()->onOneServer();
|
||||
} else {
|
||||
$this->scheduleInstance->job(new ServerCheckJob($server))->timezone($serverTimezone)->everyMinute()->onOneServer();
|
||||
}
|
||||
// $this->scheduleInstance->job(new \App\Jobs\ServerCheckNewJob($server))->everyFiveMinutes()->onOneServer();
|
||||
|
||||
$this->scheduleInstance->job(new DockerCleanupJob($server))->cron($server->settings->docker_cleanup_frequency)->timezone($serverTimezone)->onOneServer();
|
||||
$serverDiskUsageCheckFrequency = data_get($server->settings, 'server_disk_usage_check_frequency', '0 * * * *');
|
||||
if (isset(VALID_CRON_STRINGS[$serverDiskUsageCheckFrequency])) {
|
||||
$serverDiskUsageCheckFrequency = VALID_CRON_STRINGS[$serverDiskUsageCheckFrequency];
|
||||
}
|
||||
$this->scheduleInstance->job(new ServerStorageCheckJob($server))->cron($serverDiskUsageCheckFrequency)->timezone($serverTimezone)->onOneServer();
|
||||
}
|
||||
|
||||
// Cleanup multiplexed connections every hour
|
||||
// $this->scheduleInstance->job(new ServerCleanupMux($server))->hourly()->onOneServer();
|
||||
$dockerCleanupFrequency = data_get($server->settings, 'docker_cleanup_frequency', '0 * * * *');
|
||||
if (isset(VALID_CRON_STRINGS[$dockerCleanupFrequency])) {
|
||||
$dockerCleanupFrequency = VALID_CRON_STRINGS[$dockerCleanupFrequency];
|
||||
}
|
||||
$this->scheduleInstance->job(new DockerCleanupJob($server))->cron($dockerCleanupFrequency)->timezone($serverTimezone)->onOneServer();
|
||||
|
||||
// Temporary solution until we have better memory management for Sentinel
|
||||
if ($server->isSentinelEnabled()) {
|
||||
$this->scheduleInstance->job(function () use ($server) {
|
||||
$server->restartContainer('coolify-sentinel');
|
||||
})->daily()->onOneServer();
|
||||
// Cleanup multiplexed connections every hour
|
||||
// $this->scheduleInstance->job(new ServerCleanupMux($server))->hourly()->onOneServer();
|
||||
|
||||
// Temporary solution until we have better memory management for Sentinel
|
||||
if ($server->isSentinelEnabled()) {
|
||||
$this->scheduleInstance->job(function () use ($server) {
|
||||
$server->restartContainer('coolify-sentinel');
|
||||
})->daily()->onOneServer();
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error checking resources: '.$e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,24 +218,28 @@ class Kernel extends ConsoleKernel
|
||||
}
|
||||
|
||||
foreach ($finalScheduledBackups as $scheduled_backup) {
|
||||
if (isset(VALID_CRON_STRINGS[$scheduled_backup->frequency])) {
|
||||
$scheduled_backup->frequency = VALID_CRON_STRINGS[$scheduled_backup->frequency];
|
||||
}
|
||||
try {
|
||||
if (isset(VALID_CRON_STRINGS[$scheduled_backup->frequency])) {
|
||||
$scheduled_backup->frequency = VALID_CRON_STRINGS[$scheduled_backup->frequency];
|
||||
}
|
||||
$server = $scheduled_backup->server();
|
||||
$serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone);
|
||||
|
||||
$server = $scheduled_backup->server();
|
||||
$serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone);
|
||||
if (validate_timezone($serverTimezone) === false) {
|
||||
$serverTimezone = config('app.timezone');
|
||||
}
|
||||
|
||||
if (validate_timezone($serverTimezone) === false) {
|
||||
$serverTimezone = config('app.timezone');
|
||||
if (isset(VALID_CRON_STRINGS[$scheduled_backup->frequency])) {
|
||||
$scheduled_backup->frequency = VALID_CRON_STRINGS[$scheduled_backup->frequency];
|
||||
}
|
||||
$serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone);
|
||||
$this->scheduleInstance->job(new DatabaseBackupJob(
|
||||
backup: $scheduled_backup
|
||||
))->cron($scheduled_backup->frequency)->timezone($serverTimezone)->onOneServer();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error scheduling backup: '.$e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
|
||||
if (isset(VALID_CRON_STRINGS[$scheduled_backup->frequency])) {
|
||||
$scheduled_backup->frequency = VALID_CRON_STRINGS[$scheduled_backup->frequency];
|
||||
}
|
||||
$serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone);
|
||||
$this->scheduleInstance->job(new DatabaseBackupJob(
|
||||
backup: $scheduled_backup
|
||||
))->cron($scheduled_backup->frequency)->timezone($serverTimezone)->onOneServer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,18 +286,23 @@ class Kernel extends ConsoleKernel
|
||||
}
|
||||
|
||||
foreach ($finalScheduledTasks as $scheduled_task) {
|
||||
$server = $scheduled_task->server();
|
||||
if (isset(VALID_CRON_STRINGS[$scheduled_task->frequency])) {
|
||||
$scheduled_task->frequency = VALID_CRON_STRINGS[$scheduled_task->frequency];
|
||||
}
|
||||
$serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone);
|
||||
try {
|
||||
$server = $scheduled_task->server();
|
||||
if (isset(VALID_CRON_STRINGS[$scheduled_task->frequency])) {
|
||||
$scheduled_task->frequency = VALID_CRON_STRINGS[$scheduled_task->frequency];
|
||||
}
|
||||
$serverTimezone = data_get($server->settings, 'server_timezone', $this->instanceTimezone);
|
||||
|
||||
if (validate_timezone($serverTimezone) === false) {
|
||||
$serverTimezone = config('app.timezone');
|
||||
if (validate_timezone($serverTimezone) === false) {
|
||||
$serverTimezone = config('app.timezone');
|
||||
}
|
||||
$this->scheduleInstance->job(new ScheduledTaskJob(
|
||||
task: $scheduled_task
|
||||
))->cron($scheduled_task->frequency)->timezone($serverTimezone)->onOneServer();
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Error scheduling task: '.$e->getMessage());
|
||||
Log::error($e->getTraceAsString());
|
||||
}
|
||||
$this->scheduleInstance->job(new ScheduledTaskJob(
|
||||
task: $scheduled_task
|
||||
))->cron($scheduled_task->frequency)->timezone($serverTimezone)->onOneServer();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2284,7 +2284,7 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
||||
} else {
|
||||
if ($this->use_build_server) {
|
||||
$this->execute_remote_command(
|
||||
["{$this->coolify_variables} docker compose --project-name {$this->application->uuid} --project-directory {$this->configuration_dir} -f {$this->configuration_dir}{$this->docker_compose_location} up --build -d", 'hidden' => true],
|
||||
["{$this->coolify_variables} docker compose --project-name {$this->application->uuid} --project-directory {$this->configuration_dir} -f {$this->configuration_dir}{$this->docker_compose_location} up --pull always --build -d", 'hidden' => true],
|
||||
);
|
||||
} else {
|
||||
$this->execute_remote_command(
|
||||
|
||||
@@ -35,10 +35,18 @@ class Docker extends Component
|
||||
$this->network = new Cuid2;
|
||||
$this->servers = Server::isUsable()->get();
|
||||
if ($server_id) {
|
||||
$this->selectedServer = $this->servers->find($server_id) ?: $this->servers->first();
|
||||
$foundServer = $this->servers->find($server_id) ?: $this->servers->first();
|
||||
if (! $foundServer) {
|
||||
throw new \Exception('Server not found.');
|
||||
}
|
||||
$this->selectedServer = $foundServer;
|
||||
$this->serverId = $this->selectedServer->id;
|
||||
} else {
|
||||
$this->selectedServer = $this->servers->first();
|
||||
$foundServer = $this->servers->first();
|
||||
if (! $foundServer) {
|
||||
throw new \Exception('Server not found.');
|
||||
}
|
||||
$this->selectedServer = $foundServer;
|
||||
$this->serverId = $this->selectedServer->id;
|
||||
}
|
||||
$this->generateName();
|
||||
|
||||
@@ -53,13 +53,13 @@ class DeploymentNavbar extends Component
|
||||
public function cancel()
|
||||
{
|
||||
$kill_command = "docker rm -f {$this->application_deployment_queue->deployment_uuid}";
|
||||
$build_server_id = $this->application_deployment_queue->build_server_id;
|
||||
$build_server_id = $this->application_deployment_queue->build_server_id ?? $this->application->destination->server_id;
|
||||
$server_id = $this->application_deployment_queue->server_id ?? $this->application->destination->server_id;
|
||||
try {
|
||||
if ($this->application->settings->is_build_server_enabled) {
|
||||
$server = Server::find($build_server_id);
|
||||
$server = Server::ownedByCurrentTeam()->find($build_server_id);
|
||||
} else {
|
||||
$server = Server::find($server_id);
|
||||
$server = Server::ownedByCurrentTeam()->find($server_id);
|
||||
}
|
||||
if ($this->application_deployment_queue->logs) {
|
||||
$previous_logs = json_decode($this->application_deployment_queue->logs, associative: true, flags: JSON_THROW_ON_ERROR);
|
||||
|
||||
@@ -32,7 +32,7 @@ class Configuration extends Component
|
||||
return [
|
||||
"echo-private:user.{$userId},ServiceStatusChanged" => 'check_status',
|
||||
'check_status',
|
||||
'refresh' => '$refresh',
|
||||
'refreshStatus' => '$refresh',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ class Configuration extends Component
|
||||
$this->service->databases->each(function ($database) {
|
||||
$database->refresh();
|
||||
});
|
||||
$this->dispatch('refresh');
|
||||
$this->dispatch('refreshStatus');
|
||||
} catch (\Exception $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ class Navbar extends Component
|
||||
return [
|
||||
"echo-private:user.{$userId},ServiceStatusChanged" => 'serviceStarted',
|
||||
'envsUpdated' => '$refresh',
|
||||
'refreshStatus' => '$refresh',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ use App\Actions\Server\StopSentinel;
|
||||
use App\Events\ServerReachabilityChanged;
|
||||
use App\Models\Server;
|
||||
use Livewire\Attributes\Computed;
|
||||
use Livewire\Attributes\Locked;
|
||||
use Livewire\Attributes\Validate;
|
||||
use Livewire\Component;
|
||||
|
||||
@@ -50,6 +51,9 @@ class Show extends Component
|
||||
#[Validate(['required'])]
|
||||
public bool $isBuildServer;
|
||||
|
||||
#[Locked]
|
||||
public bool $isBuildServerLocked = false;
|
||||
|
||||
#[Validate(['required'])]
|
||||
public bool $isMetricsEnabled;
|
||||
|
||||
@@ -95,6 +99,9 @@ class Show extends Component
|
||||
try {
|
||||
$this->server = Server::ownedByCurrentTeam()->whereUuid($server_uuid)->firstOrFail();
|
||||
$this->syncData();
|
||||
if (! $this->server->isEmpty()) {
|
||||
$this->isBuildServerLocked = true;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
|
||||
@@ -43,8 +43,18 @@ class S3Storage extends BaseModel
|
||||
public function testConnection(bool $shouldSave = false)
|
||||
{
|
||||
try {
|
||||
set_s3_target($this);
|
||||
Storage::disk('custom-s3')->files();
|
||||
$disk = Storage::build([
|
||||
'driver' => 's3',
|
||||
'region' => $this['region'],
|
||||
'key' => $this['key'],
|
||||
'secret' => $this['secret'],
|
||||
'bucket' => $this['bucket'],
|
||||
'endpoint' => $this['endpoint'],
|
||||
'use_path_style_endpoint' => true,
|
||||
]);
|
||||
// Test the connection by listing files with ListObjectsV2 (S3)
|
||||
$disk->files();
|
||||
|
||||
$this->unusable_email_sent = false;
|
||||
$this->is_usable = true;
|
||||
} catch (\Throwable $e) {
|
||||
@@ -53,13 +63,14 @@ class S3Storage extends BaseModel
|
||||
$mail = new MailMessage;
|
||||
$mail->subject('Coolify: S3 Storage Connection Error');
|
||||
$mail->view('emails.s3-connection-error', ['name' => $this->name, 'reason' => $e->getMessage(), 'url' => route('storage.show', ['storage_uuid' => $this->uuid])]);
|
||||
$users = collect([]);
|
||||
$members = $this->team->members()->get();
|
||||
foreach ($members as $user) {
|
||||
if ($user->isAdmin()) {
|
||||
$users->push($user);
|
||||
}
|
||||
}
|
||||
|
||||
// Load the team with its members and their roles explicitly
|
||||
$team = $this->team()->with(['members' => function ($query) {
|
||||
$query->withPivot('role');
|
||||
}])->first();
|
||||
|
||||
// Get admins directly from the pivot relationship for this specific team
|
||||
$users = $team->members()->wherePivotIn('role', ['admin', 'owner'])->get(['users.id', 'users.email']);
|
||||
foreach ($users as $user) {
|
||||
send_user_an_email($mail, $user->email);
|
||||
}
|
||||
|
||||
@@ -1341,4 +1341,11 @@ $schema://$host {
|
||||
throw new \Exception('Invalid proxy type.');
|
||||
}
|
||||
}
|
||||
|
||||
public function isEmpty()
|
||||
{
|
||||
return $this->applications()->count() == 0 &&
|
||||
$this->databases()->count() == 0 &&
|
||||
$this->services()->count() == 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user