Merge pull request #2297 from coollabsio/next

v4.0.0-beta.287
This commit is contained in:
Andras Bacsai 2024-05-27 14:26:45 +02:00 committed by GitHub
commit e470096e4e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 227 additions and 65 deletions

View File

@ -42,6 +42,7 @@ ## Github Sponsors ($40+)
<a href="https://www.flint.sh/en/home?utm_source=coolify.io"> <img src="https://github.com/Flint-company.png" width="60px" alt="FlintCompany"/></a> <a href="https://www.flint.sh/en/home?utm_source=coolify.io"> <img src="https://github.com/Flint-company.png" width="60px" alt="FlintCompany"/></a>
<a href="https://americancloud.com/?utm_source=coolify.io"><img src="https://github.com/American-Cloud.png" width="60px" alt="American Cloud"/></a> <a href="https://americancloud.com/?utm_source=coolify.io"><img src="https://github.com/American-Cloud.png" width="60px" alt="American Cloud"/></a>
<a href="https://cryptojobslist.com/?utm_source=coolify.io"><img src="https://github.com/cryptojobslist.png" width="60px" alt="CryptoJobsList" /></a> <a href="https://cryptojobslist.com/?utm_source=coolify.io"><img src="https://github.com/cryptojobslist.png" width="60px" alt="CryptoJobsList" /></a>
<a href="https://x.com/mrsmith9ja?utm_source=coolify.io"><img width="60px" alt="Thompson Edolo" src="https://github.com/verygreenboi.png"/></a>
<a href="https://www.uxwizz.com/?utm_source=coolify.io"><img width="60px" alt="UXWizz" src="https://github.com/UXWizz.png"/></a> <a href="https://www.uxwizz.com/?utm_source=coolify.io"><img width="60px" alt="UXWizz" src="https://github.com/UXWizz.png"/></a>
<a href="https://github.com/Flowko"><img src="https://barrad.me/_ipx/f_webp&s_300x300/younes.jpg" width="60px" alt="Younes Barrad" /></a> <a href="https://github.com/Flowko"><img src="https://barrad.me/_ipx/f_webp&s_300x300/younes.jpg" width="60px" alt="Younes Barrad" /></a>
<a href="https://github.com/automazeio"><img src="https://github.com/automazeio.png" width="60px" alt="Automaze" /></a> <a href="https://github.com/automazeio"><img src="https://github.com/automazeio.png" width="60px" alt="Automaze" /></a>

View File

@ -29,6 +29,7 @@ public function handle(StandaloneClickhouse $database)
]; ];
$persistent_storages = $this->generate_local_persistent_volumes(); $persistent_storages = $this->generate_local_persistent_volumes();
$persistent_file_volumes = $this->database->fileStorages()->get();
$volume_names = $this->generate_local_persistent_volumes_only_volume_names(); $volume_names = $this->generate_local_persistent_volumes_only_volume_names();
$environment_variables = $this->generate_environment_variables(); $environment_variables = $this->generate_environment_variables();
@ -93,6 +94,11 @@ public function handle(StandaloneClickhouse $database)
if (count($persistent_storages) > 0) { if (count($persistent_storages) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages; $docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
} }
if (count($persistent_file_volumes) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
return "$item->fs_path:$item->mount_path";
})->toArray();
}
if (count($volume_names) > 0) { if (count($volume_names) > 0) {
$docker_compose['volumes'] = $volume_names; $docker_compose['volumes'] = $volume_names;
} }

View File

