Merge branch 'next' into feat/scheduled-tasks-cron
This commit is contained in:
		@@ -31,7 +31,7 @@ Special thanks to our biggest sponsors, [CCCareers](https://cccareers.org/) and
 | 
				
			|||||||
<a href="https://github.com/whitesidest"><img src="https://avatars.githubusercontent.com/u/12365916?s=52&v=4" width="60px" alt="Tyler Whitesides" /></a>
 | 
					<a href="https://github.com/whitesidest"><img src="https://avatars.githubusercontent.com/u/12365916?s=52&v=4" width="60px" alt="Tyler Whitesides" /></a>
 | 
				
			||||||
<a href="https://github.com/aniftyco"><img src="https://github.com/aniftyco.png" width="60px" alt="NiftyCo" /></a>
 | 
					<a href="https://github.com/aniftyco"><img src="https://github.com/aniftyco.png" width="60px" alt="NiftyCo" /></a>
 | 
				
			||||||
<a href="https://github.com/iujlaki"><img src="https://github.com/iujlaki.png" width="60px" alt="Imre Ujlaki" /></a>
 | 
					<a href="https://github.com/iujlaki"><img src="https://github.com/iujlaki.png" width="60px" alt="Imre Ujlaki" /></a>
 | 
				
			||||||
<a href="https://github.com/Illyism"><img src="https://github.com/Illyism.png" width="60px" alt="Ilias Ism" /></a>
 | 
					<a href="https://il.ly"><img src="https://github.com/Illyism.png" width="60px" alt="Ilias Ism" /></a>
 | 
				
			||||||
<a href="https://github.com/urtho"><img src="https://github.com/urtho.png" width="60px" alt="Paweł Pierścionek" /></a>
 | 
					<a href="https://github.com/urtho"><img src="https://github.com/urtho.png" width="60px" alt="Paweł Pierścionek" /></a>
 | 
				
			||||||
<a href="https://github.com/monocursive"><img src="https://github.com/monocursive.png" width="60px" alt="Michael Mazurczak" /></a>
 | 
					<a href="https://github.com/monocursive"><img src="https://github.com/monocursive.png" width="60px" alt="Michael Mazurczak" /></a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -99,7 +99,7 @@ class Init extends Command
 | 
				
			|||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Http::get("https://get.coollabs.io/coolify/v4/alive?appId=$id&version=$version");
 | 
					            Http::get("https://undead.coollabs.io/coolify/v4/alive?appId=$id&version=$version");
 | 
				
			||||||
            echo "I am alive!\n";
 | 
					            echo "I am alive!\n";
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            echo "Error in alive: {$e->getMessage()}\n";
 | 
					            echo "Error in alive: {$e->getMessage()}\n";
 | 
				
			||||||
@@ -142,83 +142,83 @@ class Init extends Command
 | 
				
			|||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $applications = Application::withTrashed()->whereNotNull('deleted_at')->get();
 | 
					            $applications = Application::withTrashed()->whereNotNull('deleted_at')->get();
 | 
				
			||||||
            foreach ($applications as $application) {
 | 
					            foreach ($applications as $application) {
 | 
				
			||||||
                echo "Deleting stucked application: {$application->name}\n";
 | 
					                echo "Deleting stuck application: {$application->name}\n";
 | 
				
			||||||
                $application->forceDelete();
 | 
					                $application->forceDelete();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            echo "Error in cleaning stucked application: {$e->getMessage()}\n";
 | 
					            echo "Error in cleaning stuck application: {$e->getMessage()}\n";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $postgresqls = StandalonePostgresql::withTrashed()->whereNotNull('deleted_at')->get();
 | 
					            $postgresqls = StandalonePostgresql::withTrashed()->whereNotNull('deleted_at')->get();
 | 
				
			||||||
            foreach ($postgresqls as $postgresql) {
 | 
					            foreach ($postgresqls as $postgresql) {
 | 
				
			||||||
                echo "Deleting stucked postgresql: {$postgresql->name}\n";
 | 
					                echo "Deleting stuck postgresql: {$postgresql->name}\n";
 | 
				
			||||||
                $postgresql->forceDelete();
 | 
					                $postgresql->forceDelete();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            echo "Error in cleaning stucked postgresql: {$e->getMessage()}\n";
 | 
					            echo "Error in cleaning stuck postgresql: {$e->getMessage()}\n";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $redis = StandaloneRedis::withTrashed()->whereNotNull('deleted_at')->get();
 | 
					            $redis = StandaloneRedis::withTrashed()->whereNotNull('deleted_at')->get();
 | 
				
			||||||
            foreach ($redis as $redis) {
 | 
					            foreach ($redis as $redis) {
 | 
				
			||||||
                echo "Deleting stucked redis: {$redis->name}\n";
 | 
					                echo "Deleting stuck redis: {$redis->name}\n";
 | 
				
			||||||
                $redis->forceDelete();
 | 
					                $redis->forceDelete();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            echo "Error in cleaning stucked redis: {$e->getMessage()}\n";
 | 
					            echo "Error in cleaning stuck redis: {$e->getMessage()}\n";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $mongodbs = StandaloneMongodb::withTrashed()->whereNotNull('deleted_at')->get();
 | 
					            $mongodbs = StandaloneMongodb::withTrashed()->whereNotNull('deleted_at')->get();
 | 
				
			||||||
            foreach ($mongodbs as $mongodb) {
 | 
					            foreach ($mongodbs as $mongodb) {
 | 
				
			||||||
                echo "Deleting stucked mongodb: {$mongodb->name}\n";
 | 
					                echo "Deleting stuck mongodb: {$mongodb->name}\n";
 | 
				
			||||||
                $mongodb->forceDelete();
 | 
					                $mongodb->forceDelete();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            echo "Error in cleaning stucked mongodb: {$e->getMessage()}\n";
 | 
					            echo "Error in cleaning stuck mongodb: {$e->getMessage()}\n";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $mysqls = StandaloneMysql::withTrashed()->whereNotNull('deleted_at')->get();
 | 
					            $mysqls = StandaloneMysql::withTrashed()->whereNotNull('deleted_at')->get();
 | 
				
			||||||
            foreach ($mysqls as $mysql) {
 | 
					            foreach ($mysqls as $mysql) {
 | 
				
			||||||
                echo "Deleting stucked mysql: {$mysql->name}\n";
 | 
					                echo "Deleting stuck mysql: {$mysql->name}\n";
 | 
				
			||||||
                $mysql->forceDelete();
 | 
					                $mysql->forceDelete();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            echo "Error in cleaning stucked mysql: {$e->getMessage()}\n";
 | 
					            echo "Error in cleaning stuck mysql: {$e->getMessage()}\n";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $mariadbs = StandaloneMariadb::withTrashed()->whereNotNull('deleted_at')->get();
 | 
					            $mariadbs = StandaloneMariadb::withTrashed()->whereNotNull('deleted_at')->get();
 | 
				
			||||||
            foreach ($mariadbs as $mariadb) {
 | 
					            foreach ($mariadbs as $mariadb) {
 | 
				
			||||||
                echo "Deleting stucked mariadb: {$mariadb->name}\n";
 | 
					                echo "Deleting stuck mariadb: {$mariadb->name}\n";
 | 
				
			||||||
                $mariadb->forceDelete();
 | 
					                $mariadb->forceDelete();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            echo "Error in cleaning stucked mariadb: {$e->getMessage()}\n";
 | 
					            echo "Error in cleaning stuck mariadb: {$e->getMessage()}\n";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $services = Service::withTrashed()->whereNotNull('deleted_at')->get();
 | 
					            $services = Service::withTrashed()->whereNotNull('deleted_at')->get();
 | 
				
			||||||
            foreach ($services as $service) {
 | 
					            foreach ($services as $service) {
 | 
				
			||||||
                echo "Deleting stucked service: {$service->name}\n";
 | 
					                echo "Deleting stuck service: {$service->name}\n";
 | 
				
			||||||
                $service->forceDelete();
 | 
					                $service->forceDelete();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            echo "Error in cleaning stucked service: {$e->getMessage()}\n";
 | 
					            echo "Error in cleaning stuck service: {$e->getMessage()}\n";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $serviceApps = ServiceApplication::withTrashed()->whereNotNull('deleted_at')->get();
 | 
					            $serviceApps = ServiceApplication::withTrashed()->whereNotNull('deleted_at')->get();
 | 
				
			||||||
            foreach ($serviceApps as $serviceApp) {
 | 
					            foreach ($serviceApps as $serviceApp) {
 | 
				
			||||||
                echo "Deleting stucked serviceapp: {$serviceApp->name}\n";
 | 
					                echo "Deleting stuck serviceapp: {$serviceApp->name}\n";
 | 
				
			||||||
                $serviceApp->forceDelete();
 | 
					                $serviceApp->forceDelete();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            echo "Error in cleaning stucked serviceapp: {$e->getMessage()}\n";
 | 
					            echo "Error in cleaning stuck serviceapp: {$e->getMessage()}\n";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $serviceDbs = ServiceDatabase::withTrashed()->whereNotNull('deleted_at')->get();
 | 
					            $serviceDbs = ServiceDatabase::withTrashed()->whereNotNull('deleted_at')->get();
 | 
				
			||||||
            foreach ($serviceDbs as $serviceDb) {
 | 
					            foreach ($serviceDbs as $serviceDb) {
 | 
				
			||||||
                echo "Deleting stucked serviceapp: {$serviceDb->name}\n";
 | 
					                echo "Deleting stuck serviceapp: {$serviceDb->name}\n";
 | 
				
			||||||
                $serviceDb->forceDelete();
 | 
					                $serviceDb->forceDelete();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            echo "Error in cleaning stucked serviceapp: {$e->getMessage()}\n";
 | 
					            echo "Error in cleaning stuck serviceapp: {$e->getMessage()}\n";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Cleanup any resources that are not attached to any environment or destination or server
 | 
					        // Cleanup any resources that are not attached to any environment or destination or server
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,11 +2,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Http\Controllers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Events\TestEvent;
 | 
				
			||||||
use App\Models\InstanceSettings;
 | 
					use App\Models\InstanceSettings;
 | 
				
			||||||
use App\Models\S3Storage;
 | 
					use App\Models\S3Storage;
 | 
				
			||||||
use App\Models\StandalonePostgresql;
 | 
					use App\Models\StandalonePostgresql;
 | 
				
			||||||
use App\Models\TeamInvitation;
 | 
					use App\Models\TeamInvitation;
 | 
				
			||||||
use App\Models\User;
 | 
					use App\Models\User;
 | 
				
			||||||
 | 
					use App\Providers\RouteServiceProvider;
 | 
				
			||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
 | 
					use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
 | 
				
			||||||
use Illuminate\Foundation\Validation\ValidatesRequests;
 | 
					use Illuminate\Foundation\Validation\ValidatesRequests;
 | 
				
			||||||
use Illuminate\Routing\Controller as BaseController;
 | 
					use Illuminate\Routing\Controller as BaseController;
 | 
				
			||||||
@@ -14,11 +16,55 @@ use Illuminate\Support\Facades\Auth;
 | 
				
			|||||||
use Illuminate\Support\Facades\Crypt;
 | 
					use Illuminate\Support\Facades\Crypt;
 | 
				
			||||||
use Illuminate\Support\Facades\Hash;
 | 
					use Illuminate\Support\Facades\Hash;
 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					use Illuminate\Support\Str;
 | 
				
			||||||
 | 
					use Laravel\Fortify\Fortify;
 | 
				
			||||||
 | 
					use Laravel\Fortify\Contracts\FailedPasswordResetLinkRequestResponse;
 | 
				
			||||||
 | 
					use Laravel\Fortify\Contracts\SuccessfulPasswordResetLinkRequestResponse;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Password;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Controller extends BaseController
 | 
					class Controller extends BaseController
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    use AuthorizesRequests, ValidatesRequests;
 | 
					    use AuthorizesRequests, ValidatesRequests;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function realtime_test() {
 | 
				
			||||||
 | 
					        if (auth()->user()?->currentTeam()->id !== 0) {
 | 
				
			||||||
 | 
					            return redirect(RouteServiceProvider::HOME);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        TestEvent::dispatch();
 | 
				
			||||||
 | 
					        return 'Look at your other tab.';
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function verify() {
 | 
				
			||||||
 | 
					        return view('auth.verify-email');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function email_verify() {
 | 
				
			||||||
 | 
					        request()->fulfill();
 | 
				
			||||||
 | 
					        $name = request()->user()?->name;
 | 
				
			||||||
 | 
					        send_internal_notification("User {$name} verified their email address.");
 | 
				
			||||||
 | 
					        return redirect(RouteServiceProvider::HOME);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function forgot_password() {
 | 
				
			||||||
 | 
					        if (is_transactional_emails_active()) {
 | 
				
			||||||
 | 
					            $arrayOfRequest = request()->only(Fortify::email());
 | 
				
			||||||
 | 
					            request()->merge([
 | 
				
			||||||
 | 
					                'email' => Str::lower($arrayOfRequest['email']),
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					            $type = set_transanctional_email_settings();
 | 
				
			||||||
 | 
					            if (!$type) {
 | 
				
			||||||
 | 
					                return response()->json(['message' => 'Transactional emails are not active'], 400);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            request()->validate([Fortify::email() => 'required|email']);
 | 
				
			||||||
 | 
					            $status = Password::broker(config('fortify.passwords'))->sendResetLink(
 | 
				
			||||||
 | 
					                request()->only(Fortify::email())
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					            if ($status == Password::RESET_LINK_SENT) {
 | 
				
			||||||
 | 
					                return app(SuccessfulPasswordResetLinkRequestResponse::class, ['status' => $status]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if ($status == Password::RESET_THROTTLED) {
 | 
				
			||||||
 | 
					                return response('Already requested a password reset in the past minutes.', 400);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return app(FailedPasswordResetLinkRequestResponse::class, ['status' => $status]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return response()->json(['message' => 'Transactional emails are not active'], 400);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    public function link()
 | 
					    public function link()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $token = request()->get('token');
 | 
					        $token = request()->get('token');
 | 
				
			||||||
@@ -51,90 +97,7 @@ class Controller extends BaseController
 | 
				
			|||||||
        return redirect()->route('login')->with('error', 'Invalid credentials.');
 | 
					        return redirect()->route('login')->with('error', 'Invalid credentials.');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function license()
 | 
					    public function accept_invitation()
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (!isCloud()) {
 | 
					 | 
				
			||||||
            abort(404);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return view('settings.license', [
 | 
					 | 
				
			||||||
            'settings' => InstanceSettings::get(),
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function force_passoword_reset()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return view('auth.force-password-reset');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    public function boarding()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (currentTeam()->boarding || isDev()) {
 | 
					 | 
				
			||||||
            return view('boarding');
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function settings()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        if (isInstanceAdmin()) {
 | 
					 | 
				
			||||||
            $settings = InstanceSettings::get();
 | 
					 | 
				
			||||||
            $database = StandalonePostgresql::whereName('coolify-db')->first();
 | 
					 | 
				
			||||||
            if ($database) {
 | 
					 | 
				
			||||||
                if ($database->status !== 'running') {
 | 
					 | 
				
			||||||
                    $database->status = 'running';
 | 
					 | 
				
			||||||
                    $database->save();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                $s3s = S3Storage::whereTeamId(0)->get();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return view('settings.configuration', [
 | 
					 | 
				
			||||||
                'settings' => $settings,
 | 
					 | 
				
			||||||
                'database' => $database,
 | 
					 | 
				
			||||||
                's3s' => $s3s ?? [],
 | 
					 | 
				
			||||||
            ]);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function team()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $invitations = [];
 | 
					 | 
				
			||||||
        if (auth()->user()->isAdminFromSession()) {
 | 
					 | 
				
			||||||
            $invitations = TeamInvitation::whereTeamId(currentTeam()->id)->get();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return view('team.index', [
 | 
					 | 
				
			||||||
            'invitations' => $invitations,
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function storages()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $s3 = S3Storage::ownedByCurrentTeam()->get();
 | 
					 | 
				
			||||||
        return view('team.storages.all', [
 | 
					 | 
				
			||||||
            's3' => $s3,
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function storages_show()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $storage = S3Storage::ownedByCurrentTeam()->whereUuid(request()->storage_uuid)->firstOrFail();
 | 
					 | 
				
			||||||
        return view('team.storages.show', [
 | 
					 | 
				
			||||||
            'storage' => $storage,
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function members()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $invitations = [];
 | 
					 | 
				
			||||||
        if (auth()->user()->isAdminFromSession()) {
 | 
					 | 
				
			||||||
            $invitations = TeamInvitation::whereTeamId(currentTeam()->id)->get();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return view('team.members', [
 | 
					 | 
				
			||||||
            'invitations' => $invitations,
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function acceptInvitation()
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $resetPassword = request()->query('reset-password');
 | 
					            $resetPassword = request()->query('reset-password');
 | 
				
			||||||
@@ -169,7 +132,7 @@ class Controller extends BaseController
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function revokeInvitation()
 | 
					    public function revoke_invitation()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $invitation = TeamInvitation::whereUuid(request()->route('uuid'))->firstOrFail();
 | 
					            $invitation = TeamInvitation::whereUuid(request()->route('uuid'))->firstOrFail();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,84 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
 | 
					 | 
				
			||||||
use Illuminate\Foundation\Validation\ValidatesRequests;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DatabaseController extends Controller
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    use AuthorizesRequests, ValidatesRequests;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function configuration()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
 | 
					 | 
				
			||||||
        if (!$project) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
 | 
					 | 
				
			||||||
        if (!$environment) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $database = $environment->databases()->where('uuid', request()->route('database_uuid'))->first();
 | 
					 | 
				
			||||||
        if (!$database) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return view('project.database.configuration', ['database' => $database]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function executions()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $backup_uuid = request()->route('backup_uuid');
 | 
					 | 
				
			||||||
        $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
 | 
					 | 
				
			||||||
        if (!$project) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
 | 
					 | 
				
			||||||
        if (!$environment) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $database = $environment->databases()->where('uuid', request()->route('database_uuid'))->first();
 | 
					 | 
				
			||||||
        if (!$database) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $backup = $database->scheduledBackups->where('uuid', $backup_uuid)->first();
 | 
					 | 
				
			||||||
        if (!$backup) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $executions = collect($backup->executions)->sortByDesc('created_at');
 | 
					 | 
				
			||||||
        return view('project.database.backups.executions', [
 | 
					 | 
				
			||||||
            'database' => $database,
 | 
					 | 
				
			||||||
            'backup' => $backup,
 | 
					 | 
				
			||||||
            'executions' => $executions,
 | 
					 | 
				
			||||||
            's3s' => currentTeam()->s3s,
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function backups()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
 | 
					 | 
				
			||||||
        if (!$project) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
 | 
					 | 
				
			||||||
        if (!$environment) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $database = $environment->databases()->where('uuid', request()->route('database_uuid'))->first();
 | 
					 | 
				
			||||||
        if (!$database) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        // No backups for redis
 | 
					 | 
				
			||||||
        if ($database->getMorphClass() === 'App\Models\StandaloneRedis') {
 | 
					 | 
				
			||||||
            return redirect()->route('project.database.configuration', [
 | 
					 | 
				
			||||||
                'project_uuid' => $project->uuid,
 | 
					 | 
				
			||||||
                'environment_name' => $environment->name,
 | 
					 | 
				
			||||||
                'database_uuid' => $database->uuid,
 | 
					 | 
				
			||||||
            ]);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return view('project.database.backups.all', [
 | 
					 | 
				
			||||||
            'database' => $database,
 | 
					 | 
				
			||||||
            's3s' => currentTeam()->s3s,
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -30,6 +30,7 @@ use Spatie\Url\Url;
 | 
				
			|||||||
use Symfony\Component\Yaml\Yaml;
 | 
					use Symfony\Component\Yaml\Yaml;
 | 
				
			||||||
use Throwable;
 | 
					use Throwable;
 | 
				
			||||||
use Visus\Cuid2\Cuid2;
 | 
					use Visus\Cuid2\Cuid2;
 | 
				
			||||||
 | 
					use Yosymfony\Toml\Toml;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
					class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -73,6 +74,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
    private $env_args;
 | 
					    private $env_args;
 | 
				
			||||||
    private $docker_compose;
 | 
					    private $docker_compose;
 | 
				
			||||||
    private $docker_compose_base64;
 | 
					    private $docker_compose_base64;
 | 
				
			||||||
 | 
					    private ?string $nixpacks_plan = null;
 | 
				
			||||||
 | 
					    private ?string $nixpacks_type = null;
 | 
				
			||||||
    private string $dockerfile_location = '/Dockerfile';
 | 
					    private string $dockerfile_location = '/Dockerfile';
 | 
				
			||||||
    private string $docker_compose_location = '/docker-compose.yml';
 | 
					    private string $docker_compose_location = '/docker-compose.yml';
 | 
				
			||||||
    private ?string $docker_compose_custom_start_command = null;
 | 
					    private ?string $docker_compose_custom_start_command = null;
 | 
				
			||||||
@@ -170,7 +173,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
                    if ($containerName === 'coolify-proxy') {
 | 
					                    if ($containerName === 'coolify-proxy') {
 | 
				
			||||||
                        continue;
 | 
					                        continue;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if (preg_match('/-(\d{12})/',$containerName)) {
 | 
					                    if (preg_match('/-(\d{12})/', $containerName)) {
 | 
				
			||||||
                        continue;
 | 
					                        continue;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    $containerIp = data_get($container, 'IPv4Address');
 | 
					                    $containerIp = data_get($container, 'IPv4Address');
 | 
				
			||||||
@@ -347,6 +350,9 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
        $this->generate_image_names();
 | 
					        $this->generate_image_names();
 | 
				
			||||||
        $this->check_image_locally_or_remotely();
 | 
					        $this->check_image_locally_or_remotely();
 | 
				
			||||||
        if (str($this->saved_outputs->get('local_image_found'))->isNotEmpty()) {
 | 
					        if (str($this->saved_outputs->get('local_image_found'))->isNotEmpty()) {
 | 
				
			||||||
 | 
					            $this->execute_remote_command([
 | 
				
			||||||
 | 
					                "echo 'Image found ({$this->production_image_name}) with the same Git Commit SHA. Restarting container.'",
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
            $this->create_workdir();
 | 
					            $this->create_workdir();
 | 
				
			||||||
            $this->generate_compose_file();
 | 
					            $this->generate_compose_file();
 | 
				
			||||||
            $this->rolling_update();
 | 
					            $this->rolling_update();
 | 
				
			||||||
@@ -579,7 +585,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
        $this->generate_nixpacks_confs();
 | 
					        $this->generate_nixpacks_confs();
 | 
				
			||||||
        $this->generate_compose_file();
 | 
					        $this->generate_compose_file();
 | 
				
			||||||
        $this->generate_build_env_variables();
 | 
					        $this->generate_build_env_variables();
 | 
				
			||||||
        $this->add_build_env_variables_to_dockerfile();
 | 
					        // $this->add_build_env_variables_to_dockerfile();
 | 
				
			||||||
        $this->build_image();
 | 
					        $this->build_image();
 | 
				
			||||||
        $this->rolling_update();
 | 
					        $this->rolling_update();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -601,6 +607,24 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
        $this->rolling_update();
 | 
					        $this->rolling_update();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private function framework_based_notification()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // Laravel old env variables
 | 
				
			||||||
 | 
					        if ($this->pull_request_id === 0) {
 | 
				
			||||||
 | 
					            $nixpacks_php_fallback_path = $this->application->environment_variables->where('key', 'NIXPACKS_PHP_FALLBACK_PATH')->first();
 | 
				
			||||||
 | 
					            $nixpacks_php_root_dir = $this->application->environment_variables->where('key', 'NIXPACKS_PHP_ROOT_DIR')->first();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $nixpacks_php_fallback_path = $this->application->environment_variables_preview->where('key', 'NIXPACKS_PHP_FALLBACK_PATH')->first();
 | 
				
			||||||
 | 
					            $nixpacks_php_root_dir = $this->application->environment_variables_preview->where('key', 'NIXPACKS_PHP_ROOT_DIR')->first();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ($nixpacks_php_fallback_path?->value === '/index.php' && $nixpacks_php_root_dir?->value === '/app/public' && $this->newVersionIsHealthy === false) {
 | 
				
			||||||
 | 
					            $this->execute_remote_command(
 | 
				
			||||||
 | 
					                [
 | 
				
			||||||
 | 
					                    "echo 'There was a change in how Laravel is deployed. Please update your environment variables to match the new deployment method. More details here: https://coolify.io/docs/frameworks/laravel#requirements'", 'type' => 'err'
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    private function rolling_update()
 | 
					    private function rolling_update()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($this->server->isSwarm()) {
 | 
					        if ($this->server->isSwarm()) {
 | 
				
			||||||
@@ -637,6 +661,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
                $this->application_deployment_queue->addLogEntry("Rolling update completed.");
 | 
					                $this->application_deployment_queue->addLogEntry("Rolling update completed.");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        $this->framework_based_notification();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    private function health_check()
 | 
					    private function health_check()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -676,7 +701,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
                            "echo 'Attempt {$counter} of {$this->application->health_check_retries} | Healthcheck status: {$this->saved_outputs->get('health_check')}'"
 | 
					                            "echo 'Attempt {$counter} of {$this->application->health_check_retries} | Healthcheck status: {$this->saved_outputs->get('health_check')}'"
 | 
				
			||||||
                        ],
 | 
					                        ],
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
                    if (Str::of($this->saved_outputs->get('health_check'))->contains('healthy')) {
 | 
					                    if (Str::of($this->saved_outputs->get('health_check'))->replace('"', '')->value() === 'healthy') {
 | 
				
			||||||
                        $this->newVersionIsHealthy = true;
 | 
					                        $this->newVersionIsHealthy = true;
 | 
				
			||||||
                        $this->application->update(['status' => 'running']);
 | 
					                        $this->application->update(['status' => 'running']);
 | 
				
			||||||
                        $this->execute_remote_command(
 | 
					                        $this->execute_remote_command(
 | 
				
			||||||
@@ -686,6 +711,10 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
                        );
 | 
					                        );
 | 
				
			||||||
                        break;
 | 
					                        break;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (Str::of($this->saved_outputs->get('health_check'))->replace('"', '')->value() === 'unhealthy') {
 | 
				
			||||||
 | 
					                        $this->newVersionIsHealthy = false;
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                    $counter++;
 | 
					                    $counter++;
 | 
				
			||||||
                    sleep($this->application->health_check_interval);
 | 
					                    sleep($this->application->health_check_interval);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -870,20 +899,28 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
            [
 | 
					            [
 | 
				
			||||||
                "echo -n 'Generating nixpacks configuration with: $nixpacks_command'",
 | 
					                "echo -n 'Generating nixpacks configuration with: $nixpacks_command'",
 | 
				
			||||||
            ],
 | 
					            ],
 | 
				
			||||||
            [executeInDocker($this->deployment_uuid, $nixpacks_command)],
 | 
					            [executeInDocker($this->deployment_uuid, $nixpacks_command), "save" => "nixpacks_plan", "hidden" => true],
 | 
				
			||||||
            [executeInDocker($this->deployment_uuid, "cp {$this->workdir}/.nixpacks/Dockerfile {$this->workdir}/Dockerfile")],
 | 
					            [executeInDocker($this->deployment_uuid, "nixpacks detect {$this->workdir}"), "save" => "nixpacks_type", "hidden" => true],
 | 
				
			||||||
            [executeInDocker($this->deployment_uuid, "rm -f {$this->workdir}/.nixpacks/Dockerfile")]
 | 
					 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					        if ($this->saved_outputs->get('nixpacks_type')) {
 | 
				
			||||||
 | 
					            $this->nixpacks_type = $this->saved_outputs->get('nixpacks_type');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if ($this->saved_outputs->get('nixpacks_plan')) {
 | 
				
			||||||
 | 
					            $this->nixpacks_plan = $this->saved_outputs->get('nixpacks_plan');
 | 
				
			||||||
 | 
					            if ($this->nixpacks_plan) {
 | 
				
			||||||
 | 
					                $parsed = Toml::Parse($this->nixpacks_plan);
 | 
				
			||||||
 | 
					                // Do any modifications here
 | 
				
			||||||
 | 
					                $cmds = collect(data_get($parsed, 'phases.setup.cmds', []));
 | 
				
			||||||
 | 
					                data_set($parsed, 'phases.setup.cmds', $cmds);
 | 
				
			||||||
 | 
					                $this->nixpacks_plan = json_encode($parsed);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private function nixpacks_build_cmd()
 | 
					    private function nixpacks_build_cmd()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->generate_env_variables();
 | 
					        $this->generate_env_variables();
 | 
				
			||||||
        // $cacheKey = $this->application->uuid;
 | 
					        $nixpacks_command = "nixpacks plan -f toml {$this->env_args}";
 | 
				
			||||||
        // if ($this->pull_request_id !== 0) {
 | 
					 | 
				
			||||||
            // $cacheKey = "{$this->application->uuid}-pr-{$this->pull_request_id}";
 | 
					 | 
				
			||||||
        // }
 | 
					 | 
				
			||||||
        $nixpacks_command = "nixpacks build {$this->env_args} --no-error-without-start";
 | 
					 | 
				
			||||||
        if ($this->application->build_command) {
 | 
					        if ($this->application->build_command) {
 | 
				
			||||||
            $nixpacks_command .= " --build-cmd \"{$this->application->build_command}\"";
 | 
					            $nixpacks_command .= " --build-cmd \"{$this->application->build_command}\"";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -893,7 +930,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
        if ($this->application->install_command) {
 | 
					        if ($this->application->install_command) {
 | 
				
			||||||
            $nixpacks_command .= " --install-cmd \"{$this->application->install_command}\"";
 | 
					            $nixpacks_command .= " --install-cmd \"{$this->application->install_command}\"";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $nixpacks_command .= " -o {$this->workdir} {$this->workdir}";
 | 
					        $nixpacks_command .= " {$this->workdir}";
 | 
				
			||||||
        return $nixpacks_command;
 | 
					        return $nixpacks_command;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -904,10 +941,16 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
            foreach ($this->application->nixpacks_environment_variables as $env) {
 | 
					            foreach ($this->application->nixpacks_environment_variables as $env) {
 | 
				
			||||||
                $this->env_args->push("--env {$env->key}={$env->value}");
 | 
					                $this->env_args->push("--env {$env->key}={$env->value}");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            foreach ($this->application->build_environment_variables as $env) {
 | 
				
			||||||
 | 
					                $this->env_args->push("--env {$env->key}={$env->value}");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            foreach ($this->application->nixpacks_environment_variables_preview as $env) {
 | 
					            foreach ($this->application->nixpacks_environment_variables_preview as $env) {
 | 
				
			||||||
                $this->env_args->push("--env {$env->key}={$env->value}");
 | 
					                $this->env_args->push("--env {$env->key}={$env->value}");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            foreach ($this->application->build_environment_variables_preview as $env) {
 | 
				
			||||||
 | 
					                $this->env_args->push("--env {$env->key}={$env->value}");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $this->env_args = $this->env_args->implode(' ');
 | 
					        $this->env_args = $this->env_args->implode(' ');
 | 
				
			||||||
@@ -1231,22 +1274,28 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
 | 
				
			|||||||
            }");
 | 
					            }");
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                if ($this->application->build_pack === 'nixpacks') {
 | 
					                if ($this->application->build_pack === 'nixpacks') {
 | 
				
			||||||
                    $this->execute_remote_command(
 | 
					                    $this->nixpacks_plan = base64_encode($this->nixpacks_plan);
 | 
				
			||||||
                        [
 | 
					                    $this->execute_remote_command([executeInDocker($this->deployment_uuid, "echo '{$this->nixpacks_plan}' | base64 -d > {$this->workdir}/thegameplan.json"), "hidden" => true]);
 | 
				
			||||||
                            executeInDocker($this->deployment_uuid, "cp {$this->workdir}/Dockerfile {$this->workdir}/.nixpacks/Dockerfile")
 | 
					                    if ($this->force_rebuild) {
 | 
				
			||||||
                        ],
 | 
					                        $this->execute_remote_command([
 | 
				
			||||||
                    );
 | 
					                            executeInDocker($this->deployment_uuid, "nixpacks build -c thegameplan.json --no-cache --no-error-without-start -n {$this->build_image_name} {$this->workdir}"), "hidden" => true
 | 
				
			||||||
                }
 | 
					                        ]);
 | 
				
			||||||
                if ($this->force_rebuild) {
 | 
					                    } else {
 | 
				
			||||||
                    $this->execute_remote_command([
 | 
					                        $this->execute_remote_command([
 | 
				
			||||||
                        executeInDocker($this->deployment_uuid, "docker build --no-cache $this->buildTarget $this->addHosts --network host -f {$this->workdir}{$this->dockerfile_location} {$this->build_args} --progress plain -t $this->build_image_name {$this->workdir}"), "hidden" => true
 | 
					                            executeInDocker($this->deployment_uuid, "nixpacks build -c thegameplan.json --cache-key '{$this->application->uuid}' --no-error-without-start -n {$this->build_image_name} {$this->workdir}"), "hidden" => true
 | 
				
			||||||
                    ]);
 | 
					                        ]);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    $this->execute_remote_command([
 | 
					                    if ($this->force_rebuild) {
 | 
				
			||||||
                        executeInDocker($this->deployment_uuid, "docker build $this->buildTarget $this->addHosts --network host -f {$this->workdir}{$this->dockerfile_location} {$this->build_args} --progress plain -t $this->build_image_name {$this->workdir}"), "hidden" => true
 | 
					                        $this->execute_remote_command([
 | 
				
			||||||
                    ]);
 | 
					                            executeInDocker($this->deployment_uuid, "docker build --no-cache {$this->buildTarget} --network {$this->destination->network} -f {$this->workdir}{$this->dockerfile_location} {$this->build_args} --progress plain -t $this->build_image_name {$this->workdir}"), "hidden" => true
 | 
				
			||||||
 | 
					                        ]);
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        $this->execute_remote_command([
 | 
				
			||||||
 | 
					                            executeInDocker($this->deployment_uuid, "docker build {$this->buildTarget} --network {$this->destination->network} -f {$this->workdir}{$this->dockerfile_location} {$this->build_args} --progress plain -t $this->build_image_name {$this->workdir}"), "hidden" => true
 | 
				
			||||||
 | 
					                        ]);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                // }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                $dockerfile = base64_encode("FROM {$this->application->static_image}
 | 
					                $dockerfile = base64_encode("FROM {$this->application->static_image}
 | 
				
			||||||
WORKDIR /usr/share/nginx/html/
 | 
					WORKDIR /usr/share/nginx/html/
 | 
				
			||||||
@@ -1279,32 +1328,38 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
 | 
				
			|||||||
                    executeInDocker($this->deployment_uuid, "echo '{$nginx_config}' | base64 -d > {$this->workdir}/nginx.conf")
 | 
					                    executeInDocker($this->deployment_uuid, "echo '{$nginx_config}' | base64 -d > {$this->workdir}/nginx.conf")
 | 
				
			||||||
                ],
 | 
					                ],
 | 
				
			||||||
                [
 | 
					                [
 | 
				
			||||||
                    executeInDocker($this->deployment_uuid, "docker build $this->addHosts --network host -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true
 | 
					                    executeInDocker($this->deployment_uuid, "docker build {$this->addHosts} --network host -f {$this->workdir}/Dockerfile {$this->build_args} --progress plain -t {$this->production_image_name} {$this->workdir}"), "hidden" => true
 | 
				
			||||||
                ]
 | 
					                ]
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            // Pure Dockerfile based deployment
 | 
					            // Pure Dockerfile based deployment
 | 
				
			||||||
            if ($this->application->dockerfile) {
 | 
					            if ($this->application->dockerfile) {
 | 
				
			||||||
                $this->execute_remote_command([
 | 
					                $this->execute_remote_command([
 | 
				
			||||||
                    executeInDocker($this->deployment_uuid, "docker build --pull $this->buildTarget $this->addHosts --network host -f {$this->workdir}{$this->dockerfile_location} {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true
 | 
					                    executeInDocker($this->deployment_uuid, "docker build --pull {$this->buildTarget} {$this->addHosts} --network host -f {$this->workdir}{$this->dockerfile_location} {$this->build_args} --progress plain -t {$this->production_image_name} {$this->workdir}"), "hidden" => true
 | 
				
			||||||
                ]);
 | 
					                ]);
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                if ($this->application->build_pack === 'nixpacks') {
 | 
					                if ($this->application->build_pack === 'nixpacks') {
 | 
				
			||||||
                    $this->execute_remote_command(
 | 
					                    $this->nixpacks_plan = base64_encode($this->nixpacks_plan);
 | 
				
			||||||
                        [
 | 
					                    $this->execute_remote_command([executeInDocker($this->deployment_uuid, "echo '{$this->nixpacks_plan}' | base64 -d > {$this->workdir}/thegameplan.json"), "hidden" => true]);
 | 
				
			||||||
                            executeInDocker($this->deployment_uuid, "cp {$this->workdir}/Dockerfile {$this->workdir}/.nixpacks/Dockerfile")
 | 
					                    if ($this->force_rebuild) {
 | 
				
			||||||
                        ],
 | 
					                        $this->execute_remote_command([
 | 
				
			||||||
                    );
 | 
					                            executeInDocker($this->deployment_uuid, "nixpacks build -c thegameplan.json --no-cache --no-error-without-start -n {$this->production_image_name} {$this->workdir}"), "hidden" => true
 | 
				
			||||||
                }
 | 
					                        ]);
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
                if ($this->force_rebuild) {
 | 
					                        $this->execute_remote_command([
 | 
				
			||||||
                    $this->execute_remote_command([
 | 
					                            executeInDocker($this->deployment_uuid, "nixpacks build -c thegameplan.json --cache-key '{$this->application->uuid}' --no-error-without-start -n {$this->production_image_name} {$this->workdir}"), "hidden" => true
 | 
				
			||||||
                        executeInDocker($this->deployment_uuid, "docker build --no-cache $this->buildTarget $this->addHosts --network host -f {$this->workdir}{$this->dockerfile_location} {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true
 | 
					                        ]);
 | 
				
			||||||
                    ]);
 | 
					                    }
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    $this->execute_remote_command([
 | 
					                    if ($this->force_rebuild) {
 | 
				
			||||||
                        executeInDocker($this->deployment_uuid, "docker build $this->buildTarget $this->addHosts --network host -f {$this->workdir}{$this->dockerfile_location} {$this->build_args} --progress plain -t $this->production_image_name {$this->workdir}"), "hidden" => true
 | 
					                        $this->execute_remote_command([
 | 
				
			||||||
                    ]);
 | 
					                            executeInDocker($this->deployment_uuid, "docker build --no-cache {$this->buildTarget} {$this->addHosts} --network host -f {$this->workdir}{$this->dockerfile_location} {$this->build_args} --progress plain -t {$this->production_image_name} {$this->workdir}"), "hidden" => true
 | 
				
			||||||
 | 
					                        ]);
 | 
				
			||||||
 | 
					                    } else {
 | 
				
			||||||
 | 
					                        $this->execute_remote_command([
 | 
				
			||||||
 | 
					                            executeInDocker($this->deployment_uuid, "docker build  {$this->buildTarget} {$this->addHosts} --network host -f {$this->workdir}{$this->dockerfile_location} {$this->build_args} --progress plain -t {$this->production_image_name} {$this->workdir}"), "hidden" => true
 | 
				
			||||||
 | 
					                        ]);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -162,6 +162,10 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
                            // Notify user that this container should not be there.
 | 
					                            // Notify user that this container should not be there.
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    if (data_get($container,'Name') === '/coolify-db') {
 | 
				
			||||||
 | 
					                        $foundDatabases[] = 0;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                $serviceLabelId = data_get($labels, 'coolify.serviceId');
 | 
					                $serviceLabelId = data_get($labels, 'coolify.serviceId');
 | 
				
			||||||
                if ($serviceLabelId) {
 | 
					                if ($serviceLabelId) {
 | 
				
			||||||
@@ -212,7 +216,7 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                $name = data_get($exitedService, 'name');
 | 
					                $name = data_get($exitedService, 'name');
 | 
				
			||||||
                $fqdn = data_get($exitedService, 'fqdn');
 | 
					                $fqdn = data_get($exitedService, 'fqdn');
 | 
				
			||||||
                $containerName = $name ? "$name ($fqdn)" : $fqdn;
 | 
					                $containerName = $name ? "$name, available at $fqdn" : $fqdn;
 | 
				
			||||||
                $projectUuid = data_get($service, 'environment.project.uuid');
 | 
					                $projectUuid = data_get($service, 'environment.project.uuid');
 | 
				
			||||||
                $serviceUuid = data_get($service, 'uuid');
 | 
					                $serviceUuid = data_get($service, 'uuid');
 | 
				
			||||||
                $environmentName = data_get($service, 'environment.name');
 | 
					                $environmentName = data_get($service, 'environment.name');
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -274,7 +274,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->skipBoarding();
 | 
					        $this->skipBoarding();
 | 
				
			||||||
        return redirect()->route(
 | 
					        return redirect()->route(
 | 
				
			||||||
            'project.resources.new',
 | 
					            'project.resource.create',
 | 
				
			||||||
            [
 | 
					            [
 | 
				
			||||||
                'project_uuid' => $this->createdProject->uuid,
 | 
					                'project_uuid' => $this->createdProject->uuid,
 | 
				
			||||||
                'environment_name' => 'production',
 | 
					                'environment_name' => 'production',
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								app/Livewire/CommandCenter/Index.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								app/Livewire/CommandCenter/Index.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Livewire\CommandCenter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Server;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Index extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $servers = [];
 | 
				
			||||||
 | 
					    public function mount() {
 | 
				
			||||||
 | 
					        $this->servers = Server::isReachable()->get();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.command-center.index');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -22,6 +22,10 @@ class ForcePasswordReset extends Component
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->email = auth()->user()->email;
 | 
					        $this->email = auth()->user()->email;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.force-password-reset')->layout('layouts.simple');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    public function submit()
 | 
					    public function submit()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,21 +5,19 @@ namespace App\Livewire\Profile;
 | 
				
			|||||||
use Livewire\Attributes\Validate;
 | 
					use Livewire\Attributes\Validate;
 | 
				
			||||||
use Livewire\Component;
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Form extends Component
 | 
					class Index extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public int $userId;
 | 
					    public int $userId;
 | 
				
			||||||
    public string $email;
 | 
					    public string $email;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[Validate('required')]
 | 
					    #[Validate('required')]
 | 
				
			||||||
    public string $name;
 | 
					    public string $name;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function mount()
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->userId = auth()->user()->id;
 | 
					        $this->userId = auth()->user()->id;
 | 
				
			||||||
        $this->name = auth()->user()->name;
 | 
					        $this->name = auth()->user()->name;
 | 
				
			||||||
        $this->email = auth()->user()->email;
 | 
					        $this->email = auth()->user()->email;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function submit()
 | 
					    public function submit()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -34,4 +32,8 @@ class Form extends Component
 | 
				
			|||||||
            return handleError($e, $this);
 | 
					            return handleError($e, $this);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.profile.index');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -27,7 +27,7 @@ class AddEnvironment extends Component
 | 
				
			|||||||
                'project_id' => $this->project->id,
 | 
					                'project_id' => $this->project->id,
 | 
				
			||||||
            ]);
 | 
					            ]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return redirect()->route('project.resources', [
 | 
					            return redirect()->route('project.resource.index', [
 | 
				
			||||||
                'project_uuid' => $this->project->uuid,
 | 
					                'project_uuid' => $this->project->uuid,
 | 
				
			||||||
                'environment_name' => $environment->name,
 | 
					                'environment_name' => $environment->name,
 | 
				
			||||||
            ]);
 | 
					            ]);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,13 +4,14 @@ namespace App\Livewire\Project\Application;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use App\Models\Application;
 | 
					use App\Models\Application;
 | 
				
			||||||
use App\Models\Server;
 | 
					use App\Models\Server;
 | 
				
			||||||
use App\Models\StandaloneDocker;
 | 
					 | 
				
			||||||
use Livewire\Component;
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Configuration extends Component
 | 
					class Configuration extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public Application $application;
 | 
					    public Application $application;
 | 
				
			||||||
    public $servers;
 | 
					    public $servers;
 | 
				
			||||||
 | 
					    protected $listeners = ['build_pack_updated' => '$refresh'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function mount()
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
 | 
					        $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,15 +1,15 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace App\Livewire\Project\Application;
 | 
					namespace App\Livewire\Project\Application\Deployment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Models\Application;
 | 
					use App\Models\Application;
 | 
				
			||||||
use Illuminate\Support\Collection;
 | 
					use Illuminate\Support\Collection;
 | 
				
			||||||
use Livewire\Component;
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Deployments extends Component
 | 
					class Index extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public Application $application;
 | 
					    public Application $application;
 | 
				
			||||||
    public Array|Collection $deployments = [];
 | 
					    public array|Collection $deployments = [];
 | 
				
			||||||
    public int $deployments_count = 0;
 | 
					    public int $deployments_count = 0;
 | 
				
			||||||
    public string $current_url;
 | 
					    public string $current_url;
 | 
				
			||||||
    public int $skip = 0;
 | 
					    public int $skip = 0;
 | 
				
			||||||
@@ -19,11 +19,28 @@ class Deployments extends Component
 | 
				
			|||||||
    protected $queryString = ['pull_request_id'];
 | 
					    protected $queryString = ['pull_request_id'];
 | 
				
			||||||
    public function mount()
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 | 
					        $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
 | 
				
			||||||
 | 
					        if (!$project) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
 | 
				
			||||||
 | 
					        if (!$environment) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $application = $environment->applications->where('uuid', request()->route('application_uuid'))->first();
 | 
				
			||||||
 | 
					        if (!$application) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ['deployments' => $deployments, 'count' => $count] = $application->deployments(0, 40);
 | 
				
			||||||
 | 
					        $this->application = $application;
 | 
				
			||||||
 | 
					        $this->deployments = $deployments;
 | 
				
			||||||
 | 
					        $this->deployments_count = $count;
 | 
				
			||||||
        $this->current_url = url()->current();
 | 
					        $this->current_url = url()->current();
 | 
				
			||||||
        $this->show_pull_request_only();
 | 
					        $this->show_pull_request_only();
 | 
				
			||||||
        $this->show_more();
 | 
					        $this->show_more();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    private function show_pull_request_only() {
 | 
					    private function show_pull_request_only()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        if ($this->pull_request_id) {
 | 
					        if ($this->pull_request_id) {
 | 
				
			||||||
            $this->deployments = $this->deployments->where('pull_request_id', $this->pull_request_id);
 | 
					            $this->deployments = $this->deployments->where('pull_request_id', $this->pull_request_id);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -57,4 +74,8 @@ class Deployments extends Component
 | 
				
			|||||||
        $this->show_pull_request_only();
 | 
					        $this->show_pull_request_only();
 | 
				
			||||||
        $this->show_more();
 | 
					        $this->show_more();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.project.application.deployment.index');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,35 +1,20 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Livewire\Project\Application\Deployment;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Application;
 | 
				
			||||||
use App\Models\ApplicationDeploymentQueue;
 | 
					use App\Models\ApplicationDeploymentQueue;
 | 
				
			||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
 | 
					use Livewire\Component;
 | 
				
			||||||
use Illuminate\Foundation\Validation\ValidatesRequests;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ApplicationController extends Controller
 | 
					class Show extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    use AuthorizesRequests, ValidatesRequests;
 | 
					    public Application $application;
 | 
				
			||||||
 | 
					    public ApplicationDeploymentQueue $application_deployment_queue;
 | 
				
			||||||
 | 
					    public string $deployment_uuid;
 | 
				
			||||||
 | 
					    public $isKeepAliveOn = true;
 | 
				
			||||||
 | 
					    protected $listeners = ['refreshQueue'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function deployments()
 | 
					    public function mount() {
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
 | 
					 | 
				
			||||||
        if (!$project) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
 | 
					 | 
				
			||||||
        if (!$environment) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $application = $environment->applications->where('uuid', request()->route('application_uuid'))->first();
 | 
					 | 
				
			||||||
        if (!$application) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        ['deployments' => $deployments, 'count' => $count] = $application->deployments(0, 40);
 | 
					 | 
				
			||||||
        return view('project.application.deployments', ['application' => $application, 'deployments' => $deployments, 'deployments_count' => $count]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function deployment()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $deploymentUuid = request()->route('deployment_uuid');
 | 
					        $deploymentUuid = request()->route('deployment_uuid');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
 | 
					        $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
 | 
				
			||||||
@@ -46,7 +31,7 @@ class ApplicationController extends Controller
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        // $activity = Activity::where('properties->type_uuid', '=', $deploymentUuid)->first();
 | 
					        // $activity = Activity::where('properties->type_uuid', '=', $deploymentUuid)->first();
 | 
				
			||||||
        // if (!$activity) {
 | 
					        // if (!$activity) {
 | 
				
			||||||
        //     return redirect()->route('project.application.deployments', [
 | 
					        //     return redirect()->route('project.application.deployment.index', [
 | 
				
			||||||
        //         'project_uuid' => $project->uuid,
 | 
					        //         'project_uuid' => $project->uuid,
 | 
				
			||||||
        //         'environment_name' => $environment->name,
 | 
					        //         'environment_name' => $environment->name,
 | 
				
			||||||
        //         'application_uuid' => $application->uuid,
 | 
					        //         'application_uuid' => $application->uuid,
 | 
				
			||||||
@@ -54,17 +39,32 @@ class ApplicationController extends Controller
 | 
				
			|||||||
        // }
 | 
					        // }
 | 
				
			||||||
        $application_deployment_queue = ApplicationDeploymentQueue::where('deployment_uuid', $deploymentUuid)->first();
 | 
					        $application_deployment_queue = ApplicationDeploymentQueue::where('deployment_uuid', $deploymentUuid)->first();
 | 
				
			||||||
        if (!$application_deployment_queue) {
 | 
					        if (!$application_deployment_queue) {
 | 
				
			||||||
            return redirect()->route('project.application.deployments', [
 | 
					            return redirect()->route('project.application.deployment.index', [
 | 
				
			||||||
                'project_uuid' => $project->uuid,
 | 
					                'project_uuid' => $project->uuid,
 | 
				
			||||||
                'environment_name' => $environment->name,
 | 
					                'environment_name' => $environment->name,
 | 
				
			||||||
                'application_uuid' => $application->uuid,
 | 
					                'application_uuid' => $application->uuid,
 | 
				
			||||||
            ]);
 | 
					            ]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return view('project.application.deployment', [
 | 
					        $this->application = $application;
 | 
				
			||||||
            'application' => $application,
 | 
					        $this->application_deployment_queue = $application_deployment_queue;
 | 
				
			||||||
            // 'activity' => $activity,
 | 
					        $this->deployment_uuid = $deploymentUuid;
 | 
				
			||||||
            'application_deployment_queue' => $application_deployment_queue,
 | 
					    }
 | 
				
			||||||
            'deployment_uuid' => $deploymentUuid,
 | 
					
 | 
				
			||||||
        ]);
 | 
					    public function refreshQueue()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->application_deployment_queue->refresh();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function polling()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->dispatch('deploymentFinished');
 | 
				
			||||||
 | 
					        $this->application_deployment_queue->refresh();
 | 
				
			||||||
 | 
					        if (data_get($this->application_deployment_queue, 'status') == 'finished' || data_get($this->application_deployment_queue, 'status') == 'failed') {
 | 
				
			||||||
 | 
					            $this->isKeepAliveOn = false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.project.application.deployment.show');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Livewire\Project\Application;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\ApplicationDeploymentQueue;
 | 
					 | 
				
			||||||
use Livewire\Component;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class DeploymentLogs extends Component
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public ApplicationDeploymentQueue $application_deployment_queue;
 | 
					 | 
				
			||||||
    public $isKeepAliveOn = true;
 | 
					 | 
				
			||||||
    protected $listeners = ['refreshQueue'];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function refreshQueue()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->application_deployment_queue->refresh();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function polling()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->dispatch('deploymentFinished');
 | 
					 | 
				
			||||||
        $this->application_deployment_queue->refresh();
 | 
					 | 
				
			||||||
        if (data_get($this->application_deployment_queue, 'status') == 'finished' || data_get($this->application_deployment_queue, 'status') == 'failed') {
 | 
					 | 
				
			||||||
            $this->isKeepAliveOn = false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -165,12 +165,20 @@ class General extends Component
 | 
				
			|||||||
        if ($this->application->build_pack !== 'nixpacks') {
 | 
					        if ($this->application->build_pack !== 'nixpacks') {
 | 
				
			||||||
            $this->application->settings->is_static = false;
 | 
					            $this->application->settings->is_static = false;
 | 
				
			||||||
            $this->application->settings->save();
 | 
					            $this->application->settings->save();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            $this->application->ports_exposes = $this->ports_exposes = 3000;
 | 
				
			||||||
 | 
					            $this->resetDefaultLabels(false);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if ($this->application->build_pack === 'dockercompose') {
 | 
					        if ($this->application->build_pack === 'dockercompose') {
 | 
				
			||||||
            $this->application->fqdn = null;
 | 
					            $this->application->fqdn = null;
 | 
				
			||||||
            $this->application->settings->save();
 | 
					            $this->application->settings->save();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        if ($this->application->build_pack === 'static') {
 | 
				
			||||||
 | 
					            $this->application->ports_exposes = $this->ports_exposes = 80;
 | 
				
			||||||
 | 
					            $this->resetDefaultLabels(false);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        $this->submit();
 | 
					        $this->submit();
 | 
				
			||||||
 | 
					        $this->dispatch('build_pack_updated');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public function checkLabelUpdates()
 | 
					    public function checkLabelUpdates()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -201,7 +209,7 @@ class General extends Component
 | 
				
			|||||||
    public function updatedApplicationFqdn()
 | 
					    public function updatedApplicationFqdn()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->resetDefaultLabels(false);
 | 
					        $this->resetDefaultLabels(false);
 | 
				
			||||||
        $this->dispatch('success', 'Labels reseted to default!');
 | 
					        $this->dispatch('success', 'Labels reset to default!');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public function submit($showToaster = true)
 | 
					    public function submit($showToaster = true)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -39,7 +39,7 @@ class Heading extends Component
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            dispatch(new ServerStatusJob($this->application->destination->server));
 | 
					            dispatch(new ServerStatusJob($this->application->destination->server));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if ($showNotification) $this->dispatch('success', 'Application status updated.');
 | 
					        if ($showNotification) $this->dispatch('success', "Application ({$this->application->name}) status updated.");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function force_deploy_without_cache()
 | 
					    public function force_deploy_without_cache()
 | 
				
			||||||
@@ -60,7 +60,7 @@ class Heading extends Component
 | 
				
			|||||||
            force_rebuild: false,
 | 
					            force_rebuild: false,
 | 
				
			||||||
            is_new_deployment: true,
 | 
					            is_new_deployment: true,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return redirect()->route('project.application.deployment', [
 | 
					        return redirect()->route('project.application.deployment.show', [
 | 
				
			||||||
            'project_uuid' => $this->parameters['project_uuid'],
 | 
					            'project_uuid' => $this->parameters['project_uuid'],
 | 
				
			||||||
            'application_uuid' => $this->parameters['application_uuid'],
 | 
					            'application_uuid' => $this->parameters['application_uuid'],
 | 
				
			||||||
            'deployment_uuid' => $this->deploymentUuid,
 | 
					            'deployment_uuid' => $this->deploymentUuid,
 | 
				
			||||||
@@ -83,7 +83,7 @@ class Heading extends Component
 | 
				
			|||||||
            deployment_uuid: $this->deploymentUuid,
 | 
					            deployment_uuid: $this->deploymentUuid,
 | 
				
			||||||
            force_rebuild: $force_rebuild,
 | 
					            force_rebuild: $force_rebuild,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return redirect()->route('project.application.deployment', [
 | 
					        return redirect()->route('project.application.deployment.show', [
 | 
				
			||||||
            'project_uuid' => $this->parameters['project_uuid'],
 | 
					            'project_uuid' => $this->parameters['project_uuid'],
 | 
				
			||||||
            'application_uuid' => $this->parameters['application_uuid'],
 | 
					            'application_uuid' => $this->parameters['application_uuid'],
 | 
				
			||||||
            'deployment_uuid' => $this->deploymentUuid,
 | 
					            'deployment_uuid' => $this->deploymentUuid,
 | 
				
			||||||
@@ -113,7 +113,7 @@ class Heading extends Component
 | 
				
			|||||||
            restart_only: true,
 | 
					            restart_only: true,
 | 
				
			||||||
            is_new_deployment: true,
 | 
					            is_new_deployment: true,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return redirect()->route('project.application.deployment', [
 | 
					        return redirect()->route('project.application.deployment.show', [
 | 
				
			||||||
            'project_uuid' => $this->parameters['project_uuid'],
 | 
					            'project_uuid' => $this->parameters['project_uuid'],
 | 
				
			||||||
            'application_uuid' => $this->parameters['application_uuid'],
 | 
					            'application_uuid' => $this->parameters['application_uuid'],
 | 
				
			||||||
            'deployment_uuid' => $this->deploymentUuid,
 | 
					            'deployment_uuid' => $this->deploymentUuid,
 | 
				
			||||||
@@ -128,7 +128,7 @@ class Heading extends Component
 | 
				
			|||||||
            deployment_uuid: $this->deploymentUuid,
 | 
					            deployment_uuid: $this->deploymentUuid,
 | 
				
			||||||
            restart_only: true,
 | 
					            restart_only: true,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return redirect()->route('project.application.deployment', [
 | 
					        return redirect()->route('project.application.deployment.show', [
 | 
				
			||||||
            'project_uuid' => $this->parameters['project_uuid'],
 | 
					            'project_uuid' => $this->parameters['project_uuid'],
 | 
				
			||||||
            'application_uuid' => $this->parameters['application_uuid'],
 | 
					            'application_uuid' => $this->parameters['application_uuid'],
 | 
				
			||||||
            'deployment_uuid' => $this->deploymentUuid,
 | 
					            'deployment_uuid' => $this->deploymentUuid,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -52,7 +52,7 @@ class Previews extends Component
 | 
				
			|||||||
                force_rebuild: true,
 | 
					                force_rebuild: true,
 | 
				
			||||||
                pull_request_id: $pull_request_id,
 | 
					                pull_request_id: $pull_request_id,
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
            return redirect()->route('project.application.deployment', [
 | 
					            return redirect()->route('project.application.deployment.show', [
 | 
				
			||||||
                'project_uuid' => $this->parameters['project_uuid'],
 | 
					                'project_uuid' => $this->parameters['project_uuid'],
 | 
				
			||||||
                'application_uuid' => $this->parameters['application_uuid'],
 | 
					                'application_uuid' => $this->parameters['application_uuid'],
 | 
				
			||||||
                'deployment_uuid' => $this->deployment_uuid,
 | 
					                'deployment_uuid' => $this->deployment_uuid,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,7 @@ class Rollback extends Component
 | 
				
			|||||||
            commit: $commit,
 | 
					            commit: $commit,
 | 
				
			||||||
            force_rebuild: false,
 | 
					            force_rebuild: false,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        return redirect()->route('project.application.deployment', [
 | 
					        return redirect()->route('project.application.deployment.show', [
 | 
				
			||||||
            'project_uuid' => $this->parameters['project_uuid'],
 | 
					            'project_uuid' => $this->parameters['project_uuid'],
 | 
				
			||||||
            'application_uuid' => $this->parameters['application_uuid'],
 | 
					            'application_uuid' => $this->parameters['application_uuid'],
 | 
				
			||||||
            'deployment_uuid' => $deployment_uuid,
 | 
					            'deployment_uuid' => $deployment_uuid,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,7 @@ use App\Models\Server;
 | 
				
			|||||||
use Livewire\Component;
 | 
					use Livewire\Component;
 | 
				
			||||||
use Visus\Cuid2\Cuid2;
 | 
					use Visus\Cuid2\Cuid2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CloneProject extends Component
 | 
					class CloneMe extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public string $project_uuid;
 | 
					    public string $project_uuid;
 | 
				
			||||||
    public string $environment_name;
 | 
					    public string $environment_name;
 | 
				
			||||||
@@ -41,7 +41,7 @@ class CloneProject extends Component
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function render()
 | 
					    public function render()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return view('livewire.project.clone-project');
 | 
					        return view('livewire.project.clone-me');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function selectServer($server_id, $destination_id)
 | 
					    public function selectServer($server_id, $destination_id)
 | 
				
			||||||
@@ -152,7 +152,7 @@ class CloneProject extends Component
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
                $newService->parse();
 | 
					                $newService->parse();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return redirect()->route('project.resources', [
 | 
					            return redirect()->route('project.resource.index', [
 | 
				
			||||||
                'project_uuid' => $newProject->uuid,
 | 
					                'project_uuid' => $newProject->uuid,
 | 
				
			||||||
                'environment_name' => $newEnvironment->name,
 | 
					                'environment_name' => $newEnvironment->name,
 | 
				
			||||||
            ]);
 | 
					            ]);
 | 
				
			||||||
							
								
								
									
										41
									
								
								app/Livewire/Project/Database/Backup/Execution.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								app/Livewire/Project/Database/Backup/Execution.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Livewire\Project\Database\Backup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Execution extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $database;
 | 
				
			||||||
 | 
					    public $backup;
 | 
				
			||||||
 | 
					    public $executions;
 | 
				
			||||||
 | 
					    public $s3s;
 | 
				
			||||||
 | 
					    public function mount() {
 | 
				
			||||||
 | 
					        $backup_uuid = request()->route('backup_uuid');
 | 
				
			||||||
 | 
					        $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
 | 
				
			||||||
 | 
					        if (!$project) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
 | 
				
			||||||
 | 
					        if (!$environment) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $database = $environment->databases()->where('uuid', request()->route('database_uuid'))->first();
 | 
				
			||||||
 | 
					        if (!$database) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $backup = $database->scheduledBackups->where('uuid', $backup_uuid)->first();
 | 
				
			||||||
 | 
					        if (!$backup) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $executions = collect($backup->executions)->sortByDesc('created_at');
 | 
				
			||||||
 | 
					        $this->database = $database;
 | 
				
			||||||
 | 
					        $this->backup = $backup;
 | 
				
			||||||
 | 
					        $this->executions = $executions;
 | 
				
			||||||
 | 
					        $this->s3s = currentTeam()->s3s;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.project.database.backup.execution');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										39
									
								
								app/Livewire/Project/Database/Backup/Index.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app/Livewire/Project/Database/Backup/Index.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Livewire\Project\Database\Backup;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Index extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $database;
 | 
				
			||||||
 | 
					    public $s3s;
 | 
				
			||||||
 | 
					    public function mount() {
 | 
				
			||||||
 | 
					        $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
 | 
				
			||||||
 | 
					        if (!$project) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
 | 
				
			||||||
 | 
					        if (!$environment) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $database = $environment->databases()->where('uuid', request()->route('database_uuid'))->first();
 | 
				
			||||||
 | 
					        if (!$database) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // No backups for redis
 | 
				
			||||||
 | 
					        if ($database->getMorphClass() === 'App\Models\StandaloneRedis') {
 | 
				
			||||||
 | 
					            return redirect()->route('project.database.configuration', [
 | 
				
			||||||
 | 
					                'project_uuid' => $project->uuid,
 | 
				
			||||||
 | 
					                'environment_name' => $environment->name,
 | 
				
			||||||
 | 
					                'database_uuid' => $database->uuid,
 | 
				
			||||||
 | 
					            ]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $this->database = $database;
 | 
				
			||||||
 | 
					        $this->s3s = currentTeam()->s3s;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.project.database.backup.index');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -52,7 +52,7 @@ class BackupEdit extends Component
 | 
				
			|||||||
            $url = $url->getPath() .  "#{$url->getFragment()}";
 | 
					            $url = $url->getPath() .  "#{$url->getFragment()}";
 | 
				
			||||||
            return redirect($url);
 | 
					            return redirect($url);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            return redirect()->route('project.database.backups.all', $this->parameters);
 | 
					            return redirect()->route('project.database.backup.index', $this->parameters);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										29
									
								
								app/Livewire/Project/Database/Configuration.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								app/Livewire/Project/Database/Configuration.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Livewire\Project\Database;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Configuration extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $database;
 | 
				
			||||||
 | 
					    public function mount() {
 | 
				
			||||||
 | 
					        $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
 | 
				
			||||||
 | 
					        if (!$project) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first()->load(['applications']);
 | 
				
			||||||
 | 
					        if (!$environment) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $database = $environment->databases()->where('uuid', request()->route('database_uuid'))->first();
 | 
				
			||||||
 | 
					        if (!$database) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $this->database = $database;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.project.database.configuration');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -25,6 +25,6 @@ class DeleteProject extends Component
 | 
				
			|||||||
            return $this->dispatch('error', 'Project has resources defined, please delete them first.');
 | 
					            return $this->dispatch('error', 'Project has resources defined, please delete them first.');
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $project->delete();
 | 
					        $project->delete();
 | 
				
			||||||
        return redirect()->route('projects');
 | 
					        return redirect()->route('project.index');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,15 @@ class Edit extends Component
 | 
				
			|||||||
        'project.name' => 'required|min:3|max:255',
 | 
					        'project.name' => 'required|min:3|max:255',
 | 
				
			||||||
        'project.description' => 'nullable|string|max:255',
 | 
					        'project.description' => 'nullable|string|max:255',
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					    public function mount() {
 | 
				
			||||||
 | 
					        $projectUuid = request()->route('project_uuid');
 | 
				
			||||||
 | 
					        $teamId = currentTeam()->id;
 | 
				
			||||||
 | 
					        $project = Project::where('team_id', $teamId)->where('uuid', $projectUuid)->first();
 | 
				
			||||||
 | 
					        if (!$project) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $this->project = $project;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function submit()
 | 
					    public function submit()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										21
									
								
								app/Livewire/Project/Index.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								app/Livewire/Project/Index.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Livewire\Project;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					use App\Models\Server;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Index extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $projects;
 | 
				
			||||||
 | 
					    public $servers;
 | 
				
			||||||
 | 
					    public function mount() {
 | 
				
			||||||
 | 
					        $this->projects = Project::ownedByCurrentTeam()->get();
 | 
				
			||||||
 | 
					        $this->servers = Server::ownedByCurrentTeam()->count();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.project.index');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -55,7 +55,7 @@ class Select extends Component
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function updatedSelectedEnvironment()
 | 
					    public function updatedSelectedEnvironment()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return redirect()->route('project.resources.new', [
 | 
					        return redirect()->route('project.resource.create', [
 | 
				
			||||||
            'project_uuid' => $this->parameters['project_uuid'],
 | 
					            'project_uuid' => $this->parameters['project_uuid'],
 | 
				
			||||||
            'environment_name' => $this->selectedEnvironment,
 | 
					            'environment_name' => $this->selectedEnvironment,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
@@ -157,7 +157,7 @@ class Select extends Component
 | 
				
			|||||||
    public function setDestination(string $destination_uuid)
 | 
					    public function setDestination(string $destination_uuid)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->destination_uuid = $destination_uuid;
 | 
					        $this->destination_uuid = $destination_uuid;
 | 
				
			||||||
        return redirect()->route('project.resources.new', [
 | 
					        return redirect()->route('project.resource.create', [
 | 
				
			||||||
            'project_uuid' => $this->parameters['project_uuid'],
 | 
					            'project_uuid' => $this->parameters['project_uuid'],
 | 
				
			||||||
            'environment_name' => $this->parameters['environment_name'],
 | 
					            'environment_name' => $this->parameters['environment_name'],
 | 
				
			||||||
            'type' => $this->type,
 | 
					            'type' => $this->type,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,52 +1,18 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Controllers;
 | 
					namespace App\Livewire\Project\Resource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Models\EnvironmentVariable;
 | 
					use App\Models\EnvironmentVariable;
 | 
				
			||||||
use App\Models\Project;
 | 
					 | 
				
			||||||
use App\Models\Server;
 | 
					 | 
				
			||||||
use App\Models\Service;
 | 
					use App\Models\Service;
 | 
				
			||||||
use App\Models\StandaloneDocker;
 | 
					use App\Models\StandaloneDocker;
 | 
				
			||||||
use Illuminate\Support\Str;
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ProjectController extends Controller
 | 
					class Create extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public function all()
 | 
					    public $type;
 | 
				
			||||||
    {
 | 
					    public function mount() {
 | 
				
			||||||
        return view('projects', [
 | 
					 | 
				
			||||||
            'projects' => Project::ownedByCurrentTeam()->get(),
 | 
					 | 
				
			||||||
            'servers' => Server::ownedByCurrentTeam()->count(),
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function edit()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $projectUuid = request()->route('project_uuid');
 | 
					 | 
				
			||||||
        $teamId = currentTeam()->id;
 | 
					 | 
				
			||||||
        $project = Project::where('team_id', $teamId)->where('uuid', $projectUuid)->first();
 | 
					 | 
				
			||||||
        if (!$project) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return view('project.edit', ['project' => $project]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function show()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $projectUuid = request()->route('project_uuid');
 | 
					 | 
				
			||||||
        $teamId = currentTeam()->id;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $project = Project::where('team_id', $teamId)->where('uuid', $projectUuid)->first();
 | 
					 | 
				
			||||||
        if (!$project) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $project->load(['environments']);
 | 
					 | 
				
			||||||
        return view('project.show', ['project' => $project]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function new()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $services = getServiceTemplates();
 | 
					        $services = getServiceTemplates();
 | 
				
			||||||
        $type = Str::of(request()->query('type'));
 | 
					        $type = str(request()->query('type'));
 | 
				
			||||||
        $destination_uuid = request()->query('destination');
 | 
					        $destination_uuid = request()->query('destination');
 | 
				
			||||||
        $server_id = request()->query('server_id');
 | 
					        $server_id = request()->query('server_id');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -81,14 +47,14 @@ class ProjectController extends Controller
 | 
				
			|||||||
            $oneClickService = data_get($services, "$oneClickServiceName.compose");
 | 
					            $oneClickService = data_get($services, "$oneClickServiceName.compose");
 | 
				
			||||||
            $oneClickDotEnvs = data_get($services, "$oneClickServiceName.envs", null);
 | 
					            $oneClickDotEnvs = data_get($services, "$oneClickServiceName.envs", null);
 | 
				
			||||||
            if ($oneClickDotEnvs) {
 | 
					            if ($oneClickDotEnvs) {
 | 
				
			||||||
                $oneClickDotEnvs = Str::of(base64_decode($oneClickDotEnvs))->split('/\r\n|\r|\n/')->filter(function ($value) {
 | 
					                $oneClickDotEnvs = str(base64_decode($oneClickDotEnvs))->split('/\r\n|\r|\n/')->filter(function ($value) {
 | 
				
			||||||
                    return !empty($value);
 | 
					                    return !empty($value);
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if ($oneClickService) {
 | 
					            if ($oneClickService) {
 | 
				
			||||||
                $destination = StandaloneDocker::whereUuid($destination_uuid)->first();
 | 
					                $destination = StandaloneDocker::whereUuid($destination_uuid)->first();
 | 
				
			||||||
                $service = Service::create([
 | 
					                $service = Service::create([
 | 
				
			||||||
                    'name' => "$oneClickServiceName-" . Str::random(10),
 | 
					                    'name' => "$oneClickServiceName-" . str()->random(10),
 | 
				
			||||||
                    'docker_compose_raw' => base64_decode($oneClickService),
 | 
					                    'docker_compose_raw' => base64_decode($oneClickService),
 | 
				
			||||||
                    'environment_id' => $environment->id,
 | 
					                    'environment_id' => $environment->id,
 | 
				
			||||||
                    'server_id' => (int) $server_id,
 | 
					                    'server_id' => (int) $server_id,
 | 
				
			||||||
@@ -99,8 +65,8 @@ class ProjectController extends Controller
 | 
				
			|||||||
                $service->save();
 | 
					                $service->save();
 | 
				
			||||||
                if ($oneClickDotEnvs?->count() > 0) {
 | 
					                if ($oneClickDotEnvs?->count() > 0) {
 | 
				
			||||||
                    $oneClickDotEnvs->each(function ($value) use ($service) {
 | 
					                    $oneClickDotEnvs->each(function ($value) use ($service) {
 | 
				
			||||||
                        $key = Str::before($value, '=');
 | 
					                        $key = str()->before($value, '=');
 | 
				
			||||||
                        $value = Str::of(Str::after($value, '='));
 | 
					                        $value = str(str()->after($value, '='));
 | 
				
			||||||
                        $generatedValue = $value;
 | 
					                        $generatedValue = $value;
 | 
				
			||||||
                        if ($value->contains('SERVICE_')) {
 | 
					                        if ($value->contains('SERVICE_')) {
 | 
				
			||||||
                            $command = $value->after('SERVICE_')->beforeLast('_');
 | 
					                            $command = $value->after('SERVICE_')->beforeLast('_');
 | 
				
			||||||
@@ -123,24 +89,10 @@ class ProjectController extends Controller
 | 
				
			|||||||
                ]);
 | 
					                ]);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return view('project.new', [
 | 
					        $this->type = $type->value();
 | 
				
			||||||
            'type' => $type->value()
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
    public function resources()
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
 | 
					        return view('livewire.project.resource.create');
 | 
				
			||||||
        if (!$project) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first();
 | 
					 | 
				
			||||||
        if (!$environment) {
 | 
					 | 
				
			||||||
            return redirect()->route('dashboard');
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return view('project.resources', [
 | 
					 | 
				
			||||||
            'project' => $project,
 | 
					 | 
				
			||||||
            'environment' => $environment
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
							
								
								
									
										29
									
								
								app/Livewire/Project/Resource/Index.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								app/Livewire/Project/Resource/Index.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Livewire\Project\Resource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Environment;
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Index extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public Project $project;
 | 
				
			||||||
 | 
					    public Environment $environment;
 | 
				
			||||||
 | 
					    public function mount () {
 | 
				
			||||||
 | 
					        $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first();
 | 
				
			||||||
 | 
					        if (!$project) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $environment = $project->load(['environments'])->environments->where('name', request()->route('environment_name'))->first();
 | 
				
			||||||
 | 
					        if (!$environment) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $this->project = $project;
 | 
				
			||||||
 | 
					        $this->environment = $environment;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.project.resource.index');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										54
									
								
								app/Livewire/Project/Service/Configuration.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								app/Livewire/Project/Service/Configuration.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Livewire\Project\Service;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Jobs\ContainerStatusJob;
 | 
				
			||||||
 | 
					use App\Models\Service;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Configuration extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public Service $service;
 | 
				
			||||||
 | 
					    public $applications;
 | 
				
			||||||
 | 
					    public $databases;
 | 
				
			||||||
 | 
					    public array $parameters;
 | 
				
			||||||
 | 
					    public array $query;
 | 
				
			||||||
 | 
					    public function getListeners()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $userId = auth()->user()->id;
 | 
				
			||||||
 | 
					        return [
 | 
				
			||||||
 | 
					            "echo-private:user.{$userId},ServiceStatusChanged" => 'checkStatus',
 | 
				
			||||||
 | 
					            "refreshStacks",
 | 
				
			||||||
 | 
					            "checkStatus",
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.project.service.configuration');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function mount()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->parameters = get_route_parameters();
 | 
				
			||||||
 | 
					        $this->query = request()->query();
 | 
				
			||||||
 | 
					        $this->service = Service::whereUuid($this->parameters['service_uuid'])->firstOrFail();
 | 
				
			||||||
 | 
					        $this->applications = $this->service->applications->sort();
 | 
				
			||||||
 | 
					        $this->databases = $this->service->databases->sort();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function checkStatus()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        dispatch_sync(new ContainerStatusJob($this->service->server));
 | 
				
			||||||
 | 
					        $this->refreshStacks();
 | 
				
			||||||
 | 
					        $this->dispatch('serviceStatusChanged');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function refreshStacks()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->applications = $this->service->applications->sort();
 | 
				
			||||||
 | 
					        $this->applications->each(function ($application) {
 | 
				
			||||||
 | 
					            $application->refresh();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        $this->databases = $this->service->databases->sort();
 | 
				
			||||||
 | 
					        $this->databases->each(function ($database) {
 | 
				
			||||||
 | 
					            $database->refresh();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -2,53 +2,51 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Livewire\Project\Service;
 | 
					namespace App\Livewire\Project\Service;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Jobs\ContainerStatusJob;
 | 
					 | 
				
			||||||
use App\Models\Service;
 | 
					use App\Models\Service;
 | 
				
			||||||
 | 
					use App\Models\ServiceApplication;
 | 
				
			||||||
 | 
					use App\Models\ServiceDatabase;
 | 
				
			||||||
 | 
					use Illuminate\Support\Collection;
 | 
				
			||||||
use Livewire\Component;
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Index extends Component
 | 
					class Index extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public Service $service;
 | 
					    public Service $service;
 | 
				
			||||||
    public $applications;
 | 
					    public ?ServiceApplication $serviceApplication = null;
 | 
				
			||||||
    public $databases;
 | 
					    public ?ServiceDatabase $serviceDatabase = null;
 | 
				
			||||||
    public array $parameters;
 | 
					    public array $parameters;
 | 
				
			||||||
    public array $query;
 | 
					    public array $query;
 | 
				
			||||||
    public function getListeners()
 | 
					    public Collection $services;
 | 
				
			||||||
 | 
					    public $s3s;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected $listeners = ['generateDockerCompose'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $userId = auth()->user()->id;
 | 
					        try {
 | 
				
			||||||
        return [
 | 
					            $this->services = collect([]);
 | 
				
			||||||
            "echo-private:user.{$userId},ServiceStatusChanged" => 'checkStatus',
 | 
					            $this->parameters = get_route_parameters();
 | 
				
			||||||
            "refreshStacks",
 | 
					            $this->query = request()->query();
 | 
				
			||||||
            "checkStatus",
 | 
					            $this->service = Service::whereUuid($this->parameters['service_uuid'])->firstOrFail();
 | 
				
			||||||
        ];
 | 
					            $service = $this->service->applications()->whereName($this->parameters['service_name'])->first();
 | 
				
			||||||
 | 
					            if ($service) {
 | 
				
			||||||
 | 
					                $this->serviceApplication = $service;
 | 
				
			||||||
 | 
					                $this->serviceApplication->getFilesFromServer();
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                $this->serviceDatabase = $this->service->databases()->whereName($this->parameters['service_name'])->first();
 | 
				
			||||||
 | 
					                $this->serviceDatabase->getFilesFromServer();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $this->s3s = currentTeam()->s3s;
 | 
				
			||||||
 | 
					        } catch(\Throwable $e) {
 | 
				
			||||||
 | 
					            return handleError($e, $this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function generateDockerCompose()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->service->parse();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public function render()
 | 
					    public function render()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return view('livewire.project.service.index');
 | 
					        return view('livewire.project.service.index');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public function mount()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->parameters = get_route_parameters();
 | 
					 | 
				
			||||||
        $this->query = request()->query();
 | 
					 | 
				
			||||||
        $this->service = Service::whereUuid($this->parameters['service_uuid'])->firstOrFail();
 | 
					 | 
				
			||||||
        $this->applications = $this->service->applications->sort();
 | 
					 | 
				
			||||||
        $this->databases = $this->service->databases->sort();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    public function checkStatus()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        dispatch_sync(new ContainerStatusJob($this->service->server));
 | 
					 | 
				
			||||||
        $this->refreshStacks();
 | 
					 | 
				
			||||||
        $this->dispatch('serviceStatusChanged');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    public function refreshStacks()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->applications = $this->service->applications->sort();
 | 
					 | 
				
			||||||
        $this->applications->each(function ($application) {
 | 
					 | 
				
			||||||
            $application->refresh();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        $this->databases = $this->service->databases->sort();
 | 
					 | 
				
			||||||
        $this->databases->each(function ($database) {
 | 
					 | 
				
			||||||
            $database->refresh();
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,52 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Livewire\Project\Service;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\Service;
 | 
					 | 
				
			||||||
use App\Models\ServiceApplication;
 | 
					 | 
				
			||||||
use App\Models\ServiceDatabase;
 | 
					 | 
				
			||||||
use Illuminate\Support\Collection;
 | 
					 | 
				
			||||||
use Livewire\Component;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Show extends Component
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public Service $service;
 | 
					 | 
				
			||||||
    public ?ServiceApplication $serviceApplication = null;
 | 
					 | 
				
			||||||
    public ?ServiceDatabase $serviceDatabase = null;
 | 
					 | 
				
			||||||
    public array $parameters;
 | 
					 | 
				
			||||||
    public array $query;
 | 
					 | 
				
			||||||
    public Collection $services;
 | 
					 | 
				
			||||||
    public $s3s;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    protected $listeners = ['generateDockerCompose'];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function mount()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            $this->services = collect([]);
 | 
					 | 
				
			||||||
            $this->parameters = get_route_parameters();
 | 
					 | 
				
			||||||
            $this->query = request()->query();
 | 
					 | 
				
			||||||
            $this->service = Service::whereUuid($this->parameters['service_uuid'])->firstOrFail();
 | 
					 | 
				
			||||||
            $service = $this->service->applications()->whereName($this->parameters['service_name'])->first();
 | 
					 | 
				
			||||||
            if ($service) {
 | 
					 | 
				
			||||||
                $this->serviceApplication = $service;
 | 
					 | 
				
			||||||
                $this->serviceApplication->getFilesFromServer();
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                $this->serviceDatabase = $this->service->databases()->whereName($this->parameters['service_name'])->first();
 | 
					 | 
				
			||||||
                $this->serviceDatabase->getFilesFromServer();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            $this->s3s = currentTeam()->s3s;
 | 
					 | 
				
			||||||
        } catch(\Throwable $e) {
 | 
					 | 
				
			||||||
            return handleError($e, $this);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    public function generateDockerCompose()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->service->parse();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    public function render()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return view('livewire.project.service.show');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -25,7 +25,7 @@ class Danger extends Component
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            DeleteResourceJob::dispatchSync($this->resource);
 | 
					            DeleteResourceJob::dispatchSync($this->resource);
 | 
				
			||||||
            return redirect()->route('project.resources', [
 | 
					            return redirect()->route('project.resource.index', [
 | 
				
			||||||
                'project_uuid' => $this->projectUuid,
 | 
					                'project_uuid' => $this->projectUuid,
 | 
				
			||||||
                'environment_name' => $this->environmentName
 | 
					                'environment_name' => $this->environmentName
 | 
				
			||||||
            ]);
 | 
					            ]);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -139,6 +139,18 @@ class All extends Component
 | 
				
			|||||||
                case 'standalone-postgresql':
 | 
					                case 'standalone-postgresql':
 | 
				
			||||||
                    $environment->standalone_postgresql_id = $this->resource->id;
 | 
					                    $environment->standalone_postgresql_id = $this->resource->id;
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 'standalone-redis':
 | 
				
			||||||
 | 
					                    $environment->standalone_redis_id = $this->resource->id;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 'standalone-mongodb':
 | 
				
			||||||
 | 
					                    $environment->standalone_mongodb_id = $this->resource->id;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 'standalone-mysql':
 | 
				
			||||||
 | 
					                    $environment->standalone_mysql_id = $this->resource->id;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
 | 
					                case 'standalone-mariadb':
 | 
				
			||||||
 | 
					                    $environment->standalone_mariadb_id = $this->resource->id;
 | 
				
			||||||
 | 
					                    break;
 | 
				
			||||||
                case 'service':
 | 
					                case 'service':
 | 
				
			||||||
                    $environment->service_id = $this->resource->id;
 | 
					                    $environment->service_id = $this->resource->id;
 | 
				
			||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,7 +10,6 @@ use App\Models\StandaloneMongodb;
 | 
				
			|||||||
use App\Models\StandaloneMysql;
 | 
					use App\Models\StandaloneMysql;
 | 
				
			||||||
use App\Models\StandalonePostgresql;
 | 
					use App\Models\StandalonePostgresql;
 | 
				
			||||||
use App\Models\StandaloneRedis;
 | 
					use App\Models\StandaloneRedis;
 | 
				
			||||||
use Illuminate\Support\Sleep;
 | 
					 | 
				
			||||||
use Livewire\Component;
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ExecuteContainerCommand extends Component
 | 
					class ExecuteContainerCommand extends Component
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										26
									
								
								app/Livewire/Project/Show.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								app/Livewire/Project/Show.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Livewire\Project;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Project;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Show extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public Project $project;
 | 
				
			||||||
 | 
					    public function mount() {
 | 
				
			||||||
 | 
					        $projectUuid = request()->route('project_uuid');
 | 
				
			||||||
 | 
					        $teamId = currentTeam()->id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $project = Project::where('team_id', $teamId)->where('uuid', $projectUuid)->first();
 | 
				
			||||||
 | 
					        if (!$project) {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $project->load(['environments']);
 | 
				
			||||||
 | 
					        $this->project = $project;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.project.show');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace App\Livewire\PrivateKey;
 | 
					namespace App\Livewire\Security\PrivateKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Models\PrivateKey;
 | 
					use App\Models\PrivateKey;
 | 
				
			||||||
use DanHarrin\LivewireRateLimiting\WithRateLimiting;
 | 
					use DanHarrin\LivewireRateLimiting\WithRateLimiting;
 | 
				
			||||||
@@ -1,11 +1,11 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace App\Livewire\PrivateKey;
 | 
					namespace App\Livewire\Security\PrivateKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Models\PrivateKey;
 | 
					use App\Models\PrivateKey;
 | 
				
			||||||
use Livewire\Component;
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Change extends Component
 | 
					class Show extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public PrivateKey $private_key;
 | 
					    public PrivateKey $private_key;
 | 
				
			||||||
    public $public_key;
 | 
					    public $public_key;
 | 
				
			||||||
@@ -24,6 +24,7 @@ class Change extends Component
 | 
				
			|||||||
    public function mount()
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
 | 
					            $this->private_key = PrivateKey::ownedByCurrentTeam(['name', 'description', 'private_key', 'is_git_related'])->whereUuid(request()->private_key_uuid)->firstOrFail();
 | 
				
			||||||
            $this->public_key = $this->private_key->publicKey();
 | 
					            $this->public_key = $this->private_key->publicKey();
 | 
				
			||||||
        }catch(\Throwable $e) {
 | 
					        }catch(\Throwable $e) {
 | 
				
			||||||
            return handleError($e, $this);
 | 
					            return handleError($e, $this);
 | 
				
			||||||
@@ -19,7 +19,7 @@ class Delete extends Component
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            $this->server->delete();
 | 
					            $this->server->delete();
 | 
				
			||||||
            return redirect()->route('server.all');
 | 
					            return redirect()->route('server.index');
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            return handleError($e, $this);
 | 
					            return handleError($e, $this);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ class Show extends Component
 | 
				
			|||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first();
 | 
					            $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first();
 | 
				
			||||||
            if (is_null($this->server)) {
 | 
					            if (is_null($this->server)) {
 | 
				
			||||||
                return redirect()->route('server.all');
 | 
					                return redirect()->route('server.index');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            return handleError($e, $this);
 | 
					            return handleError($e, $this);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,7 @@ use App\Models\Server;
 | 
				
			|||||||
use Illuminate\Database\Eloquent\Collection;
 | 
					use Illuminate\Database\Eloquent\Collection;
 | 
				
			||||||
use Livewire\Component;
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class All extends Component
 | 
					class Index extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public ?Collection $servers = null;
 | 
					    public ?Collection $servers = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -15,6 +15,6 @@ class All extends Component
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    public function render()
 | 
					    public function render()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return view('livewire.server.all');
 | 
					        return view('livewire.server.index');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -43,7 +43,7 @@ class LogDrains extends Component
 | 
				
			|||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first();
 | 
					            $server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first();
 | 
				
			||||||
            if (is_null($server)) {
 | 
					            if (is_null($server)) {
 | 
				
			||||||
                return redirect()->route('server.all');
 | 
					                return redirect()->route('server.index');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            $this->server = $server;
 | 
					            $this->server = $server;
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ class Show extends Component
 | 
				
			|||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first();
 | 
					            $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first();
 | 
				
			||||||
            if (is_null($this->server)) {
 | 
					            if (is_null($this->server)) {
 | 
				
			||||||
                return redirect()->route('server.all');
 | 
					                return redirect()->route('server.index');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            $this->privateKeys = PrivateKey::ownedByCurrentTeam()->get()->where('is_git_related', false);
 | 
					            $this->privateKeys = PrivateKey::ownedByCurrentTeam()->get()->where('is_git_related', false);
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,7 @@ class Logs extends Component
 | 
				
			|||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first();
 | 
					            $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first();
 | 
				
			||||||
            if (is_null($this->server)) {
 | 
					            if (is_null($this->server)) {
 | 
				
			||||||
                return redirect()->route('server.all');
 | 
					                return redirect()->route('server.index');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            return handleError($e, $this);
 | 
					            return handleError($e, $this);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,7 @@ class Show extends Component
 | 
				
			|||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first();
 | 
					            $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first();
 | 
				
			||||||
            if (is_null($this->server)) {
 | 
					            if (is_null($this->server)) {
 | 
				
			||||||
                return redirect()->route('server.all');
 | 
					                return redirect()->route('server.index');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            return handleError($e, $this);
 | 
					            return handleError($e, $this);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ class Show extends Component
 | 
				
			|||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first();
 | 
					            $this->server = Server::ownedByCurrentTeam()->whereUuid(request()->server_uuid)->first();
 | 
				
			||||||
            if (is_null($this->server)) {
 | 
					            if (is_null($this->server)) {
 | 
				
			||||||
                return redirect()->route('server.all');
 | 
					                return redirect()->route('server.index');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										38
									
								
								app/Livewire/Settings/Index.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								app/Livewire/Settings/Index.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Livewire\Settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\InstanceSettings;
 | 
				
			||||||
 | 
					use App\Models\S3Storage;
 | 
				
			||||||
 | 
					use App\Models\StandalonePostgresql;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Index extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public InstanceSettings $settings;
 | 
				
			||||||
 | 
					    public StandalonePostgresql $database;
 | 
				
			||||||
 | 
					    public $s3s;
 | 
				
			||||||
 | 
					    public function mount()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        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;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            return redirect()->route('dashboard');
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.settings.index');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,15 +1,16 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace App\Livewire;
 | 
					namespace App\Livewire\Settings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Actions\License\CheckResaleLicense;
 | 
					use App\Actions\License\CheckResaleLicense;
 | 
				
			||||||
use App\Models\InstanceSettings;
 | 
					use App\Models\InstanceSettings;
 | 
				
			||||||
use Livewire\Component;
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CheckLicense extends Component
 | 
					class License extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public InstanceSettings|null $settings = null;
 | 
					    public InstanceSettings $settings;
 | 
				
			||||||
    public string|null $instance_id = null;
 | 
					    public string|null $instance_id = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected $rules = [
 | 
					    protected $rules = [
 | 
				
			||||||
        'settings.resale_license' => 'nullable',
 | 
					        'settings.resale_license' => 'nullable',
 | 
				
			||||||
        'settings.is_resale_license_active' => 'nullable',
 | 
					        'settings.is_resale_license_active' => 'nullable',
 | 
				
			||||||
@@ -20,12 +21,17 @@ class CheckLicense extends Component
 | 
				
			|||||||
        'settings.is_resale_license_active' => 'Is License Active',
 | 
					        'settings.is_resale_license_active' => 'Is License Active',
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function mount()
 | 
					    public function mount () {
 | 
				
			||||||
    {
 | 
					        if (!isCloud()) {
 | 
				
			||||||
 | 
					            abort(404);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        $this->instance_id = config('app.id');
 | 
					        $this->instance_id = config('app.id');
 | 
				
			||||||
        $this->settings = InstanceSettings::get();
 | 
					        $this->settings = InstanceSettings::get();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.settings.license')->layout('layouts.subscription');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    public function submit()
 | 
					    public function submit()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->validate();
 | 
					        $this->validate();
 | 
				
			||||||
@@ -6,7 +6,7 @@ use App\Models\InstanceSettings;
 | 
				
			|||||||
use App\Providers\RouteServiceProvider;
 | 
					use App\Providers\RouteServiceProvider;
 | 
				
			||||||
use Livewire\Component;
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Show extends Component
 | 
					class Index extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    public InstanceSettings $settings;
 | 
					    public InstanceSettings $settings;
 | 
				
			||||||
    public bool $alreadySubscribed = false;
 | 
					    public bool $alreadySubscribed = false;
 | 
				
			||||||
@@ -26,6 +26,6 @@ class Show extends Component
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    public function render()
 | 
					    public function render()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return view('livewire.subscription.show')->layout('layouts.subscription');
 | 
					        return view('livewire.subscription.index')->layout('layouts.subscription');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,29 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Livewire\Team;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use Illuminate\Support\Facades\DB;
 | 
					 | 
				
			||||||
use Livewire\Component;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Delete extends Component
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public function delete()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $currentTeam = currentTeam();
 | 
					 | 
				
			||||||
        $currentTeam->delete();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $currentTeam->members->each(function ($user) use ($currentTeam) {
 | 
					 | 
				
			||||||
            if ($user->id === auth()->user()->id) {
 | 
					 | 
				
			||||||
                return;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            $user->teams()->detach($currentTeam);
 | 
					 | 
				
			||||||
            $session = DB::table('sessions')->where('user_id', $user->id)->first();
 | 
					 | 
				
			||||||
            if ($session) {
 | 
					 | 
				
			||||||
                DB::table('sessions')->where('id', $session->id)->delete();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        refreshSession();
 | 
					 | 
				
			||||||
        return redirect()->route('team.index');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,35 +0,0 @@
 | 
				
			|||||||
<?php
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace App\Livewire\Team;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
use App\Models\Team;
 | 
					 | 
				
			||||||
use Livewire\Component;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Form extends Component
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public Team $team;
 | 
					 | 
				
			||||||
    protected $rules = [
 | 
					 | 
				
			||||||
        'team.name' => 'required|min:3|max:255',
 | 
					 | 
				
			||||||
        'team.description' => 'nullable|min:3|max:255',
 | 
					 | 
				
			||||||
    ];
 | 
					 | 
				
			||||||
    protected $validationAttributes = [
 | 
					 | 
				
			||||||
        'team.name' => 'name',
 | 
					 | 
				
			||||||
        'team.description' => 'description',
 | 
					 | 
				
			||||||
    ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function mount()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->team = currentTeam();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    public function submit()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->validate();
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            $this->team->save();
 | 
					 | 
				
			||||||
            refreshSession();
 | 
					 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					 | 
				
			||||||
            return handleError($e, $this);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										65
									
								
								app/Livewire/Team/Index.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								app/Livewire/Team/Index.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,65 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Livewire\Team;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Team;
 | 
				
			||||||
 | 
					use App\Models\TeamInvitation;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\DB;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Index extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $invitations = [];
 | 
				
			||||||
 | 
					    public Team $team;
 | 
				
			||||||
 | 
					    protected $rules = [
 | 
				
			||||||
 | 
					        'team.name' => 'required|min:3|max:255',
 | 
				
			||||||
 | 
					        'team.description' => 'nullable|min:3|max:255',
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					    protected $validationAttributes = [
 | 
				
			||||||
 | 
					        'team.name' => 'name',
 | 
				
			||||||
 | 
					        'team.description' => 'description',
 | 
				
			||||||
 | 
					    ];
 | 
				
			||||||
 | 
					    public function mount() {
 | 
				
			||||||
 | 
					        $this->team = currentTeam();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (auth()->user()->isAdminFromSession()) {
 | 
				
			||||||
 | 
					            $this->invitations = TeamInvitation::whereTeamId(currentTeam()->id)->get();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.team.index');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function submit()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->validate();
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $this->team->save();
 | 
				
			||||||
 | 
					            refreshSession();
 | 
				
			||||||
 | 
					            $this->dispatch('success', 'Team updated successfully.');
 | 
				
			||||||
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
 | 
					            return handleError($e, $this);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function delete()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $currentTeam = currentTeam();
 | 
				
			||||||
 | 
					        $currentTeam->delete();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        $currentTeam->members->each(function ($user) use ($currentTeam) {
 | 
				
			||||||
 | 
					            if ($user->id === auth()->user()->id) {
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            $user->teams()->detach($currentTeam);
 | 
				
			||||||
 | 
					            $session = DB::table('sessions')->where('user_id', $user->id)->first();
 | 
				
			||||||
 | 
					            if ($session) {
 | 
				
			||||||
 | 
					                DB::table('sessions')->where('id', $session->id)->delete();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        refreshSession();
 | 
				
			||||||
 | 
					        return redirect()->route('team.index');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								app/Livewire/Team/Member/Index.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/Livewire/Team/Member/Index.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Livewire\Team\Member;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\TeamInvitation;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Index extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $invitations = [];
 | 
				
			||||||
 | 
					    public function mount() {
 | 
				
			||||||
 | 
					        if (auth()->user()->isAdminFromSession()) {
 | 
				
			||||||
 | 
					            $this->invitations = TeamInvitation::whereTeamId(currentTeam()->id)->get();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.team.member.index');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								app/Livewire/Team/Notification/Index.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								app/Livewire/Team/Notification/Index.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Livewire\Team\Notification;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Index extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.team.notification.index');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -65,7 +65,7 @@ class Create extends Component
 | 
				
			|||||||
            $this->storage->team_id = currentTeam()->id;
 | 
					            $this->storage->team_id = currentTeam()->id;
 | 
				
			||||||
            $this->storage->testConnection();
 | 
					            $this->storage->testConnection();
 | 
				
			||||||
            $this->storage->save();
 | 
					            $this->storage->save();
 | 
				
			||||||
            return redirect()->route('team.storages.show', $this->storage->uuid);
 | 
					            return redirect()->route('team.storage.show', $this->storage->uuid);
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            return handleError($e, $this);
 | 
					            return handleError($e, $this);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,7 +43,7 @@ class Form extends Component
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $this->storage->delete();
 | 
					            $this->storage->delete();
 | 
				
			||||||
            return redirect()->route('team.storages.all');
 | 
					            return redirect()->route('team.storage.index');
 | 
				
			||||||
        } catch (\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            return handleError($e, $this);
 | 
					            return handleError($e, $this);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								app/Livewire/Team/Storage/Index.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								app/Livewire/Team/Storage/Index.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Livewire\Team\Storage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\S3Storage;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Index extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $s3;
 | 
				
			||||||
 | 
					    public function mount() {
 | 
				
			||||||
 | 
					        $this->s3 = S3Storage::ownedByCurrentTeam()->get();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.team.storage.index');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										22
									
								
								app/Livewire/Team/Storage/Show.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								app/Livewire/Team/Storage/Show.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Livewire\Team\Storage;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\S3Storage;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Show extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public $storage = null;
 | 
				
			||||||
 | 
					    public function mount()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->storage = S3Storage::ownedByCurrentTeam()->whereUuid(request()->storage_uuid)->first();
 | 
				
			||||||
 | 
					        if (!$this->storage) {
 | 
				
			||||||
 | 
					            abort(404);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.team.storage.show');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -760,7 +760,6 @@ class Application extends BaseModel
 | 
				
			|||||||
        // if (count($this->ports_mappings_array) > 0) {
 | 
					        // if (count($this->ports_mappings_array) > 0) {
 | 
				
			||||||
        // $deployment->addLogEntry('Application has ports mapped to the host system, rolling update is not supported.');
 | 
					        // $deployment->addLogEntry('Application has ports mapped to the host system, rolling update is not supported.');
 | 
				
			||||||
        $containers = getCurrentApplicationContainerStatus($server, $this->id, $pullRequestId);
 | 
					        $containers = getCurrentApplicationContainerStatus($server, $this->id, $pullRequestId);
 | 
				
			||||||
        ray($containers);
 | 
					 | 
				
			||||||
        // if ($pullRequestId === 0) {
 | 
					        // if ($pullRequestId === 0) {
 | 
				
			||||||
        //     $containers = $containers->filter(function ($container) use ($containerName) {
 | 
					        //     $containers = $containers->filter(function ($container) use ($containerName) {
 | 
				
			||||||
        //         return data_get($container, 'Names') !== $containerName;
 | 
					        //         return data_get($container, 'Names') !== $containerName;
 | 
				
			||||||
@@ -872,7 +871,6 @@ class Application extends BaseModel
 | 
				
			|||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                $git_clone_command = $this->setGitImportSettings($deployment_uuid, $git_clone_command_base);
 | 
					                $git_clone_command = $this->setGitImportSettings($deployment_uuid, $git_clone_command_base);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            ray($git_clone_command);
 | 
					 | 
				
			||||||
            if ($exec_in_docker) {
 | 
					            if ($exec_in_docker) {
 | 
				
			||||||
                $commands = collect([
 | 
					                $commands = collect([
 | 
				
			||||||
                    executeInDocker($deployment_uuid, "mkdir -p /root/.ssh"),
 | 
					                    executeInDocker($deployment_uuid, "mkdir -p /root/.ssh"),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,7 +48,7 @@ class S3Storage extends BaseModel
 | 
				
			|||||||
            if ($this->unusable_email_sent === false && is_transactional_emails_active()) {
 | 
					            if ($this->unusable_email_sent === false && is_transactional_emails_active()) {
 | 
				
			||||||
                $mail = new MailMessage();
 | 
					                $mail = new MailMessage();
 | 
				
			||||||
                $mail->subject('Coolify: S3 Storage Connection Error');
 | 
					                $mail->subject('Coolify: S3 Storage Connection Error');
 | 
				
			||||||
                $mail->view('emails.s3-connection-error', ['name' => $this->name, 'reason' => $e->getMessage(), 'url' => route('team.storages.show', ['storage_uuid' => $this->uuid])]);
 | 
					                $mail->view('emails.s3-connection-error', ['name' => $this->name, 'reason' => $e->getMessage(), 'url' => route('team.storage.show', ['storage_uuid' => $this->uuid])]);
 | 
				
			||||||
                $users = collect([]);
 | 
					                $users = collect([]);
 | 
				
			||||||
                $members = $this->team->members()->get();
 | 
					                $members = $this->team->members()->get();
 | 
				
			||||||
                foreach ($members as $user) {
 | 
					                foreach ($members as $user) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -358,10 +358,10 @@ class Server extends BaseModel
 | 
				
			|||||||
    public function validateOS(): bool | Stringable
 | 
					    public function validateOS(): bool | Stringable
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $os_release = instant_remote_process(['cat /etc/os-release'], $this);
 | 
					        $os_release = instant_remote_process(['cat /etc/os-release'], $this);
 | 
				
			||||||
        $datas = collect(explode("\n", $os_release));
 | 
					        $releaseLines = collect(explode("\n", $os_release));
 | 
				
			||||||
        $collectedData = collect([]);
 | 
					        $collectedData = collect([]);
 | 
				
			||||||
        foreach ($datas as $data) {
 | 
					        foreach ($releaseLines as $line) {
 | 
				
			||||||
            $item = Str::of($data)->trim();
 | 
					            $item = Str::of($line)->trim();
 | 
				
			||||||
            $collectedData->put($item->before('=')->value(), $item->after('=')->lower()->replace('"', '')->value());
 | 
					            $collectedData->put($item->before('=')->value(), $item->after('=')->lower()->replace('"', '')->value());
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $ID = data_get($collectedData, 'ID');
 | 
					        $ID = data_get($collectedData, 'ID');
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,8 +14,8 @@ class EmailChannel
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $this->bootConfigs($notifiable);
 | 
					            $this->bootConfigs($notifiable);
 | 
				
			||||||
            $recepients = $notifiable->getRecepients($notification);
 | 
					            $recipients = $notifiable->getRecepients($notification);
 | 
				
			||||||
            if (count($recepients) === 0) {
 | 
					            if (count($recipients) === 0) {
 | 
				
			||||||
                throw new Exception('No email recipients found');
 | 
					                throw new Exception('No email recipients found');
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -24,7 +24,7 @@ class EmailChannel
 | 
				
			|||||||
                [],
 | 
					                [],
 | 
				
			||||||
                [],
 | 
					                [],
 | 
				
			||||||
                fn (Message $message) => $message
 | 
					                fn (Message $message) => $message
 | 
				
			||||||
                    ->to($recepients)
 | 
					                    ->to($recipients)
 | 
				
			||||||
                    ->subject($mailMessage->subject)
 | 
					                    ->subject($mailMessage->subject)
 | 
				
			||||||
                    ->html((string)$mailMessage->render())
 | 
					                    ->html((string)$mailMessage->render())
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
@@ -35,8 +35,8 @@ class EmailChannel
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            ray($e->getMessage());
 | 
					            ray($e->getMessage());
 | 
				
			||||||
            $message = "EmailChannel error: {$e->getMessage()}. Failed to send email to:";
 | 
					            $message = "EmailChannel error: {$e->getMessage()}. Failed to send email to:";
 | 
				
			||||||
            if (isset($recepients)) {
 | 
					            if (isset($recipients)) {
 | 
				
			||||||
                $message .= implode(', ', $recepients);
 | 
					                $message .= implode(', ', $recipients);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (isset($mailMessage)) {
 | 
					            if (isset($mailMessage)) {
 | 
				
			||||||
                $message .= " with subject: {$mailMessage->subject}";
 | 
					                $message .= " with subject: {$mailMessage->subject}";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,7 @@ class ContainerRestarted extends Notification implements ShouldQueue
 | 
				
			|||||||
    public function toMail(): MailMessage
 | 
					    public function toMail(): MailMessage
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $mail = new MailMessage();
 | 
					        $mail = new MailMessage();
 | 
				
			||||||
        $mail->subject("Coolify: A service ({$this->name}) has been restarted automatically on {$this->server->name}");
 | 
					        $mail->subject("Coolify: A resource ({$this->name}) has been restarted automatically on {$this->server->name}");
 | 
				
			||||||
        $mail->view('emails.container-restarted', [
 | 
					        $mail->view('emails.container-restarted', [
 | 
				
			||||||
            'containerName' => $this->name,
 | 
					            'containerName' => $this->name,
 | 
				
			||||||
            'serverName' => $this->server->name,
 | 
					            'serverName' => $this->server->name,
 | 
				
			||||||
@@ -38,12 +38,12 @@ class ContainerRestarted extends Notification implements ShouldQueue
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function toDiscord(): string
 | 
					    public function toDiscord(): string
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $message = "Coolify: A service ({$this->name}) has been restarted automatically on {$this->server->name}";
 | 
					        $message = "Coolify: A resource ({$this->name}) has been restarted automatically on {$this->server->name}";
 | 
				
			||||||
        return $message;
 | 
					        return $message;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public function toTelegram(): array
 | 
					    public function toTelegram(): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $message = "Coolify: A service ({$this->name}) has been restarted automatically on {$this->server->name}";
 | 
					        $message = "Coolify: A resource ({$this->name}) has been restarted automatically on {$this->server->name}";
 | 
				
			||||||
        $payload = [
 | 
					        $payload = [
 | 
				
			||||||
            "message" => $message,
 | 
					            "message" => $message,
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,7 @@ class ContainerStopped extends Notification implements ShouldQueue
 | 
				
			|||||||
    public function toMail(): MailMessage
 | 
					    public function toMail(): MailMessage
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $mail = new MailMessage();
 | 
					        $mail = new MailMessage();
 | 
				
			||||||
        $mail->subject("Coolify: A service ({$this->name}) has been stopped on {$this->server->name}");
 | 
					        $mail->subject("Coolify: A resource  has been stopped unexpectedly on {$this->server->name}");
 | 
				
			||||||
        $mail->view('emails.container-stopped', [
 | 
					        $mail->view('emails.container-stopped', [
 | 
				
			||||||
            'containerName' => $this->name,
 | 
					            'containerName' => $this->name,
 | 
				
			||||||
            'serverName' => $this->server->name,
 | 
					            'serverName' => $this->server->name,
 | 
				
			||||||
@@ -37,12 +37,12 @@ class ContainerStopped extends Notification implements ShouldQueue
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function toDiscord(): string
 | 
					    public function toDiscord(): string
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $message = "Coolify: A service ({$this->name}) has been stopped on {$this->server->name}";
 | 
					        $message = "Coolify: A resource has been stopped unexpectedly on {$this->server->name}";
 | 
				
			||||||
        return $message;
 | 
					        return $message;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public function toTelegram(): array
 | 
					    public function toTelegram(): array
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $message = "Coolify: A service ($this->name} has been stopped on {$this->server->name}";
 | 
					        $message = "Coolify: A resource has been stopped unexpectedly on {$this->server->name}";
 | 
				
			||||||
        $payload = [
 | 
					        $payload = [
 | 
				
			||||||
            "message" => $message,
 | 
					            "message" => $message,
 | 
				
			||||||
        ];
 | 
					        ];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,7 @@ class FortifyServiceProvider extends ServiceProvider
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                // First user (root) will be redirected to /settings instead of / on registration.
 | 
					                // First user (root) will be redirected to /settings instead of / on registration.
 | 
				
			||||||
                if ($request->user()->currentTeam->id === 0) {
 | 
					                if ($request->user()->currentTeam->id === 0) {
 | 
				
			||||||
                    return redirect()->route('settings.configuration');
 | 
					                    return redirect()->route('settings.index');
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return redirect(RouteServiceProvider::HOME);
 | 
					                return redirect(RouteServiceProvider::HOME);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -226,8 +226,8 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
 | 
				
			|||||||
            if (is_null($port) && !is_null($onlyPort)) {
 | 
					            if (is_null($port) && !is_null($onlyPort)) {
 | 
				
			||||||
                $port = $onlyPort;
 | 
					                $port = $onlyPort;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            $http_label = "{$uuid}-{$loop}-http";
 | 
					            $http_label = "http-{$loop}-{$uuid}";
 | 
				
			||||||
            $https_label = "{$uuid}-{$loop}-https";
 | 
					            $https_label = "https-{$loop}-{$uuid}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if ($schema === 'https') {
 | 
					            if ($schema === 'https') {
 | 
				
			||||||
                // Set labels for https
 | 
					                // Set labels for https
 | 
				
			||||||
@@ -249,6 +249,10 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
 | 
				
			|||||||
                // Set labels for http (redirect to https)
 | 
					                // Set labels for http (redirect to https)
 | 
				
			||||||
                $labels->push("traefik.http.routers.{$http_label}.rule=Host(`{$host}`) && PathPrefix(`{$path}`)");
 | 
					                $labels->push("traefik.http.routers.{$http_label}.rule=Host(`{$host}`) && PathPrefix(`{$path}`)");
 | 
				
			||||||
                $labels->push("traefik.http.routers.{$http_label}.entryPoints=http");
 | 
					                $labels->push("traefik.http.routers.{$http_label}.entryPoints=http");
 | 
				
			||||||
 | 
					                if ($port) {
 | 
				
			||||||
 | 
					                    $labels->push("traefik.http.services.{$http_label}.loadbalancer.server.port=$port");
 | 
				
			||||||
 | 
					                    $labels->push("traefik.http.routers.{$http_label}.service={$http_label}");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                if ($is_force_https_enabled) {
 | 
					                if ($is_force_https_enabled) {
 | 
				
			||||||
                    $labels->push("traefik.http.routers.{$http_label}.middlewares=redirect-to-https");
 | 
					                    $labels->push("traefik.http.routers.{$http_label}.middlewares=redirect-to-https");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -258,27 +262,26 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_
 | 
				
			|||||||
                $labels->push("traefik.http.routers.{$http_label}.entryPoints=http");
 | 
					                $labels->push("traefik.http.routers.{$http_label}.entryPoints=http");
 | 
				
			||||||
                $labels->push("traefik.http.routers.{$http_label}.middlewares=gzip");
 | 
					                $labels->push("traefik.http.routers.{$http_label}.middlewares=gzip");
 | 
				
			||||||
                if ($port) {
 | 
					                if ($port) {
 | 
				
			||||||
                    $labels->push("traefik.http.routers.{$http_label}.service={$http_label}");
 | 
					 | 
				
			||||||
                    $labels->push("traefik.http.services.{$http_label}.loadbalancer.server.port=$port");
 | 
					                    $labels->push("traefik.http.services.{$http_label}.loadbalancer.server.port=$port");
 | 
				
			||||||
 | 
					                    $labels->push("traefik.http.routers.{$http_label}.service={$http_label}");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                if ($path !== '/') {
 | 
					                if ($path !== '/') {
 | 
				
			||||||
                    $labels->push("traefik.http.routers.{$http_label}.middlewares={$http_label}-stripprefix");
 | 
					                    $labels->push("traefik.http.routers.{$http_label}.middlewares={$http_label}-stripprefix");
 | 
				
			||||||
                    $labels->push("traefik.http.middlewares.{$http_label}-stripprefix.stripprefix.prefixes={$path}");
 | 
					                    $labels->push("traefik.http.middlewares.{$http_label}-stripprefix.stripprefix.prefixes={$path}");
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch(\Throwable $e) {
 | 
					        } catch (\Throwable $e) {
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return $labels;
 | 
					    return $labels->sort();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
function generateLabelsApplication(Application $application, ?ApplicationPreview $preview = null): array
 | 
					function generateLabelsApplication(Application $application, ?ApplicationPreview $preview = null): array
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    $ports = $application->settings->is_static ? [80] : $application->ports_exposes_array;
 | 
					    $ports = $application->settings->is_static ? [80] : $application->ports_exposes_array;
 | 
				
			||||||
    $onlyPort = null;
 | 
					    $onlyPort = null;
 | 
				
			||||||
    if (count($ports) === 1) {
 | 
					    if (count($ports) > 0) {
 | 
				
			||||||
        $onlyPort = $ports[0];
 | 
					        $onlyPort = $ports[0];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $pull_request_id = data_get($preview, 'pull_request_id', 0);
 | 
					    $pull_request_id = data_get($preview, 'pull_request_id', 0);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -101,7 +101,6 @@ function generate_default_proxy_configuration(Server $server)
 | 
				
			|||||||
    $labels = [
 | 
					    $labels = [
 | 
				
			||||||
        "traefik.enable=true",
 | 
					        "traefik.enable=true",
 | 
				
			||||||
        "traefik.http.routers.traefik.entrypoints=http",
 | 
					        "traefik.http.routers.traefik.entrypoints=http",
 | 
				
			||||||
        "traefik.http.routers.traefik.middlewares=traefik-basic-auth@file",
 | 
					 | 
				
			||||||
        "traefik.http.routers.traefik.service=api@internal",
 | 
					        "traefik.http.routers.traefik.service=api@internal",
 | 
				
			||||||
        "traefik.http.services.traefik.loadbalancer.server.port=8080",
 | 
					        "traefik.http.services.traefik.loadbalancer.server.port=8080",
 | 
				
			||||||
        // Global Middlewares
 | 
					        // Global Middlewares
 | 
				
			||||||
@@ -156,7 +155,7 @@ function generate_default_proxy_configuration(Server $server)
 | 
				
			|||||||
        ],
 | 
					        ],
 | 
				
			||||||
    ];
 | 
					    ];
 | 
				
			||||||
    if (isDev()) {
 | 
					    if (isDev()) {
 | 
				
			||||||
        $config['services']['traefik']['command'][] = "--log.level=debug";
 | 
					        // $config['services']['traefik']['command'][] = "--log.level=debug";
 | 
				
			||||||
        $config['services']['traefik']['command'][] = "--accesslog.filepath=/traefik/access.log";
 | 
					        $config['services']['traefik']['command'][] = "--accesslog.filepath=/traefik/access.log";
 | 
				
			||||||
        $config['services']['traefik']['command'][] = "--accesslog.bufferingsize=100";
 | 
					        $config['services']['traefik']['command'][] = "--accesslog.bufferingsize=100";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -408,7 +408,7 @@ function generateFqdn(Server $server, string $random)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
function sslip(Server $server)
 | 
					function sslip(Server $server)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (isDev()) {
 | 
					    if (isDev() && $server->id === 0) {
 | 
				
			||||||
        return "http://127.0.0.1.sslip.io";
 | 
					        return "http://127.0.0.1.sslip.io";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if ($server->ip === 'host.docker.internal') {
 | 
					    if ($server->ip === 'host.docker.internal') {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -65,7 +65,7 @@ return [
 | 
				
			|||||||
            'driver' => 'redis',
 | 
					            'driver' => 'redis',
 | 
				
			||||||
            'connection' => 'default',
 | 
					            'connection' => 'default',
 | 
				
			||||||
            'queue' => env('REDIS_QUEUE', 'default'),
 | 
					            'queue' => env('REDIS_QUEUE', 'default'),
 | 
				
			||||||
            'retry_after' => 300,
 | 
					            'retry_after' => 3600,
 | 
				
			||||||
            'block_for' => null,
 | 
					            'block_for' => null,
 | 
				
			||||||
            'after_commit' => true,
 | 
					            'after_commit' => true,
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ return [
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // The release version of your application
 | 
					    // The release version of your application
 | 
				
			||||||
    // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
 | 
					    // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD'))
 | 
				
			||||||
    'release' => '4.0.0-beta.182',
 | 
					    'release' => '4.0.0-beta.186',
 | 
				
			||||||
    // When left empty or `null` the Laravel environment will be used
 | 
					    // When left empty or `null` the Laravel environment will be used
 | 
				
			||||||
    'environment' => config('app.env'),
 | 
					    'environment' => config('app.env'),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,3 @@
 | 
				
			|||||||
<?php
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
return '4.0.0-beta.182';
 | 
					return '4.0.0-beta.186';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,7 +16,7 @@ RUN apt-get update
 | 
				
			|||||||
RUN apt-get install postgresql-client-$POSTGRES_VERSION -y
 | 
					RUN apt-get install postgresql-client-$POSTGRES_VERSION -y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Coolify requirements
 | 
					# Coolify requirements
 | 
				
			||||||
RUN apt-get install -y php-pgsql openssh-client git git-lfs jq lsof
 | 
					RUN apt-get install -y php8.2-pgsql openssh-client git git-lfs jq lsof
 | 
				
			||||||
RUN apt-get -y autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
 | 
					RUN apt-get -y autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
 | 
				
			||||||
COPY --chmod=755 docker/dev-ssu/etc/s6-overlay/ /etc/s6-overlay/
 | 
					COPY --chmod=755 docker/dev-ssu/etc/s6-overlay/ /etc/s6-overlay/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,7 +31,7 @@ RUN apt-get update
 | 
				
			|||||||
RUN apt-get install postgresql-client-$POSTGRES_VERSION -y
 | 
					RUN apt-get install postgresql-client-$POSTGRES_VERSION -y
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Coolify requirements
 | 
					# Coolify requirements
 | 
				
			||||||
RUN apt-get install -y php-pgsql openssh-client git git-lfs jq lsof
 | 
					RUN apt-get install -y php8.2-pgsql openssh-client git git-lfs jq lsof
 | 
				
			||||||
RUN apt-get -y autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
 | 
					RUN apt-get -y autoremove && apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/share/doc/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
COPY docker/prod-ssu/nginx.conf /etc/nginx/conf.d/custom.conf
 | 
					COPY docker/prod-ssu/nginx.conf /etc/nginx/conf.d/custom.conf
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +0,0 @@
 | 
				
			|||||||
<x-layout-simple>
 | 
					 | 
				
			||||||
    <livewire:force-password-reset />
 | 
					 | 
				
			||||||
</x-layout-simple>
 | 
					 | 
				
			||||||
@@ -13,8 +13,8 @@
 | 
				
			|||||||
        href="{{ route('project.application.logs', $parameters) }}">
 | 
					        href="{{ route('project.application.logs', $parameters) }}">
 | 
				
			||||||
        <button>Logs</button>
 | 
					        <button>Logs</button>
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <a class="{{ request()->routeIs('project.application.deployments') ? 'text-white' : '' }}"
 | 
					    <a class="{{ request()->routeIs('project.application.deployment.index') ? 'text-white' : '' }}"
 | 
				
			||||||
        href="{{ route('project.application.deployments', $parameters) }}">
 | 
					        href="{{ route('project.application.deployment.index', $parameters) }}">
 | 
				
			||||||
        <button>Deployments</button>
 | 
					        <button>Deployments</button>
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
    <x-applications.links :application="$application" />
 | 
					    <x-applications.links :application="$application" />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,8 +16,8 @@
 | 
				
			|||||||
            $database->getMorphClass() === 'App\Models\StandaloneMongodb' ||
 | 
					            $database->getMorphClass() === 'App\Models\StandaloneMongodb' ||
 | 
				
			||||||
            $database->getMorphClass() === 'App\Models\StandaloneMysql' ||
 | 
					            $database->getMorphClass() === 'App\Models\StandaloneMysql' ||
 | 
				
			||||||
            $database->getMorphClass() === 'App\Models\StandaloneMariadb')
 | 
					            $database->getMorphClass() === 'App\Models\StandaloneMariadb')
 | 
				
			||||||
        <a  class="{{ request()->routeIs('project.database.backups.all') ? 'text-white' : '' }}"
 | 
					        <a  class="{{ request()->routeIs('project.database.backup.index') ? 'text-white' : '' }}"
 | 
				
			||||||
            href="{{ route('project.database.backups.all', $parameters) }}">
 | 
					            href="{{ route('project.database.backup.index', $parameters) }}">
 | 
				
			||||||
            <button>Backups</button>
 | 
					            <button>Backups</button>
 | 
				
			||||||
        </a>
 | 
					        </a>
 | 
				
			||||||
    @endif
 | 
					    @endif
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -302,7 +302,7 @@
 | 
				
			|||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div class="mt-1 text-base leading-7 text-gray-300">
 | 
					                <div class="mt-1 text-base leading-7 text-gray-300">
 | 
				
			||||||
                    Once you connected your server, Coolify will start managing it and do a
 | 
					                    Once you connected your server, Coolify will start managing it and do a
 | 
				
			||||||
                    lot of adminstrative tasks for you. You can also write your own scripts to
 | 
					                    lot of administrative tasks for you. You can also write your own scripts to
 | 
				
			||||||
                    automate your server<span class="text-warning">*</span>.
 | 
					                    automate your server<span class="text-warning">*</span>.
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
@@ -384,7 +384,7 @@
 | 
				
			|||||||
                    <div class="text-2xl font-semibold text-white">Powerful API</div>
 | 
					                    <div class="text-2xl font-semibold text-white">Powerful API</div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div class="mt-1 text-base leading-7 text-gray-300">
 | 
					                <div class="mt-1 text-base leading-7 text-gray-300">
 | 
				
			||||||
                    Programatically deploy, query, and manage your servers & resources.
 | 
					                    Programmatically deploy, query, and manage your servers & resources.
 | 
				
			||||||
                    Integrate to your CI/CD pipelines, or build your own custom integrations. <span
 | 
					                    Integrate to your CI/CD pipelines, or build your own custom integrations. <span
 | 
				
			||||||
                        class="text-warning">*</span>
 | 
					                        class="text-warning">*</span>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
<nav class="flex pt-2 pb-10">
 | 
					<nav class="flex pt-2 pb-10">
 | 
				
			||||||
    <ol class="flex items-center">
 | 
					    <ol class="flex items-center">
 | 
				
			||||||
        <li class="inline-flex items-center">
 | 
					        <li class="inline-flex items-center">
 | 
				
			||||||
            <a wire:nagivate class="text-xs truncate lg:text-sm"
 | 
					            <a wire:navigate class="text-xs truncate lg:text-sm"
 | 
				
			||||||
                href="{{ route('project.show', ['project_uuid' => $this->parameters['project_uuid']]) }}">
 | 
					                href="{{ route('project.show', ['project_uuid' => $this->parameters['project_uuid']]) }}">
 | 
				
			||||||
                {{ data_get($resource, 'environment.project.name', 'Undefined Name') }}</a>
 | 
					                {{ data_get($resource, 'environment.project.name', 'Undefined Name') }}</a>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
@@ -14,7 +14,7 @@
 | 
				
			|||||||
                        clip-rule="evenodd"></path>
 | 
					                        clip-rule="evenodd"></path>
 | 
				
			||||||
                </svg>
 | 
					                </svg>
 | 
				
			||||||
                <a  class="text-xs truncate lg:text-sm"
 | 
					                <a  class="text-xs truncate lg:text-sm"
 | 
				
			||||||
                    href="{{ route('project.resources', ['environment_name' => $this->parameters['environment_name'], 'project_uuid' => $this->parameters['project_uuid']]) }}">{{ $this->parameters['environment_name'] }}</a>
 | 
					                    href="{{ route('project.resource.index', ['environment_name' => $this->parameters['environment_name'], 'project_uuid' => $this->parameters['project_uuid']]) }}">{{ $this->parameters['environment_name'] }}</a>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </li>
 | 
					        </li>
 | 
				
			||||||
        <li>
 | 
					        <li>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,8 +2,8 @@
 | 
				
			|||||||
    <h1>Settings</h1>
 | 
					    <h1>Settings</h1>
 | 
				
			||||||
    <div class="subtitle">Instance wide settings for Coolify.</div>
 | 
					    <div class="subtitle">Instance wide settings for Coolify.</div>
 | 
				
			||||||
    <nav class="navbar-main">
 | 
					    <nav class="navbar-main">
 | 
				
			||||||
        <a class="{{ request()->routeIs('settings.configuration') ? 'text-white' : '' }}"
 | 
					        <a class="{{ request()->routeIs('settings.index') ? 'text-white' : '' }}"
 | 
				
			||||||
            href="{{ route('settings.configuration') }}">
 | 
					            href="{{ route('settings.index') }}">
 | 
				
			||||||
            <button>Configuration</button>
 | 
					            <button>Configuration</button>
 | 
				
			||||||
        </a>
 | 
					        </a>
 | 
				
			||||||
        @if (isCloud())
 | 
					        @if (isCloud())
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,15 +17,15 @@
 | 
				
			|||||||
        <a  class="{{ request()->routeIs('team.index') ? 'text-white' : '' }}" href="{{ route('team.index') }}">
 | 
					        <a  class="{{ request()->routeIs('team.index') ? 'text-white' : '' }}" href="{{ route('team.index') }}">
 | 
				
			||||||
            <button>General</button>
 | 
					            <button>General</button>
 | 
				
			||||||
        </a>
 | 
					        </a>
 | 
				
			||||||
        <a  class="{{ request()->routeIs('team.members') ? 'text-white' : '' }}" href="{{ route('team.members') }}">
 | 
					        <a  class="{{ request()->routeIs('team.member.index') ? 'text-white' : '' }}" href="{{ route('team.member.index') }}">
 | 
				
			||||||
            <button>Members</button>
 | 
					            <button>Members</button>
 | 
				
			||||||
        </a>
 | 
					        </a>
 | 
				
			||||||
        <a  class="{{ request()->routeIs('team.storages.all') ? 'text-white' : '' }}"
 | 
					        <a  class="{{ request()->routeIs('team.storage.index') ? 'text-white' : '' }}"
 | 
				
			||||||
            href="{{ route('team.storages.all') }}">
 | 
					            href="{{ route('team.storage.index') }}">
 | 
				
			||||||
            <button>S3 Storages</button>
 | 
					            <button>S3 Storages</button>
 | 
				
			||||||
        </a>
 | 
					        </a>
 | 
				
			||||||
        <a  class="{{ request()->routeIs('team.notifications') ? 'text-white' : '' }}"
 | 
					        <a  class="{{ request()->routeIs('team.notification.index') ? 'text-white' : '' }}"
 | 
				
			||||||
            href="{{ route('team.notifications') }}">
 | 
					            href="{{ route('team.notification.index') }}">
 | 
				
			||||||
            <button>Notifications</button>
 | 
					            <button>Notifications</button>
 | 
				
			||||||
        </a>
 | 
					        </a>
 | 
				
			||||||
        <div class="flex-1"></div>
 | 
					        <div class="flex-1"></div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,10 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
    @if ($pull_request_id === 0)
 | 
					@if ($pull_request_id === 0)
 | 
				
			||||||
        Failed to deploy a new version of {{ $name }} at [{{ $fqdn }}]({{ $fqdn }}) .
 | 
					Failed to deploy a new version of {{ $name }} at [{{ $fqdn }}]({{ $fqdn }}) .
 | 
				
			||||||
    @else
 | 
					@else
 | 
				
			||||||
        Failed to deploy a pull request #{{ $pull_request_id }} of {{ $name }} at
 | 
					Failed to deploy a pull request #{{ $pull_request_id }} of {{ $name }} at
 | 
				
			||||||
        [{{ $fqdn }}]({{ $fqdn }}).
 | 
					[{{ $fqdn }}]({{ $fqdn }}).
 | 
				
			||||||
    @endif
 | 
					@endif
 | 
				
			||||||
 | 
					 | 
				
			||||||
    [View Deployment Logs]({{ $deployment_url }})
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[View Deployment Logs]({{ $deployment_url }})
 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,11 +1,11 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
    @if ($pull_request_id === 0)
 | 
					@if ($pull_request_id === 0)
 | 
				
			||||||
        A new version of {{ $name }} is available at [{{ $fqdn }}]({{ $fqdn }}) .
 | 
					A new version of {{ $name }} is available at [{{ $fqdn }}]({{ $fqdn }}) .
 | 
				
			||||||
    @else
 | 
					@else
 | 
				
			||||||
        Pull request #{{ $pull_request_id }} of {{ $name }} deployed successfully
 | 
					Pull request #{{ $pull_request_id }} of {{ $name }} deployed successfully
 | 
				
			||||||
        [{{ $fqdn }}]({{ $fqdn }}).
 | 
					[{{ $fqdn }}]({{ $fqdn }}).
 | 
				
			||||||
    @endif
 | 
					@endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [View Deployment Logs]({{ $deployment_url }})
 | 
					[View Deployment Logs]({{ $deployment_url }})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,7 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
 | 
					{{ $name }} has been stopped.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    {{ $name }} has been stopped.
 | 
					If it was your intention to stop this application, you can ignore this email.
 | 
				
			||||||
 | 
					 | 
				
			||||||
    If it was your intention to stop this application, you can ignore this email.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    If not, [check what is going on]({{ $application_url }}).
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If not, [check what is going on]({{ $application_url }}).
 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,7 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
    Database backup for {{ $name }} with frequency of {{ $frequency }} was FAILED.
 | 
					Database backup for {{ $name }} with frequency of {{ $frequency }} was FAILED.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ### Reason
 | 
					### Reason
 | 
				
			||||||
 | 
					 | 
				
			||||||
    {{ $output }}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{{ $output }}
 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,3 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
    Database backup for {{ $name }} with frequency of {{ $frequency }} was successful.
 | 
					Database backup for {{ $name }} with frequency of {{ $frequency }} was successful.
 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,7 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
    We would like to inform you that a {{ config('constants.limits.trial_period') }} days of trial has been added to all
 | 
					We would like to inform you that a {{ config('constants.limits.trial_period') }} days of trial has been added to all subscription plans.
 | 
				
			||||||
    subscription plans.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You can try out Coolify, without payment information for free. If you like it, you can upgrade to a paid plan at any
 | 
					You can try out Coolify, without payment information for free. If you like it, you can upgrade to a paid plan at any time.
 | 
				
			||||||
    time.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [Click here](https://app.coolify.io/subscription) to start your trial.
 | 
					[Click here](https://app.coolify.io/subscription) to start your trial.
 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,9 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
 | 
					A resource ({{ $containerName }}) has been restarted automatically on {{ $serverName }}, because it was stopped unexpectedly.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    A service ({{ $containerName }}) has been restarted automatically on {{ $serverName }}, because it was stopped
 | 
					@if ($containerName === 'coolify-proxy')
 | 
				
			||||||
    unexpectedly.
 | 
					Coolify Proxy should run on your server as you have FQDNs set up in one of your resources.
 | 
				
			||||||
 | 
					 | 
				
			||||||
    @if ($containerName === 'coolify-proxy')
 | 
					 | 
				
			||||||
        Coolify Proxy should run on your server as you have FQDNs set up in one of your resources.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        If you don't want to use Coolify Proxy, please remove FQDN from your resources or set Proxy type to
 | 
					 | 
				
			||||||
        Custom(None).
 | 
					 | 
				
			||||||
    @endif
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you don't want to use Coolify Proxy, please remove FQDN from your resources or set Proxy type to Custom(None).
 | 
				
			||||||
 | 
					@endif
 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,7 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
 | 
					A resource ({{ $containerName }}) has been stopped unexpectedly on {{ $serverName }}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    A service ({{ $containerName }}) has been stopped unexpectedly on {{ $serverName }}.
 | 
					@if ($url)
 | 
				
			||||||
 | 
					Please check what is going on [here]({{ $url }}).
 | 
				
			||||||
    @if ($url)
 | 
					@endif
 | 
				
			||||||
        Please check what is going on [here]({{ $url }}).
 | 
					 | 
				
			||||||
    @endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,3 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
    Verify your email [here]({{ $url }}).
 | 
					Verify your email [here]({{ $url }}).
 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,7 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
 | 
					Your server ({{ $name }}) has high disk usage ({{ $disk_usage }}% used). Threshold is {{ $threshold }}%.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Your server ({{ $name }}) has high disk usage ({{ $disk_usage }}% used). Threshold is
 | 
					Please cleanup your disk to prevent data-loss. Here are some [tips](https://coolify.io/docs/automated-cleanup).
 | 
				
			||||||
    {{ $threshold }}%.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Please cleanup your disk to prevent data-loss. Here are some [tips](https://coolify.io/docs/automated-cleanup).
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    (You can change the threshold in the Server Settings menu.)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(You can change the threshold in the Server Settings menu.)
 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,9 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
 | 
					You have been invited to "{{ $team }}" on "{{ config('app.name') }}".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    You have been invited to "{{ $team }}" on "{{ config('app.name') }}".
 | 
					Please [click here]({{ $invitation_link }}) to accept the invitation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Please [click here]({{ $invitation_link }}) to accept the invitation.
 | 
					If you have any questions, please contact the team owner.<br><br>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    If you have any questions, please contact the team owner.<br><br>
 | 
					If it was not you who requested this invitation, please ignore this email.
 | 
				
			||||||
 | 
					 | 
				
			||||||
    If it was not you who requested this invitation, please ignore this email.
 | 
					 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
    A password reset has been requested for this email address.
 | 
					A password reset has been requested for this email address.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Click [here]({{ $url }}) to reset your password.
 | 
					Click [here]({{ $url }}) to reset your password.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    This link will expire in {{ $count }} minutes.
 | 
					This link will expire in {{ $count }} minutes.
 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
    Connection could not be establised with one of your S3 Storage ({{ $name }}). Please fix it
 | 
					 | 
				
			||||||
    [here]({{ $url }}).
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    {{ $reason }}
 | 
					Connection could not be established with one of your S3 Storage ({{ $name }}). Please fix it [here]({{ $url }}).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{{ $reason }}
 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,9 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
 | 
					Coolify cannot connect to your server ({{ $name }}). Please check your server and make sure it is running.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Coolify cannot connect to your server ({{ $name }}). Please check your server and make sure it is running.
 | 
					All automations & integrations are turned off!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    All automations & integrations are turned off!
 | 
					IMPORTANT: We automatically try to revive your server. If your server is back online, we will automatically turn onall automations & integrations.
 | 
				
			||||||
 | 
					 | 
				
			||||||
    IMPORTANT: We automatically try to revive your server. If your server is back online, we will automatically turn on
 | 
					 | 
				
			||||||
    all automations & integrations.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    If you have any questions, please contact us.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you have any questions, please contact us.
 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,3 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
 | 
					Your server ({{ $name }}) was offline for a while, but it is back online now. All automations & integrationsare turned on again.
 | 
				
			||||||
    Your server ({{ $name }}) was offline for a while, but it is back online now. All automations & integrations
 | 
					 | 
				
			||||||
    are turned on again.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
    Your last invoice has failed to be paid for Coolify Cloud.
 | 
					Your last invoice has failed to be paid for Coolify Cloud.
 | 
				
			||||||
 | 
					 | 
				
			||||||
    Please update payment details [here]({{ $stripeCustomerPortal }}).
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Please update payment details [here]({{ $stripeCustomerPortal }}).
 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,3 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
    If you are seeing this, it means that your Email settings are correct.
 | 
					If you are seeing this, it means that your Email settings are correct.
 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,5 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
 | 
					Your trial ended. All automations and integrations are disabled for all of your servers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Your trial ended. All automations and integrations are disabled for all of your servers.
 | 
					Please update payment details [here]({{ $stripeCustomerPortal }}) or in [Coolify Cloud](https://app.coolify.io) to continue using our services.
 | 
				
			||||||
 | 
					 | 
				
			||||||
    Please update payment details [here]({{ $stripeCustomerPortal }}) or in [Coolify Cloud](https://app.coolify.io) to
 | 
					 | 
				
			||||||
    continue using our services.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,5 @@
 | 
				
			|||||||
<x-emails.layout>
 | 
					<x-emails.layout>
 | 
				
			||||||
 | 
					Your trial ends soon. Please update payment details [here]({{ $stripeCustomerPortal }}),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Your trial ends soon. Please update payment details [here]({{ $stripeCustomerPortal }}),
 | 
					Your servers & deployed resources will be untouched, but you won't be able to deploy new resources and lost all automations and integrations.
 | 
				
			||||||
 | 
					 | 
				
			||||||
    Your servers & deployed resources will be untouched, but you won't be able to deploy new resources and lost all
 | 
					 | 
				
			||||||
    automations and integrations.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</x-emails.layout>
 | 
					</x-emails.layout>
 | 
				
			||||||
 
 | 
				
			|||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user