From 1b0e2e12573187560cb3b41c76033185baa41ade Mon Sep 17 00:00:00 2001 From: MarioZet <89627138+MarioZet23@users.noreply.github.com> Date: Sun, 29 Sep 2024 20:08:39 +0200 Subject: [PATCH 1/5] Feat. Apply all middlewares from labels to coolify router, instead of only basicauth and redirect --- bootstrap/helpers/docker.php | 81 +++++++++++------------------------- 1 file changed, 24 insertions(+), 57 deletions(-) diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php index e252bda10..7e902fcdd 100644 --- a/bootstrap/helpers/docker.php +++ b/bootstrap/helpers/docker.php @@ -325,38 +325,16 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ $labels->push('traefik.http.middlewares.gzip.compress=true'); $labels->push('traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https'); - $basic_auth = false; - $basic_auth_middleware = null; - $redirect = false; - $redirect_middleware = null; + $middlewares_from_labels = collect([]); if ($serviceLabels) { - $basic_auth = $serviceLabels->contains(function ($value) { - return str_contains($value, 'basicauth'); - }); - if ($basic_auth) { - $basic_auth_middleware = $serviceLabels - ->map(function ($item) { - if (preg_match('/traefik\.http\.middlewares\.(.*?)\.basicauth\.users/', $item, $matches)) { - return $matches[1]; - } - }) - ->filter() - ->first(); - } - $redirect = $serviceLabels->contains(function ($value) { - return str_contains($value, 'redirectregex'); - }); - if ($redirect) { - $redirect_middleware = $serviceLabels - ->map(function ($item) { - if (preg_match('/traefik\.http\.middlewares\.(.*?)\.redirectregex\.regex/', $item, $matches)) { - return $matches[1]; - } - }) - ->filter() - ->first(); - } + $middlewares_from_labels = $serviceLabels->map(function ($item) { + if (preg_match('/traefik\.http\.middlewares\.(.*?)(\.|$)/', $item, $matches)) { + return $matches[1]; + } + return null; + })->filter() + ->unique(); } foreach ($domains as $loop => $domain) { try { @@ -404,20 +382,15 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ $labels->push("traefik.http.services.{$https_label}.loadbalancer.server.port=$port"); } if ($path !== '/') { + // Middleware handling $middlewares = collect([]); - if ($is_stripprefix_enabled && ! str($image)->contains('ghost')) { + if ($is_stripprefix_enabled && !str($image)->contains('ghost')) { $labels->push("traefik.http.middlewares.{$https_label}-stripprefix.stripprefix.prefixes={$path}"); $middlewares->push("{$https_label}-stripprefix"); } if ($is_gzip_enabled) { $middlewares->push('gzip'); } - if ($basic_auth && $basic_auth_middleware) { - $middlewares->push($basic_auth_middleware); - } - if ($redirect && $redirect_middleware) { - $middlewares->push($redirect_middleware); - } if (str($image)->contains('ghost')) { $middlewares->push('redir-ghost'); } @@ -425,10 +398,13 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ $labels = $labels->merge($redirect_to_non_www); $middlewares->push($to_non_www_name); } - if ($redirect_direction === 'www' && ! str($host)->startsWith('www.')) { + if ($redirect_direction === 'www' && !str($host)->startsWith('www.')) { $labels = $labels->merge($redirect_to_www); $middlewares->push($to_www_name); } + $middlewares_from_labels->each(function ($middleware_name) use ($middlewares) { + $middlewares->push($middleware_name); + }); if ($middlewares->isNotEmpty()) { $middlewares = $middlewares->join(','); $labels->push("traefik.http.routers.{$https_label}.middlewares={$middlewares}"); @@ -437,13 +413,7 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ $middlewares = collect([]); if ($is_gzip_enabled) { $middlewares->push('gzip'); - } - if ($basic_auth && $basic_auth_middleware) { - $middlewares->push($basic_auth_middleware); - } - if ($redirect && $redirect_middleware) { - $middlewares->push($redirect_middleware); - } + } if (str($image)->contains('ghost')) { $middlewares->push('redir-ghost'); } @@ -455,6 +425,9 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ $labels = $labels->merge($redirect_to_www); $middlewares->push($to_www_name); } + $middlewares_from_labels->each(function ($middleware_name) use ($middlewares) { + $middlewares->push($middleware_name); + }); if ($middlewares->isNotEmpty()) { $middlewares = $middlewares->join(','); $labels->push("traefik.http.routers.{$https_label}.middlewares={$middlewares}"); @@ -490,12 +463,6 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ if ($is_gzip_enabled) { $middlewares->push('gzip'); } - if ($basic_auth && $basic_auth_middleware) { - $middlewares->push($basic_auth_middleware); - } - if ($redirect && $redirect_middleware) { - $middlewares->push($redirect_middleware); - } if (str($image)->contains('ghost')) { $middlewares->push('redir-ghost'); } @@ -507,6 +474,9 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ $labels = $labels->merge($redirect_to_www); $middlewares->push($to_www_name); } + $middlewares_from_labels->each(function ($middleware_name) use ($middlewares) { + $middlewares->push($middleware_name); + }); if ($middlewares->isNotEmpty()) { $middlewares = $middlewares->join(','); $labels->push("traefik.http.routers.{$http_label}.middlewares={$middlewares}"); @@ -516,12 +486,6 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ if ($is_gzip_enabled) { $middlewares->push('gzip'); } - if ($basic_auth && $basic_auth_middleware) { - $middlewares->push($basic_auth_middleware); - } - if ($redirect && $redirect_middleware) { - $middlewares->push($redirect_middleware); - } if (str($image)->contains('ghost')) { $middlewares->push('redir-ghost'); } @@ -533,6 +497,9 @@ function fqdnLabelsForTraefik(string $uuid, Collection $domains, bool $is_force_ $labels = $labels->merge($redirect_to_www); $middlewares->push($to_www_name); } + $middlewares_from_labels->each(function ($middleware_name) use ($middlewares) { + $middlewares->push($middleware_name); + }); if ($middlewares->isNotEmpty()) { $middlewares = $middlewares->join(','); $labels->push("traefik.http.routers.{$http_label}.middlewares={$middlewares}"); From 8c024ddb5754957424b149e7b2ca543080b76d87 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 3 Oct 2024 22:02:18 +0200 Subject: [PATCH 2/5] chore: Update homarr service template and remove unnecessary code --- bootstrap/helpers/shared.php | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index b44f8a624..e13f019e3 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -828,6 +828,31 @@ function convertToArray($collection) return $collection; } +function parseCommandFromMagicEnvVariable(Str|string $key): Stringable +{ + $value = str($key); + $count = substr_count($value->value(), '_'); + if ($count === 2) { + if ($value->startsWith('SERVICE_FQDN') || $value->startsWith('SERVICE_URL')) { + // SERVICE_FQDN_UMAMI + $command = $value->after('SERVICE_')->beforeLast('_'); + } else { + // SERVICE_BASE64_UMAMI + $command = $value->after('SERVICE_')->beforeLast('_'); + } + } + if ($count === 3) { + if ($value->startsWith('SERVICE_FQDN') || $value->startsWith('SERVICE_URL')) { + // SERVICE_FQDN_UMAMI_1000 + $command = $value->after('SERVICE_')->before('_'); + } else { + // SERVICE_BASE64_64_UMAMI + $command = $value->after('SERVICE_')->beforeLast('_'); + } + } + + return str($command); +} function parseEnvVariable(Str|string $value) { $value = str($value); @@ -859,6 +884,7 @@ function parseEnvVariable(Str|string $value) } else { // SERVICE_BASE64_64_UMAMI $command = $value->after('SERVICE_')->beforeLast('_'); + ray($command); } } } @@ -3117,7 +3143,7 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int foreach ($magicEnvironments as $key => $value) { $key = str($key); $value = replaceVariables($value); - $command = $key->after('SERVICE_')->before('_'); + $command = parseCommandFromMagicEnvVariable($key); $found = $resource->environment_variables()->where('key', $key->value())->where($nameOfId, $resource->id)->first(); if ($found) { continue; From 81b8a5841514088a7115cb823c096bd76f7cbb7c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 3 Oct 2024 22:38:37 +0200 Subject: [PATCH 3/5] fix: scheduled backup for services view --- .../Project/Database/ScheduledBackups.php | 9 ++- .../database/scheduled-backups.blade.php | 57 ++++++++++--------- 2 files changed, 35 insertions(+), 31 deletions(-) diff --git a/app/Livewire/Project/Database/ScheduledBackups.php b/app/Livewire/Project/Database/ScheduledBackups.php index beb5a9c39..8021e25d3 100644 --- a/app/Livewire/Project/Database/ScheduledBackups.php +++ b/app/Livewire/Project/Database/ScheduledBackups.php @@ -26,7 +26,7 @@ class ScheduledBackups extends Component public function mount(): void { if ($this->selectedBackupId) { - $this->setSelectedBackup($this->selectedBackupId); + $this->setSelectedBackup($this->selectedBackupId, true); } $this->parameters = get_route_parameters(); if ($this->database->getMorphClass() === 'App\Models\ServiceDatabase') { @@ -37,10 +37,13 @@ class ScheduledBackups extends Component $this->s3s = currentTeam()->s3s; } - public function setSelectedBackup($backupId) + public function setSelectedBackup($backupId, $force = false) { + if ($this->selectedBackupId === $backupId && ! $force) { + return; + } $this->selectedBackupId = $backupId; - $this->selectedBackup = $this->database->scheduledBackups->find($this->selectedBackupId); + $this->selectedBackup = $this->database->scheduledBackups->find($backupId); if (is_null($this->selectedBackup)) { $this->selectedBackupId = null; } diff --git a/resources/views/livewire/project/database/scheduled-backups.blade.php b/resources/views/livewire/project/database/scheduled-backups.blade.php index d1ab8a3c1..d468f090a 100644 --- a/resources/views/livewire/project/database/scheduled-backups.blade.php +++ b/resources/views/livewire/project/database/scheduled-backups.blade.php @@ -1,37 +1,38 @@
@forelse($database->scheduledBackups as $backup) - @if ($type == 'database') - -
-
Frequency: {{ $backup->frequency }}
-
Last backup: {{ data_get($backup->latest_log, 'status', 'No backup yet') }}
-
Number of backups to keep (locally): {{ $backup->number_of_backups_locally }}
-
-
- @else -
-
- data_get($backup, 'id') === data_get($selectedBackup, 'id'), - 'flex flex-col border-l-2 border-transparent', - ])> -
Frequency: {{ $backup->frequency }}
-
Last backup: {{ data_get($backup->latest_log, 'status', 'No backup yet') }}
-
Number of backups to keep (locally): {{ $backup->number_of_backups_locally }}
-
-
- @endif + @if ($type == 'database') + +
+
Frequency: {{ $backup->frequency }}
+
Last backup: {{ data_get($backup->latest_log, 'status', 'No backup yet') }}
+
Number of backups to keep (locally): {{ $backup->number_of_backups_locally }}
+
+
+ @else +
+
+ data_get($backup, 'id') === data_get($selectedBackup, 'id'), + 'flex flex-col border-l-2 border-transparent', + ])> +
Frequency: {{ $backup->frequency }}
+
Last backup: {{ data_get($backup->latest_log, 'status', 'No backup yet') }}
+
Number of backups to keep (locally): {{ $backup->number_of_backups_locally }}
+
+
+ @endif @empty -
No scheduled backups configured.
+
No scheduled backups configured.
@endforelse
@if ($type === 'service-database' && $selectedBackup) -
- -