@ -32,6 +32,7 @@ public function handle(StandaloneDragonfly $database)
]; ];
$persistent_storages = $this->generate_local_persistent_volumes(); $persistent_storages = $this->generate_local_persistent_volumes();
$persistent_file_volumes = $this->database->fileStorages()->get();
$volume_names = $this->generate_local_persistent_volumes_only_volume_names(); $volume_names = $this->generate_local_persistent_volumes_only_volume_names();
$environment_variables = $this->generate_environment_variables(); $environment_variables = $this->generate_environment_variables();
@ -94,6 +95,11 @@ public function handle(StandaloneDragonfly $database)
if (count($persistent_storages) > 0) { if (count($persistent_storages) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages; $docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
} }
if (count($persistent_file_volumes) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
return "$item->fs_path:$item->mount_path";
})->toArray();
}
if (count($volume_names) > 0) { if (count($volume_names) > 0) {
$docker_compose['volumes'] = $volume_names; $docker_compose['volumes'] = $volume_names;
} }

View File

@ -32,6 +32,7 @@ public function handle(StandaloneKeydb $database)
]; ];
$persistent_storages = $this->generate_local_persistent_volumes(); $persistent_storages = $this->generate_local_persistent_volumes();
$persistent_file_volumes = $this->database->fileStorages()->get();
$volume_names = $this->generate_local_persistent_volumes_only_volume_names(); $volume_names = $this->generate_local_persistent_volumes_only_volume_names();
$environment_variables = $this->generate_environment_variables(); $environment_variables = $this->generate_environment_variables();
$this->add_custom_keydb(); $this->add_custom_keydb();
@ -92,6 +93,11 @@ public function handle(StandaloneKeydb $database)
if (count($persistent_storages) > 0) { if (count($persistent_storages) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages; $docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
} }
if (count($persistent_file_volumes) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
return "$item->fs_path:$item->mount_path";
})->toArray();
}
if (count($volume_names) > 0) { if (count($volume_names) > 0) {
$docker_compose['volumes'] = $volume_names; $docker_compose['volumes'] = $volume_names;
} }

View File

@ -28,6 +28,7 @@ public function handle(StandaloneMariadb $database)
]; ];
$persistent_storages = $this->generate_local_persistent_volumes(); $persistent_storages = $this->generate_local_persistent_volumes();
$persistent_file_volumes = $this->database->fileStorages()->get();
$volume_names = $this->generate_local_persistent_volumes_only_volume_names(); $volume_names = $this->generate_local_persistent_volumes_only_volume_names();
$environment_variables = $this->generate_environment_variables(); $environment_variables = $this->generate_environment_variables();
$this->add_custom_mysql(); $this->add_custom_mysql();
@ -86,6 +87,11 @@ public function handle(StandaloneMariadb $database)
if (count($persistent_storages) > 0) { if (count($persistent_storages) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages; $docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
} }
if (count($persistent_file_volumes) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
return "$item->fs_path:$item->mount_path";
})->toArray();
}
if (count($volume_names) > 0) { if (count($volume_names) > 0) {
$docker_compose['volumes'] = $volume_names; $docker_compose['volumes'] = $volume_names;
} }

View File

@ -30,6 +30,7 @@ public function handle(StandaloneMongodb $database)
]; ];
$persistent_storages = $this->generate_local_persistent_volumes(); $persistent_storages = $this->generate_local_persistent_volumes();
$persistent_file_volumes = $this->database->fileStorages()->get();
$volume_names = $this->generate_local_persistent_volumes_only_volume_names(); $volume_names = $this->generate_local_persistent_volumes_only_volume_names();
$environment_variables = $this->generate_environment_variables(); $environment_variables = $this->generate_environment_variables();
$this->add_custom_mongo_conf(); $this->add_custom_mongo_conf();
@ -94,6 +95,11 @@ public function handle(StandaloneMongodb $database)
if (count($persistent_storages) > 0) { if (count($persistent_storages) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages; $docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
} }
if (count($persistent_file_volumes) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
return "$item->fs_path:$item->mount_path";
})->toArray();
}
if (count($volume_names) > 0) { if (count($volume_names) > 0) {
$docker_compose['volumes'] = $volume_names; $docker_compose['volumes'] = $volume_names;
} }

View File

