diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index e92a29fc2..e3d8420ab 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -48,23 +48,6 @@ public function license() public function force_passoword_reset() { return view('auth.force-password-reset'); } - // public function dashboard() - // { - // $projects = Project::ownedByCurrentTeam()->get(); - // $servers = Server::ownedByCurrentTeam()->get(); - // $s3s = S3Storage::ownedByCurrentTeam()->get(); - // $resources = 0; - // foreach ($projects as $project) { - // $resources += $project->applications->count(); - // $resources += $project->postgresqls->count(); - // } - // return view('dashboard', [ - // 'servers' => $servers->count(), - // 'projects' => $projects->count(), - // 'resources' => $resources, - // 's3s' => $s3s, - // ]); - // } public function boarding() { if (currentTeam()->boarding || isDev()) { return view('boarding'); diff --git a/app/Http/Livewire/Boarding/Index.php b/app/Http/Livewire/Boarding/Index.php new file mode 100644 index 000000000..d704f4f02 --- /dev/null +++ b/app/Http/Livewire/Boarding/Index.php @@ -0,0 +1,183 @@ +privateKeyName = generate_random_name(); + $this->remoteServerName = generate_random_name(); + if (isDev()) { + $this->privateKey = '-----BEGIN OPENSSH PRIVATE KEY----- +b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW +QyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevAAAAJi/QySHv0Mk +hwAAAAtzc2gtZWQyNTUxOQAAACBbhpqHhqv6aI67Mj9abM3DVbmcfYhZAhC7ca4d9UCevA +AAAECBQw4jg1WRT2IGHMncCiZhURCts2s24HoDS0thHnnRKVuGmoeGq/pojrsyP1pszcNV +uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== +-----END OPENSSH PRIVATE KEY-----'; + $this->privateKeyDescription = 'Created by Coolify'; + $this->remoteServerDescription = 'Created by Coolify'; + $this->remoteServerHost = 'coolify-testing-host'; + } + } + public function restartBoarding() + { + if ($this->createdServer) { + $this->createdServer->delete(); + } + if ($this->createdPrivateKey) { + $this->createdPrivateKey->delete(); + } + return redirect()->route('boarding'); + } + public function skipBoarding() + { + currentTeam()->update([ + 'show_boarding' => false + ]); + refreshSession(); + return redirect()->route('dashboard'); + } + public function setServer(string $type) + { + if ($type === 'localhost') { + $this->createdServer = Server::find(0); + if (!$this->createdServer) { + return $this->emit('error', 'Localhost server is not found. Something went wrong during installation. Please try to reinstall or contact support.'); + } + $this->currentState = 'select-proxy'; + } elseif ($type === 'remote') { + $this->currentState = 'private-key'; + } + } + public function setPrivateKey(string $type) + { + $this->privateKeyType = $type; + if ($type === 'create' && !isDev()) { + $this->createNewPrivateKey(); + } + $this->currentState = 'create-private-key'; + } + public function savePrivateKey() + { + $this->validate([ + 'privateKeyName' => 'required', + 'privateKey' => 'required', + ]); + $this->currentState = 'create-server'; + } + public function saveServer() + { + $this->validate([ + 'remoteServerName' => 'required', + 'remoteServerHost' => 'required', + 'remoteServerPort' => 'required', + 'remoteServerUser' => 'required', + ]); + $this->privateKey = formatPrivateKey($this->privateKey); + $this->createdPrivateKey = PrivateKey::create([ + 'name' => $this->privateKeyName, + 'description' => $this->privateKeyDescription, + 'private_key' => $this->privateKey, + 'team_id' => currentTeam()->id + ]); + $this->createdServer = Server::create([ + 'name' => $this->remoteServerName, + 'ip' => $this->remoteServerHost, + 'port' => $this->remoteServerPort, + 'user' => $this->remoteServerUser, + 'description' => $this->remoteServerDescription, + 'private_key_id' => $this->createdPrivateKey->id, + 'team_id' => currentTeam()->id + ]); + try { + ['uptime' => $uptime, 'dockerVersion' => $dockerVersion] = validateServer($this->createdServer); + if (!$uptime) { + $this->createdServer->delete(); + $this->createdPrivateKey->delete(); + throw new \Exception('Server is not reachable.'); + } else { + $this->createdServer->settings->update([ + 'is_reachable' => true, + ]); + $this->emit('success', 'Server is reachable.'); + } + if ($dockerVersion) { + $this->emit('error', 'Docker is not installed on the server.'); + $this->currentState = 'install-docker'; + return; + } + } catch (\Exception $e) { + return general_error_handler(customErrorMessage: "Server is not reachable. Reason: {$e->getMessage()}", that: $this); + } + } + public function installDocker() + { + $activity = resolve(InstallDocker::class)($this->createdServer, currentTeam()); + $this->emit('newMonitorActivity', $activity->id); + $this->currentState = 'select-proxy'; + } + public function selectProxy(string|null $proxyType = null) + { + if (!$proxyType) { + return $this->currentState = 'create-project'; + } + $this->createdServer->proxy->type = $proxyType; + $this->createdServer->proxy->status = 'exited'; + $this->createdServer->save(); + $this->currentState = 'create-project'; + } + public function createNewProject() + { + $this->createdProject = Project::create([ + 'name' => "My first project", + 'team_id' => currentTeam()->id + ]); + $this->currentState = 'create-resource'; + } + public function showNewResource() + { + $this->skipBoarding(); + return redirect()->route( + 'project.resources.new', + [ + 'project_uuid' => $this->createdProject->uuid, + 'environment_name' => 'production', + + ] + ); + } + private function createNewPrivateKey() + { + $this->privateKeyName = generate_random_name(); + $this->privateKeyDescription = 'Created by Coolify'; + ['private' => $this->privateKey, 'public'=> $this->publicKey] = generateSSHKey(); + } + public function render() + { + return view('livewire.boarding.index')->layout('layouts.boarding'); + } +} diff --git a/resources/views/boarding.blade.php b/resources/views/boarding.blade.php deleted file mode 100644 index bdf229935..000000000 --- a/resources/views/boarding.blade.php +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - Close - - - - diff --git a/resources/views/components/layout-simple.blade.php b/resources/views/components/layout-simple.blade.php index cf1328b32..538b357f0 100644 --- a/resources/views/components/layout-simple.blade.php +++ b/resources/views/components/layout-simple.blade.php @@ -1,68 +1 @@ - - - - - - - - - @env('local') - Coolify - localhost - - @else - {{ $title ?? 'Coolify' }} - - @endenv - - @vite(['resources/js/app.js', 'resources/css/app.css']) - - @livewireStyles - - - - @livewireScripts - -
- {{ $slot }} -
- - - - - - +@extends('layouts.simple') diff --git a/resources/views/components/layout-subscription.blade.php b/resources/views/components/layout-subscription.blade.php index a3b0bf806..5fdd838af 100644 --- a/resources/views/components/layout-subscription.blade.php +++ b/resources/views/components/layout-subscription.blade.php @@ -1,86 +1 @@ - - - - - - - - - @env('local') - Coolify - localhost - -@else - {{ $title ?? 'Coolify' }} - - @endenv - - @vite(['resources/js/app.js', 'resources/css/app.css']) - - @livewireStyles - - - - @livewireScripts - - @if (isSubscriptionOnGracePeriod()) -
- -
- - @else - - @endif - -
- {{ $slot }} -
- - - - - +@extends('layouts.subscription') diff --git a/resources/views/components/layout.blade.php b/resources/views/components/layout.blade.php index 32fc1c73f..f16b07f50 100644 --- a/resources/views/components/layout.blade.php +++ b/resources/views/components/layout.blade.php @@ -1,133 +1 @@ - - - - - - - - - @env('local') - Coolify - localhost - -@else - {{ $title ?? 'Coolify' }} - - @endenv - - @vite(['resources/js/app.js', 'resources/css/app.css']) - - @livewireStyles - - - - @livewireScripts - @auth - - -
- -
-
- {{ $slot }} -
- - - @endauth - @guest - {{ $slot }} - @endguest - - - +@extends('layouts.app') diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 32fc1c73f..e825b5493 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -1,133 +1,11 @@ - - - - - - - - - @env('local') - Coolify - localhost - -@else - {{ $title ?? 'Coolify' }} - - @endenv - - @vite(['resources/js/app.js', 'resources/css/app.css']) - - @livewireStyles - - - - @livewireScripts - @auth - - -
- -
-
- {{ $slot }} -
- - - @endauth - @guest +@extends('layouts.base') +@section('body') + @parent + +
+ +
+
{{ $slot }} - @endguest - - - +
+@endsection diff --git a/resources/views/layouts/base.blade.php b/resources/views/layouts/base.blade.php new file mode 100644 index 000000000..a8e2f941d --- /dev/null +++ b/resources/views/layouts/base.blade.php @@ -0,0 +1,88 @@ + + + + + + + + + Coolify + @env('local') + +@else + + @endenv + + @vite(['resources/js/app.js', 'resources/css/app.css']) + + @livewireStyles + +@section('body') + + + @livewireScripts + @auth + + + + @endauth + @guest + {{ $slot }} + @endguest + +@show + + diff --git a/resources/views/layouts/boarding.blade.php b/resources/views/layouts/boarding.blade.php new file mode 100644 index 000000000..a63d26a41 --- /dev/null +++ b/resources/views/layouts/boarding.blade.php @@ -0,0 +1,9 @@ +@extends('layouts.base') +@section('body') +
+
+ {{ $slot }} +
+
+@parent +@endsection diff --git a/resources/views/layouts/simple.blade.php b/resources/views/layouts/simple.blade.php new file mode 100644 index 000000000..c3a25cda8 --- /dev/null +++ b/resources/views/layouts/simple.blade.php @@ -0,0 +1,7 @@ +@extends('layouts.base') +@section('body') + @parent +
+ {{ $slot }} +
+@endsection diff --git a/resources/views/layouts/subscription.blade.php b/resources/views/layouts/subscription.blade.php new file mode 100644 index 000000000..2feb5199b --- /dev/null +++ b/resources/views/layouts/subscription.blade.php @@ -0,0 +1,16 @@ +@extends('layouts.base') +@section('body') + @parent + @if (isSubscriptionOnGracePeriod()) +
+ +
+ + @else + + @endif + +
+ {{ $slot }} +
+@endsection diff --git a/resources/views/livewire/boarding.blade.php b/resources/views/livewire/boarding.blade.php deleted file mode 100644 index c6482cbeb..000000000 --- a/resources/views/livewire/boarding.blade.php +++ /dev/null @@ -1,195 +0,0 @@ -@php use App\Enums\ProxyTypes; @endphp -
-
-
- @if ($currentState === 'welcome') -

