Merge branch 'new-dockerfiles' of https://github.com/peaklabs-dev/coolify into new-dockerfiles
This commit is contained in:
		
							
								
								
									
										4
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitattributes
									
									
									
									
										vendored
									
									
								
							@@ -5,3 +5,7 @@
 | 
			
		||||
*.html diff=html
 | 
			
		||||
*.md diff=markdown
 | 
			
		||||
*.php diff=php
 | 
			
		||||
 | 
			
		||||
/.github export-ignore
 | 
			
		||||
CHANGELOG.md export-ignore
 | 
			
		||||
.styleci.yml export-ignore
 | 
			
		||||
							
								
								
									
										10
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								README.md
									
									
									
									
									
								
							@@ -142,12 +142,10 @@ By subscribing to the cloud version, you get the Coolify server for the same pri
 | 
			
		||||
 | 
			
		||||
# Core Maintainers
 | 
			
		||||
 | 
			
		||||
<a href="https://github.com/andrasbacsai">
 | 
			
		||||
  <img src="https://github.com/andrasbacsai.png" width="60px" alt="andrasbacsai" />
 | 
			
		||||
</a>
 | 
			
		||||
<a href="https://github.com/peaklabs-dev">
 | 
			
		||||
  <img src="https://github.com/peaklabs-dev.png" width="60px" alt="peaklabs-dev" />
 | 
			
		||||
</a>
 | 
			
		||||
| Andras Bacsai | Peak |
 | 
			
		||||
|------------|------------|
 | 
			
		||||
| <img src="https://github.com/andrasbacsai.png" width="200px" alt="Andras Bacsai" /> | <img src="https://github.com/peaklabs-dev.png" width="200px" alt="Peak Labs" /> |
 | 
			
		||||
| <a href="https://x.com/heyandras"><img src="https://raw.githubusercontent.com/gauravghongde/social-icons/master/SVG/Color/Twitter.svg" width="25px"></a> <a href="https://github.com/andrasbacsai"><img src="https://raw.githubusercontent.com/gauravghongde/social-icons/master/SVG/Color/Github.svg" width="25px"></a> | <a href="https://x.com/peaklabs_dev"><img src="https://raw.githubusercontent.com/gauravghongde/social-icons/master/SVG/Color/Twitter.svg" width="25px"></a> <a href="https://github.com/peaklabs-dev"><img src="https://raw.githubusercontent.com/gauravghongde/social-icons/master/SVG/Color/Github.svg" width="25px"></a> |
 | 
			
		||||
 | 
			
		||||
