save
This commit is contained in:
		@@ -20,7 +20,7 @@ class CheckProxySettingsInSync
 | 
				
			|||||||
            $final_output = Str::of($output)->trim()->value;
 | 
					            $final_output = Str::of($output)->trim()->value;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $docker_compose_yml_base64 = base64_encode($final_output);
 | 
					        $docker_compose_yml_base64 = base64_encode($final_output);
 | 
				
			||||||
        $server->extra_attributes->last_saved_proxy_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value;
 | 
					        $server->extra_attributes->proxy_last_saved_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value;
 | 
				
			||||||
        $server->save();
 | 
					        $server->save();
 | 
				
			||||||
        if (is_null($output) || $reset) {
 | 
					        if (is_null($output) || $reset) {
 | 
				
			||||||
            instant_remote_process([
 | 
					            instant_remote_process([
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -31,41 +31,24 @@ class InstallProxy
 | 
				
			|||||||
            $configuration = Str::of($configuration)->trim()->value;
 | 
					            $configuration = Str::of($configuration)->trim()->value;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        $docker_compose_yml_base64 = base64_encode($configuration);
 | 
					        $docker_compose_yml_base64 = base64_encode($configuration);
 | 
				
			||||||
        $server->extra_attributes->last_applied_proxy_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value;
 | 
					        $server->extra_attributes->proxy_last_applied_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value;
 | 
				
			||||||
        $server->save();
 | 
					        $server->save();
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // $env_file_base64 = base64_encode(
 | 
					 | 
				
			||||||
        //     $this->getEnvContents()
 | 
					 | 
				
			||||||
        // );
 | 
					 | 
				
			||||||
        $activity = remote_process([
 | 
					        $activity = remote_process([
 | 
				
			||||||
 | 
					            "echo 'Creating required Docker networks...'",
 | 
				
			||||||
            ...$create_networks_command,
 | 
					            ...$create_networks_command,
 | 
				
			||||||
            "echo 'Docker networks created...'",
 | 
					 | 
				
			||||||
            "mkdir -p $proxy_path",
 | 
					            "mkdir -p $proxy_path",
 | 
				
			||||||
            "cd $proxy_path",
 | 
					            "cd $proxy_path",
 | 
				
			||||||
            "echo '$docker_compose_yml_base64' | base64 -d > $proxy_path/docker-compose.yml",
 | 
					            "echo '$docker_compose_yml_base64' | base64 -d > $proxy_path/docker-compose.yml",
 | 
				
			||||||
            // "echo '$env_file_base64' | base64 -d > $proxy_path/.env",
 | 
					            "echo 'Creating Docker Compose file...'",
 | 
				
			||||||
            "echo 'Docker compose file created...'",
 | 
					 | 
				
			||||||
            "echo 'Pulling docker image...'",
 | 
					            "echo 'Pulling docker image...'",
 | 
				
			||||||
            'docker compose pull -q',
 | 
					            'docker compose pull -q',
 | 
				
			||||||
            "echo 'Stopping proxy...'",
 | 
					            "echo 'Stopping old proxy...'",
 | 
				
			||||||
            'docker compose down -v --remove-orphans',
 | 
					            'docker compose down -v --remove-orphans',
 | 
				
			||||||
            "echo 'Starting proxy...'",
 | 
					            "echo 'Starting new proxy...'",
 | 
				
			||||||
            'docker compose up -d --remove-orphans',
 | 
					            'docker compose up -d --remove-orphans',
 | 
				
			||||||
            "echo 'Proxy installed successfully...'"
 | 
					            "echo 'Proxy installed successfully...'"
 | 
				
			||||||
        ], $server);
 | 
					        ], $server);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return $activity;
 | 
					        return $activity;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    // protected function getEnvContents()
 | 
					 | 
				
			||||||
    // {
 | 
					 | 
				
			||||||
    //     $data = [
 | 
					 | 
				
			||||||
    //         'LETS_ENCRYPT_EMAIL' => '',
 | 
					 | 
				
			||||||
    //     ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    //     return collect($data)
 | 
					 | 
				
			||||||
    //         ->map(fn ($v, $k) => "{$k}={$v}")
 | 
					 | 
				
			||||||
    //         ->push(PHP_EOL)
 | 
					 | 
				
			||||||
    //         ->implode(PHP_EOL);
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ use Spatie\Activitylog\Models\Activity;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class ActivityMonitor extends Component
 | 
					class ActivityMonitor extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    public bool $header = false;
 | 
				
			||||||
    public $activityId;
 | 
					    public $activityId;
 | 
				
			||||||
    public $isPollingActive = false;
 | 
					    public $isPollingActive = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -50,8 +51,4 @@ class ActivityMonitor extends Component
 | 
				
			|||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
        $this->activity->save();
 | 
					        $this->activity->save();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public function render()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        return view('livewire.activity-monitor');
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace App\Http\Livewire\Project\Application;
 | 
					namespace App\Http\Livewire\Project\Application;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use App\Jobs\ContainerStatusJob;
 | 
					use App\Jobs\ApplicationContainerStatusJob;
 | 
				
			||||||
use App\Models\Application;
 | 
					use App\Models\Application;
 | 
				
			||||||
use App\Models\ApplicationPreview;
 | 
					use App\Models\ApplicationPreview;
 | 
				
			||||||
use Illuminate\Support\Collection;
 | 
					use Illuminate\Support\Collection;
 | 
				
			||||||
@@ -24,7 +24,7 @@ class Previews extends Component
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    public function loadStatus($pull_request_id)
 | 
					    public function loadStatus($pull_request_id)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        dispatch(new ContainerStatusJob(
 | 
					        dispatch(new ApplicationContainerStatusJob(
 | 
				
			||||||
            application: $this->application,
 | 
					            application: $this->application,
 | 
				
			||||||
            container_name: generate_container_name($this->application->uuid, $pull_request_id),
 | 
					            container_name: generate_container_name($this->application->uuid, $pull_request_id),
 | 
				
			||||||
            pull_request_id: $pull_request_id
 | 
					            pull_request_id: $pull_request_id
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,7 +30,6 @@ class Form extends Component
 | 
				
			|||||||
    public function installDocker()
 | 
					    public function installDocker()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $activity = resolve(InstallDocker::class)($this->server);
 | 
					        $activity = resolve(InstallDocker::class)($this->server);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        $this->emit('newMonitorActivity', $activity->id);
 | 
					        $this->emit('newMonitorActivity', $activity->id);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public function validateServer()
 | 
					    public function validateServer()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,25 +11,21 @@ use Livewire\Component;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class Proxy extends Component
 | 
					class Proxy extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    protected $listeners = ['serverValidated'];
 | 
					 | 
				
			||||||
    public Server $server;
 | 
					    public Server $server;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public ProxyTypes $selectedProxy = ProxyTypes::TRAEFIK_V2;
 | 
					    public ProxyTypes $selectedProxy = ProxyTypes::TRAEFIK_V2;
 | 
				
			||||||
    public $proxy_settings = null;
 | 
					    public $proxy_settings = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function mount()
 | 
					    protected $listeners = ['serverValidated', 'saveConfiguration'];
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->proxyStatus();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    public function serverValidated()
 | 
					    public function serverValidated()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->server->settings->refresh();
 | 
					        $this->server->refresh();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public function installProxy()
 | 
					    public function installProxy()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if (
 | 
					        if (
 | 
				
			||||||
            $this->server->extra_attributes->last_applied_proxy_settings &&
 | 
					            $this->server->extra_attributes->proxy_last_applied_settings &&
 | 
				
			||||||
            $this->server->extra_attributes->last_saved_proxy_settings !== $this->server->extra_attributes->last_applied_proxy_settings
 | 
					            $this->server->extra_attributes->proxy_last_saved_settings !== $this->server->extra_attributes->proxy_last_applied_settings
 | 
				
			||||||
        ) {
 | 
					        ) {
 | 
				
			||||||
            $this->saveConfiguration($this->server);
 | 
					            $this->saveConfiguration($this->server);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -37,15 +33,9 @@ class Proxy extends Component
 | 
				
			|||||||
        $this->emit('newMonitorActivity', $activity->id);
 | 
					        $this->emit('newMonitorActivity', $activity->id);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public function proxyStatus()
 | 
					    public function setProxy(string $proxy_type)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->server->extra_attributes->proxy_status = get_container_status(server: $this->server, container_id: 'coolify-proxy');
 | 
					        $this->server->extra_attributes->proxy_type = $proxy_type;
 | 
				
			||||||
        $this->server->save();
 | 
					 | 
				
			||||||
        $this->server->refresh();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    public function setProxy()
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        $this->server->extra_attributes->proxy_type = $this->selectedProxy->value;
 | 
					 | 
				
			||||||
        $this->server->extra_attributes->proxy_status = 'exited';
 | 
					        $this->server->extra_attributes->proxy_status = 'exited';
 | 
				
			||||||
        $this->server->save();
 | 
					        $this->server->save();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -57,17 +47,17 @@ class Proxy extends Component
 | 
				
			|||||||
        $this->server->extra_attributes->proxy_status = 'exited';
 | 
					        $this->server->extra_attributes->proxy_status = 'exited';
 | 
				
			||||||
        $this->server->save();
 | 
					        $this->server->save();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public function saveConfiguration()
 | 
					    public function saveConfiguration(Server $server)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $proxy_path = config('coolify.proxy_config_path');
 | 
					            $proxy_path = config('coolify.proxy_config_path');
 | 
				
			||||||
            $this->proxy_settings = Str::of($this->proxy_settings)->trim()->value;
 | 
					            $this->proxy_settings = Str::of($this->proxy_settings)->trim()->value;
 | 
				
			||||||
            $docker_compose_yml_base64 = base64_encode($this->proxy_settings);
 | 
					            $docker_compose_yml_base64 = base64_encode($this->proxy_settings);
 | 
				
			||||||
            $this->server->extra_attributes->last_saved_proxy_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value;
 | 
					            $server->extra_attributes->proxy_last_saved_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value;
 | 
				
			||||||
            $this->server->save();
 | 
					            $server->save();
 | 
				
			||||||
            instant_remote_process([
 | 
					            instant_remote_process([
 | 
				
			||||||
                "echo '$docker_compose_yml_base64' | base64 -d > $proxy_path/docker-compose.yml",
 | 
					                "echo '$docker_compose_yml_base64' | base64 -d > $proxy_path/docker-compose.yml",
 | 
				
			||||||
            ], $this->server);
 | 
					            ], $server);
 | 
				
			||||||
        } catch (\Exception $e) {
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
            return general_error_handler($e);
 | 
					            return general_error_handler($e);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										43
									
								
								app/Http/Livewire/Server/Proxy/Deploy.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								app/Http/Livewire/Server/Proxy/Deploy.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Livewire\Server\Proxy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Actions\Proxy\InstallProxy;
 | 
				
			||||||
 | 
					use App\Models\Server;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					use Str;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Deploy extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public Server $server;
 | 
				
			||||||
 | 
					    public $proxy_settings = null;
 | 
				
			||||||
 | 
					    protected $listeners = ['proxyStatusUpdated', 'serverValidated' => 'proxyStatusUpdated'];
 | 
				
			||||||
 | 
					    public function proxyStatusUpdated()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->server->refresh();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function deploy()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if (
 | 
				
			||||||
 | 
					            $this->server->extra_attributes->proxy_last_applied_settings &&
 | 
				
			||||||
 | 
					            $this->server->extra_attributes->proxy_last_saved_settings !== $this->server->extra_attributes->proxy_last_applied_settings
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
 | 
					            $this->saveConfiguration($this->server);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        $activity = resolve(InstallProxy::class)($this->server);
 | 
				
			||||||
 | 
					        $this->emit('newMonitorActivity', $activity->id);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function stop()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        instant_remote_process([
 | 
				
			||||||
 | 
					            "docker rm -f coolify-proxy",
 | 
				
			||||||
 | 
					        ], $this->server);
 | 
				
			||||||
 | 
					        $this->server->extra_attributes->proxy_status = 'exited';
 | 
				
			||||||
 | 
					        $this->server->save();
 | 
				
			||||||
 | 
					        $this->emit('proxyStatusUpdated');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    private function saveConfiguration(Server $server)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->emit('saveConfiguration', $server);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										29
									
								
								app/Http/Livewire/Server/Proxy/Status.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								app/Http/Livewire/Server/Proxy/Status.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Livewire\Server\Proxy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Jobs\ProxyContainerStatusJob;
 | 
				
			||||||
 | 
					use App\Models\Server;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Status extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public Server $server;
 | 
				
			||||||
 | 
					    protected $listeners = ['proxyStatusUpdated', 'serverValidated' => 'proxyStatusUpdated'];
 | 
				
			||||||
 | 
					    public function proxyStatusUpdated()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        ray('Status: ' . $this->server->extra_attributes->proxy_status);
 | 
				
			||||||
 | 
					        $this->server->refresh();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function proxyStatus()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            dispatch(new ProxyContainerStatusJob(
 | 
				
			||||||
 | 
					                server: $this->server
 | 
				
			||||||
 | 
					            ));
 | 
				
			||||||
 | 
					            $this->emit('proxyStatusUpdated');
 | 
				
			||||||
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					            ray($e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -13,7 +13,7 @@ use Illuminate\Queue\InteractsWithQueue;
 | 
				
			|||||||
use Illuminate\Queue\SerializesModels;
 | 
					use Illuminate\Queue\SerializesModels;
 | 
				
			||||||
use Illuminate\Support\Facades\Log;
 | 
					use Illuminate\Support\Facades\Log;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ContainerStatusJob implements ShouldQueue, ShouldBeUnique
 | 
					class ApplicationContainerStatusJob implements ShouldQueue, ShouldBeUnique
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
					    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -35,7 +35,6 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeUnique
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            $status = get_container_status(server: $this->application->destination->server, container_id: $this->container_name, throwError: false);
 | 
					            $status = get_container_status(server: $this->application->destination->server, container_id: $this->container_name, throwError: false);
 | 
				
			||||||
            ray('Container ' . $this->container_name . ' statuus is ' . $status);
 | 
					 | 
				
			||||||
            if ($this->pull_request_id) {
 | 
					            if ($this->pull_request_id) {
 | 
				
			||||||
                $preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->application->id, $this->pull_request_id);
 | 
					                $preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->application->id, $this->pull_request_id);
 | 
				
			||||||
                $preview->status = $status;
 | 
					                $preview->status = $status;
 | 
				
			||||||
@@ -55,34 +54,4 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeUnique
 | 
				
			|||||||
            $this->application->save();
 | 
					            $this->application->save();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    // protected function check_all_servers()
 | 
					 | 
				
			||||||
    // {
 | 
					 | 
				
			||||||
    //     $servers = Server::all()->reject(fn (Server $server) => $server->settings->is_build_server);
 | 
					 | 
				
			||||||
    //     $applications = Application::all();
 | 
					 | 
				
			||||||
    //     $not_found_applications = $applications;
 | 
					 | 
				
			||||||
    //     $containers = collect();
 | 
					 | 
				
			||||||
    //     foreach ($servers as $server) {
 | 
					 | 
				
			||||||
    //         $output = instant_remote_process(['docker ps -a -q --format \'{{json .}}\''], $server);
 | 
					 | 
				
			||||||
    //         $containers = $containers->concat(format_docker_command_output_to_json($output));
 | 
					 | 
				
			||||||
    //     }
 | 
					 | 
				
			||||||
    //     foreach ($containers as $container) {
 | 
					 | 
				
			||||||
    //         $found_application = $applications->filter(function ($value, $key) use ($container) {
 | 
					 | 
				
			||||||
    //             return $value->uuid == $container['Names'];
 | 
					 | 
				
			||||||
    //         })->first();
 | 
					 | 
				
			||||||
    //         if ($found_application) {
 | 
					 | 
				
			||||||
    //             $not_found_applications = $not_found_applications->filter(function ($value, $key) use ($found_application) {
 | 
					 | 
				
			||||||
    //                 return $value->uuid != $found_application->uuid;
 | 
					 | 
				
			||||||
    //             });
 | 
					 | 
				
			||||||
    //             $found_application->status = $container['State'];
 | 
					 | 
				
			||||||
    //             $found_application->save();
 | 
					 | 
				
			||||||
    //             Log::info('Found application: ' . $found_application->uuid . '. Set status to: ' . $found_application->status);
 | 
					 | 
				
			||||||
    //         }
 | 
					 | 
				
			||||||
    //     }
 | 
					 | 
				
			||||||
    //     foreach ($not_found_applications as $not_found_application) {
 | 
					 | 
				
			||||||
    //         $not_found_application->status = 'exited';
 | 
					 | 
				
			||||||
    //         $not_found_application->save();
 | 
					 | 
				
			||||||
    //         Log::info('Not found application: ' . $not_found_application->uuid . '. Set status to: ' . $not_found_application->status);
 | 
					 | 
				
			||||||
    //     }
 | 
					 | 
				
			||||||
    // }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -277,7 +277,7 @@ COPY --from=$this->build_image_name /app/{$this->application->publish_directory}
 | 
				
			|||||||
                'status' => $status,
 | 
					                'status' => $status,
 | 
				
			||||||
            ]);
 | 
					            ]);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        dispatch(new ContainerStatusJob(
 | 
					        dispatch(new ApplicationContainerStatusJob(
 | 
				
			||||||
            application: $this->application,
 | 
					            application: $this->application,
 | 
				
			||||||
            container_name: $this->container_name,
 | 
					            container_name: $this->container_name,
 | 
				
			||||||
            pull_request_id: $this->pull_request_id
 | 
					            pull_request_id: $this->pull_request_id
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										57
									
								
								app/Jobs/ProxyContainerStatusJob.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								app/Jobs/ProxyContainerStatusJob.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,57 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Jobs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Enums\ProxyTypes;
 | 
				
			||||||
 | 
					use App\Models\Application;
 | 
				
			||||||
 | 
					use App\Models\ApplicationPreview;
 | 
				
			||||||
 | 
					use App\Models\Server;
 | 
				
			||||||
 | 
					use Illuminate\Bus\Queueable;
 | 
				
			||||||
 | 
					use Illuminate\Contracts\Queue\ShouldBeUnique;
 | 
				
			||||||
 | 
					use Illuminate\Contracts\Queue\ShouldQueue;
 | 
				
			||||||
 | 
					use Illuminate\Foundation\Bus\Dispatchable;
 | 
				
			||||||
 | 
					use Illuminate\Queue\InteractsWithQueue;
 | 
				
			||||||
 | 
					use Illuminate\Queue\SerializesModels;
 | 
				
			||||||
 | 
					use Str;
 | 
				
			||||||
 | 
					use Illuminate\Queue\Middleware\WithoutOverlapping;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ProxyContainerStatusJob implements ShouldQueue, ShouldBeUnique
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public Server $server;
 | 
				
			||||||
 | 
					    public $tries = 1;
 | 
				
			||||||
 | 
					    public $timeout = 120;
 | 
				
			||||||
 | 
					    public function middleware(): array
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return [new WithoutOverlapping($this->server->id)];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function __construct(Server $server)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->server = $server;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function uniqueId(): int
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return $this->server->id;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function handle(): void
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            $container = get_container_status(server: $this->server, all_data: true, container_id: 'coolify-proxy', throwError: false);
 | 
				
			||||||
 | 
					            $status = $container['State']['Status'];
 | 
				
			||||||
 | 
					            if ($this->server->extra_attributes->proxy_status !== $status) {
 | 
				
			||||||
 | 
					                $this->server->extra_attributes->proxy_status = $status;
 | 
				
			||||||
 | 
					                if ($this->server->extra_attributes->proxy_status === 'running') {
 | 
				
			||||||
 | 
					                    $traefik = $container['Config']['Labels']['org.opencontainers.image.title'];
 | 
				
			||||||
 | 
					                    $version = $container['Config']['Labels']['org.opencontainers.image.version'];
 | 
				
			||||||
 | 
					                    if (isset($version) && isset($traefik) && $traefik === 'Traefik' && Str::of($version)->startsWith('v2')) {
 | 
				
			||||||
 | 
					                        $this->server->extra_attributes->proxy_type = ProxyTypes::TRAEFIK_V2->value;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                $this->server->save();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } catch (\Exception $e) {
 | 
				
			||||||
 | 
					            ray($e->getMessage());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -58,6 +58,7 @@ class Server extends BaseModel
 | 
				
			|||||||
    {
 | 
					    {
 | 
				
			||||||
        return Server::where('team_id', session('currentTeam')->id)->whereRelation('settings', 'is_validated', true)->get();
 | 
					        return Server::where('team_id', session('currentTeam')->id)->whereRelation('settings', 'is_validated', true)->get();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static public function destinations(string|null $server_uuid = null)
 | 
					    static public function destinations(string|null $server_uuid = null)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($server_uuid) {
 | 
					        if ($server_uuid) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,14 +29,17 @@ function format_docker_labels_to_json($rawOutput): Collection
 | 
				
			|||||||
        })[0];
 | 
					        })[0];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function get_container_status(Server $server, string $container_id, bool $throwError = false)
 | 
					function get_container_status(Server $server, string $container_id, bool $all_data = false, bool $throwError = false)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    $container = instant_remote_process(["docker inspect --format '{{json .State}}' {$container_id}"], $server, $throwError);
 | 
					    $container = instant_remote_process(["docker inspect --format '{{json .}}' {$container_id}"], $server, $throwError);
 | 
				
			||||||
    if (!$container) {
 | 
					    if (!$container) {
 | 
				
			||||||
        return 'exited';
 | 
					        return 'exited';
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    $container = format_docker_command_output_to_json($container);
 | 
					    $container = format_docker_command_output_to_json($container);
 | 
				
			||||||
    return $container[0]['Status'];
 | 
					    if ($all_data) {
 | 
				
			||||||
 | 
					        return $container[0];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return $container[0]['State']['Status'];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function generate_container_name(string $uuid, int|null $pull_request_id = null)
 | 
					function generate_container_name(string $uuid, int|null $pull_request_id = null)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,10 +36,7 @@ class ServerSeeder extends Seeder
 | 
				
			|||||||
            'description' => "This is a test docker container",
 | 
					            'description' => "This is a test docker container",
 | 
				
			||||||
            'ip' => "coolify-testing-host-2",
 | 
					            'ip' => "coolify-testing-host-2",
 | 
				
			||||||
            'team_id' => $root_team->id,
 | 
					            'team_id' => $root_team->id,
 | 
				
			||||||
            'private_key_id' => $private_key_1->id,
 | 
					            'private_key_id' => $private_key_1->id
 | 
				
			||||||
            'extra_attributes' => ServerMetadata::from([
 | 
					 | 
				
			||||||
                //
 | 
					 | 
				
			||||||
            ]),
 | 
					 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,7 @@ class ServerSettingSeeder extends Seeder
 | 
				
			|||||||
        $server_2->settings->save();
 | 
					        $server_2->settings->save();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $server_3 = Server::find(2)->load(['settings']);
 | 
					        $server_3 = Server::find(2)->load(['settings']);
 | 
				
			||||||
        $server_3->settings->is_part_of_swarm = true;
 | 
					        $server_3->settings->is_part_of_swarm = false;
 | 
				
			||||||
        $server_3->settings->is_validated = false;
 | 
					        $server_3->settings->is_validated = false;
 | 
				
			||||||
        $server_3->settings->save();
 | 
					        $server_3->settings->save();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,8 +15,8 @@
 | 
				
			|||||||
        ]) }}">
 | 
					        ]) }}">
 | 
				
			||||||
        <button>Deployments</button>
 | 
					        <button>Deployments</button>
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
 | 
					    <livewire:project.application.status :application="$application" />
 | 
				
			||||||
    <div class="flex-1"></div>
 | 
					    <div class="flex-1"></div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
    <div class="dropdown dropdown-bottom">
 | 
					    <div class="dropdown dropdown-bottom">
 | 
				
			||||||
        <label tabindex="0">
 | 
					        <label tabindex="0">
 | 
				
			||||||
            <x-forms.button>
 | 
					            <x-forms.button>
 | 
				
			||||||
@@ -60,5 +60,4 @@
 | 
				
			|||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <livewire:project.application.deploy :applicationId="$application->id" />
 | 
					    <livewire:project.application.deploy :applicationId="$application->id" />
 | 
				
			||||||
    <livewire:project.application.status :application="$application" />
 | 
					 | 
				
			||||||
</nav>
 | 
					</nav>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,12 +4,11 @@
 | 
				
			|||||||
    'label' => $attributes->has('label'),
 | 
					    'label' => $attributes->has('label'),
 | 
				
			||||||
    'helper' => $attributes->has('helper'),
 | 
					    'helper' => $attributes->has('helper'),
 | 
				
			||||||
    'instantSave' => $attributes->has('instantSave'),
 | 
					    'instantSave' => $attributes->has('instantSave'),
 | 
				
			||||||
    'noLabel' => $attributes->has('noLabel'),
 | 
					 | 
				
			||||||
    'noDirty' => $attributes->has('noDirty'),
 | 
					    'noDirty' => $attributes->has('noDirty'),
 | 
				
			||||||
])
 | 
					])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<div class=" form-control">
 | 
					<div class=" form-control">
 | 
				
			||||||
    @if (!$noLabel)
 | 
					    @if ($label)
 | 
				
			||||||
        <label class="label">
 | 
					        <label class="label">
 | 
				
			||||||
            <span class="label-text">
 | 
					            <span class="label-text">
 | 
				
			||||||
                @if ($label)
 | 
					                @if ($label)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +1 @@
 | 
				
			|||||||
<span class="loading loading-spinner"></span>
 | 
					<span class="loading loading-bars"></span>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,6 @@
 | 
				
			|||||||
<div class="pb-6">
 | 
					<div class="pb-6">
 | 
				
			||||||
    <h1>Server</h1>
 | 
					    <h1>Server</h1>
 | 
				
			||||||
    <div class="text-sm breadcrumbs pb-11">
 | 
					    <div class="pb-10 text-sm breadcrumbs">
 | 
				
			||||||
        <ul>
 | 
					        <ul>
 | 
				
			||||||
            <li>{{ data_get($server, 'name') }}</li>
 | 
					            <li>{{ data_get($server, 'name') }}</li>
 | 
				
			||||||
        </ul>
 | 
					        </ul>
 | 
				
			||||||
@@ -18,5 +18,7 @@
 | 
				
			|||||||
            ]) }}">
 | 
					            ]) }}">
 | 
				
			||||||
            <button>Proxy</button>
 | 
					            <button>Proxy</button>
 | 
				
			||||||
        </a>
 | 
					        </a>
 | 
				
			||||||
 | 
					        <div class="flex-1"></div>
 | 
				
			||||||
 | 
					        <livewire:server.proxy.deploy :server="$server" />
 | 
				
			||||||
    </nav>
 | 
					    </nav>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,13 @@
 | 
				
			|||||||