Welcome to Coolify

-

Let me help you to set the basics.

-
-
Get Started -
-
- @endif - @if ($currentState === 'select-server') - - - Do you want to deploy your resources on your - or on a ? - - -
Localhost -
-
Remote Server -
-
- -

Servers are the main building blocks, as they will host your applications, databases, - services, called resources. Any CPU intensive process will use the server's CPU where you - are deploying your resources.

-

Localhost is the server where Coolify is running on. It is not recommended to use one server - for everyting.

-

Remote Server is a server reachable through SSH. It can be hosted at home, or from any cloud - provider.

-
-
- @endif - @if ($currentState === 'private-key') - - - Do you have your own SSH Private Key? - - -
Yes -
-
No (create one for me) -
-
- -

SSH Keys are used to connect to a remote server through a secure shell, called SSH.

-

You can use your own ssh private key, or you can let Coolify to create one for you.

-

In both ways, you need to add the public version of your ssh private key to the remote - server's - ~/.ssh/authorized_keys file. -

-
-
- @endif - @if ($currentState === 'create-private-key') - - - Please let me know your key details. - - -
- - - - @if ($privateKeyType === 'create' && !isDev()) - Copy this to your server's ~/.ssh/authorized_keys file. - - @endif - Save - -
- -

Private Keys are used to connect to a remote server through a secure shell, called SSH.