@ -28,6 +28,7 @@ public function handle(StandaloneMysql $database)
]; ];
$persistent_storages = $this->generate_local_persistent_volumes(); $persistent_storages = $this->generate_local_persistent_volumes();
$persistent_file_volumes = $this->database->fileStorages()->get();
$volume_names = $this->generate_local_persistent_volumes_only_volume_names(); $volume_names = $this->generate_local_persistent_volumes_only_volume_names();
$environment_variables = $this->generate_environment_variables(); $environment_variables = $this->generate_environment_variables();
$this->add_custom_mysql(); $this->add_custom_mysql();
@ -86,6 +87,11 @@ public function handle(StandaloneMysql $database)
if (count($persistent_storages) > 0) { if (count($persistent_storages) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages; $docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
} }
if (count($persistent_file_volumes) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
return "$item->fs_path:$item->mount_path";
})->toArray();
}
if (count($volume_names) > 0) { if (count($volume_names) > 0) {
$docker_compose['volumes'] = $volume_names; $docker_compose['volumes'] = $volume_names;
} }

View File

@ -29,6 +29,7 @@ public function handle(StandalonePostgresql $database)
]; ];
$persistent_storages = $this->generate_local_persistent_volumes(); $persistent_storages = $this->generate_local_persistent_volumes();
$persistent_file_volumes = $this->database->fileStorages()->get();
$volume_names = $this->generate_local_persistent_volumes_only_volume_names(); $volume_names = $this->generate_local_persistent_volumes_only_volume_names();
$environment_variables = $this->generate_environment_variables(); $environment_variables = $this->generate_environment_variables();
$this->generate_init_scripts(); $this->generate_init_scripts();
@ -92,6 +93,11 @@ public function handle(StandalonePostgresql $database)
if (count($persistent_storages) > 0) { if (count($persistent_storages) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages; $docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
} }
if (count($persistent_file_volumes) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
return "$item->fs_path:$item->mount_path";
})->toArray();
}
if (count($volume_names) > 0) { if (count($volume_names) > 0) {
$docker_compose['volumes'] = $volume_names; $docker_compose['volumes'] = $volume_names;
} }

View File

@ -32,6 +32,7 @@ public function handle(StandaloneRedis $database)
]; ];
$persistent_storages = $this->generate_local_persistent_volumes(); $persistent_storages = $this->generate_local_persistent_volumes();
$persistent_file_volumes = $this->database->fileStorages()->get();
$volume_names = $this->generate_local_persistent_volumes_only_volume_names(); $volume_names = $this->generate_local_persistent_volumes_only_volume_names();
$environment_variables = $this->generate_environment_variables(); $environment_variables = $this->generate_environment_variables();
$this->add_custom_redis(); $this->add_custom_redis();
@ -96,6 +97,11 @@ public function handle(StandaloneRedis $database)
if (count($persistent_storages) > 0) { if (count($persistent_storages) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_storages; $docker_compose['services'][$container_name]['volumes'] = $persistent_storages;
} }
if (count($persistent_file_volumes) > 0) {
$docker_compose['services'][$container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
return "$item->fs_path:$item->mount_path";
})->toArray();
}
if (count($volume_names) > 0) { if (count($volume_names) > 0) {
$docker_compose['volumes'] = $volume_names; $docker_compose['volumes'] = $volume_names;
} }

View File

