commit
5fda1bb932
@ -43,6 +43,7 @@ class InstallDocker
|
|||||||
"echo 'Restarting Docker Engine...'",
|
"echo 'Restarting Docker Engine...'",
|
||||||
"ls -l /tmp"
|
"ls -l /tmp"
|
||||||
]);
|
]);
|
||||||
|
return remote_process($command, $server);
|
||||||
} else {
|
} else {
|
||||||
if ($supported_os_type->contains('debian')) {
|
if ($supported_os_type->contains('debian')) {
|
||||||
$command = $command->merge([
|
$command = $command->merge([
|
||||||
@ -89,7 +90,6 @@ class InstallDocker
|
|||||||
"echo 'Done!'",
|
"echo 'Done!'",
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return remote_process($command, $server);
|
return remote_process($command, $server);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ class SyncBunny extends Command
|
|||||||
|
|
||||||
$versions = "versions.json";
|
$versions = "versions.json";
|
||||||
|
|
||||||
PendingRequest::macro('storage', function ($fileName) use($that) {
|
PendingRequest::macro('storage', function ($fileName) use ($that) {
|
||||||
$headers = [
|
$headers = [
|
||||||
'AccessKey' => env('BUNNY_STORAGE_API_KEY'),
|
'AccessKey' => env('BUNNY_STORAGE_API_KEY'),
|
||||||
'Accept' => 'application/json',
|
'Accept' => 'application/json',
|
||||||
@ -76,23 +76,26 @@ class SyncBunny extends Command
|
|||||||
}
|
}
|
||||||
if ($only_template) {
|
if ($only_template) {
|
||||||
$this->info('About to sync service-templates.json to BunnyCDN.');
|
$this->info('About to sync service-templates.json to BunnyCDN.');
|
||||||
}
|
$confirmed = confirm("Are you sure you want to sync?");
|
||||||
if ($only_version) {
|
if (!$confirmed) {
|
||||||
$this->info('About to sync versions.json to BunnyCDN.');
|
return;
|
||||||
}
|
}
|
||||||
$confirmed = confirm('Are you sure you want to sync?');
|
|
||||||
if (!$confirmed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ($only_template) {
|
|
||||||
Http::pool(fn (Pool $pool) => [
|
Http::pool(fn (Pool $pool) => [
|
||||||
$pool->storage(fileName: "$parent_dir/templates/$service_template")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$service_template"),
|
$pool->storage(fileName: "$parent_dir/templates/$service_template")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$service_template"),
|
||||||
$pool->purge("$bunny_cdn/$bunny_cdn_path/$service_template"),
|
$pool->purge("$bunny_cdn/$bunny_cdn_path/$service_template"),
|
||||||
]);
|
]);
|
||||||
$this->info('Service template uploaded & purged...');
|
$this->info('Service template uploaded & purged...');
|
||||||
return;
|
return;
|
||||||
}
|
} else if ($only_version) {
|
||||||
if ($only_version) {
|
$this->info('About to sync versions.json to BunnyCDN.');
|
||||||
|
$file = file_get_contents("$parent_dir/$versions");
|
||||||
|
$json = json_decode($file, true);
|
||||||
|
$actual_version = data_get($json, 'coolify.v4.version');
|
||||||
|
|
||||||
|
$confirmed = confirm("Are you sure you want to sync to {$actual_version}?");
|
||||||
|
if (!$confirmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Http::pool(fn (Pool $pool) => [
|
Http::pool(fn (Pool $pool) => [
|
||||||
$pool->storage(fileName: "$parent_dir/$versions")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$versions"),
|
$pool->storage(fileName: "$parent_dir/$versions")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$versions"),
|
||||||
$pool->purge("$bunny_cdn/$bunny_cdn_path/$versions"),
|
$pool->purge("$bunny_cdn/$bunny_cdn_path/$versions"),
|
||||||
@ -101,6 +104,7 @@ class SyncBunny extends Command
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Http::pool(fn (Pool $pool) => [
|
Http::pool(fn (Pool $pool) => [
|
||||||
$pool->storage(fileName: "$parent_dir/$compose_file")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$compose_file"),
|
$pool->storage(fileName: "$parent_dir/$compose_file")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$compose_file"),
|
||||||
$pool->storage(fileName: "$parent_dir/$compose_file_prod")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$compose_file_prod"),
|
$pool->storage(fileName: "$parent_dir/$compose_file_prod")->put("/$bunny_cdn_storage_name/$bunny_cdn_path/$compose_file_prod"),
|
||||||
|
@ -122,7 +122,8 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
if ($source) {
|
if ($source) {
|
||||||
$this->source = $source->getMorphClass()::where('id', $this->application->source->id)->first();
|
$this->source = $source->getMorphClass()::where('id', $this->application->source->id)->first();
|
||||||
}
|
}
|
||||||
$this->destination = $this->application->destination->getMorphClass()::where('id', $this->application->destination->id)->first();
|
$this->server = Server::find($this->application_deployment_queue->server_id);
|
||||||
|
$this->destination = $this->server->destinations()->where('id', $this->application_deployment_queue->destination_id)->first();
|
||||||
$this->server = $this->mainServer = $this->destination->server;
|
$this->server = $this->mainServer = $this->destination->server;
|
||||||
$this->serverUser = $this->server->user;
|
$this->serverUser = $this->server->user;
|
||||||
$this->basedir = $this->application->generateBaseDir($this->deployment_uuid);
|
$this->basedir = $this->application->generateBaseDir($this->deployment_uuid);
|
||||||
@ -561,12 +562,7 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
$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();
|
||||||
// if ($this->application->additional_destinations) {
|
|
||||||
// $this->push_to_docker_registry();
|
|
||||||
// $this->deploy_to_additional_destinations();
|
|
||||||
// } else {
|
|
||||||
$this->rolling_update();
|
$this->rolling_update();
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
private function deploy_nixpacks_buildpack()
|
private function deploy_nixpacks_buildpack()
|
||||||
{
|
{
|
||||||
@ -791,7 +787,18 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
}
|
}
|
||||||
private function deploy_to_additional_destinations()
|
private function deploy_to_additional_destinations()
|
||||||
{
|
{
|
||||||
|
if (str($this->application->additional_destinations)->isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$destination_ids = collect(str($this->application->additional_destinations)->explode(','));
|
$destination_ids = collect(str($this->application->additional_destinations)->explode(','));
|
||||||
|
if ($this->server->isSwarm()) {
|
||||||
|
$this->application_deployment_queue->addLogEntry("Additional destinations are not supported in swarm mode.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($destination_ids->contains($this->destination->id)) {
|
||||||
|
ray('Same destination found in additional destinations. Skipping.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
foreach ($destination_ids as $destination_id) {
|
foreach ($destination_ids as $destination_id) {
|
||||||
$destination = StandaloneDocker::find($destination_id);
|
$destination = StandaloneDocker::find($destination_id);
|
||||||
$server = $destination->server;
|
$server = $destination->server;
|
||||||
@ -799,11 +806,21 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
|
|||||||
$this->application_deployment_queue->addLogEntry("Skipping deployment to {$server->name}. Not in the same team?!");
|
$this->application_deployment_queue->addLogEntry("Skipping deployment to {$server->name}. Not in the same team?!");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$this->server = $server;
|
// ray('Deploying to additional destination: ', $server->name);
|
||||||
$this->application_deployment_queue->addLogEntry("Deploying to {$this->server->name}.");
|
$deployment_uuid = new Cuid2();
|
||||||
$this->prepare_builder_image();
|
queue_application_deployment(
|
||||||
$this->generate_image_names();
|
deployment_uuid: $deployment_uuid,
|
||||||
$this->rolling_update();
|
application: $this->application,
|
||||||
|
server: $server,
|
||||||
|
destination: $destination,
|
||||||
|
no_questions_asked: true,
|
||||||
|
);
|
||||||
|
$this->application_deployment_queue->addLogEntry("Deploying to additional server: {$server->name}. Click here to see the deployment status: " . route('project.application.deployment.show', [
|
||||||
|
'project_uuid' => data_get($this->application, 'environment.project.uuid'),
|
||||||
|
'application_uuid' => data_get($this->application, 'uuid'),
|
||||||
|
'deployment_uuid' => $deployment_uuid,
|
||||||
|
'environment_name' => data_get($this->application, 'environment.name'),
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private function set_base_dir()
|
private function set_base_dir()
|
||||||
@ -1507,11 +1524,13 @@ COPY ./nginx.conf /etc/nginx/conf.d/default.conf");
|
|||||||
'status' => $status,
|
'status' => $status,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
if ($status === ApplicationDeploymentStatus::FINISHED->value) {
|
|
||||||
$this->application->environment->project->team?->notify(new DeploymentSuccess($this->application, $this->deployment_uuid, $this->preview));
|
|
||||||
}
|
|
||||||
if ($status === ApplicationDeploymentStatus::FAILED->value) {
|
if ($status === ApplicationDeploymentStatus::FAILED->value) {
|
||||||
$this->application->environment->project->team?->notify(new DeploymentFailed($this->application, $this->deployment_uuid, $this->preview));
|
$this->application->environment->project->team?->notify(new DeploymentFailed($this->application, $this->deployment_uuid, $this->preview));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($status === ApplicationDeploymentStatus::FINISHED->value) {
|
||||||
|
// $this->deploy_to_additional_destinations();
|
||||||
|
$this->application->environment->project->team?->notify(new DeploymentSuccess($this->application, $this->deployment_uuid, $this->preview));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ class ActivityMonitor extends Component
|
|||||||
public $isPollingActive = false;
|
public $isPollingActive = false;
|
||||||
|
|
||||||
protected $activity;
|
protected $activity;
|
||||||
protected $listeners = ['newMonitorActivity'];
|
protected $listeners = ['activityMonitor' => 'newMonitorActivity'];
|
||||||
|
|
||||||
public function newMonitorActivity($activityId, $eventToDispatch = 'activityFinished')
|
public function newMonitorActivity($activityId, $eventToDispatch = 'activityFinished')
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,7 @@ use Livewire\Component;
|
|||||||
|
|
||||||
class Index extends Component
|
class Index extends Component
|
||||||
{
|
{
|
||||||
|
protected $listeners = ['serverInstalled' => 'validateServer'];
|
||||||
public string $currentState = 'welcome';
|
public string $currentState = 'welcome';
|
||||||
|
|
||||||
public ?string $selectedServerType = null;
|
public ?string $selectedServerType = null;
|
||||||
@ -93,7 +94,11 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
|||||||
$this->serverPublicKey = $this->createdServer->privateKey->publicKey();
|
$this->serverPublicKey = $this->createdServer->privateKey->publicKey();
|
||||||
return $this->validateServer('localhost');
|
return $this->validateServer('localhost');
|
||||||
} elseif ($this->selectedServerType === 'remote') {
|
} elseif ($this->selectedServerType === 'remote') {
|
||||||
$this->privateKeys = PrivateKey::ownedByCurrentTeam(['name'])->where('id', '!=', 0)->get();
|
if (isDev()) {
|
||||||
|
$this->privateKeys = PrivateKey::ownedByCurrentTeam(['name'])->get();
|
||||||
|
} else {
|
||||||
|
$this->privateKeys = PrivateKey::ownedByCurrentTeam(['name'])->where('id', '!=', 0)->get();
|
||||||
|
}
|
||||||
if ($this->privateKeys->count() > 0) {
|
if ($this->privateKeys->count() > 0) {
|
||||||
$this->selectedExistingPrivateKey = $this->privateKeys->first()->id;
|
$this->selectedExistingPrivateKey = $this->privateKeys->first()->id;
|
||||||
}
|
}
|
||||||
@ -190,6 +195,10 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
|||||||
$this->createdServer->addInitialNetwork();
|
$this->createdServer->addInitialNetwork();
|
||||||
$this->validateServer();
|
$this->validateServer();
|
||||||
}
|
}
|
||||||
|
public function installServer()
|
||||||
|
{
|
||||||
|
$this->dispatch('validateServer', true);
|
||||||
|
}
|
||||||
public function validateServer()
|
public function validateServer()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@ -228,7 +237,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA==
|
|||||||
$this->dockerInstallationStarted = true;
|
$this->dockerInstallationStarted = true;
|
||||||
$activity = InstallDocker::run($this->createdServer);
|
$activity = InstallDocker::run($this->createdServer);
|
||||||
$this->dispatch('installDocker');
|
$this->dispatch('installDocker');
|
||||||
$this->dispatch('newMonitorActivity', $activity->id);
|
$this->dispatch('activityMonitor', $activity->id);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$this->dockerInstallationStarted = false;
|
$this->dockerInstallationStarted = false;
|
||||||
return handleError(error: $e, livewire: $this);
|
return handleError(error: $e, livewire: $this);
|
||||||
|
63
app/Livewire/NewActivityMonitor.php
Normal file
63
app/Livewire/NewActivityMonitor.php
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire;
|
||||||
|
|
||||||
|
use App\Models\User;
|
||||||
|
use Livewire\Component;
|
||||||
|
use Spatie\Activitylog\Models\Activity;
|
||||||
|
|
||||||
|
class NewActivityMonitor extends Component
|
||||||
|
{
|
||||||
|
public ?string $header = null;
|
||||||
|
public $activityId;
|
||||||
|
public $eventToDispatch = 'activityFinished';
|
||||||
|
public $isPollingActive = false;
|
||||||
|
|
||||||
|
protected $activity;
|
||||||
|
protected $listeners = ['newActivityMonitor' => 'newMonitorActivity'];
|
||||||
|
|
||||||
|
public function newMonitorActivity($activityId, $eventToDispatch = 'activityFinished')
|
||||||
|
{
|
||||||
|
$this->activityId = $activityId;
|
||||||
|
$this->eventToDispatch = $eventToDispatch;
|
||||||
|
|
||||||
|
$this->hydrateActivity();
|
||||||
|
|
||||||
|
$this->isPollingActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function hydrateActivity()
|
||||||
|
{
|
||||||
|
$this->activity = Activity::find($this->activityId);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function polling()
|
||||||
|
{
|
||||||
|
$this->hydrateActivity();
|
||||||
|
// $this->setStatus(ProcessStatus::IN_PROGRESS);
|
||||||
|
$exit_code = data_get($this->activity, 'properties.exitCode');
|
||||||
|
if ($exit_code !== null) {
|
||||||
|
// if ($exit_code === 0) {
|
||||||
|
// // $this->setStatus(ProcessStatus::FINISHED);
|
||||||
|
// } else {
|
||||||
|
// // $this->setStatus(ProcessStatus::ERROR);
|
||||||
|
// }
|
||||||
|
$this->isPollingActive = false;
|
||||||
|
if ($this->eventToDispatch !== null) {
|
||||||
|
if (str($this->eventToDispatch)->startsWith('App\\Events\\')) {
|
||||||
|
$causer_id = data_get($this->activity, 'causer_id');
|
||||||
|
$user = User::find($causer_id);
|
||||||
|
if ($user) {
|
||||||
|
foreach ($user->teams as $team) {
|
||||||
|
$teamId = $team->id;
|
||||||
|
$this->eventToDispatch::dispatch($teamId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$this->dispatch($this->eventToDispatch);
|
||||||
|
ray('Dispatched event: ' . $this->eventToDispatch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,8 +7,6 @@ use App\Models\Application;
|
|||||||
use App\Models\ApplicationDeploymentQueue;
|
use App\Models\ApplicationDeploymentQueue;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
use Illuminate\Support\Facades\Process;
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class DeploymentNavbar extends Component
|
class DeploymentNavbar extends Component
|
||||||
@ -37,7 +35,15 @@ class DeploymentNavbar extends Component
|
|||||||
$this->is_debug_enabled = $this->application->settings->is_debug_enabled;
|
$this->is_debug_enabled = $this->application->settings->is_debug_enabled;
|
||||||
$this->dispatch('refreshQueue');
|
$this->dispatch('refreshQueue');
|
||||||
}
|
}
|
||||||
|
public function force_start()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
force_start_deployment($this->application_deployment_queue);
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
ray($e);
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
|
}
|
||||||
public function cancel()
|
public function cancel()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@ -67,7 +73,6 @@ class DeploymentNavbar extends Component
|
|||||||
'current_process_id' => null,
|
'current_process_id' => null,
|
||||||
'status' => ApplicationDeploymentStatus::CANCELLED_BY_USER->value,
|
'status' => ApplicationDeploymentStatus::CANCELLED_BY_USER->value,
|
||||||
]);
|
]);
|
||||||
// queue_next_deployment($this->application);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,26 +46,6 @@ class Heading extends Component
|
|||||||
$this->deploy(force_rebuild: true);
|
$this->deploy(force_rebuild: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function deployNew()
|
|
||||||
{
|
|
||||||
if ($this->application->build_pack === 'dockercompose' && is_null($this->application->docker_compose_raw)) {
|
|
||||||
$this->dispatch('error', 'Please load a Compose file first.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$this->setDeploymentUuid();
|
|
||||||
queue_application_deployment(
|
|
||||||
application: $this->application,
|
|
||||||
deployment_uuid: $this->deploymentUuid,
|
|
||||||
force_rebuild: false,
|
|
||||||
is_new_deployment: true,
|
|
||||||
);
|
|
||||||
return redirect()->route('project.application.deployment.show', [
|
|
||||||
'project_uuid' => $this->parameters['project_uuid'],
|
|
||||||
'application_uuid' => $this->parameters['application_uuid'],
|
|
||||||
'deployment_uuid' => $this->deploymentUuid,
|
|
||||||
'environment_name' => $this->parameters['environment_name'],
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
public function deploy(bool $force_rebuild = false)
|
public function deploy(bool $force_rebuild = false)
|
||||||
{
|
{
|
||||||
if ($this->application->build_pack === 'dockercompose' && is_null($this->application->docker_compose_raw)) {
|
if ($this->application->build_pack === 'dockercompose' && is_null($this->application->docker_compose_raw)) {
|
||||||
|
@ -58,19 +58,19 @@ class Heading extends Component
|
|||||||
{
|
{
|
||||||
if ($this->database->type() === 'standalone-postgresql') {
|
if ($this->database->type() === 'standalone-postgresql') {
|
||||||
$activity = StartPostgresql::run($this->database);
|
$activity = StartPostgresql::run($this->database);
|
||||||
$this->dispatch('newMonitorActivity', $activity->id);
|
$this->dispatch('activityMonitor', $activity->id);
|
||||||
} else if ($this->database->type() === 'standalone-redis') {
|
} else if ($this->database->type() === 'standalone-redis') {
|
||||||
$activity = StartRedis::run($this->database);
|
$activity = StartRedis::run($this->database);
|
||||||
$this->dispatch('newMonitorActivity', $activity->id);
|
$this->dispatch('activityMonitor', $activity->id);
|
||||||
} else if ($this->database->type() === 'standalone-mongodb') {
|
} else if ($this->database->type() === 'standalone-mongodb') {
|
||||||
$activity = StartMongodb::run($this->database);
|
$activity = StartMongodb::run($this->database);
|
||||||
$this->dispatch('newMonitorActivity', $activity->id);
|
$this->dispatch('activityMonitor', $activity->id);
|
||||||
} else if ($this->database->type() === 'standalone-mysql') {
|
} else if ($this->database->type() === 'standalone-mysql') {
|
||||||
$activity = StartMysql::run($this->database);
|
$activity = StartMysql::run($this->database);
|
||||||
$this->dispatch('newMonitorActivity', $activity->id);
|
$this->dispatch('activityMonitor', $activity->id);
|
||||||
} else if ($this->database->type() === 'standalone-mariadb') {
|
} else if ($this->database->type() === 'standalone-mariadb') {
|
||||||
$activity = StartMariadb::run($this->database);
|
$activity = StartMariadb::run($this->database);
|
||||||
$this->dispatch('newMonitorActivity', $activity->id);
|
$this->dispatch('activityMonitor', $activity->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ class Import extends Component
|
|||||||
|
|
||||||
if (!empty($this->importCommands)) {
|
if (!empty($this->importCommands)) {
|
||||||
$activity = remote_process($this->importCommands, $this->server, ignore_errors: true);
|
$activity = remote_process($this->importCommands, $this->server, ignore_errors: true);
|
||||||
$this->dispatch('newMonitorActivity', $activity->id);
|
$this->dispatch('activityMonitor', $activity->id);
|
||||||
}
|
}
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
$this->validated = false;
|
$this->validated = false;
|
||||||
|
@ -57,7 +57,7 @@ class Navbar extends Component
|
|||||||
}
|
}
|
||||||
$this->service->parse();
|
$this->service->parse();
|
||||||
$activity = StartService::run($this->service);
|
$activity = StartService::run($this->service);
|
||||||
$this->dispatch('newMonitorActivity', $activity->id);
|
$this->dispatch('activityMonitor', $activity->id);
|
||||||
}
|
}
|
||||||
public function stop(bool $forceCleanup = false)
|
public function stop(bool $forceCleanup = false)
|
||||||
{
|
{
|
||||||
@ -82,6 +82,6 @@ class Navbar extends Component
|
|||||||
StopService::run($this->service);
|
StopService::run($this->service);
|
||||||
$this->service->parse();
|
$this->service->parse();
|
||||||
$activity = StartService::run($this->service);
|
$activity = StartService::run($this->service);
|
||||||
$this->dispatch('newMonitorActivity', $activity->id);
|
$this->dispatch('activityMonitor', $activity->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ namespace App\Livewire\Project\Service;
|
|||||||
use App\Models\ServiceApplication;
|
use App\Models\ServiceApplication;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
class Application extends Component
|
class ServiceApplicationView extends Component
|
||||||
{
|
{
|
||||||
public ServiceApplication $application;
|
public ServiceApplication $application;
|
||||||
public $parameters;
|
public $parameters;
|
||||||
@ -20,7 +20,7 @@ class Application extends Component
|
|||||||
];
|
];
|
||||||
public function render()
|
public function render()
|
||||||
{
|
{
|
||||||
return view('livewire.project.service.application');
|
return view('livewire.project.service.service-application-view');
|
||||||
}
|
}
|
||||||
public function instantSave()
|
public function instantSave()
|
||||||
{
|
{
|
@ -115,7 +115,7 @@ class ExecuteContainerCommand extends Component
|
|||||||
$exec = "docker exec {$this->container} {$cmd}";
|
$exec = "docker exec {$this->container} {$cmd}";
|
||||||
}
|
}
|
||||||
$activity = remote_process([$exec], $this->server, ignore_errors: true);
|
$activity = remote_process([$exec], $this->server, ignore_errors: true);
|
||||||
$this->dispatch('newMonitorActivity', $activity->id);
|
$this->dispatch('activityMonitor', $activity->id);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ class RunCommand extends Component
|
|||||||
$this->validate();
|
$this->validate();
|
||||||
try {
|
try {
|
||||||
$activity = remote_process([$this->command], Server::where('uuid', $this->server)->first(), ignore_errors: true);
|
$activity = remote_process([$this->command], Server::where('uuid', $this->server)->first(), ignore_errors: true);
|
||||||
$this->dispatch('newMonitorActivity', $activity->id);
|
$this->dispatch('activityMonitor', $activity->id);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace App\Livewire\Server;
|
namespace App\Livewire\Server;
|
||||||
|
|
||||||
use App\Actions\Server\InstallDocker;
|
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
use Livewire\Component;
|
use Livewire\Component;
|
||||||
|
|
||||||
@ -14,7 +13,8 @@ class Form extends Component
|
|||||||
public ?string $wildcard_domain = null;
|
public ?string $wildcard_domain = null;
|
||||||
public int $cleanup_after_percentage;
|
public int $cleanup_after_percentage;
|
||||||
public bool $dockerInstallationStarted = false;
|
public bool $dockerInstallationStarted = false;
|
||||||
protected $listeners = ['serverRefresh'];
|
|
||||||
|
protected $listeners = ['serverInstalled'];
|
||||||
|
|
||||||
protected $rules = [
|
protected $rules = [
|
||||||
'server.name' => 'required',
|
'server.name' => 'required',
|
||||||
@ -49,9 +49,10 @@ class Form extends Component
|
|||||||
$this->wildcard_domain = $this->server->settings->wildcard_domain;
|
$this->wildcard_domain = $this->server->settings->wildcard_domain;
|
||||||
$this->cleanup_after_percentage = $this->server->settings->cleanup_after_percentage;
|
$this->cleanup_after_percentage = $this->server->settings->cleanup_after_percentage;
|
||||||
}
|
}
|
||||||
public function serverRefresh($install = true)
|
public function serverInstalled()
|
||||||
{
|
{
|
||||||
$this->validateServer($install);
|
$this->server->refresh();
|
||||||
|
$this->server->settings->refresh();
|
||||||
}
|
}
|
||||||
public function instantSave()
|
public function instantSave()
|
||||||
{
|
{
|
||||||
@ -64,13 +65,6 @@ class Form extends Component
|
|||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public function installDocker()
|
|
||||||
{
|
|
||||||
$this->dispatch('installDocker');
|
|
||||||
$this->dockerInstallationStarted = true;
|
|
||||||
$activity = InstallDocker::run($this->server);
|
|
||||||
$this->dispatch('newMonitorActivity', $activity->id);
|
|
||||||
}
|
|
||||||
public function checkLocalhostConnection()
|
public function checkLocalhostConnection()
|
||||||
{
|
{
|
||||||
$uptime = $this->server->validateConnection();
|
$uptime = $this->server->validateConnection();
|
||||||
@ -80,48 +74,13 @@ class Form extends Component
|
|||||||
$this->server->settings->is_usable = true;
|
$this->server->settings->is_usable = true;
|
||||||
$this->server->settings->save();
|
$this->server->settings->save();
|
||||||
} else {
|
} else {
|
||||||
$this->dispatch('error', 'Server is not reachable.<br>Please validate your configuration and connection.<br><br>Check this <a target="_blank" class="underline" href="https://coolify.io/docs/server/openssh">documentation</a> for further help.');
|
$this->dispatch('error', 'Server is not reachable.', 'Please validate your configuration and connection.<br><br>Check this <a target="_blank" class="underline" href="https://coolify.io/docs/server/openssh">documentation</a> for further help.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public function validateServer($install = true)
|
public function validateServer($install = true)
|
||||||
{
|
{
|
||||||
try {
|
$this->dispatch('validateServer', $install);
|
||||||
$uptime = $this->server->validateConnection();
|
|
||||||
if (!$uptime) {
|
|
||||||
$install && $this->dispatch('error', 'Server is not reachable.<br>Please validate your configuration and connection.<br><br>Check this <a target="_blank" class="underline" href="https://coolify.io/docs/server/openssh">documentation</a> for further help.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$supported_os_type = $this->server->validateOS();
|
|
||||||
if (!$supported_os_type) {
|
|
||||||
$install && $this->dispatch('error', 'Server OS type is not supported for automated installation. Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$dockerInstalled = $this->server->validateDockerEngine();
|
|
||||||
if ($dockerInstalled) {
|
|
||||||
$install && $this->dispatch('success', 'Docker Engine is installed.<br> Checking version.');
|
|
||||||
} else {
|
|
||||||
$install && $this->installDocker();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
$dockerVersion = $this->server->validateDockerEngineVersion();
|
|
||||||
if ($dockerVersion) {
|
|
||||||
$install && $this->dispatch('success', 'Docker Engine version is 22+.');
|
|
||||||
} else {
|
|
||||||
$install && $this->installDocker();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if ($this->server->isSwarm()) {
|
|
||||||
$swarmInstalled = $this->server->validateDockerSwarm();
|
|
||||||
if ($swarmInstalled) {
|
|
||||||
$install && $this->dispatch('success', 'Docker Swarm is initiated.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (\Throwable $e) {
|
|
||||||
return handleError($e, $this);
|
|
||||||
} finally {
|
|
||||||
$this->dispatch('proxyStatusUpdated');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function submit()
|
public function submit()
|
||||||
|
@ -71,7 +71,7 @@ class Deploy extends Component
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$activity = StartProxy::run($this->server);
|
$activity = StartProxy::run($this->server);
|
||||||
$this->dispatch('newMonitorActivity', $activity->id, ProxyStatusChanged::class);
|
$this->dispatch('activityMonitor', $activity->id, ProxyStatusChanged::class);
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
return handleError($e, $this);
|
return handleError($e, $this);
|
||||||
}
|
}
|
||||||
|
@ -12,10 +12,8 @@ class Status extends Component
|
|||||||
public Server $server;
|
public Server $server;
|
||||||
public bool $polling = false;
|
public bool $polling = false;
|
||||||
public int $numberOfPolls = 0;
|
public int $numberOfPolls = 0;
|
||||||
|
|
||||||
protected $listeners = ['proxyStatusUpdated', 'startProxyPolling'];
|
protected $listeners = ['proxyStatusUpdated', 'startProxyPolling'];
|
||||||
public function mount() {
|
|
||||||
}
|
|
||||||
public function startProxyPolling()
|
public function startProxyPolling()
|
||||||
{
|
{
|
||||||
$this->checkProxy();
|
$this->checkProxy();
|
||||||
|
@ -11,7 +11,7 @@ class Show extends Component
|
|||||||
use AuthorizesRequests;
|
use AuthorizesRequests;
|
||||||
public ?Server $server = null;
|
public ?Server $server = null;
|
||||||
public $parameters = [];
|
public $parameters = [];
|
||||||
protected $listeners = ['proxyStatusUpdated' => '$refresh'];
|
protected $listeners = ['serverInstalled' => '$refresh'];
|
||||||
public function mount()
|
public function mount()
|
||||||
{
|
{
|
||||||
$this->parameters = get_route_parameters();
|
$this->parameters = get_route_parameters();
|
||||||
|
100
app/Livewire/Server/ValidateAndInstall.php
Normal file
100
app/Livewire/Server/ValidateAndInstall.php
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Livewire\Server;
|
||||||
|
|
||||||
|
use App\Models\Server;
|
||||||
|
use Livewire\Component;
|
||||||
|
|
||||||
|
class ValidateAndInstall extends Component
|
||||||
|
{
|
||||||
|
public Server $server;
|
||||||
|
public int $number_of_tries = 0;
|
||||||
|
public int $max_tries = 1;
|
||||||
|
public bool $install = true;
|
||||||
|
public $uptime = null;
|
||||||
|
public $supported_os_type = null;
|
||||||
|
public $docker_installed = null;
|
||||||
|
public $docker_version = null;
|
||||||
|
public $error = null;
|
||||||
|
|
||||||
|
protected $listeners = ['validateServer', 'validateDockerEngine'];
|
||||||
|
|
||||||
|
public function validateServer(bool $install = true)
|
||||||
|
{
|
||||||
|
$this->install = $install;
|
||||||
|
$this->uptime = null;
|
||||||
|
$this->supported_os_type = null;
|
||||||
|
$this->docker_installed = null;
|
||||||
|
$this->docker_version = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->validateConnection();
|
||||||
|
$this->validateOS();
|
||||||
|
$this->validateDockerEngine();
|
||||||
|
|
||||||
|
if ($this->server->isSwarm()) {
|
||||||
|
$swarmInstalled = $this->server->validateDockerSwarm();
|
||||||
|
if ($swarmInstalled) {
|
||||||
|
$this->dispatch('success', 'Docker Swarm is initiated.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
return handleError($e, $this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function validateConnection()
|
||||||
|
{
|
||||||
|
$this->uptime = $this->server->validateConnection();
|
||||||
|
if (!$this->uptime) {
|
||||||
|
$this->dispatch('error', 'Server is not reachable.', 'Please validate your configuration and connection.<br><br>Check this <a target="_blank" class="underline" href="https://coolify.io/docs/server/openssh">documentation</a> for further help.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function validateOS()
|
||||||
|
{
|
||||||
|
$this->supported_os_type = $this->server->validateOS();
|
||||||
|
if (!$this->supported_os_type) {
|
||||||
|
$this->dispatch('error', 'Server OS type is not supported.', 'Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function validateDockerEngine()
|
||||||
|
{
|
||||||
|
$this->docker_installed = $this->server->validateDockerEngine();
|
||||||
|
if (!$this->docker_installed) {
|
||||||
|
if ($this->install) {
|
||||||
|
ray($this->number_of_tries, $this->max_tries);
|
||||||
|
if ($this->number_of_tries == $this->max_tries) {
|
||||||
|
$this->error = 'Docker Engine could not be installed. Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.';
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
$activity = $this->server->installDocker();
|
||||||
|
$this->number_of_tries++;
|
||||||
|
$this->dispatch('newActivityMonitor', $activity->id, 'validateDockerEngine');
|
||||||
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->dispatch('error', 'Docker Engine is not installed.', 'Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->validateDockerVersion();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function validateDockerVersion()
|
||||||
|
{
|
||||||
|
$this->docker_version = $this->server->validateDockerEngineVersion();
|
||||||
|
if ($this->docker_version) {
|
||||||
|
$this->dispatch('serverInstalled');
|
||||||
|
$this->dispatch('success', 'Server validated successfully.');
|
||||||
|
} else {
|
||||||
|
$this->dispatch('error', 'Docker Engine version is not 22+.', 'Please install Docker manually before continuing: <a target="_blank" class="underline" href="https://docs.docker.com/engine/install/#server">documentation</a>.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public function render()
|
||||||
|
{
|
||||||
|
return view('livewire.server.validate-and-install');
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App\Actions\Server\InstallDocker;
|
||||||
use App\Enums\ProxyStatus;
|
use App\Enums\ProxyStatus;
|
||||||
use App\Enums\ProxyTypes;
|
use App\Enums\ProxyTypes;
|
||||||
use App\Notifications\Server\Revived;
|
use App\Notifications\Server\Revived;
|
||||||
@ -411,6 +412,11 @@ class Server extends BaseModel
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
public function installDocker()
|
||||||
|
{
|
||||||
|
$activity = InstallDocker::run($this);
|
||||||
|
return $activity;
|
||||||
|
}
|
||||||
public function validateDockerEngine($throwError = false)
|
public function validateDockerEngine($throwError = false)
|
||||||
{
|
{
|
||||||
$dockerBinary = instant_remote_process(["command -v docker"], $this, false);
|
$dockerBinary = instant_remote_process(["command -v docker"], $this, false);
|
||||||
|
@ -5,20 +5,31 @@ use App\Jobs\ApplicationDeploymentJob;
|
|||||||
use App\Models\Application;
|
use App\Models\Application;
|
||||||
use App\Models\ApplicationDeploymentQueue;
|
use App\Models\ApplicationDeploymentQueue;
|
||||||
use App\Models\Server;
|
use App\Models\Server;
|
||||||
|
use App\Models\StandaloneDocker;
|
||||||
use Spatie\Url\Url;
|
use Spatie\Url\Url;
|
||||||
|
|
||||||
function queue_application_deployment(Application $application, string $deployment_uuid, int | null $pull_request_id = 0, string $commit = 'HEAD', bool $force_rebuild = false, bool $is_webhook = false, bool $restart_only = false, ?string $git_type = null)
|
function queue_application_deployment(Application $application, string $deployment_uuid, int | null $pull_request_id = 0, string $commit = 'HEAD', bool $force_rebuild = false, bool $is_webhook = false, bool $restart_only = false, ?string $git_type = null, bool $no_questions_asked = false, Server $server = null, StandaloneDocker $destination = null)
|
||||||
{
|
{
|
||||||
$application_id = $application->id;
|
$application_id = $application->id;
|
||||||
$deployment_link = Url::fromString($application->link() . "/deployment/{$deployment_uuid}");
|
$deployment_link = Url::fromString($application->link() . "/deployment/{$deployment_uuid}");
|
||||||
$deployment_url = $deployment_link->getPath();
|
$deployment_url = $deployment_link->getPath();
|
||||||
$server_id = $application->destination->server->id;
|
$server_id = $application->destination->server->id;
|
||||||
$server_name = $application->destination->server->name;
|
$server_name = $application->destination->server->name;
|
||||||
|
$destination_id = $application->destination->id;
|
||||||
|
|
||||||
|
if ($server) {
|
||||||
|
$server_id = $server->id;
|
||||||
|
$server_name = $server->name;
|
||||||
|
}
|
||||||
|
if ($destination) {
|
||||||
|
$destination_id = $destination->id;
|
||||||
|
}
|
||||||
$deployment = ApplicationDeploymentQueue::create([
|
$deployment = ApplicationDeploymentQueue::create([
|
||||||
'application_id' => $application_id,
|
'application_id' => $application_id,
|
||||||
'application_name' => $application->name,
|
'application_name' => $application->name,
|
||||||
'server_id' => $server_id,
|
'server_id' => $server_id,
|
||||||
'server_name' => $server_name,
|
'server_name' => $server_name,
|
||||||
|
'destination_id' => $destination_id,
|
||||||
'deployment_uuid' => $deployment_uuid,
|
'deployment_uuid' => $deployment_uuid,
|
||||||
'deployment_url' => $deployment_url,
|
'deployment_url' => $deployment_url,
|
||||||
'pull_request_id' => $pull_request_id,
|
'pull_request_id' => $pull_request_id,
|
||||||
@ -29,7 +40,14 @@ function queue_application_deployment(Application $application, string $deployme
|
|||||||
'git_type' => $git_type
|
'git_type' => $git_type
|
||||||
]);
|
]);
|
||||||
|
|
||||||
if (next_queuable($server_id, $application_id)) {
|
if ($no_questions_asked) {
|
||||||
|
$deployment->update([
|
||||||
|
'status' => ApplicationDeploymentStatus::IN_PROGRESS->value,
|
||||||
|
]);
|
||||||
|
dispatch(new ApplicationDeploymentJob(
|
||||||
|
application_deployment_queue_id: $deployment->id,
|
||||||
|
));
|
||||||
|
} else if (next_queuable($server_id, $application_id)) {
|
||||||
$deployment->update([
|
$deployment->update([
|
||||||
'status' => ApplicationDeploymentStatus::IN_PROGRESS->value,
|
'status' => ApplicationDeploymentStatus::IN_PROGRESS->value,
|
||||||
]);
|
]);
|
||||||
@ -38,7 +56,15 @@ function queue_application_deployment(Application $application, string $deployme
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function force_start_deployment(ApplicationDeploymentQueue $deployment)
|
||||||
|
{
|
||||||
|
$deployment->update([
|
||||||
|
'status' => ApplicationDeploymentStatus::IN_PROGRESS->value,
|
||||||
|
]);
|
||||||
|
dispatch(new ApplicationDeploymentJob(
|
||||||
|
application_deployment_queue_id: $deployment->id,
|
||||||
|
));
|
||||||
|
}
|
||||||
function queue_next_deployment(Application $application)
|
function queue_next_deployment(Application $application)
|
||||||
{
|
{
|
||||||
$server_id = $application->destination->server_id;
|
$server_id = $application->destination->server_id;
|
||||||
|
@ -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.206',
|
'release' => '4.0.0-beta.207',
|
||||||
// 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.206';
|
return '4.0.0-beta.207';
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
Schema::table('application_deployment_queues', function (Blueprint $table) {
|
||||||
|
$table->string('destination_id')->nullable();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::table('application_deployment_queues', function (Blueprint $table) {
|
||||||
|
$table->dropColumn('destination_id');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
@ -258,7 +258,8 @@
|
|||||||
<div class="flex items-start gap-4 text-xl tracking-tight">Need official support for
|
<div class="flex items-start gap-4 text-xl tracking-tight">Need official support for
|
||||||
your self-hosted instance?
|
your self-hosted instance?
|
||||||
<x-forms.button>
|
<x-forms.button>
|
||||||
<a class="font-bold text-white hover:no-underline" href="{{ config('coolify.contact') }}">Contact
|
<a class="font-bold text-white hover:no-underline"
|
||||||
|
href="{{ config('coolify.contact') }}">Contact
|
||||||
Us</a>
|
Us</a>
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,31 +1,37 @@
|
|||||||
|
@props(['closeWithX' => 'false', 'fullScreen' => 'false'])
|
||||||
<div x-data="{
|
<div x-data="{
|
||||||
slideOverOpen: false
|
slideOverOpen: false
|
||||||
}" class="relative w-auto h-auto">
|
}" class="relative w-auto h-auto">
|
||||||
{{ $slot }}
|
{{ $slot }}
|
||||||
<template x-teleport="body">
|
<template x-teleport="body">
|
||||||
<div x-show="slideOverOpen" @keydown.window.escape="slideOverOpen=false" class="relative z-[99]">
|
<div x-show="slideOverOpen" @if (!$closeWithX) @keydown.window.escape="slideOverOpen=false" @endif
|
||||||
<div x-show="slideOverOpen" @click="slideOverOpen = false" class="fixed inset-0 bg-black bg-opacity-60"></div>
|
class="relative z-[99]">
|
||||||
|
<div x-show="slideOverOpen" @if (!$closeWithX) @click="slideOverOpen = false" @endif
|
||||||
|
class="fixed inset-0 bg-black bg-opacity-60"></div>
|
||||||
<div class="fixed inset-0 overflow-hidden">
|
<div class="fixed inset-0 overflow-hidden">
|
||||||
<div class="absolute inset-0 overflow-hidden">
|
<div class="absolute inset-0 overflow-hidden">
|
||||||
<div class="fixed inset-y-0 right-0 flex max-w-full pl-10">
|
<div class="fixed inset-y-0 right-0 flex max-w-full pl-10">
|
||||||
<div x-show="slideOverOpen" @click.away="slideOverOpen = false"
|
<div x-show="slideOverOpen"
|
||||||
|
@if (!$closeWithX) @click.away="slideOverOpen = false" @endif
|
||||||
x-transition:enter="transform transition ease-in-out duration-100 sm:duration-300"
|
x-transition:enter="transform transition ease-in-out duration-100 sm:duration-300"
|
||||||
x-transition:enter-start="translate-x-full" x-transition:enter-end="translate-x-0"
|
x-transition:enter-start="translate-x-full" x-transition:enter-end="translate-x-0"
|
||||||
x-transition:leave="transform transition ease-in-out duration-100 sm:duration-300"
|
x-transition:leave="transform transition ease-in-out duration-100 sm:duration-300"
|
||||||
x-transition:leave-start="translate-x-0" x-transition:leave-end="translate-x-full"
|
x-transition:leave-start="translate-x-0" x-transition:leave-end="translate-x-full"
|
||||||
class="w-screen max-w-md">
|
@class([
|
||||||
|
'max-w-md w-screen' => !$fullScreen,
|
||||||
|
'max-w-7xl w-screen' => $fullScreen,
|
||||||
|
])>
|
||||||
<div
|
<div
|
||||||
class="flex flex-col h-full py-6 overflow-hidden border-l shadow-lg bg-base-100 border-neutral-800">
|
class="flex flex-col h-full py-6 overflow-hidden border-l shadow-lg bg-base-100 border-neutral-800">
|
||||||
<div class="px-4 pb-10 sm:px-5">
|
<div class="px-4 pb-4 sm:px-5">
|
||||||
<div class="flex items-start justify-between pb-1">
|
<div class="flex items-start justify-between pb-1">
|
||||||
<h2 class="text-2xl leading-6" id="slide-over-title">
|
<h2 class="text-3xl leading-6" id="slide-over-title">
|
||||||
{{ $title }}</h2>
|
{{ $title }}</h2>
|
||||||
<div class="flex items-center h-auto ml-3">
|
<div class="flex items-center h-auto ml-3">
|
||||||
<button class="icon" @click="slideOverOpen=false"
|
<button class="icon" @click="slideOverOpen=false"
|
||||||
class="absolute top-0 right-0 z-30 flex items-center justify-center px-3 py-2 mt-4 mr-2 space-x-1 text-xs font-normal border-none rounded">
|
class="absolute top-0 right-0 z-30 flex items-center justify-center px-3 py-2 mt-4 mr-2 space-x-1 text-xs font-normal border-none rounded">
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" fill="none"
|
<svg xmlns="http://www.w3.org/2000/svg" class="w-6 h-6" fill="none"
|
||||||
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
|
viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
>
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round"
|
<path stroke-linecap="round" stroke-linejoin="round"
|
||||||
d="M6 18L18 6M6 6l12 12"></path>
|
d="M6 18L18 6M6 6l12 12"></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
@ -170,6 +170,7 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
window.Livewire.on('installDocker', () => {
|
window.Livewire.on('installDocker', () => {
|
||||||
|
console.log('Installing Docker...');
|
||||||
installDocker.showModal();
|
installDocker.showModal();
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -1,15 +1,5 @@
|
|||||||
@extends('layouts.base')
|
@extends('layouts.base')
|
||||||
@section('body')
|
@section('body')
|
||||||
<x-modal noSubmit 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>
|
|
||||||
@if (isSubscriptionActive() || isDev())
|
@if (isSubscriptionActive() || isDev())
|
||||||
<div title="Send us feedback or get help!" class="fixed top-0 right-0 p-2 px-4 pt-4 mt-auto text-xs">
|
<div title="Send us feedback or get help!" class="fixed top-0 right-0 p-2 px-4 pt-4 mt-auto text-xs">
|
||||||
<button class="flex items-center justify-center gap-2" wire:click="help" onclick="help.showModal()">
|
<button class="flex items-center justify-center gap-2" wire:click="help" onclick="help.showModal()">
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
<h1 class="text-5xl font-bold">Welcome to Coolify</h1>
|
<h1 class="text-5xl font-bold">Welcome to Coolify</h1>
|
||||||
<p class="py-6 text-xl text-center">Let me help you to set the basics.</p>
|
<p class="py-6 text-xl text-center">Let me help you to set the basics.</p>
|
||||||
<div class="flex justify-center ">
|
<div class="flex justify-center ">
|
||||||
<x-forms.button class="justify-center box" wire:click="$set('currentState','explanation')">Get Started
|
<x-forms.button class="justify-center w-64 box" wire:click="$set('currentState','explanation')">Get
|
||||||
|
Started
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
@ -31,7 +32,7 @@
|
|||||||
Telegram, Email, etc.) when something goes wrong, or an action needed from your side.</p>
|
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 w-64 box" wire:click="explanation">Next
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
</x-slot:actions>
|
</x-slot:actions>
|
||||||
</x-boarding-step>
|
</x-boarding-step>
|
||||||
@ -43,11 +44,11 @@
|
|||||||
or on a <x-highlighted text="Remote Server" />?
|
or on a <x-highlighted text="Remote Server" />?
|
||||||
</x-slot:question>
|
</x-slot:question>
|
||||||
<x-slot:actions>
|
<x-slot:actions>
|
||||||
<x-forms.button class="justify-center box" wire:target="setServerType('localhost')"
|
<x-forms.button class="justify-center w-64 box" wire:target="setServerType('localhost')"
|
||||||
wire:click="setServerType('localhost')">Localhost
|
wire:click="setServerType('localhost')">Localhost
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
|
|
||||||
<x-forms.button class="justify-center box" wire:target="setServerType('remote')"
|
<x-forms.button class="justify-center w-64 box " wire:target="setServerType('remote')"
|
||||||
wire:click="setServerType('remote')">Remote Server
|
wire:click="setServerType('remote')">Remote Server
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
@if (!$serverReachable)
|
@if (!$serverReachable)
|
||||||
@ -57,9 +58,10 @@
|
|||||||
'root' or skip the boarding process and add a new private key manually to Coolify and to the
|
'root' or skip the boarding process and add a new private key manually to Coolify and to the
|
||||||
server.
|
server.
|
||||||
<br />
|
<br />
|
||||||
Check this <a target="_blank" class="underline" href="https://coolify.io/docs/server/openssh">documentation</a> for further help.
|
Check this <a target="_blank" class="underline"
|
||||||
|
href="https://coolify.io/docs/server/openssh">documentation</a> for further help.
|
||||||
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
|
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
|
||||||
<x-forms.button class="box" wire:target="setServerType('localhost')"
|
<x-forms.button class="w-64 box" wire:target="setServerType('localhost')"
|
||||||
wire:click="setServerType('localhost')">Check again
|
wire:click="setServerType('localhost')">Check again
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
@endif
|
@endif
|
||||||
@ -83,10 +85,10 @@
|
|||||||
Do you have your own SSH Private Key?
|
Do you have your own SSH Private Key?
|
||||||
</x-slot:question>
|
</x-slot:question>
|
||||||
<x-slot:actions>
|
<x-slot:actions>
|
||||||
<x-forms.button class="justify-center box" wire:target="setPrivateKey('own')"
|
<x-forms.button class="justify-center w-64 box" wire:target="setPrivateKey('own')"
|
||||||
wire:click="setPrivateKey('own')">Yes
|
wire:click="setPrivateKey('own')">Yes
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
<x-forms.button class="justify-center box" wire:target="setPrivateKey('create')"
|
<x-forms.button class="justify-center w-64 box" wire:target="setPrivateKey('create')"
|
||||||
wire:click="setPrivateKey('create')">No (create one for me)
|
wire:click="setPrivateKey('create')">No (create one for me)
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
@if (count($privateKeys) > 0)
|
@if (count($privateKeys) > 0)
|
||||||
@ -119,7 +121,7 @@
|
|||||||
There are already servers available for your Team. Do you want to use one of them?
|
There are already servers available for your Team. Do you want to use one of them?
|
||||||
</x-slot:question>
|
</x-slot:question>
|
||||||
<x-slot:actions>
|
<x-slot:actions>
|
||||||
<x-forms.button class="justify-center box" wire:click="createNewServer">No (create one for me)
|
<x-forms.button class="justify-center w-64 box" wire:click="createNewServer">No (create one for me)
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
<div>
|
<div>
|
||||||
<form wire:submit='selectExistingServer' class="flex flex-col w-full gap-4 lg:w-96">
|
<form wire:submit='selectExistingServer' class="flex flex-col w-full gap-4 lg:w-96">
|
||||||
@ -139,7 +141,7 @@
|
|||||||
'root' or skip the boarding process and add a new private key manually to Coolify and to the
|
'root' or skip the boarding process and add a new private key manually to Coolify and to the
|
||||||
server.
|
server.
|
||||||
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
|
<x-forms.input readonly id="serverPublicKey"></x-forms.input>
|
||||||
<x-forms.button class="box" wire:target="validateServer" wire:click="validateServer">Check
|
<x-forms.button class="w-64 box" wire:target="validateServer" wire:click="validateServer">Check
|
||||||
again
|
again
|
||||||
</x-forms.button>
|
</x-forms.button>
|
||||||
@endif
|
@endif
|
||||||
@ -231,12 +233,16 @@
|
|||||||
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?
|
||||||
</x-slot:question>
|
</x-slot:question>
|
||||||
<x-slot:actions>
|
<x-slot:actions>
|
||||||
<x-forms.button class="justify-center box" wire:click="installDocker">
|
<x-slide-over closeWithX fullScreen>
|
||||||
Let's do it!</x-forms.button>
|
<x-slot:title>Configuring Server</x-slot:title>
|
||||||
@if ($dockerInstallationStarted)
|
<x-slot:content>
|
||||||
<x-forms.button class="justify-center box" wire:click="dockerInstalledOrSkipped">
|
<livewire:server.validate-and-install :server="$this->createdServer" />
|
||||||
Validate Server & Continue</x-forms.button>
|
</x-slot:content>
|
||||||
@endif
|
<x-forms.button @click="slideOverOpen=true" class="font-bold box w-96"
|
||||||
|
wire:click.prevent='installServer' isHighlighted>
|
||||||
|
Let's do it!
|
||||||
|
</x-forms.button>
|
||||||
|
</x-slide-over>
|
||||||
</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
|
||||||
@ -246,7 +252,6 @@
|
|||||||
documentation</a>.</p>
|
documentation</a>.</p>
|
||||||
</x-slot:explanation>
|
</x-slot:explanation>
|
||||||
</x-boarding-step>
|
</x-boarding-step>
|
||||||
|
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
@ -289,7 +294,7 @@
|
|||||||
@endif
|
@endif
|
||||||
</x-slot:question>
|
</x-slot:question>
|
||||||
<x-slot:actions>
|
<x-slot:actions>
|
||||||
<x-forms.button class="justify-center box" wire:click="createNewProject">Let's create a new
|
<x-forms.button class="justify-center w-64 box" wire:click="createNewProject">Let's create a new
|
||||||
one!</x-forms.button>
|
one!</x-forms.button>
|
||||||
<div>
|
<div>
|
||||||
@if (count($projects) > 0)
|
@if (count($projects) > 0)
|
||||||
@ -322,7 +327,7 @@
|
|||||||
I will redirect you to the new resource page, where you can create your first resource.
|
I will redirect you to the new resource page, where you can create your first resource.
|
||||||
</x-slot:question>
|
</x-slot:question>
|
||||||
<x-slot:actions>
|
<x-slot:actions>
|
||||||
<div class="items-center justify-center box" wire:click="showNewResource">Let's do
|
<div class="items-center justify-center w-64 box" wire:click="showNewResource">Let's do
|
||||||
it!</div>
|
it!</div>
|
||||||
</x-slot:actions>
|
</x-slot:actions>
|
||||||
<x-slot:explanation>
|
<x-slot:explanation>
|
||||||
|
18
resources/views/livewire/new-activity-monitor.blade.php
Normal file
18
resources/views/livewire/new-activity-monitor.blade.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
@php use App\Actions\CoolifyTask\RunRemoteProcess; @endphp
|
||||||
|
<div>
|
||||||
|
@if ($this->activity)
|
||||||
|
@if (isset($header))
|
||||||
|
<div class="flex gap-2 pb-2">
|
||||||
|
{{ $header }}
|
||||||
|
@if ($isPollingActive)
|
||||||
|
<x-loading />
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
<div
|
||||||
|
class="scrollbar flex flex-col-reverse w-full overflow-y-auto border border-solid rounded border-coolgray-300 max-h-[32rem] p-4 pt-6 text-xs text-white">
|
||||||
|
|
||||||
|
<pre class="font-mono whitespace-pre-wrap" @if ($isPollingActive) wire:poll.1000ms="polling" @endif>{{ RunRemoteProcess::decodeOutput($this->activity) }}</pre>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
@ -5,8 +5,12 @@
|
|||||||
@else
|
@else
|
||||||
<x-forms.button wire:click.prevent="show_debug">Show Debug Logs</x-forms.button>
|
<x-forms.button wire:click.prevent="show_debug">Show Debug Logs</x-forms.button>
|
||||||
@endif
|
@endif
|
||||||
|
@if (data_get($application_deployment_queue, 'status') === 'queued')
|
||||||
|
<x-forms.button wire:click.prevent="force_start">Force Start</x-forms.button>
|
||||||
|
@endif
|
||||||
@if (data_get($application_deployment_queue, 'status') === 'in_progress' ||
|
@if (data_get($application_deployment_queue, 'status') === 'in_progress' ||
|
||||||
data_get($application_deployment_queue, 'status') === 'queued')
|
data_get($application_deployment_queue, 'status') === 'queued')
|
||||||
<x-forms.button isError wire:click.prevent="cancel">Cancel Deployment</x-forms.button>
|
<x-forms.button isError wire:click.prevent="cancel">Cancel</x-forms.button>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -106,18 +106,6 @@
|
|||||||
</svg>
|
</svg>
|
||||||
Deploy
|
Deploy
|
||||||
</button>
|
</button>
|
||||||
{{-- @if (isDev())
|
|
||||||
<button wire:click='deployNew'
|
|
||||||
class="flex items-center gap-2 cursor-pointer hover:text-white text-neutral-400">
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" class="w-5 h-5 text-warning" viewBox="0 0 24 24"
|
|
||||||
stroke-width="1.5" stroke="currentColor" fill="none" stroke-linecap="round"
|
|
||||||
stroke-linejoin="round">
|
|
||||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
|
||||||
<path d="M7 4v16l13 -8z" />
|
|
||||||
</svg>
|
|
||||||
Deploy (new)
|
|
||||||
</button>
|
|
||||||
@endif --}}
|
|
||||||
@endif
|
@endif
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
<div class="w-full pl-8">
|
<div class="w-full pl-8">
|
||||||
@isset($serviceApplication)
|
@isset($serviceApplication)
|
||||||
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
<div x-cloak x-show="activeTab === 'general'" class="h-full">
|
||||||
<livewire:project.service.application :application="$serviceApplication" />
|
<livewire:project.service.service-application-view :application="$serviceApplication" />
|
||||||
</div>
|
</div>
|
||||||
<div x-cloak x-show="activeTab === 'storages'">
|
<div x-cloak x-show="activeTab === 'storages'">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<div>
|
<div>
|
||||||
<form wire:submit='submit' class="flex flex-col">
|
<form wire:submit.prevent='submit' class="flex flex-col">
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
<h2>General</h2>
|
<h2>General</h2>
|
||||||
@if ($server->id === 0)
|
@if ($server->id === 0)
|
||||||
@ -18,10 +18,17 @@
|
|||||||
Server is reachable and validated.
|
Server is reachable and validated.
|
||||||
@endif
|
@endif
|
||||||
@if ((!$server->settings->is_reachable || !$server->settings->is_usable) && $server->id !== 0)
|
@if ((!$server->settings->is_reachable || !$server->settings->is_usable) && $server->id !== 0)
|
||||||
<x-forms.button class="mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-100"
|
<x-slide-over closeWithX fullScreen>
|
||||||
wire:click.prevent='validateServer' isHighlighted>
|
<x-slot:title>Configuring Server</x-slot:title>
|
||||||
Validate Server & Install Docker Engine
|
<x-slot:content>
|
||||||
</x-forms.button>
|
<livewire:server.validate-and-install :server="$server" />
|
||||||
|
</x-slot:content>
|
||||||
|
<x-forms.button @click="slideOverOpen=true"
|
||||||
|
class="w-full mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-100"
|
||||||
|
wire:click.prevent='validateServer' isHighlighted>
|
||||||
|
Validate Server & Install Docker Engine
|
||||||
|
</x-forms.button>
|
||||||
|
</x-slide-over>
|
||||||
@endif
|
@endif
|
||||||
@if ((!$server->settings->is_reachable || !$server->settings->is_usable) && $server->id === 0)
|
@if ((!$server->settings->is_reachable || !$server->settings->is_usable) && $server->id === 0)
|
||||||
<x-forms.button class="mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-100"
|
<x-forms.button class="mt-8 mb-4 font-bold box-without-bg bg-coollabs hover:bg-coollabs-100"
|
||||||
|
@ -1,14 +1,4 @@
|
|||||||
<div>
|
<div>
|
||||||
<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-server.navbar :server="$server" :parameters="$parameters" />
|
<x-server.navbar :server="$server" :parameters="$parameters" />
|
||||||
<livewire:server.form :server="$server" />
|
<livewire:server.form :server="$server" />
|
||||||
<livewire:server.delete :server="$server" />
|
<livewire:server.delete :server="$server" />
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
@if ($uptime)
|
||||||
|
<div class="flex w-64 gap-2">Server is reachable: <svg class="w-5 h-5 text-success" viewBox="0 0 256 256"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g fill="currentColor">
|
||||||
|
<path
|
||||||
|
d="m237.66 85.26l-128.4 128.4a8 8 0 0 1-11.32 0l-71.6-72a8 8 0 0 1 0-11.31l24-24a8 8 0 0 1 11.32 0l36.68 35.32a8 8 0 0 0 11.32 0l92.68-91.32a8 8 0 0 1 11.32 0l24 23.6a8 8 0 0 1 0 11.31"
|
||||||
|
opacity=".2" />
|
||||||
|
<path
|
||||||
|
d="m243.28 68.24l-24-23.56a16 16 0 0 0-22.58 0L104 136l-.11-.11l-36.64-35.27a16 16 0 0 0-22.57.06l-24 24a16 16 0 0 0 0 22.61l71.62 72a16 16 0 0 0 22.63 0l128.4-128.38a16 16 0 0 0-.05-22.67M103.62 208L32 136l24-24l.11.11l36.64 35.27a16 16 0 0 0 22.52 0L208.06 56L232 79.6Z" />
|
||||||
|
</g>
|
||||||
|
</svg></div>
|
||||||
|
@else
|
||||||
|
<div class="w-64"><x-loading text="Server is reachable" /></div>
|
||||||
|
@endif
|
||||||
|
@isset($supported_os_type)
|
||||||
|
<div class="flex w-64 gap-2">Supported OS type: <svg class="w-5 h-5 text-success" viewBox="0 0 256 256"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g fill="currentColor">
|
||||||
|
<path
|
||||||
|
d="m237.66 85.26l-128.4 128.4a8 8 0 0 1-11.32 0l-71.6-72a8 8 0 0 1 0-11.31l24-24a8 8 0 0 1 11.32 0l36.68 35.32a8 8 0 0 0 11.32 0l92.68-91.32a8 8 0 0 1 11.32 0l24 23.6a8 8 0 0 1 0 11.31"
|
||||||
|
opacity=".2" />
|
||||||
|
<path
|
||||||
|
d="m243.28 68.24l-24-23.56a16 16 0 0 0-22.58 0L104 136l-.11-.11l-36.64-35.27a16 16 0 0 0-22.57.06l-24 24a16 16 0 0 0 0 22.61l71.62 72a16 16 0 0 0 22.63 0l128.4-128.38a16 16 0 0 0-.05-22.67M103.62 208L32 136l24-24l.11.11l36.64 35.27a16 16 0 0 0 22.52 0L208.06 56L232 79.6Z" />
|
||||||
|
</g>
|
||||||
|
</svg></div>
|
||||||
|
@endisset
|
||||||
|
@if ($docker_installed)
|
||||||
|
<div class="flex w-64 gap-2">Docker is installed: <svg class="w-5 h-5 text-success" viewBox="0 0 256 256"
|
||||||
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g fill="currentColor">
|
||||||
|
<path
|
||||||
|
d="m237.66 85.26l-128.4 128.4a8 8 0 0 1-11.32 0l-71.6-72a8 8 0 0 1 0-11.31l24-24a8 8 0 0 1 11.32 0l36.68 35.32a8 8 0 0 0 11.32 0l92.68-91.32a8 8 0 0 1 11.32 0l24 23.6a8 8 0 0 1 0 11.31"
|
||||||
|
opacity=".2" />
|
||||||
|
<path
|
||||||
|
d="m243.28 68.24l-24-23.56a16 16 0 0 0-22.58 0L104 136l-.11-.11l-36.64-35.27a16 16 0 0 0-22.57.06l-24 24a16 16 0 0 0 0 22.61l71.62 72a16 16 0 0 0 22.63 0l128.4-128.38a16 16 0 0 0-.05-22.67M103.62 208L32 136l24-24l.11.11l36.64 35.27a16 16 0 0 0 22.52 0L208.06 56L232 79.6Z" />
|
||||||
|
</g>
|
||||||
|
</svg></div>
|
||||||
|
@endif
|
||||||
|
@isset($docker_version)
|
||||||
|
<div class="flex w-64 gap-2">Minimum Docker version installed: <svg class="w-5 h-5 text-success"
|
||||||
|
viewBox="0 0 256 256" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g fill="currentColor">
|
||||||
|
<path
|
||||||
|
d="m237.66 85.26l-128.4 128.4a8 8 0 0 1-11.32 0l-71.6-72a8 8 0 0 1 0-11.31l24-24a8 8 0 0 1 11.32 0l36.68 35.32a8 8 0 0 0 11.32 0l92.68-91.32a8 8 0 0 1 11.32 0l24 23.6a8 8 0 0 1 0 11.31"
|
||||||
|
opacity=".2" />
|
||||||
|
<path
|
||||||
|
d="m243.28 68.24l-24-23.56a16 16 0 0 0-22.58 0L104 136l-.11-.11l-36.64-35.27a16 16 0 0 0-22.57.06l-24 24a16 16 0 0 0 0 22.61l71.62 72a16 16 0 0 0 22.63 0l128.4-128.38a16 16 0 0 0-.05-22.67M103.62 208L32 136l24-24l.11.11l36.64 35.27a16 16 0 0 0 22.52 0L208.06 56L232 79.6Z" />
|
||||||
|
</g>
|
||||||
|
</svg></div>
|
||||||
|
@endisset
|
||||||
|
<livewire:new-activity-monitor header="Docker Installation" />
|
||||||
|
@isset($error)
|
||||||
|
<pre class="font-bold whitespace-pre-line text-error">{!! $error !!}</pre>
|
||||||
|
@endisset
|
||||||
|
</div>
|
@ -4,7 +4,7 @@
|
|||||||
"version": "3.12.36"
|
"version": "3.12.36"
|
||||||
},
|
},
|
||||||
"v4": {
|
"v4": {
|
||||||
"version": "4.0.0-beta.206"
|
"version": "4.0.0-beta.207"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user