mirror of
https://github.com/tiennm99/coolify.git
synced 2026-10-13 22:15:35 +00:00
Merge remote-tracking branch 'origin/next' into v5-parallel-inertia-react
This commit is contained in:
commit
ae32ab5d7b
139 files changed
+8677
-545
No files matched your search
@@ -286,6 +286,7 @@ class Advanced extends Component
|
||||
$this->application->settings->save();
|
||||
|
||||
$this->dispatch('success', 'Stop grace period updated.');
|
||||
$this->dispatch('configurationChanged');
|
||||
} catch (ValidationException $e) {
|
||||
throw $e;
|
||||
} catch (\Throwable $e) {
|
||||
|
||||
@@ -489,6 +489,7 @@ class General extends Component
|
||||
if ($this->isContainerLabelReadonlyEnabled) {
|
||||
$this->resetDefaultLabels(false);
|
||||
}
|
||||
$this->dispatch('configurationChanged');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
|
||||
@@ -147,6 +147,7 @@ class Source extends Component
|
||||
'source_id' => $source->id,
|
||||
'source_type' => $sourceType,
|
||||
]);
|
||||
$this->dispatch('configurationChanged');
|
||||
|
||||
['repository' => $customRepository] = $this->application->customRepository();
|
||||
$repository = githubApi($this->application->source, "repos/{$customRepository}");
|
||||
|
||||
@@ -57,6 +57,7 @@ class Swarm extends Component
|
||||
$this->authorize('update', $this->application);
|
||||
$this->syncData(true);
|
||||
$this->dispatch('success', 'Swarm settings updated.');
|
||||
$this->dispatch('configurationChanged');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
@@ -68,6 +69,7 @@ class Swarm extends Component
|
||||
$this->authorize('update', $this->application);
|
||||
$this->syncData(true);
|
||||
$this->dispatch('success', 'Swarm settings updated.');
|
||||
$this->dispatch('configurationChanged');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ class CloneMe extends Component
|
||||
|
||||
public ?int $selectedServer = null;
|
||||
|
||||
public ?int $selectedDestination = null;
|
||||
public ?string $selectedDestination = null;
|
||||
|
||||
public ?Server $server = null;
|
||||
|
||||
@@ -76,9 +76,9 @@ class CloneMe extends Component
|
||||
return view('livewire.project.clone-me');
|
||||
}
|
||||
|
||||
public function selectServer($server_id, $destination_id)
|
||||
public function selectServer($server_id, $destination_uuid)
|
||||
{
|
||||
if ($server_id == $this->selectedServer && $destination_id == $this->selectedDestination) {
|
||||
if ($server_id == $this->selectedServer && $destination_uuid === $this->selectedDestination) {
|
||||
$this->selectedServer = null;
|
||||
$this->selectedDestination = null;
|
||||
$this->server = null;
|
||||
@@ -86,7 +86,7 @@ class CloneMe extends Component
|
||||
return;
|
||||
}
|
||||
$this->selectedServer = $server_id;
|
||||
$this->selectedDestination = $destination_id;
|
||||
$this->selectedDestination = $destination_uuid;
|
||||
$this->server = $this->servers->where('id', $server_id)->first();
|
||||
}
|
||||
|
||||
@@ -98,6 +98,10 @@ class CloneMe extends Component
|
||||
'selectedDestination' => 'required',
|
||||
'newName' => ValidationPatterns::nameRules(),
|
||||
]);
|
||||
$selectedDestination = find_resource_destination_for_current_team($this->selectedDestination);
|
||||
if (! $selectedDestination) {
|
||||
throw new \Exception('Destination not found.');
|
||||
}
|
||||
if ($type === 'project') {
|
||||
$foundProject = Project::where('name', $this->newName)->first();
|
||||
if ($foundProject) {
|
||||
@@ -130,7 +134,6 @@ class CloneMe extends Component
|
||||
$databases = $this->environment->databases();
|
||||
$services = $this->environment->services;
|
||||
foreach ($applications as $application) {
|
||||
$selectedDestination = $this->servers->flatMap(fn ($server) => $server->destinations())->where('id', $this->selectedDestination)->first();
|
||||
clone_application($application, $selectedDestination, [
|
||||
'environment_id' => $environment->id,
|
||||
], $this->cloneVolumeData);
|
||||
@@ -147,7 +150,8 @@ class CloneMe extends Component
|
||||
'status' => 'exited',
|
||||
'started_at' => null,
|
||||
'environment_id' => $environment->id,
|
||||
'destination_id' => $this->selectedDestination,
|
||||
'destination_id' => $selectedDestination->id,
|
||||
'destination_type' => $selectedDestination->getMorphClass(),
|
||||
]);
|
||||
$newDatabase->save();
|
||||
|
||||
@@ -265,7 +269,9 @@ class CloneMe extends Component
|
||||
])->fill([
|
||||
'uuid' => $uuid,
|
||||
'environment_id' => $environment->id,
|
||||
'destination_id' => $this->selectedDestination,
|
||||
'destination_id' => $selectedDestination->id,
|
||||
'destination_type' => $selectedDestination->getMorphClass(),
|
||||
'server_id' => $selectedDestination->server_id,
|
||||
]);
|
||||
$newService->save();
|
||||
|
||||
|
||||
@@ -22,13 +22,7 @@ class Index extends Component
|
||||
if (! $database) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
// No backups
|
||||
if (
|
||||
$database->getMorphClass() === \App\Models\StandaloneRedis::class ||
|
||||
$database->getMorphClass() === \App\Models\StandaloneKeydb::class ||
|
||||
$database->getMorphClass() === \App\Models\StandaloneDragonfly::class ||
|
||||
$database->getMorphClass() === \App\Models\StandaloneClickhouse::class
|
||||
) {
|
||||
if (! $database->isBackupSolutionAvailable()) {
|
||||
return redirect()->route('project.database.configuration', [
|
||||
'project_uuid' => $project->uuid,
|
||||
'environment_uuid' => $environment->uuid,
|
||||
|
||||
@@ -48,6 +48,12 @@ class CreateScheduledBackup extends Component
|
||||
try {
|
||||
$this->authorize('manageBackups', $this->database);
|
||||
|
||||
if (! $this->database->isBackupSolutionAvailable()) {
|
||||
$this->dispatch('error', 'Scheduled backups are not supported for this database type.');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->validate();
|
||||
|
||||
if ($this->saveToS3) {
|
||||
@@ -87,6 +93,8 @@ class CreateScheduledBackup extends Component
|
||||
$payload['databases_to_backup'] = $this->database->mysql_database;
|
||||
} elseif ($this->database->type() === 'standalone-mariadb') {
|
||||
$payload['databases_to_backup'] = $this->database->mariadb_database;
|
||||
} elseif ($this->database->type() === 'standalone-clickhouse') {
|
||||
$payload['databases_to_backup'] = $this->database->clickhouse_db;
|
||||
}
|
||||
|
||||
$databaseBackup = ScheduledDatabaseBackup::create($payload);
|
||||
|
||||
@@ -47,19 +47,20 @@ class DockerCompose extends Component
|
||||
$environment = $project->environments()->where('uuid', $this->parameters['environment_uuid'])->firstOrFail();
|
||||
|
||||
$destination_uuid = $this->query['destination'] ?? null;
|
||||
$destination = find_destination_for_current_team($destination_uuid);
|
||||
$destination = find_resource_destination_for_current_team($destination_uuid);
|
||||
if (! $destination) {
|
||||
throw new \Exception('Destination not found.');
|
||||
}
|
||||
$destination_class = $destination->getMorphClass();
|
||||
|
||||
$service = Service::create([
|
||||
$service = new Service([
|
||||
'docker_compose_raw' => $this->dockerComposeRaw,
|
||||
'environment_id' => $environment->id,
|
||||
'server_id' => $destination->server_id,
|
||||
'destination_id' => $destination->id,
|
||||
'destination_type' => $destination_class,
|
||||
]);
|
||||
$service->save();
|
||||
|
||||
$variables = parseEnvFormatToArray($this->envFile);
|
||||
foreach ($variables as $key => $data) {
|
||||
|
||||
@@ -115,7 +115,7 @@ class DockerImage extends Component
|
||||
$parser->parse($dockerImage);
|
||||
|
||||
$destination_uuid = $this->query['destination'] ?? null;
|
||||
$destination = find_destination_for_current_team($destination_uuid);
|
||||
$destination = find_resource_destination_for_current_team($destination_uuid);
|
||||
if (! $destination) {
|
||||
throw new \Exception('Destination not found.');
|
||||
}
|
||||
@@ -133,7 +133,7 @@ class DockerImage extends Component
|
||||
// Determine the image tag based on whether it's a hash or regular tag
|
||||
$imageTag = $parser->isImageHash() ? 'sha256-'.$parser->getTag() : $parser->getTag();
|
||||
|
||||
$application = Application::create([
|
||||
$application = new Application([
|
||||
'name' => 'docker-image-'.new_public_id(),
|
||||
'repository_project_id' => 0,
|
||||
'git_repository' => 'coollabsio/coolify',
|
||||
@@ -147,6 +147,7 @@ class DockerImage extends Component
|
||||
'destination_type' => $destination_class,
|
||||
'health_check_enabled' => false,
|
||||
]);
|
||||
$application->save();
|
||||
|
||||
$fqdn = generateUrl(server: $destination->server, random: $application->uuid);
|
||||
$application->update([
|
||||
|
||||
@@ -192,7 +192,7 @@ class GithubPrivateRepository extends Component
|
||||
}
|
||||
|
||||
$destination_uuid = $this->query['destination'] ?? null;
|
||||
$destination = find_destination_for_current_team($destination_uuid);
|
||||
$destination = find_resource_destination_for_current_team($destination_uuid);
|
||||
if (! $destination) {
|
||||
throw new \Exception('Destination not found.');
|
||||
}
|
||||
@@ -201,7 +201,7 @@ class GithubPrivateRepository extends Component
|
||||
$project = Project::ownedByCurrentTeam()->where('uuid', $this->parameters['project_uuid'])->firstOrFail();
|
||||
$environment = $project->environments()->where('uuid', $this->parameters['environment_uuid'])->firstOrFail();
|
||||
|
||||
$application = Application::create([
|
||||
$application = new Application([
|
||||
'name' => generate_application_name($this->selected_repository_owner.'/'.$this->selected_repository_repo, $this->selected_branch_name),
|
||||
'repository_project_id' => $this->selected_repository_id,
|
||||
'git_repository' => str($this->selected_repository_owner)->trim()->toString().'/'.str($this->selected_repository_repo)->trim()->toString(),
|
||||
@@ -216,6 +216,7 @@ class GithubPrivateRepository extends Component
|
||||
'source_id' => $this->github_app->id,
|
||||
'source_type' => $this->github_app->getMorphClass(),
|
||||
]);
|
||||
$application->save();
|
||||
$application->settings->is_static = $this->is_static;
|
||||
$application->settings->save();
|
||||
|
||||
|
||||
@@ -136,7 +136,7 @@ class GithubPrivateRepositoryDeployKey extends Component
|
||||
$this->validate();
|
||||
try {
|
||||
$destination_uuid = $this->query['destination'] ?? null;
|
||||
$destination = find_destination_for_current_team($destination_uuid);
|
||||
$destination = find_resource_destination_for_current_team($destination_uuid);
|
||||
if (! $destination) {
|
||||
throw new \Exception('Destination not found.');
|
||||
}
|
||||
@@ -185,7 +185,8 @@ class GithubPrivateRepositoryDeployKey extends Component
|
||||
$application_init['docker_compose_location'] = $this->docker_compose_location;
|
||||
$application_init['base_directory'] = $this->base_directory;
|
||||
}
|
||||
$application = Application::create($application_init);
|
||||
$application = new Application($application_init);
|
||||
$application->save();
|
||||
$application->settings->is_static = $this->is_static;
|
||||
$application->settings->save();
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ class PublicGitRepository extends Component
|
||||
$project_uuid = $this->parameters['project_uuid'];
|
||||
$environment_uuid = $this->parameters['environment_uuid'];
|
||||
|
||||
$destination = find_destination_for_current_team($destination_uuid);
|
||||
$destination = find_resource_destination_for_current_team($destination_uuid);
|
||||
if (! $destination) {
|
||||
throw new \Exception('Destination not found.');
|
||||
}
|
||||
@@ -336,7 +336,8 @@ class PublicGitRepository extends Component
|
||||
$application_init['docker_compose_location'] = $this->docker_compose_location;
|
||||
$application_init['base_directory'] = $this->base_directory;
|
||||
}
|
||||
$application = Application::create($application_init);
|
||||
$application = new Application($application_init);
|
||||
$application->save();
|
||||
|
||||
$application->settings->is_static = $this->isStatic;
|
||||
$application->settings->save();
|
||||
|
||||
@@ -24,6 +24,8 @@ class Select extends Component
|
||||
|
||||
public Collection|null|Server $servers;
|
||||
|
||||
public ?Collection $buildServers = null;
|
||||
|
||||
public bool $onlyBuildServerAvailable = false;
|
||||
|
||||
public ?Collection $standaloneDockers;
|
||||
@@ -380,7 +382,7 @@ class Select extends Component
|
||||
|
||||
return;
|
||||
}
|
||||
if (count($this->servers) === 1) {
|
||||
if (count($this->servers) === 1 && $this->buildServers?->isEmpty()) {
|
||||
$server = $this->servers->first();
|
||||
if ($server instanceof Server) {
|
||||
$this->setServer($server);
|
||||
@@ -452,12 +454,8 @@ class Select extends Component
|
||||
public function loadServers()
|
||||
{
|
||||
$this->servers = Server::isUsable()->get()->sortBy('name');
|
||||
$this->allServers = $this->servers;
|
||||
|
||||
if ($this->allServers && $this->allServers->isNotEmpty()) {
|
||||
$this->onlyBuildServerAvailable = $this->allServers->every(function ($server) {
|
||||
return $server->isBuildServer();
|
||||
});
|
||||
}
|
||||
$this->buildServers = Server::isUsableBuildServer()->get()->sortBy('name');
|
||||
$this->allServers = $this->servers->concat($this->buildServers);
|
||||
$this->onlyBuildServerAvailable = $this->servers->isEmpty() && $this->buildServers->isNotEmpty();
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,7 @@ CMD ["nginx", "-g", "daemon off;"]
|
||||
'dockerfile' => 'required',
|
||||
]);
|
||||
$destination_uuid = $this->query['destination'] ?? null;
|
||||
$destination = find_destination_for_current_team($destination_uuid);
|
||||
$destination = find_resource_destination_for_current_team($destination_uuid);
|
||||
if (! $destination) {
|
||||
throw new \Exception('Destination not found.');
|
||||
}
|
||||
@@ -51,7 +51,7 @@ CMD ["nginx", "-g", "daemon off;"]
|
||||
if (! $port) {
|
||||
$port = 80;
|
||||
}
|
||||
$application = Application::create([
|
||||
$application = new Application([
|
||||
'name' => 'dockerfile-'.new_public_id(),
|
||||
'repository_project_id' => 0,
|
||||
'git_repository' => 'coollabsio/coolify',
|
||||
@@ -66,6 +66,7 @@ CMD ["nginx", "-g", "daemon off;"]
|
||||
'source_id' => 0,
|
||||
'source_type' => GithubApp::class,
|
||||
]);
|
||||
$application->save();
|
||||
|
||||
$fqdn = generateUrl(server: $destination->server, random: $application->uuid);
|
||||
$application->update([
|
||||
|
||||
@@ -33,7 +33,7 @@ class Create extends Component
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
if (isset($type) && isset($destination_uuid)) {
|
||||
$destination = find_destination_for_current_team($destination_uuid);
|
||||
$destination = find_resource_destination_for_current_team($destination_uuid);
|
||||
if (! $destination) {
|
||||
return redirect()->route('dashboard');
|
||||
}
|
||||
@@ -96,7 +96,8 @@ class Create extends Component
|
||||
if (in_array($oneClickServiceName, NEEDS_TO_CONNECT_TO_PREDEFINED_NETWORK)) {
|
||||
data_set($service_payload, 'connect_to_docker_network', true);
|
||||
}
|
||||
$service = Service::create($service_payload);
|
||||
$service = new Service($service_payload);
|
||||
$service->save();
|
||||
$service->name = "$oneClickServiceName-".$service->uuid;
|
||||
$service->save();
|
||||
if ($oneClickDotEnvs?->count() > 0) {
|
||||
|
||||
@@ -118,9 +118,8 @@ class Destination extends Component
|
||||
$server = Server::ownedByCurrentTeam()->findOrFail($server_id);
|
||||
$network = StandaloneDocker::ownedByCurrentTeam()->where('server_id', $server->id)->findOrFail($network_id);
|
||||
$this->authorize('update', $this->resource);
|
||||
|
||||
$this->resource->getConnection()->transaction(function () use ($network, $server) {
|
||||
$main_destination = $this->resource->destination;
|
||||
$mainDestination = $this->resource->destination;
|
||||
$this->resource->update([
|
||||
'destination_id' => $network->id,
|
||||
'destination_type' => StandaloneDocker::class,
|
||||
@@ -128,7 +127,7 @@ class Destination extends Component
|
||||
$this->resource->additional_networks()
|
||||
->wherePivot('server_id', $server->id)
|
||||
->detach($network->id);
|
||||
$this->resource->additional_networks()->attach($main_destination->id, ['server_id' => $main_destination->server->id]);
|
||||
$this->resource->additional_networks()->attach($mainDestination->id, ['server_id' => $mainDestination->server->id]);
|
||||
});
|
||||
$this->resource->refresh();
|
||||
$this->refreshServers();
|
||||
|
||||
@@ -76,6 +76,7 @@ class All extends Component
|
||||
$this->resource->settings->save();
|
||||
$this->getDevView();
|
||||
$this->dispatch('success', 'Environment variable settings updated.');
|
||||
$this->dispatch('configurationChanged');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
|
||||
@@ -152,6 +152,7 @@ class HealthChecks extends Component
|
||||
$this->resource->custom_healthcheck_found = $this->customHealthcheckFound;
|
||||
$this->resource->save();
|
||||
$this->dispatch('success', 'Health check updated.');
|
||||
$this->dispatch('configurationChanged');
|
||||
}
|
||||
|
||||
public function submit()
|
||||
@@ -178,6 +179,7 @@ class HealthChecks extends Component
|
||||
$this->resource->custom_healthcheck_found = $this->customHealthcheckFound;
|
||||
$this->resource->save();
|
||||
$this->dispatch('success', 'Health check updated.');
|
||||
$this->dispatch('configurationChanged');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
@@ -213,6 +215,7 @@ class HealthChecks extends Component
|
||||
} else {
|
||||
$this->dispatch('success', 'Health check '.($this->healthCheckEnabled ? 'enabled' : 'disabled').'.');
|
||||
}
|
||||
$this->dispatch('configurationChanged');
|
||||
} catch (\Throwable $e) {
|
||||
return handleError($e, $this);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ use App\Models\Application;
|
||||
use App\Models\Environment;
|
||||
use App\Models\Project;
|
||||
use App\Models\StandaloneClickhouse;
|
||||
use App\Models\StandaloneDocker;
|
||||
use App\Models\StandaloneDragonfly;
|
||||
use App\Models\StandaloneKeydb;
|
||||
use App\Models\StandaloneMariadb;
|
||||
@@ -19,7 +18,6 @@ use App\Models\StandaloneMongodb;
|
||||
use App\Models\StandaloneMysql;
|
||||
use App\Models\StandalonePostgresql;
|
||||
use App\Models\StandaloneRedis;
|
||||
use App\Models\SwarmDocker;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Livewire\Component;
|
||||
|
||||
@@ -37,6 +35,8 @@ class ResourceOperations extends Component
|
||||
|
||||
public $servers;
|
||||
|
||||
public $buildServers;
|
||||
|
||||
public bool $cloneVolumeData = false;
|
||||
|
||||
public function mount()
|
||||
@@ -45,7 +45,9 @@ class ResourceOperations extends Component
|
||||
$this->projectUuid = data_get($parameters, 'project_uuid');
|
||||
$this->environmentUuid = data_get($parameters, 'environment_uuid');
|
||||
$this->projects = Project::ownedByCurrentTeamCached();
|
||||
$this->servers = currentTeam()->servers->filter(fn ($server) => ! $server->isBuildServer());
|
||||
$servers = currentTeam()->servers()->get();
|
||||
$this->servers = $servers->reject(fn ($server) => $server->isBuildServer());
|
||||
$this->buildServers = $servers->filter(fn ($server) => $server->isBuildServer());
|
||||
}
|
||||
|
||||
public function toggleVolumeCloning(bool $value)
|
||||
@@ -53,20 +55,20 @@ class ResourceOperations extends Component
|
||||
$this->cloneVolumeData = $value;
|
||||
}
|
||||
|
||||
public function cloneTo($destination_id)
|
||||
public function cloneTo($destination_uuid)
|
||||
{
|
||||
try {
|
||||
$this->authorize('update', $this->resource);
|
||||
|
||||
$new_destination = StandaloneDocker::ownedByCurrentTeam()->find($destination_id);
|
||||
if (! $new_destination) {
|
||||
$new_destination = SwarmDocker::ownedByCurrentTeam()->find($destination_id);
|
||||
}
|
||||
$new_destination = find_resource_destination_for_current_team($destination_uuid);
|
||||
if (! $new_destination) {
|
||||
return $this->addError('destination_id', 'Destination not found.');
|
||||
}
|
||||
$uuid = new_public_id();
|
||||
$server = $new_destination->server;
|
||||
if (! $server->canHostResources()) {
|
||||
return $this->addError('destination_id', 'The selected server cannot host resources.');
|
||||
}
|
||||
|
||||
if ($this->resource->getMorphClass() === Application::class) {
|
||||
$new_resource = clone_application($this->resource, $new_destination, ['uuid' => $uuid], $this->cloneVolumeData);
|
||||
@@ -99,6 +101,7 @@ class ResourceOperations extends Component
|
||||
'status' => 'exited',
|
||||
'started_at' => null,
|
||||
'destination_id' => $new_destination->id,
|
||||
'destination_type' => $new_destination->getMorphClass(),
|
||||
]);
|
||||
$new_resource->save();
|
||||
|
||||
|
||||
Reference in new issue
Block a user