# Repo Activity
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -28,6 +28,8 @@ class Kernel extends ConsoleKernel
 | 
			
		||||
{
 | 
			
		||||
    private $allServers;
 | 
			
		||||
 | 
			
		||||
    private Schedule $scheduleInstance;
 | 
			
		||||
 | 
			
		||||
    private InstanceSettings $settings;
 | 
			
		||||
 | 
			
		||||
    private string $updateCheckFrequency;
 | 
			
		||||
@@ -36,82 +38,90 @@ class Kernel extends ConsoleKernel
 | 
			
		||||
 | 
			
		||||
    protected function schedule(Schedule $schedule): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->scheduleInstance = $schedule;
 | 
			
		||||
        $this->allServers = Server::where('ip', '!=', '1.2.3.4');
 | 
			
		||||
 | 
			
		||||
        $this->settings = instanceSettings();
 | 
			
		||||
        $this->updateCheckFrequency = $this->settings->update_check_frequency ?: '0 * * * *';
 | 
			
		||||
 | 
			
		||||
        $this->instanceTimezone = $this->settings->instance_timezone ?: config('app.timezone');
 | 
			
		||||
 | 
			
		||||
        $schedule->job(new CleanupStaleMultiplexedConnections)->hourly();
 | 
			
		||||
        if (validate_timezone($this->instanceTimezone) === false) {
 | 
			
		||||
            $this->instanceTimezone = config('app.timezone');
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $this->scheduleInstance->job(new CleanupStaleMultiplexedConnections)->hourly();
 | 
			
		||||
 | 
			
		||||
        if (isDev()) {
 | 
			
		||||
            // Instance Jobs
 | 
			
		||||
            $schedule->command('horizon:snapshot')->everyMinute();
 | 
			
		||||
            $schedule->job(new CleanupInstanceStuffsJob)->everyMinute()->onOneServer();
 | 
			
		||||
            $schedule->job(new CheckHelperImageJob)->everyTenMinutes()->onOneServer();
 | 
			
		||||
            $this->scheduleInstance->command('horizon:snapshot')->everyMinute();
 | 
			
		||||
            $this->scheduleInstance->job(new CleanupInstanceStuffsJob)->everyMinute()->onOneServer();
 | 
			
		||||
            $this->scheduleInstance->job(new CheckHelperImageJob)->everyTenMinutes()->onOneServer();
 | 
			
		||||
 | 
			
		||||
            // Server Jobs
 | 
			
		||||
            $this->checkResources($schedule);
 | 
			
		||||
            $this->checkResources();
 | 
			
		||||
 | 
			
		||||
            $this->checkScheduledBackups($schedule);
 | 
			
		||||
            $this->checkScheduledTasks($schedule);
 | 
			
		||||
            $this->checkScheduledBackups();
 | 
			
		||||
            $this->checkScheduledTasks();
 | 
			
		||||
 | 
			
		||||
            $schedule->command('uploads:clear')->everyTwoMinutes();
 | 
			
		||||
            $this->scheduleInstance->command('uploads:clear')->everyTwoMinutes();
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            // Instance Jobs
 | 
			
		||||
            $schedule->command('horizon:snapshot')->everyFiveMinutes();
 | 
			
		||||
            $schedule->command('cleanup:unreachable-servers')->daily()->onOneServer();
 | 
			
		||||
            $schedule->job(new PullTemplatesFromCDN)->cron($this->updateCheckFrequency)->timezone($this->instanceTimezone)->onOneServer();
 | 
			
		||||
            $schedule->job(new CleanupInstanceStuffsJob)->everyTwoMinutes()->onOneServer();
 | 
			
		||||
            $this->scheduleUpdates($schedule);
 | 
			
		||||
            $this->scheduleInstance->command('horizon:snapshot')->everyFiveMinutes();
 | 
			
		||||
            $this->scheduleInstance->command('cleanup:unreachable-servers')->daily()->onOneServer();
 | 
			
		||||
 | 
			
		||||
            $this->scheduleInstance->job(new PullTemplatesFromCDN)->cron($this->updateCheckFrequency)->timezone($this->instanceTimezone)->onOneServer();
 | 
			
		||||
 | 
			
		||||
            $this->scheduleInstance->job(new CleanupInstanceStuffsJob)->everyTwoMinutes()->onOneServer();
 | 
			
		||||
            $this->scheduleUpdates();
 | 
			
		||||
 | 
			
		||||
            // Server Jobs
 | 
			
		||||
            $this->checkResources($schedule);
 | 
			
		||||
            $this->checkResources();
 | 
			
		||||
 | 
			
		||||
            $this->pullImages($schedule);
 | 
			
		||||
            $this->pullImages();
 | 
			
		||||
 | 
			
		||||
            $this->checkScheduledBackups($schedule);
 | 
			
		||||
            $this->checkScheduledTasks($schedule);
 | 
			
		||||
            $this->checkScheduledBackups();
 | 
			
		||||
            $this->checkScheduledTasks();
 | 
			
		||||
 | 
			
		||||
            $schedule->command('cleanup:database --yes')->daily();
 | 
			
		||||
            $schedule->command('uploads:clear')->everyTwoMinutes();
 | 
			
		||||
            $this->scheduleInstance->command('cleanup:database --yes')->daily();
 | 
			
		||||
            $this->scheduleInstance->command('uploads:clear')->everyTwoMinutes();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function pullImages($schedule): void
 | 
			
		||||
    private function pullImages(): void
 | 
			
		||||
    {
 | 
			
		||||
        $servers = $this->allServers->whereRelation('settings', 'is_usable', true)->whereRelation('settings', 'is_reachable', true)->get();
 | 
			
		||||
        foreach ($servers as $server) {
 | 
			
		||||
            if ($server->isSentinelEnabled()) {
 | 
			
		||||
                $schedule->job(function () use ($server) {
 | 
			
		||||
                $this->scheduleInstance->job(function () use ($server) {
 | 
			
		||||
                    CheckAndStartSentinelJob::dispatch($server);
 | 
			
		||||
                })->cron($this->updateCheckFrequency)->timezone($this->instanceTimezone)->onOneServer();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        $schedule->job(new CheckHelperImageJob)
 | 
			
		||||
        $this->scheduleInstance->job(new CheckHelperImageJob)
 | 
			
		||||
            ->cron($this->updateCheckFrequency)
 | 
			
		||||
            ->timezone($this->instanceTimezone)
 | 
			
		||||
            ->onOneServer();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function scheduleUpdates($schedule): void
 | 
			
		||||
    private function scheduleUpdates(): void
 | 
			
		||||
    {
 | 
			
		||||
        $schedule->job(new CheckForUpdatesJob)
 | 
			
		||||
        $this->scheduleInstance->job(new CheckForUpdatesJob)
 | 
			
		||||
            ->cron($this->updateCheckFrequency)
 | 
			
		||||
            ->timezone($this->instanceTimezone)
 | 
			
		||||
            ->onOneServer();
 | 
			
		||||
 | 
			
		||||
        if ($this->settings->is_auto_update_enabled) {
 | 
			
		||||
            $autoUpdateFrequency = $this->settings->auto_update_frequency;
 | 
			
		||||
            $schedule->job(new UpdateCoolifyJob)
 | 
			
		||||
            $this->scheduleInstance->job(new UpdateCoolifyJob)
 | 
			
		||||
                ->cron($autoUpdateFrequency)
 | 
			
		||||
                ->timezone($this->instanceTimezone)
 | 
			
		||||
                ->onOneServer();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function checkResources($schedule): void
 | 
			
		||||
    private function checkResources(): void
 | 
			
		||||
    {
 | 
			
		||||
        if (isCloud()) {
 | 
			
		||||
            $servers = $this->allServers->whereHas('team.subscription')->get();
 | 
			
		||||
@@ -128,31 +138,34 @@ class Kernel extends ConsoleKernel
 | 
			
		||||
            $lastSentinelUpdate = $server->sentinel_updated_at;
 | 
			
		||||
            if (Carbon::parse($lastSentinelUpdate)->isBefore(now()->subSeconds($server->waitBeforeDoingSshCheck()))) {
 | 
			
		||||
                // Check container status every minute if Sentinel does not activated
 | 
			
		||||
                $schedule->job(new ServerCheckJob($server))->everyMinute()->onOneServer();
 | 
			
		||||
                // $schedule->job(new \App\Jobs\ServerCheckNewJob($server))->everyMinute()->onOneServer();
 | 
			
		||||
                if (validate_timezone($serverTimezone) === false) {
 | 
			
		||||
                    $serverTimezone = config('app.timezone');
 | 
			
		||||
                }
 | 
			
		||||
                $this->scheduleInstance->job(new ServerCheckJob($server))->timezone($serverTimezone)->everyMinute()->onOneServer();
 | 
			
		||||
                // $this->scheduleInstance->job(new \App\Jobs\ServerCheckNewJob($server))->everyMinute()->onOneServer();
 | 
			
		||||
 | 
			
		||||
                // Check storage usage every 10 minutes if Sentinel does not activated
 | 
			
		||||
                $schedule->job(new ServerStorageCheckJob($server))->everyTenMinutes()->onOneServer();
 | 
			
		||||
                $this->scheduleInstance->job(new ServerStorageCheckJob($server))->everyTenMinutes()->onOneServer();
 | 
			
		||||
            }
 | 
			
		||||
            if ($server->settings->force_docker_cleanup) {
 | 
			
		||||
                $schedule->job(new DockerCleanupJob($server))->cron($server->settings->docker_cleanup_frequency)->timezone($serverTimezone)->onOneServer();
 | 
			
		||||
                $this->scheduleInstance->job(new DockerCleanupJob($server))->cron($server->settings->docker_cleanup_frequency)->timezone($serverTimezone)->onOneServer();
 | 
			
		||||
            } else {
 | 
			
		||||
                $schedule->job(new DockerCleanupJob($server))->everyTenMinutes()->timezone($serverTimezone)->onOneServer();
 | 
			
		||||
                $this->scheduleInstance->job(new DockerCleanupJob($server))->everyTenMinutes()->timezone($serverTimezone)->onOneServer();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Cleanup multiplexed connections every hour
 | 
			
		||||
            $schedule->job(new ServerCleanupMux($server))->hourly()->onOneServer();
 | 
			
		||||
            $this->scheduleInstance->job(new ServerCleanupMux($server))->hourly()->onOneServer();
 | 
			
		||||
 | 
			
		||||
            // Temporary solution until we have better memory management for Sentinel
 | 
			
		||||
            if ($server->isSentinelEnabled()) {
 | 
			
		||||
                $schedule->job(function () use ($server) {
 | 
			
		||||
                $this->scheduleInstance->job(function () use ($server) {
 | 
			
		||||
                    $server->restartContainer('coolify-sentinel');
 | 
			
		||||
                })->daily()->onOneServer();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function checkScheduledBackups($schedule): void
 | 
			
		||||
    private function checkScheduledBackups(): void
 | 
			
		||||
    {
 | 
			
		||||
        $scheduled_backups = ScheduledDatabaseBackup::where('enabled', true)->get();
 | 
			
		||||
        if ($scheduled_backups->isEmpty()) {
 | 
			
		||||
@@ -174,13 +187,13 @@ class Kernel extends ConsoleKernel
 | 
			
		||||
            if (isset(VALID_CRON_STRINGS[$scheduled_backup->frequency])) {
 | 
			
		||||
                $scheduled_backup->frequency = VALID_CRON_STRINGS[$scheduled_backup->frequency];
 | 
			
		||||
            }
 | 
			
		||||
            $schedule->job(new DatabaseBackupJob(
 | 
			
		||||
            $this->scheduleInstance->job(new DatabaseBackupJob(
 | 
			
		||||
                backup: $scheduled_backup
 | 
			
		||||
            ))->cron($scheduled_backup->frequency)->timezone($this->instanceTimezone)->onOneServer();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function checkScheduledTasks($schedule): void
 | 
			
		||||
    private function checkScheduledTasks(): void
 | 
			
		||||
    {
 | 
			
		||||
        $scheduled_tasks = ScheduledTask::where('enabled', true)->get();
 | 
			
		||||
        if ($scheduled_tasks->isEmpty()) {
 | 
			
		||||
@@ -214,7 +227,7 @@ class Kernel extends ConsoleKernel
 | 
			
		||||
            if (isset(VALID_CRON_STRINGS[$scheduled_task->frequency])) {
 | 
			
		||||
                $scheduled_task->frequency = VALID_CRON_STRINGS[$scheduled_task->frequency];
 | 
			
		||||
            }
 | 
			
		||||
            $schedule->job(new ScheduledTaskJob(
 | 
			
		||||
            $this->scheduleInstance->job(new ScheduledTaskJob(
 | 
			
		||||
                task: $scheduled_task
 | 
			
		||||
            ))->cron($scheduled_task->frequency)->timezone($this->instanceTimezone)->onOneServer();
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ class DockerCleanupJob implements ShouldBeEncrypted, ShouldQueue
 | 
			
		||||
 | 
			
		||||
    public function middleware(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [(new WithoutOverlapping($this->server->id))->dontRelease()];
 | 
			
		||||
        return [(new WithoutOverlapping($this->server->uuid))->dontRelease()];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function __construct(public Server $server, public bool $manualCleanup = false) {}
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@ class ServerCheckJob implements ShouldBeEncrypted, ShouldQueue
 | 
			
		||||
 | 
			
		||||
    public function middleware(): array
 | 
			
		||||
    {
 | 
			
		||||
        return [(new WithoutOverlapping($this->server->id))->dontRelease()];
 | 
			
		||||
        return [(new WithoutOverlapping($this->server->uuid))->dontRelease()];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function __construct(public Server $server) {}
 | 
			
		||||
 
 | 
			
		||||
@@ -127,7 +127,14 @@ class Show extends Component
 | 
			
		||||
            $this->server->settings->sentinel_custom_url = $this->sentinelCustomUrl;
 | 
			
		||||
            $this->server->settings->is_sentinel_enabled = $this->isSentinelEnabled;
 | 
			
		||||
            $this->server->settings->is_sentinel_debug_enabled = $this->isSentinelDebugEnabled;
 | 
			
		||||
 | 
			
		||||
            if (! validate_timezone($this->serverTimezone)) {
 | 
			
		||||
                $this->serverTimezone = config('app.timezone');
 | 
			
		||||
                throw new \Exception('Invalid timezone.');
 | 
			
		||||
            } else {
 | 
			
		||||
                $this->server->settings->server_timezone = $this->serverTimezone;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            $this->server->settings->save();
 | 
			
		||||
        } else {
 | 
			
		||||
            $this->name = $this->server->name;
 | 
			
		||||
 
 | 
			
		||||
@@ -139,6 +139,14 @@ class Index extends Component
 | 
			
		||||
            $error_show = false;
 | 
			
		||||
            $this->server = Server::findOrFail(0);
 | 
			
		||||
            $this->resetErrorBag();
 | 
			
		||||
 | 
			
		||||
            if (! validate_timezone($this->instance_timezone)) {
 | 
			
		||||
                $this->instance_timezone = config('app.timezone');
 | 
			
		||||
                throw new \Exception('Invalid timezone.');
 | 
			
		||||
            } else {
 | 
			
		||||
                $this->settings->instance_timezone = $this->instance_timezone;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            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.');
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -394,7 +394,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
 | 
			
		||||
                        $middlewares->push('gzip');
 | 
			
		||||
                    }
 | 
			
		||||
                    if (str($image)->contains('ghost')) {
 | 
			
		||||
                        $middlewares->push('redir-ghost');
 | 
			
		||||
                        $middlewares->push("redir-ghost-{$uuid}");
 | 
			
		||||
                    }
 | 
			
		||||
                    if ($redirect_direction === 'non-www' && str($host)->startsWith('www.')) {
 | 
			
		||||
                        $labels = $labels->merge($redirect_to_non_www);
 | 
			
		||||
@@ -417,7 +417,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
 | 
			
		||||
                        $middlewares->push('gzip');
 | 
			
		||||
                    }
 | 
			
		||||
                    if (str($image)->contains('ghost')) {
 | 
			
		||||
                        $middlewares->push('redir-ghost');
 | 
			
		||||
                        $middlewares->push("redir-ghost-{$uuid}");
 | 
			
		||||
                    }
 | 
			
		||||
                    if ($redirect_direction === 'non-www' && str($host)->startsWith('www.')) {
 | 
			
		||||
                        $labels = $labels->merge($redirect_to_non_www);
 | 
			
		||||
@@ -466,7 +466,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
 | 
			
		||||
                        $middlewares->push('gzip');
 | 
			
		||||
                    }
 | 
			
		||||
                    if (str($image)->contains('ghost')) {
 | 
			
		||||
                        $middlewares->push('redir-ghost');
 | 
			
		||||
                        $middlewares->push("redir-ghost-{$uuid}");
 | 
			
		||||
                    }
 | 
			
		||||
                    if ($redirect_direction === 'non-www' && str($host)->startsWith('www.')) {
 | 
			
		||||
                        $labels = $labels->merge($redirect_to_non_www);
 | 
			
		||||
@@ -489,7 +489,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
 | 
			
		||||
                        $middlewares->push('gzip');
 | 
			
		||||
                    }
 | 
			
		||||
                    if (str($image)->contains('ghost')) {
 | 
			
		||||
                        $middlewares->push('redir-ghost');
 | 
			
		||||
                        $middlewares->push("redir-ghost-{$uuid}");
 | 
			
		||||
                    }
 | 
			
		||||
                    if ($redirect_direction === 'non-www' && str($host)->startsWith('www.')) {
 | 
			
		||||
                        $labels = $labels->merge($redirect_to_non_www);
 | 
			
		||||
 
 | 
			
		||||
@@ -385,6 +385,11 @@ function validate_cron_expression($expression_to_validate): bool
 | 
			
		||||
 | 
			
		||||
    return $isValid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function validate_timezone(string $timezone): bool
 | 
			
		||||
{
 | 
			
		||||
    return in_array($timezone, timezone_identifiers_list());
 | 
			
		||||
}
 | 
			
		||||
function send_internal_notification(string $message): void
 | 
			
		||||
{
 | 
			
		||||
    try {
 | 
			
		||||
 
 | 
			
		||||
@@ -74,8 +74,9 @@ services:
 | 
			
		||||
    networks:
 | 
			
		||||
      - coolify
 | 
			
		||||
  testing-host:
 | 
			
		||||
    image: "ghcr.io/coollabsio/coolify-testing-host:latest"
 | 
			
		||||
    pull_policy: always
 | 
			
		||||
    build:
 | 
			
		||||
      context: .
 | 
			
		||||
      dockerfile: ./docker/testing-host/Dockerfile
 | 
			
		||||
    init: true
 | 
			
		||||
    container_name: coolify-testing-host
 | 
			
		||||
    volumes:
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#!/command/execlineb -P
 | 
			
		||||
foreground {
 | 
			
		||||
  s6-sleep 5
 | 
			
		||||
  su - www-data -c "php /var/www/html/artisan start:horizon"
 | 
			
		||||
  su - webuser -c "php /var/www/html/artisan start:horizon"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#!/command/execlineb -P
 | 
			
		||||
foreground {
 | 
			
		||||
  s6-sleep 5
 | 
			
		||||
  su - www-data -c "php /var/www/html/artisan start:scheduler"
 | 
			
		||||
  su - webuser -c "php /var/www/html/artisan start:scheduler"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#!/command/execlineb -P
 | 
			
		||||
foreground {
 | 
			
		||||
  s6-sleep 5
 | 
			
		||||
  su - www-data -c "php /var/www/html/artisan start:horizon"
 | 
			
		||||
  su - webuser -c "php /var/www/html/artisan start:horizon"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,3 @@
 | 
			
		||||
#!/command/execlineb -P
 | 
			
		||||
s6-setuidgid www-data
 | 
			
		||||
s6-setuidgid webuser
 | 
			
		||||
php /var/www/html/artisan app:init
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
#!/command/execlineb -P
 | 
			
		||||
foreground {
 | 
			
		||||
  s6-sleep 5
 | 
			
		||||
  su - www-data -c "php /var/www/html/artisan start:scheduler"
 | 
			
		||||
  su - webuser -c "php /var/www/html/artisan start:scheduler"
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -14,8 +14,8 @@
 | 
			
		||||
    'w-full' => $fullWidth,
 | 
			
		||||
])>
 | 
			
		||||
    @if (!$hideLabel)
 | 
			
		||||
        <label @class(['flex gap-4 px-0 min-w-fit label', 'opacity-40' => $disabled])>
 | 
			
		||||
            <span class="flex gap-2">
 | 
			
		||||
        <label @class(['flex gap-4 items-center px-0 min-w-fit label w-full cursor-pointer', 'opacity-40' => $disabled])>
 | 
			
		||||
            <span class="flex flex-grow gap-2">
 | 
			
		||||
                @if ($label)
 | 
			
		||||
                    {!! $label !!}
 | 
			
		||||
                @else
 | 
			
		||||
@@ -25,11 +25,11 @@
 | 
			
		||||
                    <x-helper :helper="$helper" />
 | 
			
		||||
                @endif
 | 
			
		||||
            </span>
 | 
			
		||||
        </label>
 | 
			
		||||
    @endif
 | 
			
		||||
    <span class="flex-grow"></span>
 | 
			
		||||
            <input @disabled($disabled) type="checkbox" {{ $attributes->merge(['class' => $defaultClass]) }}
 | 
			
		||||
                @if ($instantSave) wire:loading.attr="disabled" wire:click='{{ $instantSave === 'instantSave' || $instantSave == '1' ? 'instantSave' : $instantSave }}'
 | 
			
		||||
                wire:model={{ $id }} @else wire:model={{ $value ?? $id }} @endif />
 | 
			
		||||
 | 
			
		||||
    @if (!$hideLabel)
 | 
			
		||||
        </label>
 | 
			
		||||
    @endif
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,7 @@
 | 
			
		||||
    $disableTwoStepConfirmation = data_get(InstanceSettings::get(), 'disable_two_step_confirmation');
 | 
			
		||||
@endphp
 | 
			
		||||
 | 
			
		||||
<div x-data="{
 | 
			
		||||
<div wire:ignore x-data="{
 | 
			
		||||
    modalOpen: false,
 | 
			
		||||
    step: {{ empty($checkboxes) ? 2 : 1 }},
 | 
			
		||||
    initialStep: {{ empty($checkboxes) ? 2 : 1 }},
 | 
			
		||||
@@ -106,8 +106,8 @@
 | 
			
		||||
            this.selectedActions.push(id);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}" @keydown.escape.window="modalOpen = false; resetModal()" :class="{ 'z-40': modalOpen }"
 | 
			
		||||
    class="relative w-auto h-auto">
 | 
			
		||||
}" @keydown.escape.window="modalOpen = false; resetModal()"
 | 
			
		||||
    :class="{ 'z-40': modalOpen }" class="relative w-auto h-auto">
 | 
			
		||||
    @if ($customButton)
 | 
			
		||||
        @if ($buttonFullWidth)
 | 
			
		||||
            <x-forms.button @click="modalOpen=true" class="w-full">
 | 
			
		||||
@@ -302,7 +302,8 @@
 | 
			
		||||
                                </x-forms.button>
 | 
			
		||||
                            @endif
 | 
			
		||||
                            <x-forms.button
 | 
			
		||||
                                x-bind:disabled="!disableTwoStepConfirmation && confirmWithText && userConfirmationText !== confirmationText"
 | 
			
		||||
                                x-bind:disabled="!disableTwoStepConfirmation && confirmWithText && userConfirmationText !==
 | 
			
		||||
                                    confirmationText"
 | 
			
		||||
                                class="w-auto" isError
 | 
			
		||||
                                @click="
 | 
			
		||||
                                    if (dispatchEvent) {
 | 
			
		||||
@@ -337,11 +338,14 @@
 | 
			
		||||
                                    Your Password
 | 
			
		||||
                                </label>
 | 
			
		||||
                                <form @submit.prevent="false" @keydown.enter.prevent>
 | 
			
		||||
                                    <input type="text" name="username" autocomplete="username" value="{{ auth()->user()->email }}" style="display: none;">
 | 
			
		||||
                                    <input type="password" id="password-confirm-{{ $passwordConfirm }}" x-model="password"
 | 
			
		||||
                                        class="w-full input" placeholder="Enter your password" autocomplete="current-password">
 | 
			
		||||
                                    <input type="text" name="username" autocomplete="username"
 | 
			
		||||
                                        value="{{ auth()->user()->email }}" style="display: none;">
 | 
			
		||||
                                    <input type="password" id="password-confirm-{{ $passwordConfirm }}"
 | 
			
		||||
                                        x-model="password" class="w-full input" placeholder="Enter your password"
 | 
			
		||||
                                        autocomplete="current-password">
 | 
			
		||||
                                </form>
 | 
			
		||||
                                <p x-show="passwordError" x-text="passwordError" class="mt-1 text-sm text-red-500"></p>
 | 
			
		||||
                                <p x-show="passwordError" x-text="passwordError" class="mt-1 text-sm text-red-500">
 | 
			
		||||
                                </p>
 | 
			
		||||
                                @error('password')
 | 
			
		||||
                                    <p class="mt-1 text-sm text-red-500">{{ $message }}</p>
 | 
			
		||||
                                @enderror
 | 
			
		||||
 
 | 
			
		||||
@@ -110,8 +110,7 @@
 | 
			
		||||
                                    wire:dirty.class.remove='dark:focus:ring-coolgray-300 dark:ring-coolgray-300'
 | 
			
		||||
                                    wire:dirty.class="dark:focus:ring-warning dark:ring-warning" x-model="search"
 | 
			
		||||
                                    @focus="open = true" @click.away="open = false" @input="open = true"
 | 
			
		||||
                                    class="w-full input" :placeholder="placeholder"
 | 
			
		||||
                                    wire:model.debounce.300ms="serverTimezone">
 | 
			
		||||
                                    class="w-full input" :placeholder="placeholder" wire:model="serverTimezone">
 | 
			
		||||
                                <svg class="absolute right-0 mr-2 w-4 h-4" xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
                                    fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
 | 
			
		||||
                                    @click="open = true">
 | 
			
		||||
@@ -124,7 +123,7 @@
 | 
			
		||||
                                <template
 | 
			
		||||
                                    x-for="timezone in timezones.filter(tz => tz.toLowerCase().includes(search.toLowerCase()))"
 | 
			
		||||
                                    :key="timezone">
 | 
			
		||||
                                    <div @click="search = timezone; open = false; $wire.set('serverTimezone', timezone)"
 | 
			
		||||
                                    <div @click="search = timezone; open = false; $wire.set('serverTimezone', timezone); $wire.submit()"
 | 
			
		||||
                                        class="px-4 py-2 text-gray-800 cursor-pointer hover:bg-gray-100 dark:hover:bg-coolgray-300 dark:text-gray-200"
 | 
			
		||||
                                        x-text="timezone"></div>
 | 
			
		||||
                                </template>
 | 
			
		||||
 
 | 
			
		||||
@@ -40,14 +40,13 @@
 | 
			
		||||
                                helper="Timezone for the Coolify instance. This is used for the update check and automatic update frequency." />
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="relative">
 | 
			
		||||
                            <div class="inline-flex items-center relative w-full">
 | 
			
		||||
                            <div class="inline-flex relative items-center w-full">
 | 
			
		||||
                                <input autocomplete="off"
 | 
			
		||||
                                    wire:dirty.class.remove='dark:focus:ring-coolgray-300 dark:ring-coolgray-300'
 | 
			
		||||
                                    wire:dirty.class="dark:focus:ring-warning dark:ring-warning" x-model="search"
 | 
			
		||||
                                    @focus="open = true" @click.away="open = false" @input="open = true"
 | 
			
		||||
                                    class="w-full input " :placeholder="placeholder"
 | 
			
		||||
                                    wire:model.debounce.300ms="instance_timezone">
 | 
			
		||||
                                <svg class="absolute right-0 w-4 h-4 mr-2" xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
                                    class="w-full input" :placeholder="placeholder" wire:model="instance_timezone">
 | 
			
		||||
                                <svg class="absolute right-0 mr-2 w-4 h-4" xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
                                    fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
 | 
			
		||||
                                    @click="open = true">
 | 
			
		||||
                                    <path stroke-linecap="round" stroke-linejoin="round"
 | 
			
		||||
@@ -55,18 +54,17 @@
 | 
			
		||||
                                </svg>
 | 
			
		||||
                            </div>
 | 
			
		||||
                            <div x-show="open"
 | 
			
		||||
                                class="absolute z-50 w-full  mt-1 bg-white dark:bg-coolgray-100 border dark:border-coolgray-200 rounded-md shadow-lg max-h-60 overflow-auto scrollbar overflow-x-hidden">
 | 
			
		||||
                                class="overflow-auto overflow-x-hidden absolute z-50 mt-1 w-full max-h-60 bg-white rounded-md border shadow-lg dark:bg-coolgray-100 dark:border-coolgray-200 scrollbar">
 | 
			
		||||
                                <template
 | 
			
		||||
                                    x-for="timezone in timezones.filter(tz => tz.toLowerCase().includes(search.toLowerCase()))"
 | 
			
		||||
                                    :key="timezone">
 | 
			
		||||
                                    <div @click="search = timezone; open = false; $wire.set('instance_timezone', timezone)"
 | 
			
		||||
                                        class="px-4 py-2 cursor-pointer hover:bg-gray-100 dark:hover:bg-coolgray-300 text-gray-800 dark:text-gray-200"
 | 
			
		||||
                                    <div @click="search = timezone; open = false; $wire.set('instance_timezone', timezone); $wire.submit()"
 | 
			
		||||
                                        class="px-4 py-2 text-gray-800 cursor-pointer hover:bg-gray-100 dark:hover:bg-coolgray-300 dark:text-gray-200"
 | 
			
		||||
                                        x-text="timezone"></div>
 | 
			
		||||
                                </template>
 | 
			
		||||
                            </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="flex gap-2 md:flex-row flex-col w-full">
 | 
			
		||||
                    <x-forms.input id="public_ipv4" type="password" label="Instance's IPv4"
 | 
			
		||||
@@ -134,7 +132,9 @@
 | 
			
		||||
        <h4 class="py-4">Confirmation Settings</h4>
 | 
			
		||||
        <div x-data="{ open: false }" class="mb-32 md:w-[40rem]">
 | 
			
		||||
            <button type="button" @click.prevent="open = !open"
 | 
			
		||||
                class="flex items-center justify-between w-full p-4 bg-coolgray-100 hover:bg-coolgray-200 rounded-md">
 | 
			
		||||
                class="flex items-center justify-between w-full p-4 rounded-md
 | 
			
		||||
                       dark:bg-coolgray-100 dark:hover:bg-coolgray-200
 | 
			
		||||
                       bg-gray-100 hover:bg-gray-200">
 | 
			
		||||
                <span class="font-medium">Two-Step Confirmation Settings</span>
 | 
			
		||||
                <svg class="w-5 h-5 transition-transform" :class="{ 'rotate-180': open }" fill="none"
 | 
			
		||||
                    stroke="currentColor" viewBox="0 0 24 24">
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,7 @@
 | 
			
		||||
                </x-forms.select>
 | 
			
		||||
                <x-forms.button type="submit">Connect</x-forms.button>
 | 
			
		||||
            </form>
 | 
			
		||||
            <livewire:project.shared.terminal />
 | 
			
		||||
        @endif
 | 
			
		||||
        <livewire:project.shared.terminal />
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -32,14 +32,14 @@ function sync:bunny {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function db:reset {
 | 
			
		||||
    bash spin exec -u www-data coolify php artisan migrate:fresh --seed
 | 
			
		||||
    bash spin exec -u webuser coolify php artisan migrate:fresh --seed
 | 
			
		||||
}
 | 
			
		||||
function db:reset-prod {
 | 
			
		||||
    bash spin exec -u www-data coolify php artisan migrate:fresh --force --seed --seeder=ProductionSeeder ||
 | 
			
		||||
    bash spin exec -u webuser coolify php artisan migrate:fresh --force --seed --seeder=ProductionSeeder ||
 | 
			
		||||
        php artisan migrate:fresh --force --seed --seeder=ProductionSeeder
 | 
			
		||||
}
 | 
			
		||||
function coolify {
 | 
			
		||||
    bash spin exec -u www-data coolify bash
 | 
			
		||||
    bash spin exec -u webuser coolify bash
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function coolify:root {
 | 
			
		||||
@@ -58,7 +58,7 @@ function vite {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function tinker {
 | 
			
		||||
    bash spin exec -u www-data coolify php artisan tinker
 | 
			
		||||
    bash spin exec -u webuser coolify php artisan tinker
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function default {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user