diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index 72cb55a5a..828c36447 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -454,7 +454,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue $yaml = $composeFile = $this->application->docker_compose_raw; $this->save_environment_variables(); } else { - $composeFile = $this->application->oldParser(pull_request_id: $this->pull_request_id, preview_id: data_get($this->preview, 'id')); + $composeFile = $this->application->parse(pull_request_id: $this->pull_request_id, preview_id: data_get($this->preview, 'id')); $this->save_environment_variables(); if (! is_null($this->env_filename)) { $services = collect($composeFile['services']); @@ -955,13 +955,19 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue } } if ($this->application->environment_variables->where('key', 'COOLIFY_FQDN')->isEmpty()) { - $envs->push("COOLIFY_FQDN={$this->application->fqdn}"); - $envs->push("COOLIFY_DOMAIN_URL={$this->application->fqdn}"); + if ($this->application->compose_parsing_version === '3') { + $envs->push("COOLIFY_URL={$this->application->fqdn}"); + } else { + $envs->push("COOLIFY_FQDN={$this->application->fqdn}"); + } } if ($this->application->environment_variables->where('key', 'COOLIFY_URL')->isEmpty()) { $url = str($this->application->fqdn)->replace('http://', '')->replace('https://', ''); - $envs->push("COOLIFY_URL={$url}"); - $envs->push("COOLIFY_DOMAIN_FQDN={$url}"); + if ($this->application->compose_parsing_version === '3') { + $envs->push("COOLIFY_FQDN={$url}"); + } else { + $envs->push("COOLIFY_URL={$url}"); + } } if ($this->application->build_pack !== 'dockercompose' || $this->application->compose_parsing_version === '1' || $this->application->compose_parsing_version === '2') { if ($this->application->environment_variables->where('key', 'COOLIFY_BRANCH')->isEmpty()) { diff --git a/app/Livewire/Project/Application/Advanced.php b/app/Livewire/Project/Application/Advanced.php index f037dcef9..a3a688f7c 100644 --- a/app/Livewire/Project/Application/Advanced.php +++ b/app/Livewire/Project/Application/Advanced.php @@ -68,7 +68,7 @@ class Advanced extends Component if ($this->application->settings->is_raw_compose_deployment_enabled) { $this->application->oldRawParser(); } else { - $this->application->oldParser(); + $this->application->parse(); } $this->application->settings->save(); $this->dispatch('success', 'Settings saved.'); diff --git a/app/Livewire/Project/Application/General.php b/app/Livewire/Project/Application/General.php index 5bfb56067..d2700f444 100644 --- a/app/Livewire/Project/Application/General.php +++ b/app/Livewire/Project/Application/General.php @@ -131,7 +131,7 @@ class General extends Component public function mount() { try { - $this->parsedServices = $this->application->oldParser(); + $this->parsedServices = $this->application->parse(); if (is_null($this->parsedServices) || empty($this->parsedServices)) { $this->dispatch('error', 'Failed to parse your docker-compose file. Please check the syntax and try again.'); @@ -204,7 +204,7 @@ class General extends Component return; } - $this->application->oldParser(); + $this->application->parse(); $this->dispatch('success', 'Docker compose file loaded.'); $this->dispatch('compose_loaded'); $this->dispatch('refreshStorages'); diff --git a/app/Livewire/Project/Shared/ScheduledTask/All.php b/app/Livewire/Project/Shared/ScheduledTask/All.php index 0df3040b8..b383e294a 100644 --- a/app/Livewire/Project/Shared/ScheduledTask/All.php +++ b/app/Livewire/Project/Shared/ScheduledTask/All.php @@ -26,7 +26,7 @@ class All extends Component $this->containerNames = $this->containerNames->merge($this->resource->databases()->pluck('name')); } elseif ($this->resource->type() == 'application') { if ($this->resource->build_pack === 'dockercompose') { - $parsed = $this->resource->oldParser(); + $parsed = $this->resource->parse(); $containers = collect(data_get($parsed, 'services'))->keys(); $this->containerNames = $containers; } else { diff --git a/app/Models/Application.php b/app/Models/Application.php index abdd339e9..d0cc34a06 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -3,8 +3,6 @@ namespace App\Models; use App\Enums\ApplicationDeploymentStatus; -use App\Enums\ProxyTypes; -use App\Jobs\ServerFilesFromServerJob; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\SoftDeletes; @@ -1088,547 +1086,7 @@ class Application extends BaseModel instant_remote_process($commands, $this->destination->server, false); } - public function newParser(int $pull_request_id = 0, ?int $preview_id = null) - { - // return newParser($this, $pull_request_id, $preview_id); - // $pullRequestId = $pull_request_id; - // $isPullRequest = $pullRequestId == 0 ? false : true; - - // $uuid = data_get($this, 'uuid'); - // $server = data_get($this, 'destination.server'); - // $compose = data_get($this, 'docker_compose_raw'); - // try { - // $yaml = Yaml::parse($compose); - // } catch (\Exception $e) { - // return; - // } - // $services = data_get($yaml, 'services', collect([])); - // $topLevel = collect([ - // 'volumes' => collect(data_get($yaml, 'volumes', [])), - // 'networks' => collect(data_get($yaml, 'networks', [])), - // 'configs' => collect(data_get($yaml, 'configs', [])), - // 'secrets' => collect(data_get($yaml, 'secrets', [])), - // ]); - - // // If there are predefined volumes, make sure they are not null - // if ($topLevel->get('volumes')->count() > 0) { - // $temp = collect([]); - // foreach ($topLevel['volumes'] as $volumeName => $volume) { - // if (is_null($volume)) { - // continue; - // } - // $temp->put($volumeName, $volume); - // } - // $topLevel['volumes'] = $temp; - // } - // // Get the base docker network - // $baseNetwork = collect([$uuid]); - // if ($isPullRequest) { - // $baseNetwork = collect(["{$uuid}-{$pullRequestId}"]); - // } - // $parsedServices = collect([]); - // $fileStorages = $this->fileStorages(); - // // Let's loop through the services - // foreach ($services as $serviceName => $service) { - // $image = data_get_str($service, 'image'); - // $restart = data_get_str($service, 'restart', RESTART_MODE); - // $logging = data_get($service, 'logging'); - - // if ($server->isLogDrainEnabled() && $this->isLogDrainEnabled()) { - // $logging = [ - // 'driver' => 'fluentd', - // 'options' => [ - // 'fluentd-address' => 'tcp://127.0.0.1:24224', - // 'fluentd-async' => 'true', - // 'fluentd-sub-second-precision' => 'true', - // ], - // ]; - // } - - // $volumes = collect(data_get($service, 'volumes', [])); - // $networks = collect(data_get($service, 'networks', [])); - // $depends_on = collect(data_get($service, 'depends_on', [])); - // $labels = collect(data_get($service, 'labels', [])); - // $environment = collect(data_get($service, 'environment', [])); - // $buildArgs = collect(data_get($service, 'build.args', [])); - // $environment = $environment->merge($buildArgs); - - // $baseName = generateApplicationContainerName( - // application: $this, - // pull_request_id: $pullRequestId - // ); - // $containerName = "$serviceName-$baseName"; - // $volumesParsed = collect([]); - - // if ($volumes->count() > 0) { - // foreach ($volumes as $index => $volume) { - // $type = null; - // $source = null; - // $target = null; - // $content = null; - // $isDirectory = false; - // if (is_string($volume)) { - // $source = str($volume)->before(':'); - // $target = str($volume)->after(':')->beforeLast(':'); - // $foundConfig = $fileStorages->whereMountPath($target)->first(); - // if (sourceIsLocal($source)) { - // $type = str('bind'); - // if ($foundConfig) { - // $contentNotNull_temp = data_get($foundConfig, 'content'); - // if ($contentNotNull_temp) { - // $content = $contentNotNull_temp; - // } - // $isDirectory = data_get($foundConfig, 'is_directory'); - // } else { - // // By default, we cannot determine if the bind is a directory or not, so we set it to directory - // $isDirectory = true; - // } - // } else { - // $type = str('volume'); - // } - // } elseif (is_array($volume)) { - // $type = data_get_str($volume, 'type'); - // $source = data_get_str($volume, 'source'); - // $target = data_get_str($volume, 'target'); - // $content = data_get($volume, 'content'); - // $isDirectory = (bool) data_get($volume, 'isDirectory', null) || (bool) data_get($volume, 'is_directory', null); - - // $foundConfig = $fileStorages->whereMountPath($target)->first(); - // if ($foundConfig) { - // $contentNotNull_temp = data_get($foundConfig, 'content'); - // if ($contentNotNull_temp) { - // $content = $contentNotNull_temp; - // } - // $isDirectory = data_get($foundConfig, 'is_directory'); - // } else { - // // if isDirectory is not set (or false) & content is also not set, we assume it is a directory - // if ((is_null($isDirectory) || ! $isDirectory) && is_null($content)) { - // $isDirectory = true; - // } - // } - // } - // if ($type->value() === 'bind') { - // if ($source->value() === '/var/run/docker.sock') { - // return $volume; - // } - // if ($source->value() === '/tmp' || $source->value() === '/tmp/') { - // return $volume; - // } - // $mainDirectory = str(base_configuration_dir().'/applications/'.$uuid); - // $source = replaceLocalSource($source, $mainDirectory); - // if ($isPullRequest) { - // $source = $source."-pr-$pullRequestId"; - // } - // if ( - // ! $this?->settings?->is_preserve_repository_enabled || $foundConfig?->is_based_on_git - // ) { - // LocalFileVolume::updateOrCreate( - // [ - // 'mount_path' => $target, - // 'resource_id' => $this->id, - // 'resource_type' => get_class($this), - // ], - // [ - // 'fs_path' => $source, - // 'mount_path' => $target, - // 'content' => $content, - // 'is_directory' => $isDirectory, - // 'resource_id' => $this->id, - // 'resource_type' => get_class($this), - // ] - // ); - // } - // $volume = "$source:$target"; - // } elseif ($type->value() === 'volume') { - // if ($topLevel->get('volumes')->has($source->value())) { - // $temp = $topLevel->get('volumes')->get($source->value()); - // if (data_get($temp, 'driver_opts.type') === 'cifs') { - // return $volume; - // } - // if (data_get($temp, 'driver_opts.type') === 'nfs') { - // return $volume; - // } - // } - // $slugWithoutUuid = Str::slug($source, '-'); - // $name = "{$uuid}_{$slugWithoutUuid}"; - // if ($isPullRequest) { - // $name = "{$name}-pr-$pullRequestId"; - // } - // if (is_string($volume)) { - // $source = str($volume)->before(':'); - // $target = str($volume)->after(':')->beforeLast(':'); - // $source = $name; - // $volume = "$source:$target"; - // } elseif (is_array($volume)) { - // data_set($volume, 'source', $name); - // } - // $topLevel->get('volumes')->put($name, [ - // 'name' => $name, - // ]); - - // LocalPersistentVolume::updateOrCreate( - // [ - // 'mount_path' => $target, - // 'resource_id' => $this->id, - // 'resource_type' => get_class($this), - // ], - // [ - // 'name' => $name, - // 'mount_path' => $target, - // 'resource_id' => $this->id, - // 'resource_type' => get_class($this), - // ] - // ); - // } - // dispatch(new ServerFilesFromServerJob($this)); - // $volumesParsed->put($index, $volume); - // } - // } - - // if ($depends_on?->count() > 0) { - // if ($isPullRequest) { - // $newDependsOn = collect([]); - // $depends_on->each(function ($dependency, $condition) use ($pullRequestId, $newDependsOn) { - // if (is_numeric($condition)) { - // $dependency = "$dependency-pr-$pullRequestId"; - - // $newDependsOn->put($condition, $dependency); - // } else { - // $condition = "$condition-pr-$pullRequestId"; - // $newDependsOn->put($condition, $dependency); - // } - // }); - // $depends_on = $newDependsOn; - // } - - // } - // if ($topLevel->get('networks')?->count() > 0) { - // foreach ($topLevel->get('networks') as $networkName => $network) { - // if ($networkName === 'default') { - // continue; - // } - // // ignore aliases - // if ($network['aliases'] ?? false) { - // continue; - // } - // $networkExists = $networks->contains(function ($value, $key) use ($networkName) { - // return $value == $networkName || $key == $networkName; - // }); - // if (! $networkExists) { - // $networks->put($networkName, null); - // } - // } - // } - // $baseNetworkExists = $networks->contains(function ($value, $_) use ($baseNetwork) { - // return $value == $baseNetwork; - // }); - // if (! $baseNetworkExists) { - // foreach ($baseNetwork as $network) { - // $topLevel->get('networks')->put($network, [ - // 'name' => $network, - // 'external' => true, - // ]); - // } - // } - // $networks_temp = collect(); - - // foreach ($networks as $key => $network) { - // if (gettype($network) === 'string') { - // // networks: - // // - appwrite - // $networks_temp->put($network, null); - // } elseif (gettype($network) === 'array') { - // // networks: - // // default: - // // ipv4_address: 192.168.203.254 - // $networks_temp->put($key, $network); - // } - // } - // foreach ($baseNetwork as $key => $network) { - // $networks_temp->put($network, null); - // } - - // if (data_get($this, 'settings.connect_to_docker_network')) { - // $network = $this->destination->network; - // $networks_temp->put($network, null); - // $topLevel->get('networks')->put($network, [ - // 'name' => $network, - // 'external' => true, - // ]); - // } - - // foreach ($environment as $key => $value) { - // if (is_numeric($key)) { - // if (is_array($value)) { - // // - SESSION_SECRET: 123 - // // - SESSION_SECRET: - // $key = str(collect($value)->keys()->first()); - // $value = str(collect($value)->values()->first()); - // } else { - // $variable = str($value); - // if ($variable->contains('=')) { - // // - SESSION_SECRET=123 - // // - SESSION_SECRET= - // $key = $variable->before('='); - // $value = $variable->after('='); - // } else { - // // - SESSION_SECRET - // $key = $variable; - // $value = null; - // } - // } - // } else { - // // SESSION_SECRET: 123 - // // SESSION_SECRET: - // $key = str($key); - // $value = str($value); - // } - - // // Auto generate FQDN and URL - // if ($key->startsWith('SERVICE_FQDN') || $value->startsWith('$SERVICE_FQDN') || $value->startsWith('${SERVICE_FQDN')) { - // if ($value->contains('SERVICE_FQDN')) { - // $key = str(replaceVariables($value)); - // $value = null; - // } - // $name = $key->after('SERVICE_FQDN_')->beforeLast('_')->lower(); - // $fqdn = generateFqdn($server, "{$name->value()}-{$uuid}"); - - // $url = str($fqdn)->replace('http://', '')->replace('https://', '')->replace('www.', ''); - // $keyUrl = $key->replace('SERVICE_FQDN', 'SERVICE_URL'); - // // TODO: is this needed? - // // if (substr_count($key->value(), '_') === 3) { - // // // SERVICE_FQDN_UMAMI_1000 - // // $port = $key->afterLast('_'); - // // } else { - // // // SERVICE_FQDN_UMAMI - // // $port = null; - // // } - // // if ($port) { - // // $fqdn = "$fqdn:$port"; - // // } - // if ($value && get_class($value) === 'Illuminate\Support\Stringable') { - // $path = $value->value(); - // $fqdn = "$fqdn$path"; - // } - - // // ray([ - // // 'key' => $key, - // // 'value' => $fqdn, - // // ]); - // // ray($this->environment_variables()->where('key', $key)->where('application_id', $this->id)->first()); - // $this->environment_variables()->where('key', $key)->where('application_id', $this->id)->firstOrCreate([ - // 'key' => $key, - // 'application_id' => $this->id, - // ], [ - // 'value' => $fqdn, - // 'is_build_time' => false, - // 'is_preview' => false, - // ]); - // $this->environment_variables()->where('key', $keyUrl)->where('application_id', $this->id)->firstOrCreate([ - // 'key' => $keyUrl, - // 'application_id' => $this->id, - // ], [ - // 'value' => $url, - // 'is_build_time' => false, - // 'is_preview' => false, - // ]); - // } elseif ($value->startsWith('$')) { - // // If the value is a variable then we will add it to Coolify's DB - - // // ${VARIABLE} will be VARIABLE instead - // $value = str(replaceVariables($value)); - // if ($value->contains(':-')) { - // $key = $value->before(':'); - // $defaultValue = $value->after(':-'); - // } elseif ($value->contains('-')) { - // $key = $value->before('-'); - // $defaultValue = $value->after('-'); - // } elseif ($value->contains(':?')) { - // $key = $value->before(':'); - // $defaultValue = $value->after(':?'); - // } elseif ($value->contains('?')) { - // $key = $value->before('?'); - // $defaultValue = $value->after('?'); - // } else { - // $key = $value; - // $defaultValue = null; - // } - // $this->environment_variables()->where('key', $key)->where('application_id', $this->id)->firstOrCreate([ - // 'key' => $key, - // 'application_id' => $this->id, - // 'is_preview' => false, - // ], [ - // 'value' => $defaultValue, - // 'is_build_time' => false, - // 'is_preview' => false, - // ]); - // } - // } - // $branch = $this->git_branch; - // if ($pullRequestId !== 0) { - // $branch = "pull/{$pullRequestId}/head"; - // } - // if ($this->environment_variables->where('key', 'COOLIFY_BRANCH')->isEmpty()) { - // $environment->put('COOLIFY_BRANCH', $branch); - // } - - // if ($this->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) { - // $environment->put('COOLIFY_CONTAINER_NAME', $containerName); - // } - // // Remove SERVICE_FQDN and SERVICE_URL from environment - // $environment = $environment->filter(function ($value, $key) { - // return ! str($key)->startsWith('SERVICE_FQDN') && ! str($key)->startsWith('SERVICE_URL'); - // }); - - // // Labels - // $fqdns = collect([]); - - // $domains = collect(json_decode($this->docker_compose_domains)) ?? collect([]); - // if ($domains->count() !== 0) { - // $fqdns = data_get($domains, "$serviceName.domain"); - // if (! $fqdns) { - // $fqdns = collect([]); - // } else { - // $fqdns = str($fqdns)->explode(','); - // if ($isPullRequest) { - // $preview = $this->previews()->find($preview_id); - // $docker_compose_domains = collect(json_decode(data_get($preview, 'docker_compose_domains'))); - // if ($docker_compose_domains->count() > 0) { - // $found_fqdn = data_get($docker_compose_domains, "$serviceName.domain"); - // if ($found_fqdn) { - // $fqdns = collect($found_fqdn); - // } else { - // $fqdns = collect([]); - // } - // } else { - // $fqdns = $fqdns->map(function ($fqdn) use ($pullRequestId) { - // $preview = ApplicationPreview::findPreviewByApplicationAndPullId($this->id, $pullRequestId); - // $url = Url::fromString($fqdn); - // $template = $this->preview_url_template; - // $host = $url->getHost(); - // $schema = $url->getScheme(); - // $random = new Cuid2; - // $preview_fqdn = str_replace('{{random}}', $random, $template); - // $preview_fqdn = str_replace('{{domain}}', $host, $preview_fqdn); - // $preview_fqdn = str_replace('{{pr_id}}', $pullRequestId, $preview_fqdn); - // $preview_fqdn = "$schema://$preview_fqdn"; - // $preview->fqdn = $preview_fqdn; - // $preview->save(); - - // return $preview_fqdn; - // }); - // } - // } - // $shouldGenerateLabelsExactly = $server->settings->generate_exact_labels; - // if ($shouldGenerateLabelsExactly) { - // switch ($server->proxyType()) { - // case ProxyTypes::TRAEFIK->value: - // $labels = $labels->merge( - // fqdnLabelsForTraefik( - // uuid: $this->uuid, - // domains: $fqdns, - // serviceLabels: $labels, - // generate_unique_uuid: $this->build_pack === 'dockercompose', - // image: $image, - // is_force_https_enabled: $this->isForceHttpsEnabled(), - // is_gzip_enabled: $this->isGzipEnabled(), - // is_stripprefix_enabled: $this->isStripprefixEnabled(), - // ) - // ); - // break; - // case ProxyTypes::CADDY->value: - // $labels = $labels->merge( - // fqdnLabelsForCaddy( - // network: $this->destination->network, - // uuid: $this->uuid, - // domains: $fqdns, - // serviceLabels: $labels, - // image: $image, - // is_force_https_enabled: $this->isForceHttpsEnabled(), - // is_gzip_enabled: $this->isGzipEnabled(), - // is_stripprefix_enabled: $this->isStripprefixEnabled(), - // ) - // ); - // break; - // } - // } else { - // $labels = $labels->merge( - // fqdnLabelsForTraefik( - // uuid: $this->uuid, - // domains: $fqdns, - // serviceLabels: $labels, - // generate_unique_uuid: $this->build_pack === 'dockercompose', - // image: $image, - // is_force_https_enabled: $this->isForceHttpsEnabled(), - // is_gzip_enabled: $this->isGzipEnabled(), - // is_stripprefix_enabled: $this->isStripprefixEnabled(), - // ) - // ); - // $labels = $labels->merge( - // fqdnLabelsForCaddy( - // network: $this->destination->network, - // uuid: $this->uuid, - // domains: $fqdns, - // serviceLabels: $labels, - // image: $image, - // is_force_https_enabled: $this->isForceHttpsEnabled(), - // is_gzip_enabled: $this->isGzipEnabled(), - // is_stripprefix_enabled: $this->isStripprefixEnabled(), - // ) - // ); - // } - // } - // } - - // $defaultLabels = defaultLabels( - // id: $this->id, - // name: $containerName, - // pull_request_id: $pullRequestId, - // type: 'application'); - // $labels = $labels->merge($defaultLabels); - - // if ($labels->count() > 0 && $this->settings->is_container_label_escape_enabled) { - // $labels = $labels->map(function ($value, $key) { - // return escapeDollarSign($value); - // }); - // } - // $payload = collect($service)->merge([ - // 'restart' => $restart->value(), - // 'container_name' => $containerName, - // 'volumes' => $volumesParsed, - // 'networks' => $networks_temp, - // 'labels' => $labels, - // 'environment' => $environment, - // ]); - - // if ($logging) { - // $payload['logging'] = $logging; - // } - // if ($depends_on->count() > 0) { - // $payload['depends_on'] = $depends_on; - // } - // if ($isPullRequest) { - // $serviceName = "{$serviceName}-pr-{$pullRequestId}"; - // } - // $parsedServices->put($serviceName, $payload); - - // } - - // $topLevel->put('services', $parsedServices); - // $customOrder = ['services', 'volumes', 'networks', 'configs', 'secrets']; - - // $topLevel = $topLevel->sortBy(function ($value, $key) use ($customOrder) { - // return array_search($key, $customOrder); - // }); - // $this->docker_compose = Yaml::dump(convertToArray($topLevel), 10, 2); - // data_forget($this, 'environment_variables'); - // data_forget($this, 'environment_variables_preview'); - // $this->save(); - - // return $topLevel; - } - - public function oldParser(int $pull_request_id = 0, ?int $preview_id = null) + public function parse(int $pull_request_id = 0, ?int $preview_id = null) { if ($this->compose_parsing_version === '3') { return newParser($this, $pull_request_id, $preview_id); @@ -1684,7 +1142,7 @@ class Application extends BaseModel if ($composeFileContent) { $this->docker_compose_raw = $composeFileContent; $this->save(); - $parsedServices = $this->oldParser(); + $parsedServices = $this->parse(); if ($this->docker_compose_domains) { $json = collect(json_decode($this->docker_compose_domains)); $names = collect(data_get($parsedServices, 'services'))->keys()->toArray(); diff --git a/app/Models/ApplicationPreview.php b/app/Models/ApplicationPreview.php index abf402377..04a0ab27e 100644 --- a/app/Models/ApplicationPreview.php +++ b/app/Models/ApplicationPreview.php @@ -14,7 +14,7 @@ class ApplicationPreview extends BaseModel static::deleting(function ($preview) { if (data_get($preview, 'application.build_pack') === 'dockercompose') { $server = $preview->application->destination->server; - $composeFile = newParser($preview->application, pull_request_id: $preview->pull_request_id); + $composeFile = $preview->application->parse(pull_request_id: $preview->pull_request_id); $volumes = data_get($composeFile, 'volumes'); $networks = data_get($composeFile, 'networks'); $networkKeys = collect($networks)->keys(); diff --git a/app/Models/Service.php b/app/Models/Service.php index a1ff4e90b..e55c0bea5 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -2,14 +2,11 @@ namespace App\Models; -use App\Enums\ProxyTypes; -use App\Jobs\ServerFilesFromServerJob; use Illuminate\Database\Eloquent\Casts\Attribute; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Relations\HasMany; use Illuminate\Database\Eloquent\SoftDeletes; use Illuminate\Support\Collection; -use Illuminate\Support\Str; use OpenApi\Attributes as OA; use Spatie\Url\Url; use Symfony\Component\Yaml\Yaml; @@ -1022,532 +1019,6 @@ class Service extends BaseModel instant_remote_process($commands, $this->server); } - public function newParser() - { - // $uuid = data_get($this, 'uuid'); - // $server = data_get($this, 'destination.server'); - // $compose = data_get($this, 'docker_compose_raw'); - // try { - // $yaml = Yaml::parse($compose); - // } catch (\Exception $e) { - // return; - // } - // $allServices = get_service_templates(); - // $services = data_get($yaml, 'services', collect([])); - // $topLevel = collect([ - // 'volumes' => collect(data_get($yaml, 'volumes', [])), - // 'networks' => collect(data_get($yaml, 'networks', [])), - // 'configs' => collect(data_get($yaml, 'configs', [])), - // 'secrets' => collect(data_get($yaml, 'secrets', [])), - // ]); - // // If there are predefined volumes, make sure they are not null - // if ($topLevel->get('volumes')->count() > 0) { - // $temp = collect([]); - // foreach ($topLevel['volumes'] as $volumeName => $volume) { - // if (is_null($volume)) { - // continue; - // } - // $temp->put($volumeName, $volume); - // } - // $topLevel['volumes'] = $temp; - // } - // // Get the base docker network - // $baseNetwork = collect([$uuid]); - // $parsedServices = collect([]); - - // // Let's loop through the services - // foreach ($services as $serviceName => $service) { - // if ($serviceName === 'registry') { - // $tempServiceName = 'docker-registry'; - // } else { - // $tempServiceName = $serviceName; - // } - // if (str(data_get($service, 'image'))->contains('glitchtip')) { - // $tempServiceName = 'glitchtip'; - // } - // if ($serviceName === 'supabase-kong') { - // $tempServiceName = 'supabase'; - // } - // $serviceDefinition = data_get($allServices, $tempServiceName); - // $predefinedPort = data_get($serviceDefinition, 'port'); - // if ($serviceName === 'plausible') { - // $predefinedPort = '8000'; - // } - // $image = data_get_str($service, 'image'); - // $restart = data_get_str($service, 'restart', RESTART_MODE); - // $logging = data_get($service, 'logging'); - - // if ($server->isLogDrainEnabled() && $this->isLogDrainEnabled()) { - // $logging = [ - // 'driver' => 'fluentd', - // 'options' => [ - // 'fluentd-address' => 'tcp://127.0.0.1:24224', - // 'fluentd-async' => 'true', - // 'fluentd-sub-second-precision' => 'true', - // ], - // ]; - // } - - // $volumes = collect(data_get($service, 'volumes', [])); - // $networks = collect(data_get($service, 'networks', [])); - // $labels = collect(data_get($service, 'labels', [])); - // $environment = collect(data_get($service, 'environment', [])); - // $buildArgs = collect(data_get($service, 'build.args', [])); - // $environment = $environment->merge($buildArgs); - // $hasHostNetworkMode = data_get($service, 'network_mode') === 'host' ? true : false; - - // $containerName = "$serviceName-{$this->uuid}"; - // $isDatabase = isDatabaseImage(data_get_str($service, 'image')); - // $volumesParsed = collect([]); - - // if ($isDatabase) { - // $savedService = ServiceDatabase::firstOrCreate([ - // 'name' => $serviceName, - // 'image' => $image, - // 'service_id' => $this->id, - // ]); - // } else { - // $savedService = ServiceApplication::firstOrCreate([ - // 'name' => $serviceName, - // 'image' => $image, - // 'service_id' => $this->id, - // ]); - // } - // $fileStorages = $savedService->fileStorages(); - - // // Check if image changed - // if ($savedService->image !== $image) { - // $savedService->image = $image; - // $savedService->save(); - // } - // if ($volumes->count() > 0) { - // foreach ($volumes as $index => $volume) { - // $type = null; - // $source = null; - // $target = null; - // $content = null; - // $isDirectory = false; - // if (is_string($volume)) { - // $source = str($volume)->before(':'); - // $target = str($volume)->after(':')->beforeLast(':'); - // $foundConfig = $fileStorages->whereMountPath($target)->first(); - // if (sourceIsLocal($source)) { - // $type = str('bind'); - // if ($foundConfig) { - // $contentNotNull_temp = data_get($foundConfig, 'content'); - // if ($contentNotNull_temp) { - // $content = $contentNotNull_temp; - // } - // $isDirectory = data_get($foundConfig, 'is_directory'); - // } else { - // // By default, we cannot determine if the bind is a directory or not, so we set it to directory - // $isDirectory = true; - // } - // } else { - // $type = str('volume'); - // } - // } elseif (is_array($volume)) { - // $type = data_get_str($volume, 'type'); - // $source = data_get_str($volume, 'source'); - // $target = data_get_str($volume, 'target'); - // $content = data_get($volume, 'content'); - // $isDirectory = (bool) data_get($volume, 'isDirectory', null) || (bool) data_get($volume, 'is_directory', null); - - // $foundConfig = $fileStorages->whereMountPath($target)->first(); - // if ($foundConfig) { - // $contentNotNull_temp = data_get($foundConfig, 'content'); - // if ($contentNotNull_temp) { - // $content = $contentNotNull_temp; - // } - // $isDirectory = data_get($foundConfig, 'is_directory'); - // } else { - // // if isDirectory is not set (or false) & content is also not set, we assume it is a directory - // if ((is_null($isDirectory) || ! $isDirectory) && is_null($content)) { - // $isDirectory = true; - // } - // } - // } - // if ($type->value() === 'bind') { - // if ($source->value() === '/var/run/docker.sock') { - // return $volume; - // } - // if ($source->value() === '/tmp' || $source->value() === '/tmp/') { - // return $volume; - // } - // $mainDirectory = str(base_configuration_dir().'/applications/'.$uuid); - // $source = replaceLocalSource($source, $mainDirectory); - - // LocalFileVolume::updateOrCreate( - // [ - // 'mount_path' => $target, - // 'resource_id' => $savedService->id, - // 'resource_type' => get_class($savedService), - // ], - // [ - // 'fs_path' => $source, - // 'mount_path' => $target, - // 'content' => $content, - // 'is_directory' => $isDirectory, - // 'resource_id' => $savedService->id, - // 'resource_type' => get_class($savedService), - // ] - // ); - // $volume = "$source:$target"; - // } elseif ($type->value() === 'volume') { - // if ($topLevel->get('volumes')->has($source->value())) { - // $temp = $topLevel->get('volumes')->get($source->value()); - // if (data_get($temp, 'driver_opts.type') === 'cifs') { - // return $volume; - // } - // if (data_get($temp, 'driver_opts.type') === 'nfs') { - // return $volume; - // } - // } - // $slugWithoutUuid = Str::slug($source, '-'); - // $name = "{$uuid}_{$slugWithoutUuid}"; - // if (is_string($volume)) { - // $source = str($volume)->before(':'); - // $target = str($volume)->after(':')->beforeLast(':'); - // $source = $name; - // $volume = "$source:$target"; - // } elseif (is_array($volume)) { - // data_set($volume, 'source', $name); - // } - // $topLevel->get('volumes')->put($name, [ - // 'name' => $name, - // ]); - - // LocalPersistentVolume::updateOrCreate( - // [ - // 'mount_path' => $target, - // 'resource_id' => $savedService->id, - // 'resource_type' => get_class($savedService), - // ], - // [ - // 'name' => $name, - // 'mount_path' => $target, - // 'resource_id' => $savedService->id, - // 'resource_type' => get_class($savedService), - // ] - // ); - // } - // dispatch(new ServerFilesFromServerJob($savedService)); - // $volumesParsed->put($index, $volume); - // } - // } - // if ($topLevel->get('networks')?->count() > 0) { - // foreach ($topLevel->get('networks') as $networkName => $network) { - // if ($networkName === 'default') { - // continue; - // } - // // ignore aliases - // if ($network['aliases'] ?? false) { - // continue; - // } - // $networkExists = $networks->contains(function ($value, $key) use ($networkName) { - // return $value == $networkName || $key == $networkName; - // }); - // if (! $networkExists) { - // $networks->put($networkName, null); - // } - // } - // } - // $baseNetworkExists = $networks->contains(function ($value, $_) use ($baseNetwork) { - // return $value == $baseNetwork; - // }); - // if (! $baseNetworkExists) { - // foreach ($baseNetwork as $network) { - // $topLevel->get('networks')->put($network, [ - // 'name' => $network, - // 'external' => true, - // ]); - // } - // } - // $networks_temp = collect(); - - // foreach ($networks as $key => $network) { - // if (gettype($network) === 'string') { - // // networks: - // // - appwrite - // $networks_temp->put($network, null); - // } elseif (gettype($network) === 'array') { - // // networks: - // // default: - // // ipv4_address: 192.168.203.254 - // $networks_temp->put($key, $network); - // } - // } - // foreach ($baseNetwork as $key => $network) { - // $networks_temp->put($network, null); - // } - - // // Convert - // // - SESSION_SECRET: 123 to - SESSION_SECRET=123 - // $convertedServiceVariables = collect([]); - // foreach ($environment as $variableName => $variable) { - // if (is_numeric($variableName)) { - // if (is_array($variable)) { - // $key = str(collect($variable)->keys()->first()); - // $value = str(collect($variable)->values()->first()); - // $variable = "$key=$value"; - // $convertedServiceVariables->put($variableName, $variable); - // } elseif (is_string($variable)) { - // $convertedServiceVariables->put($variableName, $variable); - // } - // } elseif (is_string($variableName)) { - // $convertedServiceVariables->put($variableName, $variable); - // } - // } - // $environment = $convertedServiceVariables; - - // // filter magic environments - // $magicEnvironments = $environment->filter(function ($value, $key) { - // return str($key)->startsWith('SERVICE_FQDN') || str($key)->startsWith('SERVICE_URL') || str($value)->startsWith('SERVICE_FQDN') || str($value)->startsWith('SERVICE_URL'); - // }); - // if ($magicEnvironments->count() > 0) { - // foreach ($magicEnvironments as $key => $value) { - // $key = str($key); - // $value = str($value); - // $command = $key->after('SERVICE_')->beforeLast('_'); - // if ($command->value() === 'FQDN') { - // $fqdn = generateFqdn($server, "{$savedService->name}-{$uuid}"); - // if ($value && get_class($value) === 'Illuminate\Support\Stringable' && $value->startsWith('/')) { - // $path = $value->value(); - // $value = "$fqdn$path"; - // } else { - // $value = $fqdn; - // } - // } elseif ($command->value() === 'URL') { - // $fqdn = generateFqdn($server, "{$savedService->name}-{$uuid}"); - // $value = str($fqdn)->replace('http://', '')->replace('https://', '')->replace('www.', ''); - // } - // if (! $isDatabase && ! $this->environment_variables()->where('key', $key)->where('service_id', $this->id)->first()) { - // $savedService->fqdn = $value; - // $savedService->save(); - // } - // $this->environment_variables()->where('key', $key)->where('service_id', $this->id)->firstOrCreate([ - // 'key' => $key, - // 'service_id' => $this->id, - // ], [ - // 'value' => $value, - // 'is_build_time' => false, - // 'is_preview' => false, - // ]); - // } - // } - // foreach ($environment as $key => $value) { - // if (is_numeric($key)) { - // if (is_array($value)) { - // // - SESSION_SECRET: 123 - // // - SESSION_SECRET: - // $key = str(collect($value)->keys()->first()); - // $value = str(collect($value)->values()->first()); - // } else { - // $variable = str($value); - // if ($variable->contains('=')) { - // // - SESSION_SECRET=123 - // // - SESSION_SECRET= - // $key = $variable->before('='); - // $value = $variable->after('='); - // } else { - // // - SESSION_SECRET - // $key = $variable; - // $value = null; - // } - // } - // } else { - // // SESSION_SECRET: 123 - // // SESSION_SECRET: - // $key = str($key); - // $value = str($value); - // } - - // // Auto generate FQDN and URL - // // environment: - // // - SERVICE_FQDN_UMAMI=/umami - // // - FQDN=$SERVICE_FQDN_UMAMI - // // - URL=$SERVICE_URL_UMAMI - // // - TEST=${TEST:-initial} - // // - HARDCODED=stuff - - // if ($value->startsWith('$')) { - // $value = str(replaceVariables($value)); - // if ($value->startsWith('SERVICE_')) { - // // $value = SERVICE_FQDN_UMAMI - // $command = $value->after('SERVICE_')->beforeLast('_'); - // if ($command->value() === 'FQDN') { - // if ($magicEnvironments->has($value->value())) { - // $found = $magicEnvironments->get($value->value()); - // if ($found) { - // $found = $this->environment_variables()->where('key', $value->value())->where('service_id', $this->id)->first(); - // if ($found) { - // $value = $found->value; - // } - // } - // } else { - // $fqdn = generateFqdn($server, "{$savedService->name}-{$uuid}"); - // if ($value && get_class($value) === 'Illuminate\Support\Stringable' && $value->startsWith('/')) { - // $path = $value->value(); - // $value = "$fqdn$path"; - // } else { - // $value = $fqdn; - // } - // } - // } elseif ($command->value() === 'URL') { - // if ($magicEnvironments->has($value->value())) { - // $found = $magicEnvironments->get($value->value()); - // if ($found) { - // $found = $this->environment_variables()->where('key', $value->value())->where('service_id', $this->id)->first(); - // if ($found) { - // $value = str($found->value)->replace('http://', '')->replace('https://', '')->replace('www.', ''); - // } - // } - // } else { - // $fqdn = generateFqdn($server, "{$savedService->name}-{$uuid}"); - // $value = str($fqdn)->replace('http://', '')->replace('https://', '')->replace('www.', ''); - // } - // } else { - // $value = generateEnvValue($command, $this); - // } - // $this->environment_variables()->where('key', $key)->where('service_id', $this->id)->firstOrCreate([ - // 'key' => $key, - // 'service_id' => $this->id, - // ], [ - // 'value' => $value, - // 'is_build_time' => false, - // 'is_preview' => false, - // ]); - // } else { - // if ($value->contains(':-')) { - // $key = $value->before(':'); - // $value = $value->after(':-'); - // } elseif ($value->contains('-')) { - // $key = $value->before('-'); - // $value = $value->after('-'); - // } elseif ($value->contains(':?')) { - // $key = $value->before(':'); - // $value = $value->after(':?'); - // } elseif ($value->contains('?')) { - // $key = $value->before('?'); - // $value = $value->after('?'); - // } else { - // $key = $value; - // $value = null; - // } - // $this->environment_variables()->where('key', $key)->where('service_id', $this->id)->firstOrCreate([ - // 'key' => $key, - // 'service_id' => $this->id, - // ], [ - // 'value' => $value, - // 'is_build_time' => false, - // 'is_preview' => false, - // ]); - // } - // } - - // if ($this->environment_variables->where('key', 'COOLIFY_CONTAINER_NAME')->isEmpty()) { - // $environment->put('COOLIFY_CONTAINER_NAME', $containerName); - // } - // // Remove SERVICE_FQDN and SERVICE_URL from environment - // $environment = $environment->filter(function ($value, $key) { - // return ! str($key)->startsWith('SERVICE_FQDN') && ! str($key)->startsWith('SERVICE_URL'); - // }); - - // } - // if ($savedService->serviceType()) { - // $fqdns = generateServiceSpecificFqdns($savedService); - // } else { - // $fqdns = collect(data_get($savedService, 'fqdns'))->filter(); - // } - // $defaultLabels = defaultLabels($this->id, $containerName, type: 'service', subType: $isDatabase ? 'database' : 'application', subId: $savedService->id); - // $serviceLabels = $labels->merge($defaultLabels); - // if (! $isDatabase && $fqdns->count() > 0) { - // if ($fqdns) { - // $shouldGenerateLabelsExactly = $this->server->settings->generate_exact_labels; - // if ($shouldGenerateLabelsExactly) { - // switch ($this->server->proxyType()) { - // case ProxyTypes::TRAEFIK->value: - // $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik( - // uuid: $this->uuid, - // domains: $fqdns, - // is_force_https_enabled: true, - // serviceLabels: $serviceLabels, - // is_gzip_enabled: $savedService->isGzipEnabled(), - // is_stripprefix_enabled: $savedService->isStripprefixEnabled(), - // service_name: $serviceName, - // image: data_get($service, 'image') - // )); - // break; - // case ProxyTypes::CADDY->value: - // $serviceLabels = $serviceLabels->merge(fqdnLabelsForCaddy( - // network: $this->destination->network, - // uuid: $this->uuid, - // domains: $fqdns, - // is_force_https_enabled: true, - // serviceLabels: $serviceLabels, - // is_gzip_enabled: $savedService->isGzipEnabled(), - // is_stripprefix_enabled: $savedService->isStripprefixEnabled(), - // service_name: $serviceName, - // image: data_get($service, 'image') - // )); - // break; - // } - // } else { - // $serviceLabels = $serviceLabels->merge(fqdnLabelsForTraefik( - // uuid: $this->uuid, - // domains: $fqdns, - // is_force_https_enabled: true, - // serviceLabels: $serviceLabels, - // is_gzip_enabled: $savedService->isGzipEnabled(), - // is_stripprefix_enabled: $savedService->isStripprefixEnabled(), - // service_name: $serviceName, - // image: data_get($service, 'image') - // )); - // $serviceLabels = $serviceLabels->merge(fqdnLabelsForCaddy( - // network: $this->destination->network, - // uuid: $this->uuid, - // domains: $fqdns, - // is_force_https_enabled: true, - // serviceLabels: $serviceLabels, - // is_gzip_enabled: $savedService->isGzipEnabled(), - // is_stripprefix_enabled: $savedService->isStripprefixEnabled(), - // service_name: $serviceName, - // image: data_get($service, 'image') - // )); - // } - // } - // } - // $payload = collect($service)->merge([ - // 'restart' => $restart->value(), - // 'container_name' => $containerName, - // 'volumes' => $volumesParsed, - // 'networks' => $networks_temp, - // 'labels' => $serviceLabels, - // 'environment' => $environment, - // ]); - - // if ($logging) { - // $payload['logging'] = $logging; - // } - - // $parsedServices->put($serviceName, $payload); - // } - - // $topLevel->put('services', $parsedServices); - // $customOrder = ['services', 'volumes', 'networks', 'configs', 'secrets']; - - // $topLevel = $topLevel->sortBy(function ($value, $key) use ($customOrder) { - // return array_search($key, $customOrder); - // }); - // $this->docker_compose = Yaml::dump(convertToArray($topLevel), 10, 2); - // data_forget($this, 'environment_variables'); - // data_forget($this, 'environment_variables_preview'); - // $this->save(); - - // return $topLevel; - - } - public function parse(bool $isNew = false): Collection { if ($this->compose_parsing_version === '3') { diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index aff9e0ab7..d86cbf65a 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -3267,19 +3267,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int } else { $value = $fqdn; } - if (! $isDatabase) { - if ($isApplication && is_null($resource->fqdn)) { - data_forget($resource, 'environment_variables'); - data_forget($resource, 'environment_variables_preview'); - $resource->fqdn = $value; - $resource->save(); - } elseif ($isService && is_null($savedService->fqdn)) { - if ($key->startsWith('SERVICE_FQDN_')) { - $savedService->fqdn = $value; - $savedService->save(); - } - } - } + $value = str($fqdn)->replace('http://', '')->replace('https://', ''); } elseif ($keyCommand->value() === 'URL' || $valueCommand->value() === 'URL') { if ($isApplication) { @@ -3293,7 +3281,19 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int } else { $value = $fqdn; } - $value = str($fqdn)->replace('http://', '')->replace('https://', ''); + if (! $isDatabase) { + if ($isApplication && is_null($resource->fqdn)) { + data_forget($resource, 'environment_variables'); + data_forget($resource, 'environment_variables_preview'); + $resource->fqdn = $value; + $resource->save(); + } elseif ($isService && is_null($savedService->fqdn)) { + if ($key->startsWith('SERVICE_URL_')) { + $savedService->fqdn = $value; + $savedService->save(); + } + } + } } else { $generatedValue = generateEnvValue($valueCommand, $resource); if ($generatedValue) { @@ -3428,14 +3428,12 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int } // Add COOLIFY_FQDN & COOLIFY_URL to environment if (! $isDatabase && $fqdns?->count() > 0) { - $environment->put('COOLIFY_FQDN', $fqdns->implode(',')); - $environment->put('COOLIFY_DOMAIN_URL', $fqdns->implode(',')); + $environment->put('COOLIFY_URL', $fqdns->implode(',')); $urls = $fqdns->map(function ($fqdn) { return str($fqdn)->replace('http://', '')->replace('https://', ''); }); - $environment->put('COOLIFY_URL', $urls->implode(',')); - $environment->put('COOLIFY_DOMAIN_FQDN', $urls->implode(',')); + $environment->put('COOLIFY_FQDN', $urls->implode(',')); } $serviceLabels = $labels->merge($defaultLabels); diff --git a/tests/Feature/DockerComposeParseTest.php b/tests/Feature/DockerComposeParseTest.php index a2e97bebc..2826c7860 100644 --- a/tests/Feature/DockerComposeParseTest.php +++ b/tests/Feature/DockerComposeParseTest.php @@ -173,7 +173,7 @@ afterEach(function () { // expect($this->jsonapplicationComposeFile)->toBeJson()->ray(); // $output = $this->application->newParser(); -// $outputOld = $this->application->oldParser(); +// $outputOld = $this->application->parse(); // expect($output)->toBeInstanceOf(Collection::class); // expect($outputOld)->toBeInstanceOf(Collection::class); @@ -252,7 +252,7 @@ afterEach(function () { // expect($this->jsonapplicationComposeFile)->toBeJson()->ray(); // $output = $this->application->newParser(pull_request_id: $pullRequestId, preview_id: $previewId); -// $outputOld = $this->application->oldParser(); +// $outputOld = $this->application->parse(); // expect($output)->toBeInstanceOf(Collection::class); // expect($outputOld)->toBeInstanceOf(Collection::class);