@@ -127,7 +127,7 @@ class General extends Component
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            if (data_get($this->application, 'dockerfile')) {
 | 
					            if (data_get($this->application, 'dockerfile')) {
 | 
				
			||||||
                $port = get_port_from_dockerfile($this->application->dockerfile);
 | 
					                $port = get_port_from_dockerfile($this->application->dockerfile);
 | 
				
			||||||
                if ($port) {
 | 
					                if ($port && !$this->application->ports_exposes) {
 | 
				
			||||||
                    $this->application->ports_exposes = $port;
 | 
					                    $this->application->ports_exposes = $port;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,7 +21,6 @@ class Navbar extends Component
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    public function serviceStatusUpdated()
 | 
					    public function serviceStatusUpdated()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        ray('serviceStatusUpdated');
 | 
					 | 
				
			||||||
        $this->check_status();
 | 
					        $this->check_status();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    public function check_status()
 | 
					    public function check_status()
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										40
									
								
								app/Http/Livewire/Project/Shared/GetLogs.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								app/Http/Livewire/Project/Shared/GetLogs.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Livewire\Project\Shared;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Server;
 | 
				
			||||||
 | 
					use Illuminate\Support\Facades\Process;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GetLogs extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public string $outputs = '';
 | 
				
			||||||
 | 
					    public string $errors = '';
 | 
				
			||||||
 | 
					    public Server $server;
 | 
				
			||||||
 | 
					    public ?string $container = null;
 | 
				
			||||||
 | 
					    public ?bool $streamLogs = false;
 | 
				
			||||||
 | 
					    public int $numberOfLines = 100;
 | 
				
			||||||
 | 
					    public function doSomethingWithThisChunkOfOutput($output)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->outputs .= $output;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function instantSave()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function getLogs($refresh = false)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if ($this->container) {
 | 
				
			||||||
 | 
					            $sshCommand = generateSshCommand($this->server, "docker logs -n {$this->numberOfLines} -t {$this->container}");
 | 
				
			||||||
 | 
					            if ($refresh) {
 | 
				
			||||||
 | 
					                $this->outputs = '';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Process::run($sshCommand, function (string $type, string $output) {
 | 
				
			||||||
 | 
					                $this->doSomethingWithThisChunkOfOutput($output);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.project.shared.get-logs');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										53
									
								
								app/Http/Livewire/Project/Shared/Logs.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								app/Http/Livewire/Project/Shared/Logs.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,53 @@
 | 
				
			|||||||
 | 
					<?php
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace App\Http\Livewire\Project\Shared;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use App\Models\Application;
 | 
				
			||||||
 | 
					use App\Models\Server;
 | 
				
			||||||
 | 
					use App\Models\Service;
 | 
				
			||||||
 | 
					use App\Models\StandalonePostgresql;
 | 
				
			||||||
 | 
					use Livewire\Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Logs extends Component
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public ?string $type = null;
 | 
				
			||||||
 | 
					    public Application|StandalonePostgresql|Service $resource;
 | 
				
			||||||
 | 
					    public Server $server;
 | 
				
			||||||
 | 
					    public ?string $container = null;
 | 
				
			||||||
 | 
					    public $parameters;
 | 
				
			||||||
 | 
					    public $query;
 | 
				
			||||||
 | 
					    public $status;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function mount()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        $this->parameters = get_route_parameters();
 | 
				
			||||||
 | 
					        $this->query = request()->query();
 | 
				
			||||||
 | 
					        if (data_get($this->parameters, 'application_uuid')) {
 | 
				
			||||||
 | 
					            $this->type = 'application';
 | 
				
			||||||
 | 
					            $this->resource = Application::where('uuid', $this->parameters['application_uuid'])->firstOrFail();
 | 
				
			||||||
 | 
					            $this->status = $this->resource->status;
 | 
				
			||||||
 | 
					            $this->server = $this->resource->destination->server;
 | 
				
			||||||
 | 
					            $containers = getCurrentApplicationContainerStatus($this->server, $this->resource->id);
 | 
				
			||||||
 | 
					            if ($containers->count() > 0) {
 | 
				
			||||||
 | 
					                $this->container = data_get($containers[0], 'Names');
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else if (data_get($this->parameters, 'database_uuid')) {
 | 
				
			||||||
 | 
					            $this->type = 'database';
 | 
				
			||||||
 | 
					            $this->resource = StandalonePostgresql::where('uuid', $this->parameters['database_uuid'])->firstOrFail();
 | 
				
			||||||
 | 
					            $this->status = $this->resource->status;
 | 
				
			||||||
 | 
					            $this->server = $this->resource->destination->server;
 | 
				
			||||||
 | 
					            $this->container = $this->resource->uuid;
 | 
				
			||||||
 | 
					        } else if (data_get($this->parameters, 'service_uuid')) {
 | 
				
			||||||
 | 
					            $this->type = 'service';
 | 
				
			||||||
 | 
					            $this->resource = Service::where('uuid', $this->parameters['service_uuid'])->firstOrFail();
 | 
				
			||||||
 | 
					            $this->status = $this->resource->status;
 | 
				
			||||||
 | 
					            $this->server = $this->resource->server;
 | 
				
			||||||
 | 
					            $this->container = data_get($this->parameters, 'service_name') . '-' . $this->resource->uuid;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public function render()
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        return view('livewire.project.shared.logs');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -6,6 +6,7 @@ use Livewire\Component;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class Add extends Component
 | 
					class Add extends Component
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    public $uuid;
 | 
				
			||||||
    public $parameters;
 | 
					    public $parameters;
 | 
				
			||||||
    public string $name;
 | 
					    public string $name;
 | 
				
			||||||
    public string $mount_path;
 | 
					    public string $mount_path;
 | 
				
			||||||
@@ -31,8 +32,9 @@ class Add extends Component
 | 
				
			|||||||
    public function submit()
 | 
					    public function submit()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $this->validate();
 | 
					        $this->validate();
 | 
				
			||||||
 | 
					        $name = $this->uuid . '-' . $this->name;
 | 
				
			||||||
        $this->emitUp('submit', [
 | 
					        $this->emitUp('submit', [
 | 
				
			||||||
            'name' => $this->name,
 | 
					            'name' => $name,
 | 
				
			||||||
            'mount_path' => $this->mount_path,
 | 
					            'mount_path' => $this->mount_path,
 | 
				
			||||||
            'host_path' => $this->host_path,
 | 
					            'host_path' => $this->host_path,
 | 
				
			||||||
        ]);
 | 
					        ]);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,6 @@ class Show extends Component
 | 
				
			|||||||
    public LocalPersistentVolume $storage;
 | 
					    public LocalPersistentVolume $storage;
 | 
				
			||||||
    public bool $isReadOnly = false;
 | 
					    public bool $isReadOnly = false;
 | 
				
			||||||
    public ?string $modalId = null;
 | 
					    public ?string $modalId = null;
 | 
				
			||||||
    public ?string $realName = null;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected $rules = [
 | 
					    protected $rules = [
 | 
				
			||||||
        'storage.name' => 'required|string',
 | 
					        'storage.name' => 'required|string',
 | 
				
			||||||
@@ -26,11 +25,6 @@ class Show extends Component
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public function mount()
 | 
					    public function mount()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        if ($this->storage->resource_type === 'App\Models\ServiceApplication' || $this->storage->resource_type === 'App\Models\ServiceDatabase') {
 | 
					 | 
				
			||||||
            $this->realName = "{$this->storage->service->service->uuid}_{$this->storage->name}";
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            $this->realName = $this->storage->name;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $this->modalId = new Cuid2(7);
 | 
					        $this->modalId = new Cuid2(7);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -379,9 +379,6 @@ class ApplicationDeploymentJob implements ShouldQueue, ShouldBeEncrypted
 | 
				
			|||||||
    private function prepare_builder_image()
 | 
					    private function prepare_builder_image()
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        $pull = "--pull=always";
 | 
					        $pull = "--pull=always";
 | 
				
			||||||
        if (isDev()) {
 | 
					 | 
				
			||||||
            $pull = "--pull=never";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        $helperImage = config('coolify.helper_image');
 | 
					        $helperImage = config('coolify.helper_image');
 | 
				
			||||||
        $runCommand = "docker run {$pull} -d --network {$this->destination->network} -v /:/host  --name {$this->deployment_uuid} --rm -v /var/run/docker.sock:/var/run/docker.sock {$helperImage}";
 | 
					        $runCommand = "docker run {$pull} -d --network {$this->destination->network} -v /:/host  --name {$this->deployment_uuid} --rm -v /var/run/docker.sock:/var/run/docker.sock {$helperImage}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -248,7 +248,7 @@ class Service extends BaseModel
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                // Collect/create/update volumes
 | 
					                // Collect/create/update volumes
 | 
				
			||||||
                if ($serviceVolumes->count() > 0) {
 | 
					                if ($serviceVolumes->count() > 0) {
 | 
				
			||||||
                    foreach ($serviceVolumes as $volume) {
 | 
					                    $serviceVolumes = $serviceVolumes->map(function ($volume) use ($savedService, $topLevelVolumes, $isNew) {
 | 
				
			||||||
                        $type = null;
 | 
					                        $type = null;
 | 
				
			||||||
                        $source = null;
 | 
					                        $source = null;
 | 
				
			||||||
                        $target = null;
 | 
					                        $target = null;
 | 
				
			||||||
@@ -276,10 +276,10 @@ class Service extends BaseModel
 | 
				
			|||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        if ($type->value() === 'bind') {
 | 
					                        if ($type->value() === 'bind') {
 | 
				
			||||||
                            if ($source->value() === "/var/run/docker.sock") {
 | 
					                            if ($source->value() === "/var/run/docker.sock") {
 | 
				
			||||||
                                continue;
 | 
					                                return $volume;
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            if ($source->value() === '/tmp' || $source->value() === '/tmp/') {
 | 
					                            if ($source->value() === '/tmp' || $source->value() === '/tmp/') {
 | 
				
			||||||
                                continue;
 | 
					                                return $volume;
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            LocalFileVolume::updateOrCreate(
 | 
					                            LocalFileVolume::updateOrCreate(
 | 
				
			||||||
                                [
 | 
					                                [
 | 
				
			||||||
@@ -297,7 +297,21 @@ class Service extends BaseModel
 | 
				
			|||||||
                                ]
 | 
					                                ]
 | 
				
			||||||
                            );
 | 
					                            );
 | 
				
			||||||
                        } else if ($type->value() === 'volume') {
 | 
					                        } else if ($type->value() === 'volume') {
 | 
				
			||||||
                            $topLevelVolumes->put($source->value(), null);
 | 
					                            $slug = Str::slug($source, '-');
 | 
				
			||||||
 | 
					                            if ($isNew) {
 | 
				
			||||||
 | 
					                                $name = "{$savedService->service->uuid}-{$slug}";
 | 
				
			||||||
 | 
					                            } else {
 | 
				
			||||||
 | 
					                                $name = "{$savedService->service->uuid}_{$slug}";
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            if (is_string($volume)) {
 | 
				
			||||||
 | 
					                                $source = Str::of($volume)->before(':');
 | 
				
			||||||
 | 
					                                $target = Str::of($volume)->after(':')->beforeLast(':');
 | 
				
			||||||
 | 
					                                $source = $name;
 | 
				
			||||||
 | 
					                                $volume = "$source:$target";
 | 
				
			||||||
 | 
					                            } else if(is_array($volume)) {
 | 
				
			||||||
 | 
					                                data_set($volume, 'source', $name);
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                            $topLevelVolumes->put($name, null);
 | 
				
			||||||
                            LocalPersistentVolume::updateOrCreate(
 | 
					                            LocalPersistentVolume::updateOrCreate(
 | 
				
			||||||
                                [
 | 
					                                [
 | 
				
			||||||
                                    'mount_path' => $target,
 | 
					                                    'mount_path' => $target,
 | 
				
			||||||
@@ -305,7 +319,7 @@ class Service extends BaseModel
 | 
				
			|||||||
                                    'resource_type' => get_class($savedService)
 | 
					                                    'resource_type' => get_class($savedService)
 | 
				
			||||||
                                ],
 | 
					                                ],
 | 
				
			||||||
                                [
 | 
					                                [
 | 
				
			||||||
                                    'name' => Str::slug($source, '-'),
 | 
					                                    'name' => $name,
 | 
				
			||||||
                                    'mount_path' => $target,
 | 
					                                    'mount_path' => $target,
 | 
				
			||||||
                                    'resource_id' => $savedService->id,
 | 
					                                    'resource_id' => $savedService->id,
 | 
				
			||||||
                                    'resource_type' => get_class($savedService)
 | 
					                                    'resource_type' => get_class($savedService)
 | 
				
			||||||
@@ -313,7 +327,9 @@ class Service extends BaseModel
 | 
				
			|||||||
                            );
 | 
					                            );
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        $savedService->getFilesFromServer();
 | 
					                        $savedService->getFilesFromServer();
 | 
				
			||||||
                    }
 | 
					                        return $volume;
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                    data_set($service, 'volumes', $serviceVolumes->toArray());
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                // Add env_file with at least .env to the service
 | 
					                // Add env_file with at least .env to the service
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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.56',
 | 
					    'release' => '4.0.0-beta.57',
 | 
				
			||||||
    // 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.56';
 | 
					return '4.0.0-beta.57';
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,6 +7,10 @@
 | 
				
			|||||||
        href="{{ route('project.application.deployments', $parameters) }}">
 | 
					        href="{{ route('project.application.deployments', $parameters) }}">
 | 
				
			||||||
        <button>Deployments</button>
 | 
					        <button>Deployments</button>
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
 | 
					    <a class="{{ request()->routeIs('project.application.logs') ? 'text-white' : '' }}"
 | 
				
			||||||
 | 
					        href="{{ route('project.application.logs', $parameters) }}">
 | 
				
			||||||
 | 
					        <button>Logs</button>
 | 
				
			||||||
 | 
					    </a>
 | 
				
			||||||
    <x-applications.links :application="$application" />
 | 
					    <x-applications.links :application="$application" />
 | 
				
			||||||
    <div class="flex-1"></div>
 | 
					    <div class="flex-1"></div>
 | 
				
			||||||
    <x-applications.advanced :application="$application" />
 | 
					    <x-applications.advanced :application="$application" />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,6 +3,10 @@
 | 
				
			|||||||
        href="{{ route('project.database.configuration', $parameters) }}">
 | 
					        href="{{ route('project.database.configuration', $parameters) }}">
 | 
				
			||||||
        <button>Configuration</button>
 | 
					        <button>Configuration</button>
 | 
				
			||||||
    </a>
 | 
					    </a>
 | 
				
			||||||
 | 
					    <a class="{{ request()->routeIs('project.database.logs') ? 'text-white' : '' }}"
 | 
				
			||||||
 | 
					        href="{{ route('project.database.logs', $parameters) }}">
 | 
				
			||||||
 | 
					        <button>Logs</button>
 | 
				
			||||||
 | 
					    </a>
 | 
				
			||||||
    <a class="{{ request()->routeIs('project.database.backups.all') ? 'text-white' : '' }}"
 | 
					    <a class="{{ request()->routeIs('project.database.backups.all') ? 'text-white' : '' }}"
 | 
				
			||||||
        href="{{ route('project.database.backups.all', $parameters) }}">
 | 
					        href="{{ route('project.database.backups.all', $parameters) }}">
 | 
				
			||||||
        <button>Backups</button>
 | 
					        <button>Backups</button>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,8 @@
 | 
				
			|||||||
<div class="navbar-main">
 | 
					<div class="navbar-main">
 | 
				
			||||||
 | 
					    <a class="{{ request()->routeIs('project.service') ? 'text-white' : '' }}"
 | 
				
			||||||
 | 
					        href="{{ route('project.service', $parameters) }}">
 | 
				
			||||||
 | 
					        <button>Configuration</button>
 | 
				
			||||||
 | 
					    </a>
 | 
				
			||||||
    <x-services.links :service="$service" />
 | 
					    <x-services.links :service="$service" />
 | 
				
			||||||
    <div class="flex-1"></div>
 | 
					    <div class="flex-1"></div>
 | 
				
			||||||
    @if (serviceStatus($service) === 'degraded')
 | 
					    @if (serviceStatus($service) === 'degraded')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,7 +24,8 @@
 | 
				
			|||||||
                            <div>Configuration</div>
 | 
					                            <div>Configuration</div>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
                        <x-forms.button type="submit">Save</x-forms.button>
 | 
					                        <x-forms.button type="submit">Save</x-forms.button>
 | 
				
			||||||
                        <x-forms.button class="w-64" onclick="composeModal.showModal()">Edit Compose File</x-forms.button>
 | 
					                        <x-forms.button class="w-64" onclick="composeModal.showModal()">Edit Compose
 | 
				
			||||||
 | 
					                            File</x-forms.button>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                    <div class="flex gap-2">
 | 
					                    <div class="flex gap-2">
 | 
				
			||||||
                        <x-forms.input id="service.name" required label="Service Name"
 | 
					                        <x-forms.input id="service.name" required label="Service Name"
 | 
				
			||||||
@@ -34,16 +35,18 @@
 | 
				
			|||||||
                </form>
 | 
					                </form>
 | 
				
			||||||
                <div class="grid grid-cols-1 gap-2 pt-4 xl:grid-cols-3">
 | 
					                <div class="grid grid-cols-1 gap-2 pt-4 xl:grid-cols-3">
 | 
				
			||||||
                    @foreach ($service->applications as $application)
 | 
					                    @foreach ($service->applications as $application)
 | 
				
			||||||
                        <a @class([
 | 
					                        <div @class([
 | 
				
			||||||
                            'border-l border-dashed border-red-500' => Str::of(
 | 
					                            'border-l border-dashed border-red-500' => Str::of(
 | 
				
			||||||
                                $application->status)->contains(['exited']),
 | 
					                                $application->status)->contains(['exited']),
 | 
				
			||||||
                            'border-l border-dashed border-success' => Str::of(
 | 
					                            'border-l border-dashed border-success' => Str::of(
 | 
				
			||||||
                                $application->status)->contains(['running']),
 | 
					                                $application->status)->contains(['running']),
 | 
				
			||||||
                            'border-l border-dashed border-warning' => Str::of(
 | 
					                            'border-l border-dashed border-warning' => Str::of(
 | 
				
			||||||
                                $application->status)->contains(['starting']),
 | 
					                                $application->status)->contains(['starting']),
 | 
				
			||||||
                            'flex flex-col justify-center box',
 | 
					                            'flex gap-2 box group',
 | 
				
			||||||
                        ])
 | 
					                        ])>
 | 
				
			||||||
 | 
					                            <a class="flex flex-col flex-1 group-hover:text-white hover:no-underline"
 | 
				
			||||||
                                href="{{ route('project.service.show', [...$parameters, 'service_name' => $application->name]) }}">
 | 
					                                href="{{ route('project.service.show', [...$parameters, 'service_name' => $application->name]) }}">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                @if ($application->human_name)
 | 
					                                @if ($application->human_name)
 | 
				
			||||||
                                    {{ Str::headline($application->human_name) }}
 | 
					                                    {{ Str::headline($application->human_name) }}
 | 
				
			||||||
                                @else
 | 
					                                @else
 | 
				
			||||||
@@ -60,17 +63,21 @@
 | 
				
			|||||||
                                @endif
 | 
					                                @endif
 | 
				
			||||||
                                <div class="text-xs">{{ $application->status }}</div>
 | 
					                                <div class="text-xs">{{ $application->status }}</div>
 | 
				
			||||||
                            </a>
 | 
					                            </a>
 | 
				
			||||||
 | 
					                            <a class="flex gap-2 p-1 mx-4 text-xs font-bold rounded hover:no-underline hover:text-warning"
 | 
				
			||||||
 | 
					                                href="{{ route('project.service.logs', [...$parameters, 'service_name' => $application->name]) }}">Logs</a>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
                    @endforeach
 | 
					                    @endforeach
 | 
				
			||||||
                    @foreach ($databases as $database)
 | 
					                    @foreach ($databases as $database)
 | 
				
			||||||
                        <a @class([
 | 
					                        <div @class([
 | 
				
			||||||
                            'border-l border-dashed border-red-500' => Str::of(
 | 
					                            'border-l border-dashed border-red-500' => Str::of(
 | 
				
			||||||
                                $database->status)->contains(['exited']),
 | 
					                                $database->status)->contains(['exited']),
 | 
				
			||||||
                            'border-l border-dashed border-success' => Str::of(
 | 
					                            'border-l border-dashed border-success' => Str::of(
 | 
				
			||||||
                                $database->status)->contains(['running']),
 | 
					                                $database->status)->contains(['running']),
 | 
				
			||||||
                            'border-l border-dashed border-warning' => Str::of(
 | 
					                            'border-l border-dashed border-warning' => Str::of(
 | 
				
			||||||
                                $database->status)->contains(['restarting']),
 | 
					                                $database->status)->contains(['restarting']),
 | 
				
			||||||
                            'flex flex-col justify-center box',
 | 
					                            'flex gap-2 box group',
 | 
				
			||||||
                        ])
 | 
					                        ])>
 | 
				
			||||||
 | 
					                            <a class="flex flex-col flex-1 group-hover:text-white hover:no-underline"
 | 
				
			||||||
                                href="{{ route('project.service.show', [...$parameters, 'service_name' => $database->name]) }}">
 | 
					                                href="{{ route('project.service.show', [...$parameters, 'service_name' => $database->name]) }}">
 | 
				
			||||||
                                @if ($database->human_name)
 | 
					                                @if ($database->human_name)
 | 
				
			||||||
                                    {{ Str::headline($database->human_name) }}
 | 
					                                    {{ Str::headline($database->human_name) }}
 | 
				
			||||||
@@ -85,6 +92,9 @@
 | 
				
			|||||||
                                @endif
 | 
					                                @endif
 | 
				
			||||||
                                <div class="text-xs">{{ $database->status }}</div>
 | 
					                                <div class="text-xs">{{ $database->status }}</div>
 | 
				
			||||||
                            </a>
 | 
					                            </a>
 | 
				
			||||||
 | 
					                            <a class="flex gap-2 p-1 mx-4 text-xs font-bold rounded hover:no-underline hover:text-warning"
 | 
				
			||||||
 | 
					                                href="{{ route('project.service.logs', [...$parameters, 'service_name' => $database->name]) }}">Logs</a>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
                    @endforeach
 | 
					                    @endforeach
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,12 @@
 | 
				
			|||||||
            <a :class="activeTab === 'storages' && 'text-white'"
 | 
					            <a :class="activeTab === 'storages' && 'text-white'"
 | 
				
			||||||
                @click.prevent="activeTab = 'storages'; window.location.hash = 'storages'" href="#">Storages
 | 
					                @click.prevent="activeTab = 'storages'; window.location.hash = 'storages'" href="#">Storages
 | 
				
			||||||
            </a>
 | 
					            </a>
 | 
				
			||||||
 | 
					            @if (data_get($parameters, 'service_name'))
 | 
				
			||||||
 | 
					                <a class="{{ request()->routeIs('project.service.logs') ? 'text-white' : '' }}"
 | 
				
			||||||
 | 
					                    href="{{ route('project.service.logs', $parameters) }}">
 | 
				
			||||||
 | 
					                    <button>Logs</button>
 | 
				
			||||||
 | 
					                </a>
 | 
				
			||||||
 | 
					            @endif
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="w-full pl-8">
 | 
					        <div class="w-full pl-8">
 | 
				
			||||||
            @isset($serviceApplication)
 | 
					            @isset($serviceApplication)
 | 
				
			||||||
@@ -32,7 +38,6 @@
 | 
				
			|||||||
            @isset($serviceDatabase)
 | 
					            @isset($serviceDatabase)
 | 
				
			||||||
                <div x-cloak x-show="activeTab === 'general'" class="h-full">
 | 
					                <div x-cloak x-show="activeTab === 'general'" class="h-full">
 | 
				
			||||||
                    <livewire:project.service.database :database="$serviceDatabase" />
 | 
					                    <livewire:project.service.database :database="$serviceDatabase" />
 | 
				
			||||||
 | 
					 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div x-cloak x-show="activeTab === 'storages'">
 | 
					                <div x-cloak x-show="activeTab === 'storages'">
 | 
				
			||||||
                    <livewire:project.shared.storages.all :resource="$serviceDatabase" />
 | 
					                    <livewire:project.shared.storages.all :resource="$serviceDatabase" />
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								resources/views/livewire/project/shared/get-logs.blade.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								resources/views/livewire/project/shared/get-logs.blade.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					<div x-init="$wire.getLogs">
 | 
				
			||||||
 | 
					    <div class="flex gap-2">
 | 
				
			||||||
 | 
					        <h2>Logs</h2>
 | 
				
			||||||
 | 
					        @if ($streamLogs)
 | 
				
			||||||
 | 
					            <span wire:poll.2000ms='getLogs(true)' class="loading loading-xs text-warning loading-spinner"></span>
 | 
				
			||||||
 | 
					        @endif
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <form wire:submit.prevent='getLogs(true)' class="flex items-end gap-2">
 | 
				
			||||||
 | 
					        <x-forms.input label="Only Show Number of Lines" placeholder="1000" required id="numberOfLines"></x-forms.input>
 | 
				
			||||||
 | 
					        <x-forms.button type="submit">Refresh</x-forms.button>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					    <div class="w-32">
 | 
				
			||||||
 | 
					        <x-forms.checkbox instantSave label="Stream Logs" id="streamLogs"></x-forms.checkbox>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					    <div class="container w-full pt-4 mx-auto">
 | 
				
			||||||
 | 
					        <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">{{ $outputs }}</pre>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										41
									
								
								resources/views/livewire/project/shared/logs.blade.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								resources/views/livewire/project/shared/logs.blade.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,41 @@
 | 
				
			|||||||
 | 
					<x-layout>
 | 
				
			||||||
 | 
					    @if ($type === 'application')
 | 
				
			||||||
 | 
					        <h1>Logs</h1>
 | 
				
			||||||
 | 
					        <livewire:project.application.heading :application="$resource" />
 | 
				
			||||||
 | 
					        <div class="pt-4">
 | 
				
			||||||
 | 
					            @if (Str::of($status)->startsWith('running'))
 | 
				
			||||||
 | 
					                <livewire:project.shared.get-logs :server="$server" :container="$container" />
 | 
				
			||||||
 | 
					            @else
 | 
				
			||||||
 | 
					                Application is not running.
 | 
				
			||||||
 | 
					            @endif
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    @elseif ($type === 'database')
 | 
				
			||||||
 | 
					        <h1>Logs</h1>
 | 
				
			||||||
 | 
					        <livewire:project.database.heading :database="$resource" />
 | 
				
			||||||
 | 
					        <div class="pt-4">
 | 
				
			||||||
 | 
					            @if (Str::of($status)->startsWith('running'))
 | 
				
			||||||
 | 
					                <livewire:project.shared.get-logs :server="$server" :container="$container" />
 | 
				
			||||||
 | 
					            @else
 | 
				
			||||||
 | 
					                Database is not running.
 | 
				
			||||||
 | 
					            @endif
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    @elseif ($type === 'service')
 | 
				
			||||||
 | 
					        <livewire:project.service.navbar :service="$resource" :parameters="$parameters" :query="$query" />
 | 
				
			||||||
 | 
					        <div class="flex gap-4 pt-6">
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					                <a class="{{ request()->routeIs('project.service.show') ? 'text-white' : '' }}"
 | 
				
			||||||
 | 
					                    href="{{ route('project.service.show', $parameters) }}">
 | 
				
			||||||
 | 
					                    <button><- Back</button>
 | 
				
			||||||
 | 
					                </a>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					            <div class="flex-1 pl-8">
 | 
				
			||||||
 | 
					                @if (serviceStatus($resource) === 'running')
 | 
				
			||||||
 | 
					                    <livewire:project.shared.get-logs :server="$server" :container="$container" />
 | 
				
			||||||
 | 
					                @else
 | 
				
			||||||
 | 
					                    Service is not running.
 | 
				
			||||||
 | 
					                @endif
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    @endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</x-layout>
 | 
				
			||||||
@@ -8,7 +8,7 @@
 | 
				
			|||||||
            volume
 | 
					            volume
 | 
				
			||||||
            name, example: <span class='text-helper'>-pr-1</span>" />
 | 
					            name, example: <span class='text-helper'>-pr-1</span>" />
 | 
				
			||||||
                <x-forms.button class="btn" onclick="newStorage.showModal()">+ Add</x-forms.button>
 | 
					                <x-forms.button class="btn" onclick="newStorage.showModal()">+ Add</x-forms.button>
 | 
				
			||||||
                <livewire:project.shared.storages.add />
 | 
					                <livewire:project.shared.storages.add :uuid="$resource->uuid" />
 | 
				
			||||||
            @endif
 | 
					            @endif
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div>Persistent storage to preserve data between deployments.</div>
 | 
					        <div>Persistent storage to preserve data between deployments.</div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,7 @@
 | 
				
			|||||||
    @endonce
 | 
					    @endonce
 | 
				
			||||||
    <form wire:submit.prevent='submit' class="flex flex-col gap-2 pt-4 xl:items-end xl:flex-row">
 | 
					    <form wire:submit.prevent='submit' class="flex flex-col gap-2 pt-4 xl:items-end xl:flex-row">
 | 
				
			||||||
        @if ($isReadOnly)
 | 
					        @if ($isReadOnly)
 | 
				
			||||||
            <x-forms.input id="realName" label="Volume Name" required readonly />
 | 
					            <x-forms.input id="storage.name" label="Volume Name" required readonly />
 | 
				
			||||||
            <x-forms.input id="storage.host_path" label="Source Path" readonly />
 | 
					            <x-forms.input id="storage.host_path" label="Source Path" readonly />
 | 
				
			||||||
            <x-forms.input id="storage.mount_path" label="Destination Path" required readonly />
 | 
					            <x-forms.input id="storage.mount_path" label="Destination Path" required readonly />
 | 
				
			||||||
        @else
 | 
					        @else
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@ use App\Http\Livewire\Boarding\Index as BoardingIndex;
 | 
				
			|||||||
use App\Http\Livewire\Project\Service\Index as ServiceIndex;
 | 
					use App\Http\Livewire\Project\Service\Index as ServiceIndex;
 | 
				
			||||||
use App\Http\Livewire\Project\Service\Show as ServiceShow;
 | 
					use App\Http\Livewire\Project\Service\Show as ServiceShow;
 | 
				
			||||||
use App\Http\Livewire\Dashboard;
 | 
					use App\Http\Livewire\Dashboard;
 | 
				
			||||||
 | 
					use App\Http\Livewire\Project\Shared\Logs;
 | 
				
			||||||
use App\Http\Livewire\Server\All;
 | 
					use App\Http\Livewire\Server\All;
 | 
				
			||||||
use App\Http\Livewire\Server\Show;
 | 
					use App\Http\Livewire\Server\Show;
 | 
				
			||||||
use App\Http\Livewire\Waitlist\Index as WaitlistIndex;
 | 
					use App\Http\Livewire\Waitlist\Index as WaitlistIndex;
 | 
				
			||||||
@@ -80,14 +81,20 @@ Route::middleware(['auth'])->group(function () {
 | 
				
			|||||||
        [ApplicationController::class, 'deployment']
 | 
					        [ApplicationController::class, 'deployment']
 | 
				
			||||||
    )->name('project.application.deployment');
 | 
					    )->name('project.application.deployment');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Route::get('/project/{project_uuid}/{environment_name}/application/{application_uuid}/logs', Logs::class)->name('project.application.logs');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Databases
 | 
					    // Databases
 | 
				
			||||||
    Route::get('/project/{project_uuid}/{environment_name}/database/{database_uuid}', [DatabaseController::class, 'configuration'])->name('project.database.configuration');
 | 
					    Route::get('/project/{project_uuid}/{environment_name}/database/{database_uuid}', [DatabaseController::class, 'configuration'])->name('project.database.configuration');
 | 
				
			||||||
    Route::get('/project/{project_uuid}/{environment_name}/database/{database_uuid}/backups', [DatabaseController::class, 'backups'])->name('project.database.backups.all');
 | 
					    Route::get('/project/{project_uuid}/{environment_name}/database/{database_uuid}/backups', [DatabaseController::class, 'backups'])->name('project.database.backups.all');
 | 
				
			||||||
    Route::get('/project/{project_uuid}/{environment_name}/database/{database_uuid}/backups/{backup_uuid}', [DatabaseController::class, 'executions'])->name('project.database.backups.executions');
 | 
					    Route::get('/project/{project_uuid}/{environment_name}/database/{database_uuid}/backups/{backup_uuid}', [DatabaseController::class, 'executions'])->name('project.database.backups.executions');
 | 
				
			||||||
 | 
					    Route::get('/project/{project_uuid}/{environment_name}/database/{database_uuid}/logs', Logs::class)->name('project.database.logs');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Services
 | 
					    // Services
 | 
				
			||||||
    Route::get('/project/{project_uuid}/{environment_name}/service/{service_uuid}', ServiceIndex::class)->name('project.service');
 | 
					    Route::get('/project/{project_uuid}/{environment_name}/service/{service_uuid}', ServiceIndex::class)->name('project.service');
 | 
				
			||||||
    Route::get('/project/{project_uuid}/{environment_name}/service/{service_uuid}/{service_name}', ServiceShow::class)->name('project.service.show');
 | 
					    Route::get('/project/{project_uuid}/{environment_name}/service/{service_uuid}/{service_name}', ServiceShow::class)->name('project.service.show');
 | 
				
			||||||
 | 
					    Route::get('/project/{project_uuid}/{environment_name}/service/{service_uuid}/{service_name}/logs', Logs::class)->name('project.service.logs');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Route::middleware(['auth'])->group(function () {
 | 
					Route::middleware(['auth'])->group(function () {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@
 | 
				
			|||||||
            "version": "3.12.36"
 | 
					            "version": "3.12.36"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "v4": {
 | 
					        "v4": {
 | 
				
			||||||
            "version": "4.0.0-beta.56"
 | 
					            "version": "4.0.0-beta.57"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user