diff --git a/.dockerignore b/.dockerignore index 090a80fbb..5953cb0d9 100644 --- a/.dockerignore +++ b/.dockerignore @@ -20,3 +20,4 @@ yarn-error.log /.npm /.bash_history /_data +.rnd diff --git a/.gitignore b/.gitignore index e1b6b679e..9de2a7c13 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,4 @@ _ide_helper.php .gitignore .phpstorm.meta.php _ide_helper_models.php +.rnd diff --git a/app/Actions/Server/InstallDocker.php b/app/Actions/Server/InstallDocker.php index 7c58445dc..732d58d52 100644 --- a/app/Actions/Server/InstallDocker.php +++ b/app/Actions/Server/InstallDocker.php @@ -12,29 +12,38 @@ public function __invoke(Server $server, Team $team) { $dockerVersion = '23.0'; $config = base64_encode('{ "live-restore": true }'); - $activity = remote_process([ - "echo ####### Installing Prerequisites...", - "command -v jq >/dev/null || apt-get update", - "command -v jq >/dev/null || apt install -y jq", - "echo ####### Installing/updating Docker Engine...", - "curl https://releases.rancher.com/install-docker/{$dockerVersion}.sh | sh", - "echo ####### Configuring Docker Engine (merging existing configuration with the required)...", - "test -s /etc/docker/daemon.json && cp /etc/docker/daemon.json \"/etc/docker/daemon.json.original-`date +\"%Y%m%d-%H%M%S\"`\" || echo '{$config}' | base64 -d > /etc/docker/daemon.json", - "echo '{$config}' | base64 -d > /etc/docker/daemon.json.coolify", - "cat <<< $(jq . /etc/docker/daemon.json.coolify) > /etc/docker/daemon.json.coolify", - "cat <<< $(jq -s '.[0] * .[1]' /etc/docker/daemon.json /etc/docker/daemon.json.coolify) > /etc/docker/daemon.json", - "echo ####### Restarting Docker Engine...", - "systemctl restart docker", - "echo ####### Creating default network...", - "docker network create --attachable coolify", - "echo ####### Done!" - ], $server); - StandaloneDocker::create([ - 'name' => 'coolify', - 'network' => 'coolify', - 'server_id' => $server->id, - 'team_id' => $team->id - ]); + if (is_dev()) { + $activity = remote_process([ + "echo ####### Installing Prerequisites...", + "echo ####### Installing/updating Docker Engine...", + "echo ####### Configuring Docker Engine (merging existing configuration with the required)...", + "echo ####### Restarting Docker Engine...", + ], $server); + } else { + $activity = remote_process([ + "echo ####### Installing Prerequisites...", + "command -v jq >/dev/null || apt-get update", + "command -v jq >/dev/null || apt install -y jq", + "echo ####### Installing/updating Docker Engine...", + "curl https://releases.rancher.com/install-docker/{$dockerVersion}.sh | sh", + "echo ####### Configuring Docker Engine (merging existing configuration with the required)...", + "test -s /etc/docker/daemon.json && cp /etc/docker/daemon.json \"/etc/docker/daemon.json.original-`date +\"%Y%m%d-%H%M%S\"`\" || echo '{$config}' | base64 -d > /etc/docker/daemon.json", + "echo '{$config}' | base64 -d > /etc/docker/daemon.json.coolify", + "cat <<< $(jq . /etc/docker/daemon.json.coolify) > /etc/docker/daemon.json.coolify", + "cat <<< $(jq -s '.[0] * .[1]' /etc/docker/daemon.json /etc/docker/daemon.json.coolify) > /etc/docker/daemon.json", + "echo ####### Restarting Docker Engine...", + "systemctl restart docker", + "echo ####### Creating default network...", + "docker network create --attachable coolify", + "echo ####### Done!" + ], $server); + StandaloneDocker::create([ + 'name' => 'coolify', + 'network' => 'coolify', + 'server_id' => $server->id, + ]); + } + return $activity; } diff --git a/app/Http/Livewire/Boarding.php b/app/Http/Livewire/Boarding.php index 47dd072ba..0b1b9b86b 100644 --- a/app/Http/Livewire/Boarding.php +++ b/app/Http/Livewire/Boarding.php @@ -2,6 +2,7 @@ namespace App\Http\Livewire; +use App\Actions\Server\InstallDocker; use App\Models\PrivateKey; use App\Models\Project; use App\Models\Server; @@ -9,9 +10,7 @@ class Boarding extends Component { - - public string $currentState = 'create-private-key'; - // public ?string $serverType = null; + public string $currentState = 'welcome'; public ?string $privateKeyType = null; public ?string $privateKey = null; @@ -26,6 +25,8 @@ class Boarding extends Component public ?string $remoteServerUser = 'root'; public ?Server $createdServer = null; + public ?Project $createdProject = null; + public function mount() { $this->privateKeyName = generate_random_name(); @@ -64,7 +65,11 @@ public function skipBoarding() public function setServer(string $type) { if ($type === 'localhost') { - $this->currentState = 'create-project'; + $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'; } @@ -126,22 +131,50 @@ public function saveServer() $this->currentState = 'install-docker'; return; } - ray($uptime, $dockerVersion); } 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' => generate_random_name(), + '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'; - $this->privateKey = generateSSHKey(); - } - public function createNewProject() - { - Project::create([ - 'name' => generate_random_name(), - 'team_id' => currentTeam()->id - ]); + ['private' => $this->privateKey] = generateSSHKey(); } } diff --git a/app/Http/Livewire/Destination/New/StandaloneDocker.php b/app/Http/Livewire/Destination/New/StandaloneDocker.php index f67180b69..1af7bc2df 100644 --- a/app/Http/Livewire/Destination/New/StandaloneDocker.php +++ b/app/Http/Livewire/Destination/New/StandaloneDocker.php @@ -60,20 +60,19 @@ public function submit() $found = $this->server->standaloneDockers()->where('network', $this->network)->first(); if ($found) { $this->createNetworkAndAttachToProxy(); - $this->addError('network', 'Network already added to this server.'); + $this->emit('error', 'Network already added to this server.'); return; } else { $docker = ModelsStandaloneDocker::create([ 'name' => $this->name, 'network' => $this->network, 'server_id' => $this->server_id, - 'team_id' => currentTeam()->id ]); } $this->createNetworkAndAttachToProxy(); return redirect()->route('destination.show', $docker->uuid); } catch (\Exception $e) { - return general_error_handler(err: $e); + return general_error_handler(err: $e, that: $this); } } diff --git a/app/Http/Livewire/Project/New/Select.php b/app/Http/Livewire/Project/New/Select.php index e2271ab53..b3109ef8c 100644 --- a/app/Http/Livewire/Project/New/Select.php +++ b/app/Http/Livewire/Project/New/Select.php @@ -3,6 +3,7 @@ namespace App\Http\Livewire\Project\New; use App\Models\Server; +use Countable; use Livewire\Component; class Select extends Component @@ -11,7 +12,7 @@ class Select extends Component public string $type; public string $server_id; public string $destination_uuid; - public $servers = []; + public Countable|array|Server $servers; public $destinations = []; public array $parameters; @@ -23,6 +24,13 @@ public function mount() public function set_type(string $type) { $this->type = $type; + if (count($this->servers) === 1) { + $server = $this->servers->first(); + $this->set_server($server); + if (count($server->destinations()) === 1) { + $this->set_destination($server->destinations()->first()->uuid); + } + } $this->current_step = 'servers'; } diff --git a/app/Http/Livewire/Server/Proxy.php b/app/Http/Livewire/Server/Proxy.php index 1f51d1b1c..944b5e898 100644 --- a/app/Http/Livewire/Server/Proxy.php +++ b/app/Http/Livewire/Server/Proxy.php @@ -35,7 +35,7 @@ public function change_proxy() $this->emit('proxyStatusUpdated'); } - public function select_proxy(string $proxy_type) + public function select_proxy(ProxyTypes $proxy_type) { $this->server->proxy->type = $proxy_type; $this->server->proxy->status = 'exited'; diff --git a/app/Models/Server.php b/app/Models/Server.php index d14d5f974..8f70ef1f3 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -10,21 +10,30 @@ class Server extends BaseModel { use SchemalessAttributesTrait; + protected static function booted() + { + static::created(function ($server) { + ServerSetting::create([ + 'server_id' => $server->id, + ]); + StandaloneDocker::create([ + 'name' => 'coolify', + 'network' => 'coolify', + 'server_id' => $server->id, + ]); + }); + static::deleting(function ($server) { + $server->settings()->delete(); + }); + } + public $casts = [ 'proxy' => SchemalessAttributes::class, ]; protected $schemalessAttributes = [ 'proxy', ]; - protected $fillable = [ - 'name', - 'ip', - 'user', - 'port', - 'team_id', - 'private_key_id', - 'proxy', - ]; + protected $guarded = []; static public function isReachable() { @@ -51,17 +60,7 @@ static public function destinationsByServer(string $server_id) return $standaloneDocker->concat($swarmDocker); } - protected static function booted() - { - static::created(function ($server) { - ServerSetting::create([ - 'server_id' => $server->id, - ]); - }); - static::deleting(function ($server) { - $server->settings()->delete(); - }); - } + public function settings() { diff --git a/resources/css/app.css b/resources/css/app.css index 2e0f079ee..7703ef608 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -53,7 +53,7 @@ .icon:hover { @apply text-white; } .box { - @apply flex items-center justify-center p-2 transition-colors rounded cursor-pointer min-h-12 bg-coolgray-200 hover:bg-coollabs-100 hover:text-white hover:no-underline; + @apply flex items-center p-2 transition-colors cursor-pointer min-h-16 bg-coolgray-200 hover:bg-coollabs-100 hover:text-white hover:no-underline min-w-[24rem]; } .lds-heart { diff --git a/resources/js/components/MagicBar.vue b/resources/js/components/MagicBar.vue index a0b08c283..a0e8f762c 100644 --- a/resources/js/components/MagicBar.vue +++ b/resources/js/components/MagicBar.vue @@ -53,12 +53,12 @@ {{ sequenceState.sequence[sequenceState.currentActionIndex] }} name will be: - + {{ search }} {{ sequenceState.sequence[sequenceState.currentActionIndex] }} name will be: - + randomly generated (type to change) diff --git a/resources/views/boarding.blade.php b/resources/views/boarding.blade.php index d089e0650..bdf229935 100644 --- a/resources/views/boarding.blade.php +++ b/resources/views/boarding.blade.php @@ -1,3 +1,13 @@ + + + + + + + Close + + + diff --git a/resources/views/components/boarding-step.blade.php b/resources/views/components/boarding-step.blade.php index 4776f3365..e9341cbd9 100644 --- a/resources/views/components/boarding-step.blade.php +++ b/resources/views/components/boarding-step.blade.php @@ -1,5 +1,5 @@
-
+

{{$title}}

@isset($question) @@ -9,7 +9,7 @@ @endisset
@if($actions) -
+
{{$actions}}
@endif diff --git a/resources/views/livewire/boarding.blade.php b/resources/views/livewire/boarding.blade.php index 5d9348eba..29a114318 100644 --- a/resources/views/livewire/boarding.blade.php +++ b/resources/views/livewire/boarding.blade.php @@ -1,3 +1,4 @@ +@php use App\Enums\ProxyTypes; @endphp
@@ -5,7 +6,7 @@

Welcome to Coolify

Let me help you to set the basics.

-
Get Started +
Get Started
@endif @@ -16,9 +17,9 @@ or on a ? -
Localhost +
Localhost
-
Remote Server +
Remote Server
@@ -33,21 +34,21 @@ @endif @if ($currentState === 'private-key') - + - Do you have your own Private Key? + Do you have your own SSH Private Key? -
Yes +
Yes
-
No (create one for me) +
No (create one for me)
-

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. +

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.

@@ -109,25 +110,53 @@ @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 + + + 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!
+
Let's do it!

Projects are bound together several resources into one virtual group. There are no @@ -137,6 +166,20 @@ @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
Skip boarding process Restart boarding process diff --git a/resources/views/livewire/destination/show.blade.php b/resources/views/livewire/destination/show.blade.php index a0718f017..1ab18826e 100644 --- a/resources/views/livewire/destination/show.blade.php +++ b/resources/views/livewire/destination/show.blade.php @@ -18,18 +18,23 @@
N/A
@endforelse
-
+
@if (count($networks) > 0) -

Found Destinations

+

Found Destinations

@endif +
@foreach ($networks as $network) + @endforeach
+
@else
Server is not validated. Validate first.
@endif diff --git a/resources/views/livewire/project/edit.blade.php b/resources/views/livewire/project/edit.blade.php index 1d212956e..dfcab8d22 100644 --- a/resources/views/livewire/project/edit.blade.php +++ b/resources/views/livewire/project/edit.blade.php @@ -3,9 +3,6 @@

Project: {{ data_get($project, 'name') }}

Save - @if ($project->applications->count() === 0) - - @endif
Edit project details here.
diff --git a/resources/views/livewire/project/new/select.blade.php b/resources/views/livewire/project/new/select.blade.php index c187a98fc..bdb6ac4ad 100644 --- a/resources/views/livewire/project/new/select.blade.php +++ b/resources/views/livewire/project/new/select.blade.php @@ -10,7 +10,7 @@

Applications

-
@@ -21,7 +21,7 @@
-
@@ -32,7 +32,7 @@
-
@@ -45,7 +45,7 @@
-
@@ -59,7 +59,7 @@

Databases

-
@@ -79,9 +79,9 @@
  • Select a Server
  • Select a Destination
  • -
    +
    @forelse($servers as $server) -
    @@ -108,9 +108,9 @@
  • Select a Server
  • Select a Destination
  • -
    +
    @foreach ($destinations as $destination) -
    diff --git a/resources/views/project/show.blade.php b/resources/views/project/show.blade.php index dcd350419..288e2ce9d 100644 --- a/resources/views/project/show.blade.php +++ b/resources/views/project/show.blade.php @@ -3,8 +3,11 @@

    Environments

    + Add + @if ($project->applications->count() === 0) + + @endif
    -
    {{ $project->name }}
    +
    {{ $project->name }}
    @forelse ($project->environments as $environment)