@ -150,6 +150,10 @@ public function events(Request $request)
$subscription = Subscription::where('stripe_customer_id', $customerId)->first(); $subscription = Subscription::where('stripe_customer_id', $customerId)->first();
} }
if (!$subscription) { if (!$subscription) {
if ($status === 'incomplete_expired') {
send_internal_notification('Subscription incomplete expired for customer: ' . $customerId);
return response("Subscription incomplete expired", 200);
}
send_internal_notification('No subscription found for: ' . $customerId); send_internal_notification('No subscription found for: ' . $customerId);
return response("No subscription found", 400); return response("No subscription found", 400);
} }
@ -166,9 +170,11 @@ public function events(Request $request)
$quantity = data_get($data, 'items.data.0.quantity', 10); $quantity = data_get($data, 'items.data.0.quantity', 10);
} }
$team = data_get($subscription, 'team'); $team = data_get($subscription, 'team');
$team->update([ if ($team) {
'custom_server_limit' => $quantity, $team->update([
]); 'custom_server_limit' => $quantity,
]);
}
ServerLimitCheckJob::dispatch($team); ServerLimitCheckJob::dispatch($team);
} }
$subscription->update([ $subscription->update([
@ -210,7 +216,9 @@ public function events(Request $request)
$customerId = data_get($data, 'customer'); $customerId = data_get($data, 'customer');
$subscription = Subscription::where('stripe_customer_id', $customerId)->firstOrFail(); $subscription = Subscription::where('stripe_customer_id', $customerId)->firstOrFail();
$team = data_get($subscription, 'team'); $team = data_get($subscription, 'team');
$team->trialEnded(); if ($team) {
$team->trialEnded();
}
$subscription->update([ $subscription->update([
'stripe_subscription_id' => null, 'stripe_subscription_id' => null,
'stripe_plan_id' => null, 'stripe_plan_id' => null,

View File

@ -1359,6 +1359,7 @@ private function generate_compose_file()
$onlyPort = $ports[0]; $onlyPort = $ports[0];
} }
$persistent_storages = $this->generate_local_persistent_volumes(); $persistent_storages = $this->generate_local_persistent_volumes();
$persistent_file_volumes = $this->application->fileStorages()->get();
$volume_names = $this->generate_local_persistent_volumes_only_volume_names(); $volume_names = $this->generate_local_persistent_volumes_only_volume_names();
// $environment_variables = $this->generate_environment_variables($ports); // $environment_variables = $this->generate_environment_variables($ports);
$this->save_environment_variables(); $this->save_environment_variables();
@ -1559,6 +1560,11 @@ private function generate_compose_file()
if (count($persistent_storages) > 0) { if (count($persistent_storages) > 0) {
$docker_compose['services'][$this->container_name]['volumes'] = $persistent_storages; $docker_compose['services'][$this->container_name]['volumes'] = $persistent_storages;
} }
if (count($persistent_file_volumes) > 0) {
$docker_compose['services'][$this->container_name]['volumes'] = $persistent_file_volumes->map(function ($item) {
return "$item->fs_path:$item->mount_path";
})->toArray();
}
if (count($volume_names) > 0) { if (count($volume_names) > 0) {
$docker_compose['volumes'] = $volume_names; $docker_compose['volumes'] = $volume_names;
} }

View File

@ -47,13 +47,17 @@ public function handle()
if (config('coolify.is_sentinel_enabled')) { if (config('coolify.is_sentinel_enabled')) {
$this->server->checkSentinel(); $this->server->checkSentinel();
} }
$this->check_docker_engine();
} }
} catch (\Throwable $e) { } catch (\Throwable $e) {
send_internal_notification('ServerStatusJob failed with: ' . $e->getMessage()); send_internal_notification('ServerStatusJob failed with: ' . $e->getMessage());
ray($e->getMessage()); ray($e->getMessage());
return handleError($e); return handleError($e);
} }
try {
// $this->check_docker_engine();
} catch (\Throwable $e) {
// Do nothing
}
} }
private function check_docker_engine() private function check_docker_engine()
{ {

View File

@ -91,7 +91,7 @@ public function loadServices(bool $force = false)
}); });
} else { } else {
$this->search = null; $this->search = null;
$this->allServices = get_service_templates(); $this->allServices = get_service_templates($force);
$this->services = $this->allServices->filter(function ($service, $key) { $this->services = $this->allServices->filter(function ($service, $key) {
return str_contains(strtolower($key), strtolower($this->search)); return str_contains(strtolower($key), strtolower($this->search));
}); });

View File

@ -7,13 +7,20 @@
use App\Models\ServiceApplication; use App\Models\ServiceApplication;
use App\Models\ServiceDatabase; use App\Models\ServiceDatabase;
use App\Models\StandaloneClickhouse; use App\Models\StandaloneClickhouse;
use App\Models\StandaloneDragonfly;
use App\Models\StandaloneKeydb;
use App\Models\StandaloneMariadb;
use App\Models\StandaloneMongodb;
use App\Models\StandaloneMysql;
use App\Models\StandalonePostgresql;
use App\Models\StandaloneRedis;
use Livewire\Component; use Livewire\Component;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class FileStorage extends Component class FileStorage extends Component
{ {
public LocalFileVolume $fileStorage; public LocalFileVolume $fileStorage;
public ServiceApplication|ServiceDatabase|StandaloneClickhouse|Application $resource; public ServiceApplication|StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse|ServiceDatabase|Application $resource;
public string $fs_path; public string $fs_path;
public ?string $workdir = null; public ?string $workdir = null;
@ -27,7 +34,7 @@ public function mount()
{ {
$this->resource = $this->fileStorage->service; $this->resource = $this->fileStorage->service;
if (Str::of($this->fileStorage->fs_path)->startsWith('.')) { if (Str::of($this->fileStorage->fs_path)->startsWith('.')) {
$this->workdir = $this->resource->service->workdir(); $this->workdir = $this->resource->service?->workdir();
$this->fs_path = Str::of($this->fileStorage->fs_path)->after('.'); $this->fs_path = Str::of($this->fileStorage->fs_path)->after('.');
} else { } else {
$this->workdir = null; $this->workdir = null;

View File

@ -3,21 +3,31 @@
namespace App\Livewire\Project\Shared\Storages; namespace App\Livewire\Project\Shared\Storages;
use App\Models\Application; use App\Models\Application;
use App\Models\LocalFileVolume;
use Livewire\Component; use Livewire\Component;
class Add extends Component class Add extends Component
{ {
public $resource;
public $uuid; public $uuid;
public $parameters; public $parameters;
public $isSwarm = false; public $isSwarm = false;
public string $name; public string $name;
public string $mount_path; public string $mount_path;
public ?string $host_path = null; public ?string $host_path = null;
public string $file_storage_path;
public string $file_storage_content;
public string $file_storage_directory_source;
public string $file_storage_directory_destination;
public $rules = [ public $rules = [
'name' => 'required|string', 'name' => 'required|string',
'mount_path' => 'required|string', 'mount_path' => 'required|string',
'host_path' => 'string|nullable', 'host_path' => 'string|nullable',
'file_storage_path' => 'string',
'file_storage_content' => 'string',
'file_storage_directory_source' => 'string',
'file_storage_directory_destination' => 'string',
]; ];
protected $listeners = ['clearAddStorage' => 'clear']; protected $listeners = ['clearAddStorage' => 'clear'];
@ -26,10 +36,16 @@ class Add extends Component
'name' => 'name', 'name' => 'name',
'mount_path' => 'mount', 'mount_path' => 'mount',
'host_path' => 'host', 'host_path' => 'host',
'file_storage_path' => 'file storage path',
'file_storage_content' => 'file storage content',
'file_storage_directory_source' => 'file storage directory source',
'file_storage_directory_destination' => 'file storage directory destination',
]; ];
public function mount() public function mount()
{ {
$this->file_storage_directory_source = application_configuration_dir() . "/{$this->resource->uuid}";
$this->uuid = $this->resource->uuid;
$this->parameters = get_route_parameters(); $this->parameters = get_route_parameters();
if (data_get($this->parameters, 'application_uuid')) { if (data_get($this->parameters, 'application_uuid')) {
$applicationUuid = $this->parameters['application_uuid']; $applicationUuid = $this->parameters['application_uuid'];
@ -43,8 +59,53 @@ public function mount()
} }
} }
} }
public function submitFileStorage()
{
try {
$this->file_storage_path = trim($this->file_storage_path);
$this->file_storage_path = str($this->file_storage_path)->start('/')->value();
if ($this->resource->getMorphClass() === 'App\Models\Application') {
$fs_path = application_configuration_dir() . '/' . $this->resource->uuid . $this->file_storage_path;
}
LocalFileVolume::create(
[
'fs_path' => $fs_path,
'mount_path' => $this->file_storage_path,
'content' => $this->file_storage_content,
'is_directory' => false,
'resource_id' => $this->resource->id,
'resource_type' => get_class($this->resource)
],
);
$this->dispatch('refresh_storages');
} catch (\Throwable $e) {
return handleError($e, $this);
}
public function submit() }
public function submitFileStorageDirectory()
{
try {
$this->file_storage_directory_source = trim($this->file_storage_directory_source);
$this->file_storage_directory_source = str($this->file_storage_directory_source)->start('/')->value();
$this->file_storage_directory_destination = trim($this->file_storage_directory_destination);
$this->file_storage_directory_destination = str($this->file_storage_directory_destination)->start('/')->value();
LocalFileVolume::create(
[
'fs_path' => $this->file_storage_directory_source,
'mount_path' => $this->file_storage_directory_destination,
'is_directory' => true,
'resource_id' => $this->resource->id,
'resource_type' => get_class($this->resource)
],
);
$this->dispatch('refresh_storages');
} catch (\Throwable $e) {
return handleError($e, $this);
}
}
public function submitPersistentVolume()
{ {
try { try {
$this->validate($this->rules); $this->validate($this->rules);
@ -54,7 +115,7 @@ public function submit()
'mount_path' => $this->mount_path, 'mount_path' => $this->mount_path,
'host_path' => $this->host_path, 'host_path' => $this->host_path,
]); ]);
$this->dispatch('closeStorageModal');
} catch (\Throwable $e) { } catch (\Throwable $e) {
return handleError($e, $this); return handleError($e, $this);
} }

View File

@ -465,25 +465,24 @@ function sslip(Server $server)
return "http://{$server->ip}.sslip.io"; return "http://{$server->ip}.sslip.io";
} }
function get_service_templates() function get_service_templates(bool $force = false): Collection
{ {
// if (isDev()) { if ($force) {
// $services = File::get(base_path('templates/service-templates.json')); try {
// $services = collect(json_decode($services))->sortKeys(); $response = Http::retry(3, 50)->get(config('constants.services.official'));
// } else { if ($response->failed()) {
// try { return collect([]);
// $response = Http::retry(3, 50)->get(config('constants.services.official')); }
// if ($response->failed()) { $services = $response->json();
// return collect([]); return collect($services);
// } } catch (\Throwable $e) {
// $services = $response->json(); $services = File::get(base_path('templates/service-templates.json'));
// $services = collect($services)->sortKeys(); return collect(json_decode($services))->sortKeys();
// } catch (\Throwable $e) { }
// $services = collect([]); } else {
// } $services = File::get(base_path('templates/service-templates.json'));
// } return collect(json_decode($services))->sortKeys();
$services = File::get(base_path('templates/service-templates.json')); }
return collect(json_decode($services))->sortKeys();
} }
function getResourceByUuid(string $uuid, ?int $teamId = null) function getResourceByUuid(string $uuid, ?int $teamId = null)

