fix: boarding

This commit is contained in:
Andras Bacsai 2023-09-18 11:21:10 +02:00
parent efa7cab3e2
commit df433efe62
4 changed files with 82 additions and 84 deletions

View File

@ -4,11 +4,10 @@ namespace App\Actions\Server;
use App\Models\Server; use App\Models\Server;
use App\Models\StandaloneDocker; use App\Models\StandaloneDocker;
use App\Models\Team;
class InstallDocker class InstallDocker
{ {
public function __invoke(Server $server) public function __invoke(Server $server, bool $instant = false)
{ {
$dockerVersion = '24.0'; $dockerVersion = '24.0';
$config = base64_encode('{ $config = base64_encode('{
@ -26,8 +25,9 @@ class InstallDocker
'server_id' => $server->id, 'server_id' => $server->id,
]); ]);
} }
if (isDev()) {
return remote_process([ if (isDev() && $server->id === 0) {
$command = [
"echo '####### Installing Prerequisites...'", "echo '####### Installing Prerequisites...'",
"sleep 1", "sleep 1",
"echo '####### Installing/updating Docker Engine...'", "echo '####### Installing/updating Docker Engine...'",
@ -35,9 +35,9 @@ class InstallDocker
"sleep 4", "sleep 4",
"echo '####### Restarting Docker Engine...'", "echo '####### Restarting Docker Engine...'",
"ls -l /tmp" "ls -l /tmp"
], $server); ];
} else { } else {
return remote_process([ $command = [
"echo '####### Installing Prerequisites...'", "echo '####### Installing Prerequisites...'",
"command -v jq >/dev/null || apt-get update", "command -v jq >/dev/null || apt-get update",
"command -v jq >/dev/null || apt install -y jq", "command -v jq >/dev/null || apt install -y jq",
@ -53,7 +53,11 @@ class InstallDocker
"echo '####### Creating default Docker network (coolify)...'", "echo '####### Creating default Docker network (coolify)...'",
"docker network create --attachable coolify >/dev/null 2>&1 || true", "docker network create --attachable coolify >/dev/null 2>&1 || true",
"echo '####### Done!'" "echo '####### Done!'"
], $server); ];
} }
if ($instant) {
return instant_remote_process($command, $server);
}
return remote_process($command, $server);
} }
} }

View File