<div>
 | 
					<div>
 | 
				
			||||||
    @if ($this->activity)
 | 
					    @if ($this->activity)
 | 
				
			||||||
 | 
					        @if ($header)
 | 
				
			||||||
 | 
					            <h2>Logs</h2>
 | 
				
			||||||
 | 
					        @endif
 | 
				
			||||||
        <div
 | 
					        <div
 | 
				
			||||||
            class="scrollbar flex flex-col-reverse w-full overflow-y-auto border border-solid rounded border-coolgray-300 max-h-[32rem] p-4 text-xs text-white">
 | 
					            class="scrollbar flex flex-col-reverse w-full overflow-y-auto border border-solid rounded border-coolgray-300 max-h-[32rem] p-4 text-xs text-white">
 | 
				
			||||||
 | 
					            @if ($isPollingActive)
 | 
				
			||||||
 | 
					                <span class="loading loading-bars"></span>
 | 
				
			||||||
 | 
					            @endif
 | 
				
			||||||
            <pre class="font-mono whitespace-pre-wrap" @if ($isPollingActive) wire:poll.2000ms="polling" @endif>{{ \App\Actions\CoolifyTask\RunRemoteProcess::decodeOutput($this->activity) }}</pre>
 | 
					            <pre class="font-mono whitespace-pre-wrap" @if ($isPollingActive) wire:poll.2000ms="polling" @endif>{{ \App\Actions\CoolifyTask\RunRemoteProcess::decodeOutput($this->activity) }}</pre>
 | 
				
			||||||
            {{-- @else
 | 
					            {{-- @else
 | 
				
			||||||
            <pre class="whitespace-pre-wrap">Output will be here...</pre> --}}
 | 
					            <pre class="whitespace-pre-wrap">Output will be here...</pre> --}}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,16 @@
 | 
				
			|||||||
 <div class="flex flex-col gap-2" wire:init='load_deployments'
 | 
					 <div class="flex flex-col gap-2" wire:init='load_deployments'
 | 
				
			||||||
     @if ($skip == 0) wire:poll.5000ms='reload_deployments' @endif>
 | 
					     @if ($skip == 0) wire:poll.5000ms='reload_deployments' @endif>
 | 
				
			||||||
     @if (count($deployments) > 0)
 | 
					 | 
				
			||||||
     <h2 class="pt-4">Deployments <span class="text-xs">({{ $deployments_count }})</span></h2>
 | 
					     <h2 class="pt-4">Deployments <span class="text-xs">({{ $deployments_count }})</span></h2>
 | 
				
			||||||
 | 
					     @if (count($deployments) === 0)
 | 
				
			||||||
 | 
					         <x-forms.button isHighlighted wire:click="load_deployments({{ $default_take }})">Load Deployments
 | 
				
			||||||
 | 
					         </x-forms.button>
 | 
				
			||||||
 | 
					     @endif
 | 
				
			||||||
 | 
					     <div wire:loading wire:target='load_deployments'>
 | 
				
			||||||
 | 
					         <x-loading />
 | 
				
			||||||
 | 
					     </div>
 | 
				
			||||||
     @if ($show_next)
 | 
					     @if ($show_next)
 | 
				
			||||||
         <x-forms.button isHighlighted wire:click="load_deployments({{ $default_take }})">Show More
 | 
					         <x-forms.button isHighlighted wire:click="load_deployments({{ $default_take }})">Show More
 | 
				
			||||||
         </x-forms.button>
 | 
					         </x-forms.button>
 | 
				
			||||||
         @else
 | 
					 | 
				
			||||||
             <x-forms.button disabled>Show More
 | 
					 | 
				
			||||||
             </x-forms.button>
 | 
					 | 
				
			||||||
     @endif
 | 
					     @endif
 | 
				
			||||||
     @foreach ($deployments as $deployment)
 | 
					     @foreach ($deployments as $deployment)
 | 
				
			||||||
         <a @class([
 | 
					         <a @class([
 | 
				
			||||||
@@ -54,9 +57,8 @@
 | 
				
			|||||||
     </div>
 | 
					     </div>
 | 
				
			||||||
     </a>
 | 
					     </a>
 | 
				
			||||||
     @endforeach
 | 
					     @endforeach
 | 
				
			||||||
 @else
 | 
					
 | 
				
			||||||
     <span wire:loading.remove wire:target='load_deployments' class="loading loading-spinner"></span>
 | 
					
 | 
				
			||||||
     @endif
 | 
					 | 
				
			||||||
     <script src="https://cdn.jsdelivr.net/npm/dayjs@1/dayjs.min.js"></script>
 | 
					     <script src="https://cdn.jsdelivr.net/npm/dayjs@1/dayjs.min.js"></script>
 | 
				
			||||||
     <script src="https://cdn.jsdelivr.net/npm/dayjs@1/plugin/utc.js"></script>
 | 
					     <script src="https://cdn.jsdelivr.net/npm/dayjs@1/plugin/utc.js"></script>
 | 
				
			||||||
     <script src="https://cdn.jsdelivr.net/npm/dayjs@1/plugin/relativeTime.js"></script>
 | 
					     <script src="https://cdn.jsdelivr.net/npm/dayjs@1/plugin/relativeTime.js"></script>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,14 +2,12 @@
 | 
				
			|||||||
    @if ($application->status === 'running')
 | 
					    @if ($application->status === 'running')
 | 
				
			||||||
        <span class="text-xs text-pink-600" wire:loading.delay.longer>Loading current status...</span>
 | 
					        <span class="text-xs text-pink-600" wire:loading.delay.longer>Loading current status...</span>
 | 
				
			||||||
        <div class="flex items-center gap-2 text-sm" wire:loading.remove.delay.longer>
 | 
					        <div class="flex items-center gap-2 text-sm" wire:loading.remove.delay.longer>
 | 
				
			||||||
            <span class="flex w-3 h-3 rounded-full bg-success"></span>
 | 
					            <div class="text-xs font-medium tracking-wide text-white badge border-success">Running</div>
 | 
				
			||||||
            <span class="text-green-500">Running</span>
 | 
					 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    @else
 | 
					    @else
 | 
				
			||||||
        <span class="text-xs text-pink-600" wire:loading.delay.longer>Loading current status...</span>
 | 
					        <span class="text-xs text-pink-600" wire:loading.delay.longer>Loading current status...</span>
 | 
				
			||||||
        <div class="flex items-center gap-2 text-sm" wire:loading.remove.delay.longer>
 | 
					        <div class="flex items-center gap-2 text-sm" wire:loading.remove.delay.longer>
 | 
				
			||||||
            <span class="flex w-3 h-3 rounded-full bg-error"></span>
 | 
					            <div class="text-xs font-medium tracking-wide text-white badge border-error">Stopped</div>
 | 
				
			||||||
            <span class="text-error">Stopped</span>
 | 
					 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
    @endif
 | 
					    @endif
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,17 +37,20 @@
 | 
				
			|||||||
                @endif
 | 
					                @endif
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					        @if (!$server->settings->is_validated)
 | 
				
			||||||
 | 
					            <x-forms.button class="mt-4" isHighlighted wire:click.prevent='validateServer'>
 | 
				
			||||||
 | 
					                Validate Server
 | 
				
			||||||
 | 
					            </x-forms.button>
 | 
				
			||||||
 | 
					        @endif
 | 
				
			||||||
 | 
					        @if ($server->settings->is_validated)
 | 
				
			||||||
            <h3 class="pt-8 pb-4">Quick Actions</h3>
 | 
					            <h3 class="pt-8 pb-4">Quick Actions</h3>
 | 
				
			||||||
            <div class="flex items-center gap-2">
 | 
					            <div class="flex items-center gap-2">
 | 
				
			||||||
                <x-forms.button wire:click.prevent='validateServer'>
 | 
					                <x-forms.button wire:click.prevent='validateServer'>
 | 
				
			||||||
                @if ($server->settings->is_validated)
 | 
					 | 
				
			||||||
                    Check Connection
 | 
					                    Check Connection
 | 
				
			||||||
                @else
 | 
					 | 
				
			||||||
                    Validate Server
 | 
					 | 
				
			||||||
                @endif
 | 
					 | 
				
			||||||
                </x-forms.button>
 | 
					                </x-forms.button>
 | 
				
			||||||
                {{-- <x-forms.button wire:click.prevent='installDocker'>Install Docker</x-forms.button> --}}
 | 
					                {{-- <x-forms.button wire:click.prevent='installDocker'>Install Docker</x-forms.button> --}}
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					        @endif
 | 
				
			||||||
        <div class="pt-3 text-sm">
 | 
					        <div class="pt-3 text-sm">
 | 
				
			||||||
            @isset($uptime)
 | 
					            @isset($uptime)
 | 
				
			||||||
                <p>Uptime: {{ $uptime }}</p>
 | 
					                <p>Uptime: {{ $uptime }}</p>
 | 
				
			||||||
@@ -76,10 +79,12 @@
 | 
				
			|||||||
        </a>
 | 
					        </a>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div>
 | 
					    <div>
 | 
				
			||||||
        @foreach ($server->standaloneDockers as $docker)
 | 
					        @forelse ($server->standaloneDockers as $docker)
 | 
				
			||||||
            <a href="{{ route('destination.show', ['destination_uuid' => data_get($docker, 'uuid')]) }}">
 | 
					            <a href="{{ route('destination.show', ['destination_uuid' => data_get($docker, 'uuid')]) }}">
 | 
				
			||||||
                <button class="text-white btn-link">{{ data_get($docker, 'network') }}</button>
 | 
					                <button class="text-white btn-link">{{ data_get($docker, 'network') }}</button>
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
        @endforeach
 | 
					        @empty
 | 
				
			||||||
 | 
					            <div class="text-sm">No destinations added</div>
 | 
				
			||||||
 | 
					        @endforelse
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,38 +2,6 @@
 | 
				
			|||||||
    <x-naked-modal show="stopProxy" action="stopProxy"
 | 
					    <x-naked-modal show="stopProxy" action="stopProxy"
 | 
				
			||||||
        message='Are you sure you would like to stop the proxy? All resources will be unavailable.' />
 | 
					        message='Are you sure you would like to stop the proxy? All resources will be unavailable.' />
 | 
				
			||||||
    @if ($server->settings->is_validated)
 | 
					    @if ($server->settings->is_validated)
 | 
				
			||||||
        <div class="flex items-center gap-2 mb-2">
 | 
					 | 
				
			||||||
            <h2>Proxy</h2>
 | 
					 | 
				
			||||||
            @if ($server->extra_attributes->proxy_type)
 | 
					 | 
				
			||||||
                <x-forms.button isHighlighted wire:click.prevent="installProxy">
 | 
					 | 
				
			||||||
                    Start/Reconfigure Proxy
 | 
					 | 
				
			||||||
                </x-forms.button>
 | 
					 | 
				
			||||||
                <x-forms.button x-on:click.prevent="stopProxy = true">Stop
 | 
					 | 
				
			||||||
                </x-forms.button>
 | 
					 | 
				
			||||||
                <div wire:poll.5000ms="proxyStatus">
 | 
					 | 
				
			||||||
                    @if (
 | 
					 | 
				
			||||||
                        $server->extra_attributes->last_applied_proxy_settings &&
 | 
					 | 
				
			||||||
                            $server->extra_attributes->last_saved_proxy_settings !== $server->extra_attributes->last_applied_proxy_settings)
 | 
					 | 
				
			||||||
                        <div class="text-red-500">Configuration out of sync.</div>
 | 
					 | 
				
			||||||
                    @endif
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            @endif
 | 
					 | 
				
			||||||
            @if ($server->extra_attributes->proxy_status === 'running')
 | 
					 | 
				
			||||||
                <span class="text-xs text-pink-600" wire:loading.delay.longer>Loading current status...</span>
 | 
					 | 
				
			||||||
                <div class="flex items-center gap-2 text-sm" wire:loading.remove.delay.longer>
 | 
					 | 
				
			||||||
                    <span class="flex w-3 h-3 rounded-full bg-success"></span>
 | 
					 | 
				
			||||||
                    <span class="text-green-500">Running</span>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            @else
 | 
					 | 
				
			||||||
                <span class="text-xs text-pink-600" wire:loading.delay.longer>Loading current status...</span>
 | 
					 | 
				
			||||||
                <div class="flex items-center gap-2 text-sm" wire:loading.remove.delay.longer>
 | 
					 | 
				
			||||||
                    <span class="flex w-3 h-3 rounded-full bg-error"></span>
 | 
					 | 
				
			||||||
                    <span class="text-error">Stopped</span>
 | 
					 | 
				
			||||||
                </div>
 | 
					 | 
				
			||||||
            @endif
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        <livewire:activity-monitor />
 | 
					 | 
				
			||||||
        @if ($server->extra_attributes->proxy_type)
 | 
					        @if ($server->extra_attributes->proxy_type)
 | 
				
			||||||
            <div x-init="$wire.checkProxySettingsInSync">
 | 
					            <div x-init="$wire.checkProxySettingsInSync">
 | 
				
			||||||
                <div wire:loading wire:target="checkProxySettingsInSync">
 | 
					                <div wire:loading wire:target="checkProxySettingsInSync">
 | 
				
			||||||
@@ -41,15 +9,23 @@
 | 
				
			|||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                @isset($proxy_settings)
 | 
					                @isset($proxy_settings)
 | 
				
			||||||
                    @if ($selectedProxy->value === 'TRAEFIK_V2')
 | 
					                    @if ($selectedProxy->value === 'TRAEFIK_V2')
 | 
				
			||||||
                        <form wire:submit.prevent='saveConfiguration'>
 | 
					                        <form wire:submit.prevent='saveConfiguration({{ $server }})'>
 | 
				
			||||||
                            <div class="flex items-center gap-2">
 | 
					                            <div class="flex items-center gap-2">
 | 
				
			||||||
                                <h3>Configuration</h3>
 | 
					                                <h2>Proxy</h2>
 | 
				
			||||||
 | 
					                                <livewire:server.proxy.status :server="$server" />
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                            <div class="pb-4 text-sm">Traefik v2</div>
 | 
				
			||||||
 | 
					                            @if (
 | 
				
			||||||
 | 
					                                $server->extra_attributes->proxy_last_applied_settings &&
 | 
				
			||||||
 | 
					                                    $server->extra_attributes->proxy_last_saved_settings !== $server->extra_attributes->proxy_last_applied_settings)
 | 
				
			||||||
 | 
					                                <div class="text-sm text-red-500">Configuration out of sync. Restart to get the new configs.
 | 
				
			||||||
 | 
					                                </div>
 | 
				
			||||||
 | 
					                            @endif
 | 
				
			||||||
                            <x-forms.button type="submit">Save</x-forms.button>
 | 
					                            <x-forms.button type="submit">Save</x-forms.button>
 | 
				
			||||||
                            <x-forms.button wire:click.prevent="resetProxy">
 | 
					                            <x-forms.button wire:click.prevent="resetProxy">
 | 
				
			||||||
                                    Reset Configuration
 | 
					                                Reset to default
 | 
				
			||||||
                            </x-forms.button>
 | 
					                            </x-forms.button>
 | 
				
			||||||
                            </div>
 | 
					                            <div class="pt-4 pb-0 text-xs">traefik.conf</div>
 | 
				
			||||||
                            <h4>traefik.conf</h4>
 | 
					 | 
				
			||||||
                            <x-forms.textarea class="text-xs" noDirty name="proxy_settings"
 | 
					                            <x-forms.textarea class="text-xs" noDirty name="proxy_settings"
 | 
				
			||||||
                                wire:model.defer="proxy_settings" rows="30" />
 | 
					                                wire:model.defer="proxy_settings" rows="30" />
 | 
				
			||||||
                        </form>
 | 
					                        </form>
 | 
				
			||||||
@@ -57,14 +33,16 @@
 | 
				
			|||||||
                @endisset
 | 
					                @endisset
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        @else
 | 
					        @else
 | 
				
			||||||
            <select wire:model="selectedProxy">
 | 
					            <div>
 | 
				
			||||||
                <option value="{{ \App\Enums\ProxyTypes::TRAEFIK_V2 }}">
 | 
					                <h2>Select a Proxy</h2>
 | 
				
			||||||
                    {{ \App\Enums\ProxyTypes::TRAEFIK_V2 }}
 | 
					                <x-forms.button wire:click="setProxy('{{ \App\Enums\ProxyTypes::TRAEFIK_V2 }}')">Traefik v2
 | 
				
			||||||
                </option>
 | 
					                </x-forms.button>
 | 
				
			||||||
            </select>
 | 
					            </div>
 | 
				
			||||||
            <x-forms.button wire:click="setProxy">Set Proxy</x-forms.button>
 | 
					 | 
				
			||||||
        @endif
 | 
					        @endif
 | 
				
			||||||
 | 
					        <div class="container w-full pt-4 mx-auto">
 | 
				
			||||||
 | 
					            <livewire:activity-monitor :header="true" />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
    @else
 | 
					    @else
 | 
				
			||||||
        <p>Server is not validated. Validate first.</p>
 | 
					        <div class="text-sm">Server is not validated. Validate first.</div>
 | 
				
			||||||
    @endif
 | 
					    @endif
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								resources/views/livewire/server/proxy/deploy.blade.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								resources/views/livewire/server/proxy/deploy.blade.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					<div>
 | 
				
			||||||
 | 
					    @if ($server->settings->is_validated)
 | 
				
			||||||
 | 
					        @if ($server->extra_attributes->proxy_status === 'running')
 | 
				
			||||||
 | 
					            <div class="dropdown dropdown-bottom">
 | 
				
			||||||
 | 
					                <x-forms.button isHighlighted tabindex="0">
 | 
				
			||||||
 | 
					                    Actions
 | 
				
			||||||
 | 
					                    <x-chevron-down />
 | 
				
			||||||
 | 
					                </x-forms.button>
 | 
				
			||||||
 | 
					                <ul tabindex="0"
 | 
				
			||||||
 | 
					                    class="mt-1 text-xs text-white normal-case rounded min-w-max dropdown-content menu bg-coolgray-200">
 | 
				
			||||||
 | 
					                    <li>
 | 
				
			||||||
 | 
					                        <div class="rounded-none hover:bg-coollabs" wire:click='deploy'><svg
 | 
				
			||||||
 | 
					                                xmlns="http://www.w3.org/2000/svg" class="icon" 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="M9 4.55a8 8 0 0 1 6 14.9m0 -4.45v5h5" />
 | 
				
			||||||
 | 
					                                <path d="M5.63 7.16l0 .01" />
 | 
				
			||||||
 | 
					                                <path d="M4.06 11l0 .01" />
 | 
				
			||||||
 | 
					                                <path d="M4.63 15.1l0 .01" />
 | 
				
			||||||
 | 
					                                <path d="M7.16 18.37l0 .01" />
 | 
				
			||||||
 | 
					                                <path d="M11 19.94l0 .01" />
 | 
				
			||||||
 | 
					                            </svg>Restart</div>
 | 
				
			||||||
 | 
					                    </li>
 | 
				
			||||||
 | 
					                    <li>
 | 
				
			||||||
 | 
					                        <div class="rounded-none hover:bg-red-500" wire:click='stop'> <svg
 | 
				
			||||||
 | 
					                                xmlns="http://www.w3.org/2000/svg" class="icon" 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="M5 5m0 2a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v10a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2z" />
 | 
				
			||||||
 | 
					                            </svg>Stop</div>
 | 
				
			||||||
 | 
					                    </li>
 | 
				
			||||||
 | 
					                </ul>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        @else
 | 
				
			||||||
 | 
					            <x-forms.button isHighlighted wire:click='deploy'> <svg xmlns="http://www.w3.org/2000/svg" class="icon"
 | 
				
			||||||
 | 
					                    width="44" height="44" 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>Start</x-forms.button>
 | 
				
			||||||
 | 
					        @endif
 | 
				
			||||||
 | 
					    @endif
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										17
									
								
								resources/views/livewire/server/proxy/status.blade.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								resources/views/livewire/server/proxy/status.blade.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					<div>
 | 
				
			||||||
 | 
					    @if ($server->settings->is_validated)
 | 
				
			||||||
 | 
					        <div wire:poll.5000ms="proxyStatus">
 | 
				
			||||||
 | 
					            @if ($server->extra_attributes->proxy_status === 'running')
 | 
				
			||||||
 | 
					                <span class="text-xs text-pink-600" wire:loading.delay.longer>Loading current status...</span>
 | 
				
			||||||
 | 
					                <div class="flex items-center gap-2 text-sm" wire:loading.remove.delay.longer>
 | 
				
			||||||
 | 
					                    <div class="text-xs font-medium tracking-wide text-white badge border-success">Running</div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            @else
 | 
				
			||||||
 | 
					                <span class="text-xs text-pink-600" wire:loading.delay.longer>Loading current status...</span>
 | 
				
			||||||
 | 
					                <div class="flex items-center gap-2 text-sm" wire:loading.remove.delay.longer>
 | 
				
			||||||
 | 
					                    <div class="text-xs font-medium tracking-wide text-white badge border-error">Stopped</div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            @endif
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    @endif
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
@@ -7,6 +7,7 @@
 | 
				
			|||||||
            </li>
 | 
					            </li>
 | 
				
			||||||
        </ul>
 | 
					        </ul>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="flex flex-col gap-2">
 | 
				
			||||||
        @forelse ($servers as $server)
 | 
					        @forelse ($servers as $server)
 | 
				
			||||||
            <a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}"
 | 
					            <a href="{{ route('server.show', ['server_uuid' => data_get($server, 'uuid')]) }}"
 | 
				
			||||||
                class="box">{{ $server->name }}</a>
 | 
					                class="box">{{ $server->name }}</a>
 | 
				
			||||||
@@ -17,4 +18,5 @@
 | 
				
			|||||||
                    first one.</div>
 | 
					                    first one.</div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        @endforelse
 | 
					        @endforelse
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
</x-layout>
 | 
					</x-layout>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -195,10 +195,8 @@ Route::middleware(['auth'])->group(function () {
 | 
				
			|||||||
    })->name('source.github.show');
 | 
					    })->name('source.github.show');
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
Route::middleware(['auth'])->group(function () {
 | 
					Route::middleware(['auth'])->group(function () {
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Route::get('/servers', fn () => view('servers', [
 | 
					    Route::get('/servers', fn () => view('servers', [
 | 
				
			||||||
        'servers' => Server::validated(),
 | 
					        'servers' => Server::where('team_id', session('currentTeam')->id)->get(),
 | 
				
			||||||
    ]))->name('servers');
 | 
					    ]))->name('servers');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Route::get('/server/new', fn () => view('server.new', [
 | 
					    Route::get('/server/new', fn () => view('server.new', [
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user