View File

@ -7,7 +7,7 @@
// 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.286', 'release' => '4.0.0-beta.287',
// 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'),

View File

@ -1,3 +1,3 @@
<?php <?php
return '4.0.0-beta.286'; return '4.0.0-beta.287';

View File

@ -1,12 +1,14 @@
<div class="p-4 transition border rounded dark:border-coolgray-200"> <div class="p-4 transition border rounded dark:border-coolgray-200">
<div class="flex flex-col justify-center pb-4 text-sm select-text"> <div class="flex flex-col justify-center pb-4 text-sm select-text">
<h2>{{ data_get($resource, 'name', 'unknown') }}</h2> @if (data_get($resource, 'build_pack') === 'dockercompose')
<div>{{ $workdir }}{{ $fs_path }} -> {{ $fileStorage->mount_path }}</div> <h2>{{ data_get($resource, 'name', 'unknown') }}</h2>
@if ($fileStorage->is_directory)
<div class="text-xs">Directory</div>
@else
<div class="text-xs">File</div>
@endif @endif
@if ($fileStorage->is_directory)
<div class="dark:text-white">Directory Mount</div>
@else
<div class="dark:text-white">File Mount</div>
@endif
<div>{{ $workdir }}{{ $fs_path }} -> {{ $fileStorage->mount_path }}</div>
</div> </div>
<form wire:submit='submit' class="flex flex-col gap-2"> <form wire:submit='submit' class="flex flex-col gap-2">
<div class="flex gap-2"> <div class="flex gap-2">
@ -16,7 +18,8 @@
</x-modal-confirmation> </x-modal-confirmation>
@else @else
<x-modal-confirmation action="convertToDirectory" buttonTitle="Convert to directory"> <x-modal-confirmation action="convertToDirectory" buttonTitle="Convert to directory">
This will convert this to a directory. If it was a file, it will be deleted. It is not reversible. <br>Please think again. This will convert this to a directory. If it was a file, it will be deleted. It is not reversible.
<br>Please think again.
</x-modal-confirmation> </x-modal-confirmation>
@endif @endif
<x-modal-confirmation isErrorButton buttonTitle="Delete"> <x-modal-confirmation isErrorButton buttonTitle="Delete">