@ -38,6 +38,7 @@ class Index extends Component
public ?int $selectedExistingProject = null; public ?int $selectedExistingProject = null;
public ?Project $createdProject = null; public ?Project $createdProject = null;
public bool $dockerInstallationStarted = false;
public function mount() public function mount()
{ {
$this->privateKeyName = generate_random_name(); $this->privateKeyName = generate_random_name();
@ -65,14 +66,14 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
public function restartBoarding() public function restartBoarding()
{ {
if ($this->selectedServerType !== 'localhost') { // if ($this->selectedServerType !== 'localhost') {
if ($this->createdServer) { // if ($this->createdServer) {
$this->createdServer->delete(); // $this->createdServer->delete();
} // }
if ($this->createdPrivateKey) { // if ($this->createdPrivateKey) {
$this->createdPrivateKey->delete(); // $this->createdPrivateKey->delete();
} // }
} // }
return redirect()->route('boarding'); return redirect()->route('boarding');
} }
public function skipBoarding() public function skipBoarding()
@ -118,8 +119,6 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
} }
$this->selectedExistingPrivateKey = $this->createdServer->privateKey->id; $this->selectedExistingPrivateKey = $this->createdServer->privateKey->id;
$this->validateServer(); $this->validateServer();
$this->getProxyType();
$this->getProjects();
} }
public function getProxyType() public function getProxyType()
{ {
@ -132,6 +131,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
} }
public function selectExistingPrivateKey() public function selectExistingPrivateKey()
{ {
$this->createdPrivateKey = PrivateKey::find($this->selectedExistingPrivateKey);
$this->currentState = 'create-server'; $this->currentState = 'create-server';
} }
public function createNewServer() public function createNewServer()
@ -154,6 +154,13 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
'privateKeyName' => 'required', 'privateKeyName' => 'required',
'privateKey' => 'required', 'privateKey' => 'required',
]); ]);
$this->createdPrivateKey = PrivateKey::create([
'name' => $this->privateKeyName,
'description' => $this->privateKeyDescription,
'private_key' => $this->privateKey,
'team_id' => currentTeam()->id
]);
$this->createdPrivateKey->save();
$this->currentState = 'create-server'; $this->currentState = 'create-server';
} }
public function saveServer() public function saveServer()
@ -165,28 +172,20 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
'remoteServerUser' => 'required', 'remoteServerUser' => 'required',
]); ]);
$this->privateKey = formatPrivateKey($this->privateKey); $this->privateKey = formatPrivateKey($this->privateKey);
$this->createdPrivateKey = new PrivateKey();
$this->createdPrivateKey->private_key = $this->privateKey;
$this->createdPrivateKey->name = $this->privateKeyName;
$this->createdPrivateKey->description = $this->privateKeyDescription;
$this->createdPrivateKey->team_id = currentTeam()->id;
$foundServer = Server::whereIp($this->remoteServerHost)->first(); $foundServer = Server::whereIp($this->remoteServerHost)->first();
if ($foundServer) { if ($foundServer) {
return $this->emit('error', 'IP address is already in use by another team.'); return $this->emit('error', 'IP address is already in use by another team.');
} }
$this->createdServer = new Server(); $this->createdServer = Server::create([
$this->createdServer->uuid = (string)new Cuid2(7); 'name' => $this->remoteServerName,
$this->createdServer->name = $this->remoteServerName; 'ip' => $this->remoteServerHost,
$this->createdServer->ip = $this->remoteServerHost; 'port' => $this->remoteServerPort,
$this->createdServer->port = $this->remoteServerPort; 'user' => $this->remoteServerUser,
$this->createdServer->user = $this->remoteServerUser; 'description' => $this->remoteServerDescription,
$this->createdServer->description = $this->remoteServerDescription; 'private_key_id' => $this->createdPrivateKey->id,
$this->createdServer->privateKey = $this->createdPrivateKey; 'team_id' => currentTeam()->id,
$this->createdServer->team_id = currentTeam()->id; ]);
$this->createdServer->save();
ray($this->createdServer);
$this->validateServer(); $this->validateServer();
} }
public function validateServer(?string $type = null) public function validateServer(?string $type = null)
@ -194,47 +193,36 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
try { try {
$customErrorMessage = "Server is not reachable:"; $customErrorMessage = "Server is not reachable:";
config()->set('coolify.mux_enabled', false); config()->set('coolify.mux_enabled', false);
instant_remote_process(['uptime'], $this->createdServer, true); instant_remote_process(['uptime'], $this->createdServer, true);
$dockerVersion = instant_remote_process(["docker version|head -2|grep -i version| awk '{print $2}'"], $this->createdServer, true);
$dockerVersion = checkMinimumDockerEngineVersion($dockerVersion);
if (is_null($dockerVersion)) {
throw new \Exception('No Docker Engine or older than 23 version installed.');
}
$customErrorMessage = "Cannot create Server or Private Key. Please try again.";
if ($type !== 'localhost') {
$createdPrivateKey = PrivateKey::create([
'name' => $this->privateKeyName,
'description' => $this->privateKeyDescription,
'private_key' => $this->privateKey,
'team_id' => currentTeam()->id
]);
$server = Server::create([
'name' => $this->remoteServerName,
'ip' => $this->remoteServerHost,
'port' => $this->remoteServerPort,
'user' => $this->remoteServerUser,
'description' => $this->remoteServerDescription,
'private_key_id' => $createdPrivateKey->id,
'team_id' => currentTeam()->id,
]);
$server->settings->is_reachable = true;
$server->settings->is_usable = true;
$server->settings->save();
} else {
$this->createdServer->settings->update([ $this->createdServer->settings->update([
'is_reachable' => true, 'is_reachable' => true,
]); ]);
$dockerVersion = instant_remote_process(["docker version|head -2|grep -i version| awk '{print $2}'"], $this->createdServer, true);
$dockerVersion = checkMinimumDockerEngineVersion($dockerVersion);
if (is_null($dockerVersion)) {
$this->currentState = 'install-docker';
throw new \Exception('Docker version is not supported or not installed.');
} }
$this->getProxyType(); $this->dockerInstalledOrSkipped();
} catch (\Throwable $e) { } catch (\Throwable $e) {
return handleError(error: $e, customErrorMessage: $customErrorMessage, livewire: $this); return handleError(error: $e, customErrorMessage: $customErrorMessage, livewire: $this);
} }
} }
public function installDocker() public function installDocker()
{ {
$this->dockerInstallationStarted = true;
$activity = resolve(InstallDocker::class)($this->createdServer); $activity = resolve(InstallDocker::class)($this->createdServer);
$this->emit('newMonitorActivity', $activity->id); $this->emit('newMonitorActivity', $activity->id);
$this->currentState = 'select-proxy'; }
public function dockerInstalledOrSkipped()
{
$this->createdServer->settings->update([
'is_usable' => true,
]);
$this->getProxyType();
} }
public function selectProxy(string|null $proxyType = null) public function selectProxy(string|null $proxyType = null)
{ {

View File

@ -2,6 +2,16 @@
@section('body') @section('body')
<main class="min-h-screen hero"> <main class="min-h-screen hero">
<div class="hero-content"> <div class="hero-content">
<x-modal modalId="installDocker">
<x-slot:modalBody>
<livewire:activity-monitor header="Docker Installation Logs" />
</x-slot:modalBody>
<x-slot:modalSubmit>
<x-forms.button onclick="installDocker.close()" type="submit">
Close
</x-forms.button>
</x-slot:modalSubmit>
</x-modal>
{{ $slot }} {{ $slot }}
</div> </div>
</main> </main>

View File

@ -23,9 +23,12 @@
<x-highlighted text="Self-hosting with superpowers!" /></span> <x-highlighted text="Self-hosting with superpowers!" /></span>
</x-slot:question> </x-slot:question>
<x-slot:explanation> <x-slot:explanation>
<p><x-highlighted text="Task automation:" /> You do not to manage your servers too much. Coolify do it for you.</p> <p><x-highlighted text="Task automation:" /> You do not to manage your servers too much. Coolify do
<p><x-highlighted text="No vendor lock-in:" /> All configurations are stored on your server, so everything works without Coolify (except integrations and automations).</p> it for you.</p>
<p><x-highlighted text="Monitoring:" />You will get notified on your favourite platform (Discord, Telegram, Email, etc.) when something goes wrong, or an action needed from your side.</p> <p><x-highlighted text="No vendor lock-in:" /> All configurations are stored on your server, so
everything works without Coolify (except integrations and automations).</p>
<p><x-highlighted text="Monitoring:" />You will get notified on your favourite platform (Discord,
Telegram, Email, etc.) when something goes wrong, or an action needed from your side.</p>
</x-slot:explanation> </x-slot:explanation>
<x-slot:actions> <x-slot:actions>
<x-forms.button class="justify-center box" wire:click="explanation">Next <x-forms.button class="justify-center box" wire:click="explanation">Next
@ -194,16 +197,6 @@
</div> </div>
<div> <div>
@if ($currentState === 'install-docker') @if ($currentState === 'install-docker')
<x-modal modalId="installDocker">
<x-slot:modalBody>
<livewire:activity-monitor header="Docker Installation Logs" />
</x-slot:modalBody>
<x-slot:modalSubmit>
<x-forms.button onclick="installDocker.close()" type="submit">
Close
</x-forms.button>
</x-slot:modalSubmit>
</x-modal>
<x-boarding-step title="Install Docker"> <x-boarding-step title="Install Docker">
<x-slot:question> <x-slot:question>
Could not find Docker Engine on your server. Do you want me to install it for you? Could not find Docker Engine on your server. Do you want me to install it for you?
@ -211,8 +204,11 @@
<x-slot:actions> <x-slot:actions>
<x-forms.button class="justify-center box" wire:click="installDocker" <x-forms.button class="justify-center box" wire:click="installDocker"
onclick="installDocker.showModal()"> onclick="installDocker.showModal()">
Let's do Let's do it!</x-forms.button>
it!</x-forms.button> @if ($dockerInstallationStarted)
<x-forms.button class="justify-center box" wire:click="dockerInstalledOrSkipped">
Next</x-forms.button>
@endif
</x-slot:actions> </x-slot:actions>
<x-slot:explanation> <x-slot:explanation>
<p>This will install the latest Docker Engine on your server, configure a few things to be able <p>This will install the latest Docker Engine on your server, configure a few things to be able