-

You can use your own private key, or you can let Coolify to create one for you.

-

In both ways, you need to add the public version of your private key to the remote server's - ~/.ssh/authorized_keys file. -

-
-
- @endif - @if ($currentState === 'create-server') - - - Please let me know your server details. - - -
-
- - -
-
- - - -
- Save -
-
- -

Username should be for now. We are working on to use - non-root users.

-
-
- @endif - @if ($currentState === 'install-docker') - - - Could not find Docker Engine on your server. Do you want me to install it for you? - - -
- Let's do - it!
-
- -

This will install the latest Docker Engine on your server, configure a few things to be able - to run optimal.

-
-
- @endif - @if ($currentState === 'select-proxy') - - - If you would like to attach any kind of domain to your resources, you need a proxy. - - - - Decide later - - - Traefik - v2 - - - Nginx - - - Caddy - - - -

This will install the latest Docker Engine on your server, configure a few things to be able - to run optimal.

-
-
- @endif - @if ($currentState === 'create-project') - - - I will create an initial project for you. You can change all the details later on. - - -
Let's do it!
-
- -

Projects are bound together several resources into one virtual group. There are no - limitations on the number of projects you could have.

-

Each project should have at least one environment. This helps you to create a production & - staging version of the same application, but grouped separately.

-
-
- @endif - @if ($currentState === 'create-resource') - - - I will redirect you to the new resource page, where you can create your first resource. - - -
Let's do - it!
-
- -