View File

@ -15,8 +15,8 @@
volume volume
name, example: <span class='text-helper'>-pr-1</span>" /> name, example: <span class='text-helper'>-pr-1</span>" />
@if ($resource?->build_pack !== 'dockercompose') @if ($resource?->build_pack !== 'dockercompose')
<x-modal-input buttonTitle="+ Add" title="New Persistent Storage"> <x-modal-input :closeOutside="false" buttonTitle="+ Add" title="New Persistent Storage">
<livewire:project.shared.storages.add :uuid="$resource->uuid" /> <livewire:project.shared.storages.add :resource="$resource"/>
</x-modal-input> </x-modal-input>
@endif @endif
</div> </div>

View File

@ -1,18 +1,43 @@
<form class="flex flex-col w-full gap-2 rounded" wire:submit='submit'> <div class="flex flex-col w-full gap-2 rounded">
@if ($isSwarm) You can add Volumes, Files and Directories to your resources here.
<h5>Swarm Mode detected: You need to set a shared volume (EFS/NFS/etc) on all the worker nodes if you would <form class="flex flex-col w-full gap-2 rounded" wire:submit='submitPersistentVolume'>
like to use a persistent volumes.</h5> <h3>Volume Mount</h3>
@endif @if ($isSwarm)
<x-forms.input placeholder="pv-name" id="name" label="Name" required helper="Volume name." /> <h5>Swarm Mode detected: You need to set a shared volume (EFS/NFS/etc) on all the worker nodes if you would
@if ($isSwarm) like to use a persistent volumes.</h5>
<x-forms.input placeholder="/root" id="host_path" label="Source Path" required @endif
<x-forms.input placeholder="pv-name" id="name" label="Name" required helper="Volume name." />
@if ($isSwarm)
<x-forms.input placeholder="/root" id="host_path" label="Source Path" required
helper="Directory on the host system." />
@else
<x-forms.input placeholder="/root" id="host_path" label="Source Path"
helper="Directory on the host system." />
@endif
<x-forms.input placeholder="/tmp/root" id="mount_path" label="Destination Path" required
helper="Directory inside the container." />
<x-forms.button type="submit" @click="modalOpen=false">
Save
</x-forms.button>
</form>
<form class="flex flex-col w-full gap-2 rounded" wire:submit='submitFileStorage'>
<h3>File Mount</h3>
<x-forms.input placeholder="/etc/nginx/nginx.conf" id="file_storage_path" label="Destination Path" required
helper="File inside the container" />
<x-forms.textarea label="Content" id="file_storage_content"></x-forms.textarea>
<x-forms.button type="submit" @click="modalOpen=false">
Save
</x-forms.button>
</form>
<form class="flex flex-col w-full gap-2 rounded" wire:submit='submitFileStorageDirectory'>
<h3>Directory Mount</h3>
<x-forms.input placeholder="{{ application_configuration_dir() }}/{{ $resource->uuid }}/etc/nginx"
id="file_storage_directory_source" label="Source Directory" required
helper="Directory on the host system." /> helper="Directory on the host system." />
@else <x-forms.input placeholder="/etc/nginx" id="file_storage_directory_destination" label="Destination Directory"
<x-forms.input placeholder="/root" id="host_path" label="Source Path" helper="Directory on the host system." /> required helper="Directory inside the container." />
@endif <x-forms.button type="submit" @click="modalOpen=false">
<x-forms.input placeholder="/tmp/root" id="mount_path" label="Destination Path" required Save
helper="Directory inside the container." /> </x-forms.button>
<x-forms.button type="submit" @click="slideOverOpen=false"> </form>
Save </div>
</x-forms.button>
</form>