Executions

- -
+
+ + +
@endif
From 2468d0044b22689192764230e2fec70ad83f1979 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 3 Oct 2024 22:39:44 +0200 Subject: [PATCH 4/5] chore: Update version to 4.0.0-beta.355 --- config/sentry.php | 2 +- config/version.php | 2 +- versions.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/sentry.php b/config/sentry.php index 28fb12a2c..e9ccf0a32 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.354', + 'release' => '4.0.0-beta.355', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index ef5b5a967..03fbf57ef 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ Date: Thu, 3 Oct 2024 22:58:06 +0200 Subject: [PATCH 5/5] fix: parser, espacing container labels --- bootstrap/helpers/shared.php | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index e13f019e3..4d78021c4 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -3702,6 +3702,18 @@ function newParser(Application|Service $resource, int $pull_request_id = 0, ?int }); } $serviceLabels = $labels->merge($defaultLabels); + if ($serviceLabels->count() > 0) { + if ($isApplication) { + $isContainerLabelEscapeEnabled = data_get($resource, 'settings.is_container_label_escape_enabled'); + } else { + $isContainerLabelEscapeEnabled = data_get($resource, 'is_container_label_escape_enabled'); + } + if ($isContainerLabelEscapeEnabled) { + $serviceLabels = $serviceLabels->map(function ($value, $key) { + return escapeDollarSign($value); + }); + } + } if (! $isDatabase && $fqdns instanceof Collection && $fqdns->count() > 0) { if ($isApplication) { $shouldGenerateLabelsExactly = $resource->destination->server->settings->generate_exact_labels;