A resource could be an application, a database or a service (like WordPress).

-
-
- @endif - -
-
-
diff --git a/resources/views/livewire/boarding/index.blade.php b/resources/views/livewire/boarding/index.blade.php new file mode 100644 index 000000000..4bda0e4dc --- /dev/null +++ b/resources/views/livewire/boarding/index.blade.php @@ -0,0 +1,192 @@ +@php use App\Enums\ProxyTypes; @endphp +
+ @if ($currentState === 'welcome') +

Welcome to Coolify

+

Let me help you to set the basics.

+
+
Get Started +
+
+ @endif + @if ($currentState === 'select-server') + + + Do you want to deploy your resources on your + or on a ? + + +
Localhost +
+
Remote Server +
+
+ +

Servers are the main building blocks, as they will host your applications, databases, + services, called resources. Any CPU intensive process will use the server's CPU where you + are deploying your resources.

+

Localhost is the server where Coolify is running on. It is not recommended to use one server + for everyting.

+

Remote Server is a server reachable through SSH. It can be hosted at home, or from any cloud + provider.

+
+
+ @endif + @if ($currentState === 'private-key') + + + Do you have your own SSH Private Key? + + +
Yes +
+
No (create one for me) +
+
+ +

SSH Keys are used to connect to a remote server through a secure shell, called SSH.

+

You can use your own ssh private key, or you can let Coolify to create one for you.

+

In both ways, you need to add the public version of your ssh private key to the remote + server's + ~/.ssh/authorized_keys file. +

+
+
+ @endif + @if ($currentState === 'create-private-key') + + + Please let me know your key details. + + +
+ + + + @if ($privateKeyType === 'create' && !isDev()) + Copy this to your server's ~/.ssh/authorized_keys + file. + + @endif + Save + +
+ +

Private Keys are used to connect to a remote server through a secure shell, called SSH.

+

You can use your own private key, or you can let Coolify to create one for you.

+

In both ways, you need to add the public version of your private key to the remote server's + ~/.ssh/authorized_keys file. +

+
+
+ @endif + @if ($currentState === 'create-server') + + + Please let me know your server details. + + +
+
+ + +
+
+ + + +
+ Save +
+
+ +

Username should be for now. We are working on to use + non-root users.

+
+
+ @endif + @if ($currentState === 'install-docker') + + + Could not find Docker Engine on your server. Do you want me to install it for you? + + +
+ Let's do + it!
+
+ +

This will install the latest Docker Engine on your server, configure a few things to be able + to run optimal.

+
+
+ @endif + @if ($currentState === 'select-proxy') + + + If you would like to attach any kind of domain to your resources, you need a proxy. + + + + Decide later + + + Traefik + v2 + + + Nginx + + + Caddy + + + +

This will install the latest Docker Engine on your server, configure a few things to be able + to run optimal.

+
+
+ @endif + @if ($currentState === 'create-project') + + + I will create an initial project for you. You can change all the details later on. + + +
Let's do it!
+
+ +

Projects are bound together several resources into one virtual group. There are no + limitations on the number of projects you could have.

+

Each project should have at least one environment. This helps you to create a production & + staging version of the same application, but grouped separately.

+
+
+ @endif + @if ($currentState === 'create-resource') + + + I will redirect you to the new resource page, where you can create your first resource. + + +
Let's do + it!
+
+ +

A resource could be an application, a database or a service (like WordPress).

+
+
+ @endif + +
diff --git a/routes/web.php b/routes/web.php index 2824a0be1..839786385 100644 --- a/routes/web.php +++ b/routes/web.php @@ -6,6 +6,8 @@ use App\Http\Controllers\MagicController; use App\Http\Controllers\ProjectController; use App\Http\Controllers\ServerController; +use App\Http\Livewire\Boarding\Index; +use App\Http\Livewire\Boarding\Server as BoardingServer; use App\Http\Livewire\Dashboard; use App\Http\Livewire\Server\All; use App\Http\Livewire\Server\Show; @@ -92,7 +94,7 @@ Route::middleware(['auth'])->group(function () { Route::get('/', Dashboard::class)->name('dashboard'); - Route::get('/boarding', [Controller::class, 'boarding'])->name('boarding'); + Route::get('/boarding', Index::class)->name('boarding'); Route::middleware(['throttle:force-password-reset'])->group(function () { Route::get('/force-password-reset', [Controller::class, 'force_passoword_reset'])->name('auth.force-password-reset'); });