Merge branch 'next' into next
This commit is contained in:
		@@ -4,6 +4,8 @@ namespace App\Actions\Server;
 | 
			
		||||
 | 
			
		||||
use App\Models\InstanceSettings;
 | 
			
		||||
use App\Models\Server;
 | 
			
		||||
use Illuminate\Support\Facades\File;
 | 
			
		||||
use Illuminate\Support\Facades\Http;
 | 
			
		||||
use Lorisleiva\Actions\Concerns\AsAction;
 | 
			
		||||
 | 
			
		||||
class UpdateCoolify
 | 
			
		||||
@@ -25,6 +27,11 @@ class UpdateCoolify
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            CleanupDocker::dispatch($this->server, false)->onQueue('high');
 | 
			
		||||
            $response = Http::retry(3, 1000)->get('https://cdn.coollabs.io/coolify/versions.json');
 | 
			
		||||
            if ($response->successful()) {
 | 
			
		||||
                $versions = $response->json();
 | 
			
		||||
                File::put(base_path('versions.json'), json_encode($versions, JSON_PRETTY_PRINT));
 | 
			
		||||
            }
 | 
			
		||||
            $this->latestVersion = get_latest_version_of_coolify();
 | 
			
		||||
            $this->currentVersion = config('version');
 | 
			
		||||
            if (! $manual_update) {
 | 
			
		||||
@@ -39,6 +46,8 @@ class UpdateCoolify
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            $this->update();
 | 
			
		||||
            $settings->new_version_available = false;
 | 
			
		||||
            $settings->save();
 | 
			
		||||
        } catch (\Throwable $e) {
 | 
			
		||||
            throw $e;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -99,24 +99,32 @@ class Init extends Command
 | 
			
		||||
 | 
			
		||||
    private function update_traefik_labels()
 | 
			
		||||
    {
 | 
			
		||||
        Server::where('proxy->type', 'TRAEFIK_V2')->update(['proxy->type' => 'TRAEFIK']);
 | 
			
		||||
        try {
 | 
			
		||||
            Server::where('proxy->type', 'TRAEFIK_V2')->update(['proxy->type' => 'TRAEFIK']);
 | 
			
		||||
        } catch (\Throwable $e) {
 | 
			
		||||
            echo "Error in updating traefik labels: {$e->getMessage()}\n";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private function cleanup_unnecessary_dynamic_proxy_configuration()
 | 
			
		||||
    {
 | 
			
		||||
        if (isCloud()) {
 | 
			
		||||
            foreach ($this->servers as $server) {
 | 
			
		||||
                if (! $server->isFunctional()) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                if ($server->id === 0) {
 | 
			
		||||
                    continue;
 | 
			
		||||
                }
 | 
			
		||||
                $file = $server->proxyPath().'/dynamic/coolify.yaml';
 | 
			
		||||
                try {
 | 
			
		||||
                    if (! $server->isFunctional()) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    if ($server->id === 0) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    $file = $server->proxyPath().'/dynamic/coolify.yaml';
 | 
			
		||||
 | 
			
		||||
                return instant_remote_process([
 | 
			
		||||
                    "rm -f $file",
 | 
			
		||||
                ], $server, false);
 | 
			
		||||
                    return instant_remote_process([
 | 
			
		||||
                        "rm -f $file",
 | 
			
		||||
                    ], $server, false);
 | 
			
		||||
                } catch (\Throwable $e) {
 | 
			
		||||
                    echo "Error in cleaning up unnecessary dynamic proxy configuration: {$e->getMessage()}\n";
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -124,7 +132,6 @@ class Init extends Command
 | 
			
		||||
 | 
			
		||||
    private function cleanup_unused_network_from_coolify_proxy()
 | 
			
		||||
    {
 | 
			
		||||
        ray()->clearAll();
 | 
			
		||||
        foreach ($this->servers as $server) {
 | 
			
		||||
            if (! $server->isFunctional()) {
 | 
			
		||||
                continue;
 | 
			
		||||
@@ -132,29 +139,33 @@ class Init extends Command
 | 
			
		||||
            if (! $server->isProxyShouldRun()) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            ['networks' => $networks, 'allNetworks' => $allNetworks] = collectDockerNetworksByServer($server);
 | 
			
		||||
            $removeNetworks = $allNetworks->diff($networks);
 | 
			
		||||
            $commands = collect();
 | 
			
		||||
            foreach ($removeNetworks as $network) {
 | 
			
		||||
                $out = instant_remote_process(["docker network inspect -f json $network | jq '.[].Containers | if . == {} then null else . end'"], $server, false);
 | 
			
		||||
                if (empty($out)) {
 | 
			
		||||
                    $commands->push("docker network disconnect $network coolify-proxy >/dev/null 2>&1 || true");
 | 
			
		||||
                    $commands->push("docker network rm $network >/dev/null 2>&1 || true");
 | 
			
		||||
                } else {
 | 
			
		||||
                    $data = collect(json_decode($out, true));
 | 
			
		||||
                    if ($data->count() === 1) {
 | 
			
		||||
                        // If only coolify-proxy itself is connected to that network (it should not be possible, but who knows)
 | 
			
		||||
                        $isCoolifyProxyItself = data_get($data->first(), 'Name') === 'coolify-proxy';
 | 
			
		||||
                        if ($isCoolifyProxyItself) {
 | 
			
		||||
                            $commands->push("docker network disconnect $network coolify-proxy >/dev/null 2>&1 || true");
 | 
			
		||||
                            $commands->push("docker network rm $network >/dev/null 2>&1 || true");
 | 
			
		||||
            try {
 | 
			
		||||
                ['networks' => $networks, 'allNetworks' => $allNetworks] = collectDockerNetworksByServer($server);
 | 
			
		||||
                $removeNetworks = $allNetworks->diff($networks);
 | 
			
		||||
                $commands = collect();
 | 
			
		||||
                foreach ($removeNetworks as $network) {
 | 
			
		||||
                    $out = instant_remote_process(["docker network inspect -f json $network | jq '.[].Containers | if . == {} then null else . end'"], $server, false);
 | 
			
		||||
                    if (empty($out)) {
 | 
			
		||||
                        $commands->push("docker network disconnect $network coolify-proxy >/dev/null 2>&1 || true");
 | 
			
		||||
                        $commands->push("docker network rm $network >/dev/null 2>&1 || true");
 | 
			
		||||
                    } else {
 | 
			
		||||
                        $data = collect(json_decode($out, true));
 | 
			
		||||
                        if ($data->count() === 1) {
 | 
			
		||||
                            // If only coolify-proxy itself is connected to that network (it should not be possible, but who knows)
 | 
			
		||||
                            $isCoolifyProxyItself = data_get($data->first(), 'Name') === 'coolify-proxy';
 | 
			
		||||
                            if ($isCoolifyProxyItself) {
 | 
			
		||||
                                $commands->push("docker network disconnect $network coolify-proxy >/dev/null 2>&1 || true");
 | 
			
		||||
                                $commands->push("docker network rm $network >/dev/null 2>&1 || true");
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            if ($commands->isNotEmpty()) {
 | 
			
		||||
                echo "Cleaning up unused networks from coolify proxy\n";
 | 
			
		||||
                remote_process(command: $commands, type: ActivityTypes::INLINE->value, server: $server, ignore_errors: false);
 | 
			
		||||
                if ($commands->isNotEmpty()) {
 | 
			
		||||
                    echo "Cleaning up unused networks from coolify proxy\n";
 | 
			
		||||
                    remote_process(command: $commands, type: ActivityTypes::INLINE->value, server: $server, ignore_errors: false);
 | 
			
		||||
                }
 | 
			
		||||
            } catch (\Throwable $e) {
 | 
			
		||||
                echo "Error in cleaning up unused networks from coolify proxy: {$e->getMessage()}\n";
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -231,7 +242,6 @@ class Init extends Command
 | 
			
		||||
    private function cleanup_in_progress_application_deployments()
 | 
			
		||||
    {
 | 
			
		||||
        // Cleanup any failed deployments
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            if (isCloud()) {
 | 
			
		||||
                return;
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ use Illuminate\Contracts\Queue\ShouldBeEncrypted;
 | 
			
		||||
use Illuminate\Contracts\Queue\ShouldQueue;
 | 
			
		||||
use Illuminate\Foundation\Bus\Dispatchable;
 | 
			
		||||
use Illuminate\Queue\InteractsWithQueue;
 | 
			
		||||
use Illuminate\Queue\Middleware\WithoutOverlapping;
 | 
			
		||||
use Illuminate\Queue\SerializesModels;
 | 
			
		||||
use Illuminate\Support\Arr;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,7 +16,7 @@ class SettingsBackup extends Component
 | 
			
		||||
 | 
			
		||||
    public $s3s;
 | 
			
		||||
 | 
			
		||||
    public StandalonePostgresql|null|array $database = [];
 | 
			
		||||
    public ?StandalonePostgresql $database = null;
 | 
			
		||||
 | 
			
		||||
    public ScheduledDatabaseBackup|null|array $backup = [];
 | 
			
		||||
 | 
			
		||||
@@ -43,19 +43,19 @@ class SettingsBackup extends Component
 | 
			
		||||
    {
 | 
			
		||||
        if (isInstanceAdmin()) {
 | 
			
		||||
            $settings = InstanceSettings::get();
 | 
			
		||||
            $database = StandalonePostgresql::whereName('coolify-db')->first();
 | 
			
		||||
            $this->database = StandalonePostgresql::whereName('coolify-db')->first();
 | 
			
		||||
            $s3s = S3Storage::whereTeamId(0)->get() ?? [];
 | 
			
		||||
            if ($database) {
 | 
			
		||||
                if ($database->status !== 'running') {
 | 
			
		||||
                    $database->status = 'running';
 | 
			
		||||
                    $database->save();
 | 
			
		||||
            if ($this->database) {
 | 
			
		||||
                if ($this->database->status !== 'running') {
 | 
			
		||||
                    $this->database->status = 'running';
 | 
			
		||||
                    $this->database->save();
 | 
			
		||||
                }
 | 
			
		||||
                $this->database = $database;
 | 
			
		||||
                $this->backup = $this->database->scheduledBackups->first();
 | 
			
		||||
                $this->executions = $this->backup->executions;
 | 
			
		||||
            }
 | 
			
		||||
            $this->settings = $settings;
 | 
			
		||||
            $this->s3s = $s3s;
 | 
			
		||||
            $this->backup = $this->database?->scheduledBackups?->first() ?? null;
 | 
			
		||||
            $this->executions = $this->backup?->executions ?? [];
 | 
			
		||||
 | 
			
		||||
        } else {
 | 
			
		||||
            return redirect()->route('dashboard');
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -715,8 +715,8 @@ $schema://$host {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return [
 | 
			
		||||
            'containers' => $containers ?? collect([]),
 | 
			
		||||
            'containerReplicates' => $containerReplicates ?? collect([]),
 | 
			
		||||
            'containers' => collect($containers) ?? collect([]),
 | 
			
		||||
            'containerReplicates' => collect($containerReplicates) ?? collect([]),
 | 
			
		||||
        ];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,11 @@ const VALID_CRON_STRINGS = [
 | 
			
		||||
    'weekly' => '0 0 * * 0',
 | 
			
		||||
    'monthly' => '0 0 1 * *',
 | 
			
		||||
    'yearly' => '0 0 1 1 *',
 | 
			
		||||
    '@hourly' => '0 * * * *',
 | 
			
		||||
    '@daily' => '0 0 * * *',
 | 
			
		||||
    '@weekly' => '0 0 * * 0',
 | 
			
		||||
    '@monthly' => '0 0 1 * *',
 | 
			
		||||
    '@yearly' => '0 0 1 1 *',
 | 
			
		||||
];
 | 
			
		||||
const RESTART_MODE = 'unless-stopped';
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
use App\Actions\Proxy\SaveConfiguration;
 | 
			
		||||
use App\Enums\ProxyTypes;
 | 
			
		||||
use App\Models\Application;
 | 
			
		||||
use App\Models\Server;
 | 
			
		||||
use Symfony\Component\Yaml\Yaml;
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ return [
 | 
			
		||||
 | 
			
		||||
    // The release version of your application
 | 
			
		||||
    // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
 | 
			
		||||
    'release' => '4.0.0-beta.320',
 | 
			
		||||
    'release' => '4.0.0-beta.323',
 | 
			
		||||
    // When left empty or `null` the Laravel environment will be used
 | 
			
		||||
    'environment' => config('app.env'),
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,3 @@
 | 
			
		||||
<?php
 | 
			
		||||
 | 
			
		||||
return '4.0.0-beta.320';
 | 
			
		||||
return '4.0.0-beta.323';
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
<form class="flex flex-col w-full gap-2 rounded" wire:submit='submit'>
 | 
			
		||||
    <x-forms.input autofocus placeholder="0 0 * * * or daily" id="frequency" label="Frequency" required />
 | 
			
		||||
    <x-forms.input autofocus placeholder="0 0 * * * or daily" id="frequency"
 | 
			
		||||
        helper="You can use every_minute, hourly, daily, weekly, monthly, yearly or a cron expression." label="Frequency"
 | 
			
		||||
        required />
 | 
			
		||||
    <x-forms.checkbox id="save_s3" label="Save to S3" />
 | 
			
		||||
    <x-forms.select id="selected_storage_id">
 | 
			
		||||
        @if ($s3s->count() === 0)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,9 @@
 | 
			
		||||
<form class="flex flex-col w-full gap-2 rounded" wire:submit='submit'>
 | 
			
		||||
    <x-forms.input autofocus placeholder="Run cron" id="name" label="Name" />
 | 
			
		||||
    <x-forms.input placeholder="php artisan schedule:run" id="command" label="Command" />
 | 
			
		||||
    <x-forms.input placeholder="0 0 * * * or daily" id="frequency" label="Frequency" />
 | 
			
		||||
    <x-forms.input placeholder="0 0 * * * or daily"
 | 
			
		||||
        helper="You can use every_minute, hourly, daily, weekly, monthly, yearly or a cron expression." id="frequency"
 | 
			
		||||
        label="Frequency" />
 | 
			
		||||
    @if ($type === 'application')
 | 
			
		||||
        @if ($containerNames->count() > 1)
 | 
			
		||||
            <x-forms.select id="container" label="Container name">
 | 
			
		||||
 
 | 
			
		||||
@@ -14,7 +14,7 @@
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="pb-4">Backup configuration for Coolify instance.</div>
 | 
			
		||||
        <div>
 | 
			
		||||
            @if (isset($database))
 | 
			
		||||
            @if (isset($database) && isset($backup))
 | 
			
		||||
                <div class="flex flex-col gap-3 pb-4">
 | 
			
		||||
                    <div class="flex gap-2">
 | 
			
		||||
                        <x-forms.input label="UUID" readonly id="database.uuid" />
 | 
			
		||||
@@ -27,14 +27,15 @@
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <livewire:project.database.backup-edit :backup="$backup" :s3s="$s3s" :status="data_get($database, 'status')" />
 | 
			
		||||
                <div class="py-4">
 | 
			
		||||
                    <livewire:project.database.backup-executions :backup="$backup" />
 | 
			
		||||
                </div>
 | 
			
		||||
            @else
 | 
			
		||||
                To configure automatic backup for your Coolify instance, you first need to add a database resource
 | 
			
		||||
                into Coolify.
 | 
			
		||||
                <x-forms.button class="mt-2" wire:click="add_coolify_database">Add Database</x-forms.button>
 | 
			
		||||
            @endif
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="py-4">
 | 
			
		||||
            <livewire:project.database.backup-executions :backup="$backup" />
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
    </div>
 | 
			
		||||
</div>
 | 
			
		||||
 
 | 
			
		||||
@@ -60,13 +60,13 @@
 | 
			
		||||
            <div class="flex items-end gap-2">
 | 
			
		||||
                <x-forms.input required id="update_check_frequency" label="Update Check Frequency"
 | 
			
		||||
                    placeholder="0 * * * *"
 | 
			
		||||
                    helper="Cron expression for update check frequency (check for new Coolify versions and pull new Service Templates from CDN). Default is every hour." />
 | 
			
		||||
                    helper="Cron expression for update check frequency (check for new Coolify versions and pull new Service Templates from CDN).<br>You can use every_minute, hourly, daily, weekly, monthly, yearly.<br><br>Default is every hour." />
 | 
			
		||||
                <x-forms.button wire:click='checkManually'>Check Manually</x-forms.button>
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            @if (is_null(env('AUTOUPDATE', null)) && $is_auto_update_enabled)
 | 
			
		||||
                <x-forms.input required 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" />
 | 
			
		||||
                    helper="Cron expression for auto update frequency (automatically update coolify).<br>You can use every_minute, hourly, daily, weekly, monthly, yearly.<br><br>Default is every day at 00:00" />
 | 
			
		||||
            @endif
 | 
			
		||||
        </div>
 | 
			
		||||
    </form>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    "coolify": {
 | 
			
		||||
        "v4": {
 | 
			
		||||
            "version": "4.0.0-beta.320"
 | 
			
		||||
            "version": "4.0.0-beta.323"
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user