View File

@ -4,27 +4,27 @@
@if ($isFirst) @if ($isFirst)
<x-forms.input id="storage.name" label="Volume Name" required <x-forms.input id="storage.name" label="Volume Name" required
helper="Warning: Changing the volume name after the initial start could cause problems. Only use it when you know what are you doing." /> helper="Warning: Changing the volume name after the initial start could cause problems. Only use it when you know what are you doing." />
<x-forms.input id="storage.host_path" label="Source Path (on host)" <x-forms.input id="storage.host_path" helper="Directory on the host system." label="Source Path"
helper="Warning: Changing the source path after the initial start could cause problems. Only use it when you know what are you doing." /> helper="Warning: Changing the source path after the initial start could cause problems. Only use it when you know what are you doing." />
<x-forms.input id="storage.mount_path" label="Destination Path (in container)" required readonly /> <x-forms.input id="storage.mount_path" label="Destination Path" helper="Directory inside the container." required readonly />
<x-forms.button type="submit"> <x-forms.button type="submit">
Update Update
</x-forms.button> </x-forms.button>
@else @else
<x-forms.input id="storage.name" required readonly <x-forms.input id="storage.name" required readonly
helper="Warning: Changing the volume name after the initial start could cause problems. Only use it when you know what are you doing." /> helper="Warning: Changing the volume name after the initial start could cause problems. Only use it when you know what are you doing." />
<x-forms.input id="storage.host_path" readonly /> <x-forms.input id="storage.host_path" helper="Directory on the host system." readonly />
<x-forms.input id="storage.mount_path" required readonly /> <x-forms.input id="storage.mount_path" helper="Directory inside the container." required readonly />
@endif @endif
@else @else
@if ($isFirst) @if ($isFirst)
<x-forms.input id="storage.name" label="Volume Name" required /> <x-forms.input id="storage.name" label="Volume Name" required />
<x-forms.input id="storage.host_path" label="Source Path (on host)" /> <x-forms.input id="storage.host_path" helper="Directory on the host system." label="Source Path" />
<x-forms.input id="storage.mount_path" label="Destination Path (in container)" required /> <x-forms.input id="storage.mount_path" label="Destination Path" helper="Directory inside the container." required />
@else @else
<x-forms.input id="storage.name" required /> <x-forms.input id="storage.name" required />
<x-forms.input id="storage.host_path" /> <x-forms.input id="storage.host_path" helper="Directory on the host system." />
<x-forms.input id="storage.mount_path" required /> <x-forms.input id="storage.mount_path" helper="Directory inside the container." required />
@endif @endif
<div class="flex gap-2"> <div class="flex gap-2">
<x-forms.button type="submit"> <x-forms.button type="submit">

View File

@ -1,7 +1,7 @@
{ {
"coolify": { "coolify": {
"v4": { "v4": {
"version": "4.0.0-beta.286" "version": "4.0.0-beta.287"
}, },
"sentinel": { "sentinel": {
"version": "0.0.4" "version": "0.0.4"