From 5ee8015a0fc7cea3c0602a00a71bcb027db33268 Mon Sep 17 00:00:00 2001 From: Praveen Pendyala Date: Tue, 25 Nov 2025 13:14:09 +0000 Subject: [PATCH 001/191] Add Transcript LOL link and logo to README My account is a small sponsor --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index a84b3bfa9..276ef07b5 100644 --- a/README.md +++ b/README.md @@ -141,6 +141,7 @@ Thank you so much! Niklas Lausch Cap-go InterviewPal +Transcript LOL ...and many more at [GitHub Sponsors](https://github.com/sponsors/coollabsio) From 7c075551ff07c261d0a10ad7cfc8ff4df62c18a3 Mon Sep 17 00:00:00 2001 From: Aleksander Lis Date: Mon, 5 Jan 2026 21:32:34 +0100 Subject: [PATCH 002/191] fix(log): preserve leading whitespace in logs (#7879) --- resources/views/livewire/project/shared/get-logs.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/livewire/project/shared/get-logs.blade.php b/resources/views/livewire/project/shared/get-logs.blade.php index 8ddd42120..28d6109d0 100644 --- a/resources/views/livewire/project/shared/get-logs.blade.php +++ b/resources/views/livewire/project/shared/get-logs.blade.php @@ -435,7 +435,7 @@ // Parse timestamp from log line (ISO 8601 format: 2025-12-04T11:48:39.136764033Z) $timestamp = ''; $logContent = $line; - if (preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}:\d{2}:\d{2})(?:\.(\d+))?Z?\s*(.*)$/', $line, $matches)) { + if (preg_match('/^(\d{4})-(\d{2})-(\d{2})T(\d{2}:\d{2}:\d{2})(?:\.(\d+))?Z?\s(.*)$/', $line, $matches)) { $year = $matches[1]; $month = $matches[2]; $day = $matches[3]; From 86ffef2df59e7ef90b91a875c79925c89f496637 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 5 Jan 2026 21:39:39 +0100 Subject: [PATCH 003/191] feat(ui): add port mapping format to helper and fix typo --- .../views/livewire/project/application/general.blade.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/views/livewire/project/application/general.blade.php b/resources/views/livewire/project/application/general.blade.php index cf9621462..f576a4a12 100644 --- a/resources/views/livewire/project/application/general.blade.php +++ b/resources/views/livewire/project/application/general.blade.php @@ -500,8 +500,8 @@ @endif @endif @if (!$application->destination->server->isSwarm()) - @endif @if (!$application->destination->server->isSwarm()) From 38fefa7330aecb8848c8f975e2f11eec3293a42d Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 5 Jan 2026 21:52:10 +0100 Subject: [PATCH 004/191] fix(docs): remove environments from projects endpoint --- app/Models/Project.php | 6 ------ openapi.json | 7 ------- openapi.yaml | 5 ----- 3 files changed, 18 deletions(-) diff --git a/app/Models/Project.php b/app/Models/Project.php index 8b26672f0..181951f14 100644 --- a/app/Models/Project.php +++ b/app/Models/Project.php @@ -15,12 +15,6 @@ use Visus\Cuid2\Cuid2; 'uuid' => ['type' => 'string'], 'name' => ['type' => 'string'], 'description' => ['type' => 'string'], - 'environments' => new OA\Property( - property: 'environments', - type: 'array', - items: new OA\Items(ref: '#/components/schemas/Environment'), - description: 'The environments of the project.' - ), ] )] class Project extends BaseModel diff --git a/openapi.json b/openapi.json index 096726cd5..571720d40 100644 --- a/openapi.json +++ b/openapi.json @@ -10566,13 +10566,6 @@ }, "description": { "type": "string" - }, - "environments": { - "description": "The environments of the project.", - "type": "array", - "items": { - "$ref": "#\/components\/schemas\/Environment" - } } }, "type": "object" diff --git a/openapi.yaml b/openapi.yaml index 7439d6f55..896b97b9e 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -6692,11 +6692,6 @@ components: type: string description: type: string - environments: - description: 'The environments of the project.' - type: array - items: - $ref: '#/components/schemas/Environment' type: object Server: description: 'Server model' From 7d26b527fb242d7b4be74f6ed3f21ec77b2dde86 Mon Sep 17 00:00:00 2001 From: Murat Aslan <78961478+murataslan1@users.noreply.github.com> Date: Tue, 6 Jan 2026 00:12:19 +0300 Subject: [PATCH 005/191] fix: instance public ips initialization validation (#7762) --- bootstrap/helpers/shared.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index 58543c0c7..2173e7619 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -1190,7 +1190,7 @@ function get_public_ips() $ipv4 = $first->output(); if ($ipv4) { $ipv4 = trim($ipv4); - $validate_ipv4 = filter_var($ipv4, FILTER_VALIDATE_IP); + $validate_ipv4 = filter_var($ipv4, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4); if ($validate_ipv4 == false) { echo "Invalid ipv4: $ipv4\n"; @@ -1205,7 +1205,7 @@ function get_public_ips() $ipv6 = $second->output(); if ($ipv6) { $ipv6 = trim($ipv6); - $validate_ipv6 = filter_var($ipv6, FILTER_VALIDATE_IP); + $validate_ipv6 = filter_var($ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6); if ($validate_ipv6 == false) { echo "Invalid ipv6: $ipv6\n"; From 51640b0e64b90a6cdd235b48b7795b57bb6492fa Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 5 Jan 2026 22:14:51 +0100 Subject: [PATCH 006/191] fix(ui): instance public ips ui validation --- app/Livewire/Settings/Index.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Livewire/Settings/Index.php b/app/Livewire/Settings/Index.php index ded1c1a4d..2d7de9e58 100644 --- a/app/Livewire/Settings/Index.php +++ b/app/Livewire/Settings/Index.php @@ -26,10 +26,10 @@ class Index extends Component #[Validate('nullable|string|max:255')] public ?string $instance_name = null; - #[Validate('nullable|string')] + #[Validate('nullable|ipv4')] public ?string $public_ipv4 = null; - #[Validate('nullable|string')] + #[Validate('nullable|ipv6')] public ?string $public_ipv6 = null; #[Validate('required|string|timezone')] From ef07c68588f6853f3e229174874c329b074731e6 Mon Sep 17 00:00:00 2001 From: Murat Aslan <78961478+murataslan1@users.noreply.github.com> Date: Tue, 6 Jan 2026 00:20:47 +0300 Subject: [PATCH 007/191] fix: cast docker version to int for proper comparison (#7760) --- bootstrap/helpers/docker.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bootstrap/helpers/docker.php b/bootstrap/helpers/docker.php index a0f810480..b0d401b5f 100644 --- a/bootstrap/helpers/docker.php +++ b/bootstrap/helpers/docker.php @@ -129,8 +129,8 @@ function format_docker_envs_to_json($rawOutput) } function checkMinimumDockerEngineVersion($dockerVersion) { - $majorDockerVersion = str($dockerVersion)->before('.')->value(); - $requiredDockerVersion = str(config('constants.docker.minimum_required_version'))->before('.')->value(); + $majorDockerVersion = (int) str($dockerVersion)->before('.')->value(); + $requiredDockerVersion = (int) str(config('constants.docker.minimum_required_version'))->before('.')->value(); if ($majorDockerVersion < $requiredDockerVersion) { $dockerVersion = null; } From 8e002e0558b243a345439051e1a5b90c55d87e03 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 5 Jan 2026 23:04:36 +0100 Subject: [PATCH 008/191] chore(services): update service json --- templates/service-templates-latest.json | 101 ++++++++++++++++++++++-- templates/service-templates.json | 97 ++++++++++++++++++++++- 2 files changed, 190 insertions(+), 8 deletions(-) diff --git a/templates/service-templates-latest.json b/templates/service-templates-latest.json index e48b61ac9..d20d3cd8e 100644 --- a/templates/service-templates-latest.json +++ b/templates/service-templates-latest.json @@ -580,6 +580,21 @@ "logo": "svgs/cloudflared.svg", "minversion": "0.0.0" }, + "cloudreve": { + "documentation": "https://docs.cloudreve.org/?utm_source=coolify.io", + "slogan": "A self-hosted file management and sharing system.", + "compose": "c2VydmljZXM6CiAgY2xvdWRyZXZlOgogICAgaW1hZ2U6ICdjbG91ZHJldmUvY2xvdWRyZXZlOjQuMTAuMScKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfVVJMX0NMT1VEUkVWRV81MjEyCiAgICAgIC0gQ1JfQ09ORl9EYXRhYmFzZS5UeXBlPXBvc3RncmVzCiAgICAgIC0gQ1JfQ09ORl9EYXRhYmFzZS5Ib3N0PXBvc3RncmVzCiAgICAgIC0gJ0NSX0NPTkZfRGF0YWJhc2UuVXNlcj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ0NSX0NPTkZfRGF0YWJhc2UuUGFzc3dvcmQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnQ1JfQ09ORl9EYXRhYmFzZS5OYW1lPSR7UE9TVEdSRVNfREI6LWNsb3VkcmV2ZS1kYn0nCiAgICAgIC0gQ1JfQ09ORl9EYXRhYmFzZS5Qb3J0PTU0MzIKICAgICAgLSAnQ1JfQ09ORl9SZWRpcy5TZXJ2ZXI9cmVkaXM6NjM3OScKICAgICAgLSAnQ1JfQ09ORl9SZWRpcy5QYXNzd29yZD0ke1NFUlZJQ0VfUEFTU1dPUkRfUkVESVN9JwogICAgdm9sdW1lczoKICAgICAgLSAnY2xvdWRyZXZlLWRhdGE6L2Nsb3VkcmV2ZS9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIG5jCiAgICAgICAgLSAnLXonCiAgICAgICAgLSBsb2NhbGhvc3QKICAgICAgICAtICc1MjEyJwogICAgICBpbnRlcnZhbDogMjBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3JlczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICByZWRpczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogIHBvc3RncmVzOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxOC1hbHBpbmUnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LWNsb3VkcmV2ZS1kYn0nCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0Z3Jlcy1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQn0nCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogNQogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczo3LWFscGluZScKICAgIGNvbW1hbmQ6ICdyZWRpcy1zZXJ2ZXIgLS1yZXF1aXJlcGFzcyAke1NFUlZJQ0VfUEFTU1dPUkRfUkVESVN9JwogICAgdm9sdW1lczoKICAgICAgLSAncmVkaXMtZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtICctYScKICAgICAgICAtICcke1NFUlZJQ0VfUEFTU1dPUkRfUkVESVN9JwogICAgICAgIC0gcGluZwogICAgICBpbnRlcnZhbDogMTBzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDUK", + "tags": [ + "file sharing", + "cloud storage", + "self-hosted", + "open-source" + ], + "category": "storage", + "logo": "svgs/cloudreve.svg", + "minversion": "0.0.0", + "port": "5212" + }, "cockpit": { "documentation": "https://getcockpit.com/documentation/?utm_source=coolify.io", "slogan": "Cockpit is a headless content platform that is lightweight, fast and ready for takeoff.", @@ -1073,6 +1088,21 @@ "minversion": "0.0.0", "port": "8080" }, + "esphome": { + "documentation": "https://esphome.io/guides/getting_started_command_line/?utm_source=coolify.io", + "slogan": "Smart Home Made Simple.", + "compose": "c2VydmljZXM6CiAgZXNwaG9tZToKICAgIGltYWdlOiAnZ2hjci5pby9lc3Bob21lL2VzcGhvbWU6MjAyNS4xMi40JwogICAgdm9sdW1lczoKICAgICAgLSAnZXNwX2NvbmZpZzovY29uZmlnJwogICAgICAtICcvZXRjL2xvY2FsdGltZTovZXRjL2xvY2FsdGltZTpybycKICAgIHByaXZpbGVnZWQ6IHRydWUKICAgIG5ldHdvcmtfbW9kZTogaG9zdAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9VUkxfRVNQSE9NRV82MDUyCiAgICAgIC0gJ1VTRVJOQU1FPSR7U0VSVklDRV9VU0VSX0FETUlOfScKICAgICAgLSAnUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX0FETUlOfScK", + "tags": [ + "home", + "smart", + "assistant", + "microcontroller" + ], + "category": "automation", + "logo": "svgs/esphome.svg", + "minversion": "0.0.0", + "port": "6052" + }, "evolution-api": { "documentation": "https://doc.evolution-api.com/v2/en/get-started/introduction?utm_source=coolify.io", "slogan": "Multi-platform messaging (whatsapp and more) integration API", @@ -1766,6 +1796,21 @@ "logo": "svgs/grocy.svg", "minversion": "0.0.0" }, + "hatchet": { + "documentation": "https://docs.hatchet.run/self-hosting/docker-compose?utm_source=coolify.io", + "slogan": "Hatchet is a high-throughput, low-latency computing service. It's built on an open-source, fault-tolerant queue, allowing work to be delivered as fast as your system can handle", + "compose": "c2VydmljZXM6CiAgaGF0Y2hldC1kYXNoYm9hcmQ6CiAgICBpbWFnZTogJ2doY3IuaW8vaGF0Y2hldC1kZXYvaGF0Y2hldC9oYXRjaGV0LWRhc2hib2FyZDpsYXRlc3QnCiAgICBjb21tYW5kOiAnc2ggLi9lbnRyeXBvaW50LnNoIC0tY29uZmlnIC9oYXRjaGV0L2NvbmZpZycKICAgIGVudmlyb25tZW50OgogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzOjU0MzIvJFBPU1RHUkVTX0RCJwogICAgICAtIFNFUlZJQ0VfVVJMX0hBVENIRVRfODAKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHJhYmJpdG1xOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHNldHVwLWNvbmZpZzoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfY29tcGxldGVkX3N1Y2Nlc3NmdWxseQogICAgICBtaWdyYXRpb246CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2NvbXBsZXRlZF9zdWNjZXNzZnVsbHkKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2hhdGNoZXQtY2VydHM6L2hhdGNoZXQvY2VydHMnCiAgICAgIC0gJ2hhdGNoZXQtY29uZmlnOi9oYXRjaGV0L2NvbmZpZycKICBoYXRjaGV0LWVuZ2luZToKICAgIGltYWdlOiAnZ2hjci5pby9oYXRjaGV0LWRldi9oYXRjaGV0L2hhdGNoZXQtZW5naW5lOmxhdGVzdCcKICAgIGNvbW1hbmQ6ICcvaGF0Y2hldC9oYXRjaGV0LWVuZ2luZSAtLWNvbmZpZyAvaGF0Y2hldC9jb25maWcnCiAgICByZXN0YXJ0OiBvbi1mYWlsdXJlCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3JlczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICByYWJiaXRtcToKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBzZXR1cC1jb25maWc6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2NvbXBsZXRlZF9zdWNjZXNzZnVsbHkKICAgICAgbWlncmF0aW9uOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9jb21wbGV0ZWRfc3VjY2Vzc2Z1bGx5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0Bwb3N0Z3Jlczo1NDMyLyRQT1NUR1JFU19EQicKICAgICAgLSAnU0VSVkVSX0dSUENfQklORF9BRERSRVNTPSR7U0VSVkVSX0dSUENfQklORF9BRERSRVNTOi0wLjAuMC4wfScKICAgICAgLSAnU0VSVkVSX0dSUENfSU5TRUNVUkU9JHtTRVJWRVJfR1JQQ19JTlNFQ1VSRTotdH0nCiAgICB2b2x1bWVzOgogICAgICAtICdoYXRjaGV0LWNlcnRzOi9oYXRjaGV0L2NlcnRzJwogICAgICAtICdoYXRjaGV0LWNvbmZpZzovaGF0Y2hldC9jb25maWcnCiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Bvc3RncmVzcWwtZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBQT1NUR1JFU19VU0VSPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1oYXRjaGV0fScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQn0nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICByYWJiaXRtcToKICAgIGltYWdlOiAncmFiYml0bXE6My1tYW5hZ2VtZW50JwogICAgaG9zdG5hbWU6IHJhYmJpdG1xCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX1VSTF9SQUJCSVRNUV8xNTY3MgogICAgICAtIFJBQkJJVE1RX0RFRkFVTFRfVVNFUj0kU0VSVklDRV9VU0VSX1JBQkJJVE1RCiAgICAgIC0gUkFCQklUTVFfREVGQVVMVF9QQVNTPSRTRVJWSUNFX1BBU1NXT1JEX1JBQkJJVE1RCiAgICAgIC0gJ1BPUlQ9JHtSQUJCSVRNUV9QT1JUOi01NjcyfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OiAncmFiYml0bXEtZGlhZ25vc3RpY3MgLXEgcGluZycKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDMwcwogICAgICByZXRyaWVzOiAxMAogICAgdm9sdW1lczoKICAgICAgLSAncmFiYml0bXEtZGF0YTovdmFyL2xpYi9yYWJiaXRtcS8nCiAgbWlncmF0aW9uOgogICAgaW1hZ2U6ICdnaGNyLmlvL2hhdGNoZXQtZGV2L2hhdGNoZXQvaGF0Y2hldC1taWdyYXRlOmxhdGVzdCcKICAgIGNvbW1hbmQ6IC9oYXRjaGV0L2hhdGNoZXQtbWlncmF0ZQogICAgcmVzdGFydDogJ25vJwogICAgZXhjbHVkZV9mcm9tX2hjOiB0cnVlCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0Bwb3N0Z3Jlczo1NDMyLyRQT1NUR1JFU19EQicKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgc2V0dXAtY29uZmlnOgogICAgaW1hZ2U6ICdnaGNyLmlvL2hhdGNoZXQtZGV2L2hhdGNoZXQvaGF0Y2hldC1hZG1pbjpsYXRlc3QnCiAgICBjb21tYW5kOiAnL2hhdGNoZXQvaGF0Y2hldC1hZG1pbiBxdWlja3N0YXJ0IC0tc2tpcCBjZXJ0cyAtLWdlbmVyYXRlZC1jb25maWctZGlyIC9oYXRjaGV0L2NvbmZpZyAtLW92ZXJ3cml0ZT1mYWxzZScKICAgIHJlc3RhcnQ6ICdubycKICAgIGVudmlyb25tZW50OgogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzOjU0MzIvJFBPU1RHUkVTX0RCJwogICAgICAtICdTRVJWRVJfVEFTS1FVRVVFX1JBQkJJVE1RX1VSTD1hbXFwOi8vJFNFUlZJQ0VfVVNFUl9SQUJCSVRNUTokU0VSVklDRV9QQVNTV09SRF9SQUJCSVRNUUByYWJiaXRtcTo1NjcyLycKICAgICAgLSAnU0VSVkVSX0FVVEhfQ09PS0lFX0RPTUFJTj0ke1NFUlZFUl9BVVRIX0NPT0tJRV9ET01BSU46LWxvY2FsaG9zdDo4MDgwfScKICAgICAgLSAnU0VSVkVSX0FVVEhfQ09PS0lFX0lOU0VDVVJFPSR7U0VSVkVSX0FVVEhfQ09PS0lFX0lOU0VDVVJFOi10fScKICAgICAgLSAnU0VSVkVSX0dSUENfQklORF9BRERSRVNTPSR7U0VSVkVSX0dSUENfQklORF9BRERSRVNTOi0wLjAuMC4wfScKICAgICAgLSAnU0VSVkVSX0dSUENfSU5TRUNVUkU9JHtTRVJWRVJfR1JQQ19JTlNFQ1VSRTotdH0nCiAgICAgIC0gJ1NFUlZFUl9HUlBDX0JST0FEQ0FTVF9BRERSRVNTPSR7U0VSVkVSX0dSUENfQlJPQURDQVNUX0FERFJFU1M6LWxvY2FsaG9zdDo3MDc3fScKICAgICAgLSBTRVJWRVJfREVGQVVMVF9FTkdJTkVfVkVSU0lPTj1WMQogICAgICAtICdTRVJWRVJfSU5URVJOQUxfQ0xJRU5UX0lOVEVSTkFMX0dSUENfQlJPQURDQVNUX0FERFJFU1M9JHtTRVJWRVJfSU5URVJOQUxfQ0xJRU5UX0lOVEVSTkFMX0dSUENfQlJPQURDQVNUX0FERFJFU1M6LWhhdGNoZXQtZW5naW5lOjcwNzd9JwogICAgdm9sdW1lczoKICAgICAgLSAnaGF0Y2hldF9jZXJ0czovaGF0Y2hldC9jZXJ0cycKICAgICAgLSAnaGF0Y2hldF9jb25maWc6L2hhdGNoZXQvY29uZmlnJwogICAgZGVwZW5kc19vbjoKICAgICAgbWlncmF0aW9uOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9jb21wbGV0ZWRfc3VjY2Vzc2Z1bGx5CiAgICAgIHJhYmJpdG1xOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHBvc3RncmVzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5Cg==", + "tags": [ + "ai-agents", + "background-tasks", + "data-pipelines", + "scheduling" + ], + "category": null, + "logo": "svgs/hatchet.svg", + "minversion": "0.0.0", + "port": "80" + }, "heimdall": { "documentation": "https://github.com/linuxserver/Heimdall?utm_source=coolify.io", "slogan": "Heimdall is a dashboard for managing and organizing your server applications.", @@ -1862,7 +1907,7 @@ "hoppscotch": { "documentation": "https://docs.hoppscotch.io?utm_source=coolify.io", "slogan": "The Open Source API Development Platform", - "compose": "c2VydmljZXM6CiAgYmFja2VuZDoKICAgIGltYWdlOiAnaG9wcHNjb3RjaC9ob3Bwc2NvdGNoOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfVVJMX0hPUFBTQ09UQ0hfODAKICAgICAgLSAnVklURV9BTExPV0VEX0FVVEhfUFJPVklERVJTPSR7VklURV9BTExPV0VEX0FVVEhfUFJPVklERVJTOi1HT09HTEUsR0lUSFVCLE1JQ1JPU09GVCxFTUFJTH0nCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AaG9wcHNjb3RjaC1kYjo1NDMyLyR7UE9TVEdSRVNfREJ9JwogICAgICAtICdKV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdUT0tFTl9TQUxUX0NPTVBMRVhJVFk9JHtUT0tFTl9TQUxUX0NPTVBMRVhJVFk6LTEwfScKICAgICAgLSAnTUFHSUNfTElOS19UT0tFTl9WQUxJRElUWT0ke01BR0lDX0xJTktfVE9LRU5fVkFMSURJVFk6LTN9JwogICAgICAtICdSRUZSRVNIX1RPS0VOX1ZBTElESVRZPSR7UkVGUkVTSF9UT0tFTl9WQUxJRElUWTotNjA0ODAwMDAwfScKICAgICAgLSAnQUNDRVNTX1RPS0VOX1ZBTElESVRZPSR7QUNDRVNTX1RPS0VOX1ZBTElESVRZOi04NjQwMDAwMH0nCiAgICAgIC0gJ1NFU1NJT05fU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9TRUNSRVR9JwogICAgICAtICdBTExPV19TRUNVUkVfQ09PS0lFUz0ke0FMTE9XX1NFQ1VSRV9DT09LSUVTOi10cnVlfScKICAgICAgLSAnREFUQV9FTkNSWVBUSU9OX0tFWT0ke0RBVEFfRU5DUllQVElPTl9LRVk6LW11c3RiZWV4YWN0cnkzMmNoYXJhY3Rlcmxpa2V0aGF0fScKICAgICAgLSAnUkVESVJFQ1RfVVJMPSR7U0VSVklDRV9VUkxfSE9QUFNDT1RDSH0nCiAgICAgIC0gJ1dISVRFTElTVEVEX09SSUdJTlM9JHtTRVJWSUNFX1VSTF9IT1BQU0NPVENIfS9iYWNrZW5kLCR7U0VSVklDRV9VUkxfSE9QUFNDT1RDSH0sJHtTRVJWSUNFX1VSTF9IT1BQU0NPVENIfS9hZG1pbicKICAgICAgLSAnR09PR0xFX0NMSUVOVF9JRD0ke0dPT0dMRV9DTElFTlRfSUQ6LSoqKioqfScKICAgICAgLSAnR09PR0xFX0NMSUVOVF9TRUNSRVQ9JHtHT09HTEVfQ0xJRU5UX1NFQ1JFVDotKioqKip9JwogICAgICAtICdHT09HTEVfQ0FMTEJBQ0tfVVJMPSR7U0VSVklDRV9VUkxfSE9QUFNDT1RDSH0vYmFja2VuZC92MS9hdXRoL2dvb2dsZS9jYWxsYmFjaycKICAgICAgLSAnR09PR0xFX1NDT1BFPWVtYWlsLHByb2ZpbGUnCiAgICAgIC0gJ0dJVEhVQl9DTElFTlRfSUQ9JHtHSVRIVUJfQ0xJRU5UX0lEOi0qKioqKn0nCiAgICAgIC0gJ0dJVEhVQl9DTElFTlRfU0VDUkVUPSR7R0lUSFVCX0NMSUVOVF9TRUNSRVQ6LSoqKioqfScKICAgICAgLSAnR0lUSFVCX0NBTExCQUNLX1VSTD0ke1NFUlZJQ0VfVVJMX0hPUFBTQ09UQ0h9L2JhY2tlbmQvdjEvYXV0aC9naXRodWIvY2FsbGJhY2snCiAgICAgIC0gJ0dJVEhVQl9TQ09QRT11c2VyOmVtYWlsJwogICAgICAtICdNSUNST1NPRlRfQ0xJRU5UX0lEPSR7TUlDUk9TT0ZUX0NMSUVOVF9JRDotKioqKip9JwogICAgICAtICdNSUNST1NPRlRfQ0xJRU5UX1NFQ1JFVD0ke01JQ1JPU09GVF9DTElFTlRfU0VDUkVUOi0qKioqKn0nCiAgICAgIC0gJ01JQ1JPU09GVF9DQUxMQkFDS19VUkw9JHtTRVJWSUNFX1VSTF9IT1BQU0NPVENIfS9iYWNrZW5kL3YxL2F1dGgvbWljcm9zb2Z0L2NhbGxiYWNrJwogICAgICAtIE1JQ1JPU09GVF9TQ09QRT11c2VyLnJlYWQKICAgICAgLSBNSUNST1NPRlRfVEVOQU5UPWNvbW1vbgogICAgICAtICdNQUlMRVJfU01UUF9FTkFCTEU9JHtNQUlMRVJfU01UUF9FTkFCTEU6LWZhbHNlfScKICAgICAgLSAnTUFJTEVSX1VTRV9DVVNUT01fQ09ORklHUz0ke01BSUxFUl9VU0VfQ1VTVE9NX0NPTkZJR1M6LXRydWV9JwogICAgICAtICdNQUlMRVJfQUREUkVTU19GUk9NPSR7TUFJTEVSX0FERFJFU1NfRlJPTTotdXNlckBleGFtcGxlLmNvbX0nCiAgICAgIC0gJ01BSUxFUl9TTVRQX1VSTD0ke01BSUxFUl9TTVRQX1VSTDotc210cHNfdXJsfScKICAgICAgLSAnTUFJTEVSX1NNVFBfSE9TVD0ke01BSUxFUl9TTVRQX0hPU1Q6LXNtdHAuZXhhbXBsZS5jb219JwogICAgICAtICdNQUlMRVJfU01UUF9QT1JUPSR7TUFJTEVSX1NNVFBfUE9SVDotNDY1fScKICAgICAgLSAnTUFJTEVSX1NNVFBfU0VDVVJFPSR7TUFJTEVSX1NNVFBfU0VDVVJFOi10cnVlfScKICAgICAgLSAnTUFJTEVSX1NNVFBfVVNFUj0ke01BSUxFUl9TTVRQX1VTRVI6LXVzZXJAZXhhbXBsZS5jb219JwogICAgICAtICdNQUlMRVJfU01UUF9QQVNTV09SRD0ke01BSUxFUl9TTVRQX1BBU1NXT1JEOi1tYWlscGFzc30nCiAgICAgIC0gJ01BSUxFUl9UTFNfUkVKRUNUX1VOQVVUSE9SSVpFRD0ke01BSUxFUl9UTFNfUkVKRUNUX1VOQVVUSE9SSVpFRDotZmFsc2V9JwogICAgICAtICdSQVRFX0xJTUlUX1RUTD0ke1JBVEVfTElNSVRfVFRMOi02MH0nCiAgICAgIC0gJ1JBVEVfTElNSVRfTUFYPSR7UkFURV9MSU1JVF9NQVg6LTEwMH0nCiAgICAgIC0gJ1ZJVEVfQkFTRV9VUkw9JHtTRVJWSUNFX1VSTF9IT1BQU0NPVENIfScKICAgICAgLSAnVklURV9TSE9SVENPREVfQkFTRV9VUkw9JHtTRVJWSUNFX1VSTF9IT1BQU0NPVENIfScKICAgICAgLSAnVklURV9BRE1JTl9VUkw9JHtTRVJWSUNFX1VSTF9IT1BQU0NPVENIfS9hZG1pbicKICAgICAgLSAnVklURV9CQUNLRU5EX0dRTF9VUkw9JHtTRVJWSUNFX1VSTF9IT1BQU0NPVENIfS9iYWNrZW5kL2dyYXBocWwnCiAgICAgIC0gJ1ZJVEVfQkFDS0VORF9XU19VUkw9d3NzOi8vJHtTRVJWSUNFX1VSTF9IT1BQU0NPVENIfS9iYWNrZW5kL2dyYXBocWwnCiAgICAgIC0gJ1ZJVEVfQkFDS0VORF9BUElfVVJMPSR7U0VSVklDRV9VUkxfSE9QUFNDT1RDSH0vYmFja2VuZC92MScKICAgICAgLSAnVklURV9BUFBfVE9TX0xJTks9aHR0cHM6Ly9kb2NzLmhvcHBzY290Y2guaW8vc3VwcG9ydC90ZXJtcycKICAgICAgLSAnVklURV9BUFBfUFJJVkFDWV9QT0xJQ1lfTElOSz1odHRwczovL2RvY3MuaG9wcHNjb3RjaC5pby9zdXBwb3J0L3ByaXZhY3knCiAgICAgIC0gRU5BQkxFX1NVQlBBVEhfQkFTRURfQUNDRVNTPXRydWUKICAgIGRlcGVuZHNfb246CiAgICAgIGRiLW1pZ3JhdGlvbjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfY29tcGxldGVkX3N1Y2Nlc3NmdWxseQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICd3Z2V0IC1xTy0gaHR0cDovLzEyNy4wLjAuMTo4MC8nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICBob3Bwc2NvdGNoLWRiOgogICAgaW1hZ2U6ICdwb3N0Z3JlczpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0Z3Jlc19kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotaG9wcHNjb3RjaH0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLWggbG9jYWxob3N0IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxMAogIGRiLW1pZ3JhdGlvbjoKICAgIGV4Y2x1ZGVfZnJvbV9oYzogdHJ1ZQogICAgaW1hZ2U6ICdob3Bwc2NvdGNoL2hvcHBzY290Y2g6bGF0ZXN0JwogICAgZGVwZW5kc19vbjoKICAgICAgaG9wcHNjb3RjaC1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgY29tbWFuZDogJ3BucHggcHJpc21hIG1pZ3JhdGUgZGVwbG95JwogICAgcmVzdGFydDogb24tZmFpbHVyZQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1ob3Bwc2NvdGNofScKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AaG9wcHNjb3RjaC1kYjo1NDMyLyR7UE9TVEdSRVNfREI6LWhvcHBzY290Y2h9Jwo=", + "compose": "c2VydmljZXM6CiAgYmFja2VuZDoKICAgIGltYWdlOiAnaG9wcHNjb3RjaC9ob3Bwc2NvdGNoOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfVVJMX0hPUFBTQ09UQ0hfODAKICAgICAgLSAnVklURV9BTExPV0VEX0FVVEhfUFJPVklERVJTPSR7VklURV9BTExPV0VEX0FVVEhfUFJPVklERVJTOi1HT09HTEUsR0lUSFVCLE1JQ1JPU09GVCxFTUFJTH0nCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AaG9wcHNjb3RjaC1kYjo1NDMyLyR7UE9TVEdSRVNfREJ9JwogICAgICAtICdEQVRBX0VOQ1JZUFRJT05fS0VZPSR7U0VSVklDRV9CQVNFNjRfREFUQUVOQ1JZUFRJT05LRVl9JwogICAgICAtICdXSElURUxJU1RFRF9PUklHSU5TPSR7U0VSVklDRV9VUkxfSE9QUFNDT1RDSH0vYmFja2VuZCwke1NFUlZJQ0VfVVJMX0hPUFBTQ09UQ0h9LCR7U0VSVklDRV9VUkxfSE9QUFNDT1RDSH0vYWRtaW4nCiAgICAgIC0gJ01BSUxFUl9VU0VfQ1VTVE9NX0NPTkZJR1M9JHtNQUlMRVJfVVNFX0NVU1RPTV9DT05GSUdTOi10cnVlfScKICAgICAgLSAnVklURV9CQVNFX1VSTD0ke1NFUlZJQ0VfVVJMX0hPUFBTQ09UQ0h9JwogICAgICAtICdWSVRFX1NIT1JUQ09ERV9CQVNFX1VSTD0ke1NFUlZJQ0VfVVJMX0hPUFBTQ09UQ0h9JwogICAgICAtICdWSVRFX0FETUlOX1VSTD0ke1NFUlZJQ0VfVVJMX0hPUFBTQ09UQ0h9L2FkbWluJwogICAgICAtICdWSVRFX0JBQ0tFTkRfR1FMX1VSTD0ke1NFUlZJQ0VfVVJMX0hPUFBTQ09UQ0h9L2JhY2tlbmQvZ3JhcGhxbCcKICAgICAgLSAnVklURV9CQUNLRU5EX1dTX1VSTD13c3M6Ly8ke1NFUlZJQ0VfRlFETl9IT1BQU0NPVENIfS9iYWNrZW5kL2dyYXBocWwnCiAgICAgIC0gJ1ZJVEVfQkFDS0VORF9BUElfVVJMPSR7U0VSVklDRV9VUkxfSE9QUFNDT1RDSH0vYmFja2VuZC92MScKICAgICAgLSAnVklURV9BUFBfVE9TX0xJTks9aHR0cHM6Ly9kb2NzLmhvcHBzY290Y2guaW8vc3VwcG9ydC90ZXJtcycKICAgICAgLSAnVklURV9BUFBfUFJJVkFDWV9QT0xJQ1lfTElOSz1odHRwczovL2RvY3MuaG9wcHNjb3RjaC5pby9zdXBwb3J0L3ByaXZhY3knCiAgICAgIC0gRU5BQkxFX1NVQlBBVEhfQkFTRURfQUNDRVNTPXRydWUKICAgIGRlcGVuZHNfb246CiAgICAgIGRiLW1pZ3JhdGlvbjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfY29tcGxldGVkX3N1Y2Nlc3NmdWxseQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICd3Z2V0IC1xTy0gaHR0cDovLzEyNy4wLjAuMTo4MC8nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICBob3Bwc2NvdGNoLWRiOgogICAgaW1hZ2U6ICdwb3N0Z3JlczpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0Z3Jlc19kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotaG9wcHNjb3RjaH0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLWggbG9jYWxob3N0IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxMAogIGRiLW1pZ3JhdGlvbjoKICAgIGV4Y2x1ZGVfZnJvbV9oYzogdHJ1ZQogICAgaW1hZ2U6ICdob3Bwc2NvdGNoL2hvcHBzY290Y2g6bGF0ZXN0JwogICAgZGVwZW5kc19vbjoKICAgICAgaG9wcHNjb3RjaC1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgY29tbWFuZDogJ3BucHggcHJpc21hIG1pZ3JhdGUgZGVwbG95JwogICAgcmVzdGFydDogb24tZmFpbHVyZQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1ob3Bwc2NvdGNofScKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AaG9wcHNjb3RjaC1kYjo1NDMyLyR7UE9TVEdSRVNfREI6LWhvcHBzY290Y2h9Jwo=", "tags": [ "api", "development", @@ -2687,7 +2732,7 @@ "mosquitto": { "documentation": "https://mosquitto.org/documentation/?utm_source=coolify.io", "slogan": "Mosquitto is lightweight and suitable for use on all devices, from low-power single-board computers to full servers.", - "compose": "c2VydmljZXM6CiAgbW9zcXVpdHRvOgogICAgaW1hZ2U6IGVjbGlwc2UtbW9zcXVpdHRvCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX1VSTF9NT1NRVUlUVE9fMTg4MwogICAgICAtICdNUVRUX1VTRVJOQU1FPSR7U0VSVklDRV9VU0VSX01PU1FVSVRUT30nCiAgICAgIC0gJ01RVFRfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01PU1FVSVRUT30nCiAgICAgIC0gJ1JFUVVJUkVfQ0VSVElGSUNBVEU9JHtSRVFVSVJFX0NFUlRJRklDQVRFOi1mYWxzZX0nCiAgICAgIC0gJ0FMTE9XX0FOT05ZTU9VUz0ke0FMTE9XX0FOT05ZTU9VUzotdHJ1ZX0nCiAgICB2b2x1bWVzOgogICAgICAtICdtb3NxdWl0dG8tY29uZmlnOi9tb3NxdWl0dG8vY29uZmlnJwogICAgICAtICdtb3NxdWl0dG8tY2VydHM6L2NlcnRzJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdleGl0IDAnCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDMKICAgIGVudHJ5cG9pbnQ6ICJzaCAtYyBcIiBpZiBbICckUkVRVUlSRV9DRVJUSUZJQ0FURScgPSAndHJ1ZScgXTsgdGhlbiBlY2hvICdsaXN0ZW5lciA4ODgzJyA+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mICYmIGVjaG8gJ2NhZmlsZSAvY2VydHMvY2EuY3J0JyA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiAmJiBlY2hvICdjZXJ0ZmlsZSAvY2VydHMvc2VydmVyLmNydCcgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgJiYgZWNobyAna2V5ZmlsZSAgL2NlcnRzL3NlcnZlci5rZXknID4+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mOyBlbHNlIGVjaG8gJ2xpc3RlbmVyIDE4ODMnID4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmY7IGZpICYmIGVjaG8gJ3JlcXVpcmVfY2VydGlmaWNhdGUgJyRSRVFVSVJFX0NFUlRJRklDQVRFID4+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mICYmIGVjaG8gJ2FsbG93X2Fub255bW91cyAnJEFMTE9XX0FOT05ZTU9VUyA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZjsgaWYgWyAtbiAnJFNFUlZJQ0VfVVNFUl9NT1NRVUlUVE8nIF0gJiYgWyAtbiAnJFNFUlZJQ0VfUEFTU1dPUkRfTU9TUVVJVFRPJyBdOyB0aGVuIGVjaG8gJ3Bhc3N3b3JkX2ZpbGUgL21vc3F1aXR0by9jb25maWcvcGFzc3dvcmRzJyA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiAmJiB0b3VjaCAvbW9zcXVpdHRvL2NvbmZpZy9wYXNzd29yZHMgJiYgY2htb2QgMDcwMCAvbW9zcXVpdHRvL2NvbmZpZy9wYXNzd29yZHMgJiYgY2hvd24gcm9vdDpyb290IC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkcyAmJiBtb3NxdWl0dG9fcGFzc3dkIC1iIC1jIC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkcyAkU0VSVklDRV9VU0VSX01PU1FVSVRUTyAkU0VSVklDRV9QQVNTV09SRF9NT1NRVUlUVE8gJiYgY2hvd24gbW9zcXVpdHRvOm1vc3F1aXR0byAvbW9zcXVpdHRvL2NvbmZpZy9wYXNzd29yZHM7IGZpICYmIGV4ZWMgbW9zcXVpdHRvIC1jIC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mIFwiIgogICAgbGFiZWxzOgogICAgICAtIHRyYWVmaWsudGNwLnJvdXRlcnMubXF0dC5lbnRyeXBvaW50cz1tcXR0CiAgICAgIC0gdHJhZWZpay50Y3Aucm91dGVycy5tcXR0cy5lbnRyeXBvaW50cz1tcXR0cwo=", + "compose": "c2VydmljZXM6CiAgbW9zcXVpdHRvOgogICAgaW1hZ2U6IGVjbGlwc2UtbW9zcXVpdHRvCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX1VSTF9NT1NRVUlUVE9fMTg4MwogICAgICAtICdNUVRUX1VTRVJOQU1FPSR7U0VSVklDRV9VU0VSX01PU1FVSVRUT30nCiAgICAgIC0gJ01RVFRfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01PU1FVSVRUT30nCiAgICAgIC0gJ1JFUVVJUkVfQ0VSVElGSUNBVEU9JHtSRVFVSVJFX0NFUlRJRklDQVRFOi1mYWxzZX0nCiAgICAgIC0gJ0FMTE9XX0FOT05ZTU9VUz0ke0FMTE9XX0FOT05ZTU9VUzotdHJ1ZX0nCiAgICB2b2x1bWVzOgogICAgICAtICcuL21vc3F1aXR0by9jb25maWc6L21vc3F1aXR0by9jb25maWcnCiAgICAgIC0gJy4vY2VydHM6L2NlcnRzJwogICAgcG9ydHM6CiAgICAgIC0gJzg4ODM6ODg4MycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnZXhpdCAwJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgICBlbnRyeXBvaW50OiAic2ggLWMgXCIgaWYgWyAnJFJFUVVJUkVfQ0VSVElGSUNBVEUnID0gJ3RydWUnIF07IHRoZW4gZWNobyAnbGlzdGVuZXIgODg4MycgPiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiAmJiBlY2hvICdjYWZpbGUgL2NlcnRzL2NhLmNydCcgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgJiYgZWNobyAnY2VydGZpbGUgL2NlcnRzL3NlcnZlci5jcnQnID4+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mICYmIGVjaG8gJ2tleWZpbGUgIC9jZXJ0cy9zZXJ2ZXIua2V5JyA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZjsgZWxzZSBlY2hvICdsaXN0ZW5lciAxODgzJyA+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mOyBmaSAmJiBlY2hvICdyZXF1aXJlX2NlcnRpZmljYXRlICckUkVRVUlSRV9DRVJUSUZJQ0FURSA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiAmJiBlY2hvICdhbGxvd19hbm9ueW1vdXMgJyRBTExPV19BTk9OWU1PVVMgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmY7IGlmIFsgLW4gJyRTRVJWSUNFX1VTRVJfTU9TUVVJVFRPJyBdICYmIFsgLW4gJyRTRVJWSUNFX1BBU1NXT1JEX01PU1FVSVRUTycgXTsgdGhlbiBlY2hvICdwYXNzd29yZF9maWxlIC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkcycgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgJiYgdG91Y2ggL21vc3F1aXR0by9jb25maWcvcGFzc3dvcmRzICYmIGNobW9kIDA3MDAgL21vc3F1aXR0by9jb25maWcvcGFzc3dvcmRzICYmIGNob3duIHJvb3Q6cm9vdCAvbW9zcXVpdHRvL2NvbmZpZy9wYXNzd29yZHMgJiYgbW9zcXVpdHRvX3Bhc3N3ZCAtYiAtYyAvbW9zcXVpdHRvL2NvbmZpZy9wYXNzd29yZHMgJFNFUlZJQ0VfVVNFUl9NT1NRVUlUVE8gJFNFUlZJQ0VfUEFTU1dPUkRfTU9TUVVJVFRPICYmIGNob3duIG1vc3F1aXR0bzptb3NxdWl0dG8gL21vc3F1aXR0by9jb25maWcvcGFzc3dvcmRzOyBmaSAmJiBleGVjIG1vc3F1aXR0byAtYyAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiBcIiIKICAgIGxhYmVsczoKICAgICAgLSB0cmFlZmlrLnRjcC5yb3V0ZXJzLm1xdHQuZW50cnlwb2ludHM9bXF0dAogICAgICAtIHRyYWVmaWsudGNwLnJvdXRlcnMubXF0dHMuZW50cnlwb2ludHM9bXF0dHMK", "tags": [ "mosquitto", "mqtt", @@ -3536,7 +3581,7 @@ "postiz": { "documentation": "https://docs.postiz.com?utm_source=coolify.io", "slogan": "Open source social media scheduling tool.", - "compose": "c2VydmljZXM6CiAgcG9zdGl6OgogICAgaW1hZ2U6ICdnaGNyLmlvL2dpdHJvb21ocS9wb3N0aXotYXBwOnYyLjEwLjEnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX1VSTF9QT1NUSVpfNTAwMAogICAgICAtICdNQUlOX1VSTD0ke1NFUlZJQ0VfVVJMX1BPU1RJWn0nCiAgICAgIC0gJ0ZST05URU5EX1VSTD0ke1NFUlZJQ0VfVVJMX1BPU1RJWn0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0JBQ0tFTkRfVVJMPSR7U0VSVklDRV9VUkxfUE9TVElafS9hcGknCiAgICAgIC0gJ0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVFNFQ1JFVH0nCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vcG9zdGdyZXM6JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTUUx9QHBvc3RncmVzOjU0MzIvJHtQT1NUR1JFU1FMX0RBVEFCQVNFOi1wb3N0aXotZGJ9JwogICAgICAtICdSRURJU19VUkw9cmVkaXM6Ly9kZWZhdWx0OiR7U0VSVklDRV9QQVNTV09SRF9SRURJU31AcmVkaXM6NjM3OScKICAgICAgLSAnQkFDS0VORF9JTlRFUk5BTF9VUkw9aHR0cDovL2xvY2FsaG9zdDozMDAwJwogICAgICAtICdDTE9VREZMQVJFX0FDQ09VTlRfSUQ9JHtDTE9VREZMQVJFX0FDQ09VTlRfSUR9JwogICAgICAtICdDTE9VREZMQVJFX0FDQ0VTU19LRVk9JHtDTE9VREZMQVJFX0FDQ0VTU19LRVl9JwogICAgICAtICdDTE9VREZMQVJFX1NFQ1JFVF9BQ0NFU1NfS0VZPSR7Q0xPVURGTEFSRV9TRUNSRVRfQUNDRVNTX0tFWX0nCiAgICAgIC0gJ0NMT1VERkxBUkVfQlVDS0VUTkFNRT0ke0NMT1VERkxBUkVfQlVDS0VUTkFNRX0nCiAgICAgIC0gJ0NMT1VERkxBUkVfQlVDS0VUX1VSTD0ke0NMT1VERkxBUkVfQlVDS0VUX1VSTH0nCiAgICAgIC0gJ0NMT1VERkxBUkVfUkVHSU9OPSR7Q0xPVURGTEFSRV9SRUdJT059JwogICAgICAtICdTVE9SQUdFX1BST1ZJREVSPSR7U1RPUkFHRV9QUk9WSURFUjotbG9jYWx9JwogICAgICAtICdVUExPQURfRElSRUNUT1JZPSR7VVBMT0FEX0RJUkVDVE9SWTotL3VwbG9hZHN9JwogICAgICAtICdORVhUX1BVQkxJQ19VUExPQURfRElSRUNUT1JZPSR7TkVYVF9QVUJMSUNfVVBMT0FEX0RJUkVDVE9SWTotL3VwbG9hZHN9JwogICAgICAtICdORVhUX1BVQkxJQ19VUExPQURfU1RBVElDX0RJUkVDVE9SWT0ke05FWFRfUFVCTElDX1VQTE9BRF9TVEFUSUNfRElSRUNUT1JZfScKICAgICAgLSAnUkVTRU5EX0FQSV9LRVk9JHtSRVNFTkRfQVBJX0tFWX0nCiAgICAgIC0gJ0VNQUlMX0ZST01fQUREUkVTUz0ke0VNQUlMX0ZST01fQUREUkVTU30nCiAgICAgIC0gJ0VNQUlMX0ZST01fTkFNRT0ke0VNQUlMX0ZST01fTkFNRX0nCiAgICAgIC0gJ0VNQUlMX1BST1ZJREVSPSR7RU1BSUxfUFJPVklERVJ9JwogICAgICAtICdYX0FQSV9LRVk9JHtTRVJWSUNFX1hfQVBJfScKICAgICAgLSAnWF9BUElfU0VDUkVUPSR7U0VSVklDRV9YX1NFQ1JFVH0nCiAgICAgIC0gJ0xJTktFRElOX0NMSUVOVF9JRD0ke1NFUlZJQ0VfTElOS0VESU5fSUR9JwogICAgICAtICdMSU5LRURJTl9DTElFTlRfU0VDUkVUPSR7U0VSVklDRV9MSU5LRURJTl9TRUNSRVR9JwogICAgICAtICdSRURESVRfQ0xJRU5UX0lEPSR7U0VSVklDRV9SRURESVRfQVBJfScKICAgICAgLSAnUkVERElUX0NMSUVOVF9TRUNSRVQ9JHtTRVJWSUNFX1JFRERJVF9TRUNSRVR9JwogICAgICAtICdHSVRIVUJfQ0xJRU5UX0lEPSR7U0VSVklDRV9HSVRIVUJfSUR9JwogICAgICAtICdHSVRIVUJfQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfR0lUSFVCX1NFQ1JFVH0nCiAgICAgIC0gJ1RIUkVBRFNfQVBQX0lEPSR7U0VSVklDRV9USFJFQURTX0lEfScKICAgICAgLSAnVEhSRUFEU19BUFBfU0VDUkVUPSR7U0VSVklDRV9USFJFQURTX1NFQ1JFVH0nCiAgICAgIC0gJ0ZBQ0VCT09LX0FQUF9JRD0ke1NFUlZJQ0VfRkFDRUJPT0tfSUR9JwogICAgICAtICdGQUNFQk9PS19BUFBfU0VDUkVUPSR7U0VSVklDRV9GQUNFQk9PS19TRUNSRVR9JwogICAgICAtICdZT1VUVUJFX0NMSUVOVF9JRD0ke1NFUlZJQ0VfWU9VVFVCRV9JRH0nCiAgICAgIC0gJ1lPVVRVQkVfQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfWU9VVFVCRV9TRUNSRVR9JwogICAgICAtICdUSUtUT0tfQ0xJRU5UX0lEPSR7U0VSVklDRV9USUtUT0tfSUR9JwogICAgICAtICdUSUtUT0tfQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfVElLVE9LX1NFQ1JFVH0nCiAgICAgIC0gJ1BJTlRFUkVTVF9DTElFTlRfSUQ9JHtTRVJWSUNFX1BJTlRFUkVTVF9JRH0nCiAgICAgIC0gJ1BJTlRFUkVTVF9DTElFTlRfU0VDUkVUPSR7U0VSVklDRV9QSU5URVJFU1RfU0VDUkVUfScKICAgICAgLSAnRFJJQkJCTEVfQ0xJRU5UX0lEPSR7U0VSVklDRV9EUklCQkxFX0lEfScKICAgICAgLSAnRFJJQkJCTEVfQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfRFJJQkJMRV9TRUNSRVR9JwogICAgICAtICdESVNDT1JEX0NMSUVOVF9JRD0ke1NFUlZJQ0VfRElTQ09SRF9JRH0nCiAgICAgIC0gJ0RJU0NPUkRfQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfRElTQ09SRF9TRUNSRVR9JwogICAgICAtICdESVNDT1JEX0JPVF9UT0tFTl9JRD0ke1NFUlZJQ0VfRElTQ09SRF9UT0tFTn0nCiAgICAgIC0gJ1NMQUNLX0lEPSR7U0VSVklDRV9TTEFDS19JRH0nCiAgICAgIC0gJ1NMQUNLX1NFQ1JFVD0ke1NFUlZJQ0VfU0xBQ0tfU0VDUkVUfScKICAgICAgLSAnU0xBQ0tfU0lHTklOR19TRUNSRVQ9JHtTTEFDS19TSUdOSU5HX1NFQ1JFVH0nCiAgICAgIC0gJ01BU1RPRE9OX0NMSUVOVF9JRD0ke1NFUlZJQ0VfTUFTVE9ET05fSUR9JwogICAgICAtICdNQVNUT0RPTl9DTElFTlRfU0VDUkVUPSR7U0VSVklDRV9NQVNUT0RPTl9TRUNSRVR9JwogICAgICAtICdCRUVISUlWRV9BUElfS0VZPSR7U0VSVklDRV9CRUVISUlWRV9LRVl9JwogICAgICAtICdCRUVISUlWRV9QVUJMSUNBVElPTl9JRD0ke1NFUlZJQ0VfQkVFSElJVkVfUFVCSUR9JwogICAgICAtICdPUEVOQUlfQVBJX0tFWT0ke1NFUlZJQ0VfT1BFTkFJX0tFWX0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0RJU0NPUkRfU1VQUE9SVD0ke05FWFRfUFVCTElDX0RJU0NPUkRfU1VQUE9SVH0nCiAgICAgIC0gJ05FWFRfUFVCTElDX1BPTE9UTk89JHtORVhUX1BVQkxJQ19QT0xPVE5PfScKICAgICAgLSBJU19HRU5FUkFMPXRydWUKICAgICAgLSAnTlhfQUREX1BMVUdJTlM9JHtOWF9BRERfUExVR0lOUzotZmFsc2V9JwogICAgICAtICdOT1RfU0VDVVJFRD0ke05PVF9TRUNVUkVEOi1mYWxzZX0nCiAgICAgIC0gJ0ZFRV9BTU9VTlQ9JHtGRUVfQU1PVU5UOi0wLjA1fScKICAgICAgLSAnU1RSSVBFX1BVQkxJU0hBQkxFX0tFWT0ke1NUUklQRV9QVUJMSVNIQUJMRV9LRVl9JwogICAgICAtICdTVFJJUEVfU0VDUkVUX0tFWT0ke1NUUklQRV9TRUNSRVRfS0VZfScKICAgICAgLSAnU1RSSVBFX1NJR05JTkdfS0VZPSR7U1RSSVBFX1NJR05JTkdfS0VZfScKICAgICAgLSAnU1RSSVBFX1NJR05JTkdfS0VZX0NPTk5FQ1Q9JHtTVFJJUEVfU0lHTklOR19LRVlfQ09OTkVDVH0nCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0aXpfY29uZmlnOi9jb25maWcvJwogICAgICAtICdwb3N0aXpfdXBsb2FkczovdXBsb2Fkcy8nCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3JlczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICByZWRpczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICd3Z2V0IC1xTy0gaHR0cDovLzEyNy4wLjAuMTo1MDAwLycKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHBvc3RncmVzOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNC41JwogICAgdm9sdW1lczoKICAgICAgLSAncG9zdGl6X3Bvc3RncmVzcWxfZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBQT1NUR1JFU19VU0VSPXBvc3RncmVzCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU1FMX0RBVEFCQVNFOi1wb3N0aXotZGJ9JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCOi1wb3N0aXotZGJ9JwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOjcuMicKICAgIGVudmlyb25tZW50OgogICAgICAtICdSRURJU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUkVESVN9JwogICAgY29tbWFuZDogJ3JlZGlzLXNlcnZlciAtLXJlcXVpcmVwYXNzICR7U0VSVklDRV9QQVNTV09SRF9SRURJU30nCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0aXpfcmVkaXNfZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtICctYScKICAgICAgICAtICcke1NFUlZJQ0VfUEFTU1dPUkRfUkVESVN9JwogICAgICAgIC0gcGluZwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDIwCg==", + "compose": "c2VydmljZXM6CiAgcG9zdGl6OgogICAgaW1hZ2U6ICdnaGNyLmlvL2dpdHJvb21ocS9wb3N0aXotYXBwOnYyLjEwLjEnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX1VSTF9QT1NUSVpfNTAwMAogICAgICAtICdNQUlOX1VSTD0ke1NFUlZJQ0VfVVJMX1BPU1RJWn0nCiAgICAgIC0gJ0ZST05URU5EX1VSTD0ke1NFUlZJQ0VfVVJMX1BPU1RJWn0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0JBQ0tFTkRfVVJMPSR7U0VSVklDRV9VUkxfUE9TVElafS9hcGknCiAgICAgIC0gJ0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVFNFQ1JFVH0nCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vcG9zdGdyZXM6JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTUUx9QHBvc3RncmVzOjU0MzIvJHtQT1NUR1JFU1FMX0RBVEFCQVNFOi1wb3N0aXotZGJ9JwogICAgICAtICdSRURJU19VUkw9cmVkaXM6Ly9kZWZhdWx0OiR7U0VSVklDRV9QQVNTV09SRF9SRURJU31AcmVkaXM6NjM3OScKICAgICAgLSAnQkFDS0VORF9JTlRFUk5BTF9VUkw9aHR0cDovL2xvY2FsaG9zdDozMDAwJwogICAgICAtICdDTE9VREZMQVJFX0FDQ09VTlRfSUQ9JHtDTE9VREZMQVJFX0FDQ09VTlRfSUR9JwogICAgICAtICdDTE9VREZMQVJFX0FDQ0VTU19LRVk9JHtDTE9VREZMQVJFX0FDQ0VTU19LRVl9JwogICAgICAtICdDTE9VREZMQVJFX1NFQ1JFVF9BQ0NFU1NfS0VZPSR7Q0xPVURGTEFSRV9TRUNSRVRfQUNDRVNTX0tFWX0nCiAgICAgIC0gJ0NMT1VERkxBUkVfQlVDS0VUTkFNRT0ke0NMT1VERkxBUkVfQlVDS0VUTkFNRX0nCiAgICAgIC0gJ0NMT1VERkxBUkVfQlVDS0VUX1VSTD0ke0NMT1VERkxBUkVfQlVDS0VUX1VSTH0nCiAgICAgIC0gJ0NMT1VERkxBUkVfUkVHSU9OPSR7Q0xPVURGTEFSRV9SRUdJT059JwogICAgICAtICdTVE9SQUdFX1BST1ZJREVSPSR7U1RPUkFHRV9QUk9WSURFUjotbG9jYWx9JwogICAgICAtICdVUExPQURfRElSRUNUT1JZPSR7VVBMT0FEX0RJUkVDVE9SWTotL3VwbG9hZHN9JwogICAgICAtICdORVhUX1BVQkxJQ19VUExPQURfRElSRUNUT1JZPSR7TkVYVF9QVUJMSUNfVVBMT0FEX0RJUkVDVE9SWTotL3VwbG9hZHN9JwogICAgICAtICdORVhUX1BVQkxJQ19VUExPQURfU1RBVElDX0RJUkVDVE9SWT0ke05FWFRfUFVCTElDX1VQTE9BRF9TVEFUSUNfRElSRUNUT1JZfScKICAgICAgLSAnUkVTRU5EX0FQSV9LRVk9JHtSRVNFTkRfQVBJX0tFWX0nCiAgICAgIC0gJ0VNQUlMX0ZST01fQUREUkVTUz0ke0VNQUlMX0ZST01fQUREUkVTU30nCiAgICAgIC0gJ0VNQUlMX0ZST01fTkFNRT0ke0VNQUlMX0ZST01fTkFNRX0nCiAgICAgIC0gJ0VNQUlMX1BST1ZJREVSPSR7RU1BSUxfUFJPVklERVJ9JwogICAgICAtICdYX0FQSV9LRVk9JHtTRVJWSUNFX1hfQVBJfScKICAgICAgLSAnWF9BUElfU0VDUkVUPSR7U0VSVklDRV9YX1NFQ1JFVH0nCiAgICAgIC0gJ0xJTktFRElOX0NMSUVOVF9JRD0ke1NFUlZJQ0VfTElOS0VESU5fSUR9JwogICAgICAtICdMSU5LRURJTl9DTElFTlRfU0VDUkVUPSR7U0VSVklDRV9MSU5LRURJTl9TRUNSRVR9JwogICAgICAtICdSRURESVRfQ0xJRU5UX0lEPSR7U0VSVklDRV9SRURESVRfQVBJfScKICAgICAgLSAnUkVERElUX0NMSUVOVF9TRUNSRVQ9JHtTRVJWSUNFX1JFRERJVF9TRUNSRVR9JwogICAgICAtICdHSVRIVUJfQ0xJRU5UX0lEPSR7U0VSVklDRV9HSVRIVUJfSUR9JwogICAgICAtICdHSVRIVUJfQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfR0lUSFVCX1NFQ1JFVH0nCiAgICAgIC0gJ1RIUkVBRFNfQVBQX0lEPSR7U0VSVklDRV9USFJFQURTX0lEfScKICAgICAgLSAnVEhSRUFEU19BUFBfU0VDUkVUPSR7U0VSVklDRV9USFJFQURTX1NFQ1JFVH0nCiAgICAgIC0gJ0ZBQ0VCT09LX0FQUF9JRD0ke1NFUlZJQ0VfRkFDRUJPT0tfSUR9JwogICAgICAtICdGQUNFQk9PS19BUFBfU0VDUkVUPSR7U0VSVklDRV9GQUNFQk9PS19TRUNSRVR9JwogICAgICAtICdZT1VUVUJFX0NMSUVOVF9JRD0ke1NFUlZJQ0VfWU9VVFVCRV9JRH0nCiAgICAgIC0gJ1lPVVRVQkVfQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfWU9VVFVCRV9TRUNSRVR9JwogICAgICAtICdUSUtUT0tfQ0xJRU5UX0lEPSR7U0VSVklDRV9USUtUT0tfSUR9JwogICAgICAtICdUSUtUT0tfQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfVElLVE9LX1NFQ1JFVH0nCiAgICAgIC0gJ1BJTlRFUkVTVF9DTElFTlRfSUQ9JHtTRVJWSUNFX1BJTlRFUkVTVF9JRH0nCiAgICAgIC0gJ1BJTlRFUkVTVF9DTElFTlRfU0VDUkVUPSR7U0VSVklDRV9QSU5URVJFU1RfU0VDUkVUfScKICAgICAgLSAnRFJJQkJCTEVfQ0xJRU5UX0lEPSR7U0VSVklDRV9EUklCQkxFX0lEfScKICAgICAgLSAnRFJJQkJCTEVfQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfRFJJQkJMRV9TRUNSRVR9JwogICAgICAtICdESVNDT1JEX0NMSUVOVF9JRD0ke1NFUlZJQ0VfRElTQ09SRF9JRH0nCiAgICAgIC0gJ0RJU0NPUkRfQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfRElTQ09SRF9TRUNSRVR9JwogICAgICAtICdESVNDT1JEX0JPVF9UT0tFTl9JRD0ke1NFUlZJQ0VfRElTQ09SRF9UT0tFTn0nCiAgICAgIC0gJ1NMQUNLX0lEPSR7U0VSVklDRV9TTEFDS19JRH0nCiAgICAgIC0gJ1NMQUNLX1NFQ1JFVD0ke1NFUlZJQ0VfU0xBQ0tfU0VDUkVUfScKICAgICAgLSAnU0xBQ0tfU0lHTklOR19TRUNSRVQ9JHtTTEFDS19TSUdOSU5HX1NFQ1JFVH0nCiAgICAgIC0gJ01BU1RPRE9OX0NMSUVOVF9JRD0ke1NFUlZJQ0VfTUFTVE9ET05fSUR9JwogICAgICAtICdNQVNUT0RPTl9DTElFTlRfU0VDUkVUPSR7U0VSVklDRV9NQVNUT0RPTl9TRUNSRVR9JwogICAgICAtICdJTlNUQUdSQU1fQVBQX0lEPSR7SU5TVEFHUkFNX0FQUF9JRH0nCiAgICAgIC0gJ0lOU1RBR1JBTV9BUFBfU0VDUkVUPSR7SU5TVEFHUkFNX0FQUF9TRUNSRVR9JwogICAgICAtICdCRUVISUlWRV9BUElfS0VZPSR7U0VSVklDRV9CRUVISUlWRV9LRVl9JwogICAgICAtICdCRUVISUlWRV9QVUJMSUNBVElPTl9JRD0ke1NFUlZJQ0VfQkVFSElJVkVfUFVCSUR9JwogICAgICAtICdPUEVOQUlfQVBJX0tFWT0ke1NFUlZJQ0VfT1BFTkFJX0tFWX0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0RJU0NPUkRfU1VQUE9SVD0ke05FWFRfUFVCTElDX0RJU0NPUkRfU1VQUE9SVH0nCiAgICAgIC0gJ05FWFRfUFVCTElDX1BPTE9UTk89JHtORVhUX1BVQkxJQ19QT0xPVE5PfScKICAgICAgLSBJU19HRU5FUkFMPXRydWUKICAgICAgLSAnTlhfQUREX1BMVUdJTlM9JHtOWF9BRERfUExVR0lOUzotZmFsc2V9JwogICAgICAtICdOT1RfU0VDVVJFRD0ke05PVF9TRUNVUkVEOi1mYWxzZX0nCiAgICAgIC0gJ0ZFRV9BTU9VTlQ9JHtGRUVfQU1PVU5UOi0wLjA1fScKICAgICAgLSAnU1RSSVBFX1BVQkxJU0hBQkxFX0tFWT0ke1NUUklQRV9QVUJMSVNIQUJMRV9LRVl9JwogICAgICAtICdTVFJJUEVfU0VDUkVUX0tFWT0ke1NUUklQRV9TRUNSRVRfS0VZfScKICAgICAgLSAnU1RSSVBFX1NJR05JTkdfS0VZPSR7U1RSSVBFX1NJR05JTkdfS0VZfScKICAgICAgLSAnU1RSSVBFX1NJR05JTkdfS0VZX0NPTk5FQ1Q9JHtTVFJJUEVfU0lHTklOR19LRVlfQ09OTkVDVH0nCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0aXpfY29uZmlnOi9jb25maWcvJwogICAgICAtICdwb3N0aXpfdXBsb2FkczovdXBsb2Fkcy8nCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3JlczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICByZWRpczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICd3Z2V0IC1xTy0gaHR0cDovLzEyNy4wLjAuMTo1MDAwLycKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHBvc3RncmVzOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNC41JwogICAgdm9sdW1lczoKICAgICAgLSAncG9zdGl6X3Bvc3RncmVzcWxfZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBQT1NUR1JFU19VU0VSPXBvc3RncmVzCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU1FMX0RBVEFCQVNFOi1wb3N0aXotZGJ9JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCOi1wb3N0aXotZGJ9JwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOjcuMicKICAgIGVudmlyb25tZW50OgogICAgICAtICdSRURJU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUkVESVN9JwogICAgY29tbWFuZDogJ3JlZGlzLXNlcnZlciAtLXJlcXVpcmVwYXNzICR7U0VSVklDRV9QQVNTV09SRF9SRURJU30nCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0aXpfcmVkaXNfZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtICctYScKICAgICAgICAtICcke1NFUlZJQ0VfUEFTU1dPUkRfUkVESVN9JwogICAgICAgIC0gcGluZwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDIwCg==", "tags": [ "post everywhere", "social media", @@ -3892,7 +3937,7 @@ "sequin": { "documentation": "https://sequinstream.com/docs/?utm_source=coolify.io", "slogan": "The fastest Postgres change data capture", - "compose": "c2VydmljZXM6CiAgc2VxdWluOgogICAgaW1hZ2U6ICdzZXF1aW4vc2VxdWluOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfVVJMX1NFUVVJTl83Mzc2CiAgICAgIC0gJ1NFUlZFUl9IT1NUPSR7U0VSVklDRV9VUkxfU0VRVUlOfScKICAgICAgLSBQR19IT1NUTkFNRT1wb3N0Z3JlcwogICAgICAtICdQR19EQVRBQkFTRT0ke1BPU1RHUkVTX0RCOi1zZXF1aW4tZGJ9JwogICAgICAtIFBHX1BPUlQ9NTQzMgogICAgICAtICdQR19VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BHX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gUEdfUE9PTF9TSVpFPTIwCiAgICAgIC0gJ1NFQ1JFVF9LRVlfQkFTRT0ke1NFUlZJQ0VfUkVBTEJBU0U2NF82NF9TRUNSRVRLRVl9JwogICAgICAtICdWQVVMVF9LRVk9JHtTRVJWSUNFX1JFQUxCQVNFNjRfVkFVTFRLRVl9JwogICAgICAtICdSRURJU19VUkw9cmVkaXM6Ly9yZWRpczo2Mzc5JwogICAgICAtIENPTkZJR19GSUxFX1BBVEg9L2NvbmZpZy9wbGF5Z3JvdW5kLnltbAogICAgICAtICdGRUFUVVJFX0FDQ09VTlRfU0VMRl9TSUdOVVA9JHtGRUFUVVJFX0FDQ09VTlRfU0VMRl9TSUdOVVA6LWZhbHNlfScKICAgICAgLSAnU0VRVUlOX1RFTEVNRVRSWV9ESVNBQkxFRD0ke1NFUVVJTl9URUxFTUVUUllfRElTQUJMRUQ6LWZhbHNlfScKICAgICAgLSAnQ1JBU0hfUkVQT1JUSU5HX0RJU0FCTEVEPSR7Q1JBU0hfUkVQT1JUSU5HX0RJU0FCTEVEOi1mYWxzZX0nCiAgICBkZXBlbmRzX29uOgogICAgICByZWRpczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBwb3N0Z3JlczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjczNzYvaGVhbHRoJwogIHBvc3RncmVzOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNicKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1zZXF1aW4tZGJ9JwogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgIGNvbW1hbmQ6CiAgICAgIC0gcG9zdGdyZXMKICAgICAgLSAnLWMnCiAgICAgIC0gd2FsX2xldmVsPWxvZ2ljYWwKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30gLWQgc2VxdWluJwogICAgICBpbnRlcnZhbDogMTBzCiAgICAgIHRpbWVvdXQ6IDJzCiAgICAgIHJldHJpZXM6IDUKICAgICAgc3RhcnRfcGVyaW9kOiAycwogICAgICBzdGFydF9pbnRlcnZhbDogMXMKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Bvc3RncmVzX2RhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczo3JwogICAgY29tbWFuZDoKICAgICAgLSByZWRpcy1zZXJ2ZXIKICAgICAgLSAnLS1wb3J0JwogICAgICAtICc2Mzc5JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHJlZGlzLWNsaQogICAgICAgIC0gcGluZwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgICB2b2x1bWVzOgogICAgICAtICdyZWRpc19kYXRhOi9kYXRhJwo=", + "compose": "c2VydmljZXM6CiAgc2VxdWluOgogICAgaW1hZ2U6ICdzZXF1aW4vc2VxdWluOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfVVJMX1NFUVVJTl83Mzc2CiAgICAgIC0gJ1NFUlZFUl9IT1NUPSR7U0VSVklDRV9GUUROX1NFUVVJTn0nCiAgICAgIC0gUEdfSE9TVE5BTUU9cG9zdGdyZXMKICAgICAgLSAnUEdfREFUQUJBU0U9JHtQT1NUR1JFU19EQjotc2VxdWluLWRifScKICAgICAgLSBQR19QT1JUPTU0MzIKICAgICAgLSAnUEdfVVNFUk5BTUU9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQR19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtIFBHX1BPT0xfU0laRT0yMAogICAgICAtICdTRUNSRVRfS0VZX0JBU0U9JHtTRVJWSUNFX1JFQUxCQVNFNjRfNjRfU0VDUkVUS0VZfScKICAgICAgLSAnVkFVTFRfS0VZPSR7U0VSVklDRV9SRUFMQkFTRTY0X1ZBVUxUS0VZfScKICAgICAgLSAnUkVESVNfVVJMPXJlZGlzOi8vcmVkaXM6NjM3OScKICAgICAgLSBDT05GSUdfRklMRV9QQVRIPS9jb25maWcvcGxheWdyb3VuZC55bWwKICAgICAgLSAnRkVBVFVSRV9BQ0NPVU5UX1NFTEZfU0lHTlVQPSR7RkVBVFVSRV9BQ0NPVU5UX1NFTEZfU0lHTlVQOi1mYWxzZX0nCiAgICAgIC0gJ1NFUVVJTl9URUxFTUVUUllfRElTQUJMRUQ9JHtTRVFVSU5fVEVMRU1FVFJZX0RJU0FCTEVEOi1mYWxzZX0nCiAgICAgIC0gJ0NSQVNIX1JFUE9SVElOR19ESVNBQkxFRD0ke0NSQVNIX1JFUE9SVElOR19ESVNBQkxFRDotZmFsc2V9JwogICAgZGVwZW5kc19vbjoKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcG9zdGdyZXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo3Mzc2L2hlYWx0aCcKICBwb3N0Z3JlczoKICAgIGltYWdlOiAncG9zdGdyZXM6MTYnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotc2VxdWluLWRifScKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICBjb21tYW5kOgogICAgICAtIHBvc3RncmVzCiAgICAgIC0gJy1jJwogICAgICAtIHdhbF9sZXZlbD1sb2dpY2FsCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLVUgJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9IC1kIHNlcXVpbicKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiAycwogICAgICByZXRyaWVzOiA1CiAgICAgIHN0YXJ0X3BlcmlvZDogMnMKICAgICAgc3RhcnRfaW50ZXJ2YWw6IDFzCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0Z3Jlc19kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICByZWRpczoKICAgIGltYWdlOiAncmVkaXM6NycKICAgIGNvbW1hbmQ6CiAgICAgIC0gcmVkaXMtc2VydmVyCiAgICAgIC0gJy0tcG9ydCcKICAgICAgLSAnNjM3OScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogICAgdm9sdW1lczoKICAgICAgLSAncmVkaXNfZGF0YTovZGF0YScK", "tags": [ "postgres", "sync", @@ -3903,6 +3948,22 @@ "minversion": "0.0.0", "port": "7376" }, + "sftpgo": { + "documentation": "https://docs.sftpgo.com/2.7/?utm_source=coolify.io", + "slogan": "SFTPGo is an event-driven SFTP, FTP/S, HTTP/S and WebDAV server.", + "compose": "c2VydmljZXM6CiAgc2Z0cGdvOgogICAgaW1hZ2U6ICdnaGNyLmlvL2RyYWtrYW4vc2Z0cGdvOnYyLjctYWxwaW5lJwogICAgcG9ydHM6CiAgICAgIC0gJzIyMjI6MjIyMicKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9TRlRQR09fODA4MAogICAgICAtIFNGVFBHT19EQVRBX1BST1ZJREVSX19EUklWRVI9cG9zdGdyZXNxbAogICAgICAtICdTRlRQR09fREFUQV9QUk9WSURFUl9fQ09OTkVDVElPTl9TVFJJTkc9cG9zdGdyZXNxbDovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfNjRfUE9TVEdSRVN9QHBvc3RncmVzcWw6NTQzMi8ke1BPU1RHUkVTX0RBVEFCQVNFOi1zZnRwZ28tZGJ9JwogICAgICAtIFNGVFBHT19TRlRQRF9fQklORElOR1NfXzBfX1BPUlQ9MjAyMgogICAgICAtICdTRlRQR09fTE9HX0xFVkVMPSR7TE9HX0xFVkVMOi1pbmZvfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnd2dldCAtcU8tIGh0dHA6Ly8xMjcuMC4wLjE6ODA4MC8nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzcWw6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3NmdHBnby1kYXRhOi9zcnYvc2Z0cGdvL2RhdGEnCiAgICAgIC0gJ3NmdHBnby1rZXlzOi92YXIvbGliL3NmdHBnbycKICBwb3N0Z3Jlc3FsOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNy1hbHBpbmUnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF82NF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREFUQUJBU0U6LXNmdHBnby1kYn0nCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0Z3Jlc3FsLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAyMAo=", + "tags": [ + "sftpgo", + "sftp", + "ftp", + "file", + "webdav" + ], + "category": null, + "logo": "svgs/sftpgo.png", + "minversion": "0.0.0", + "port": "8080" + }, "shlink": { "documentation": "https://shlink.io/?utm_source=coolify.io", "slogan": "The definitive self-hosted URL shortener", @@ -3940,6 +4001,20 @@ "minversion": "0.0.0", "port": "8080" }, + "silverbullet": { + "documentation": "https://v2.silverbullet.md/Install/Configuration?utm_source=coolify.io", + "slogan": "SilverBullet is a tool to develop, organize, and structure your personal knowledge and to make it universally accessible across all your devices.", + "compose": "c2VydmljZXM6CiAgc2lsdmVyYnVsbGV0OgogICAgaW1hZ2U6ICdnaGNyLmlvL3NpbHZlcmJ1bGxldG1kL3NpbHZlcmJ1bGxldDp2MicKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfVVJMX1NJTFZFUkJVTExFVF8zMDAwCiAgICAgIC0gJ1NCX1VTRVI9JHtTRVJWSUNFX1VTRVJfU0lMVkVSQlVMTEVUfToke1NFUlZJQ0VfUEFTU1dPUkRfU0lMVkVSQlVMTEVUfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3NpbHZlcmJ1bGxldC1zcGFjZTovc3BhY2UnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gd2dldAogICAgICAgIC0gJy0tc3BpZGVyJwogICAgICAgIC0gJy0tcXVpZXQnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTozMDAwJwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDUK", + "tags": [ + "note-taking", + "markdown", + "pkm" + ], + "category": null, + "logo": "svgs/silverbullet.png", + "minversion": "0.0.0", + "port": "3000" + }, "siyuan": { "documentation": "https://github.com/siyuan-note/siyuan?utm_source=coolify.io", "slogan": "A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang.", @@ -4282,6 +4357,22 @@ "minversion": "0.0.0", "port": "8082" }, + "trailbase": { + "documentation": "https://trailbase.io/?utm_source=coolify.io", + "slogan": "A blazingly fast Rust/SQLite/Wasmtime app server with type-safe APIs", + "compose": "c2VydmljZXM6CiAgdHJhaWxiYXNlOgogICAgaW1hZ2U6ICd0cmFpbGJhc2UvdHJhaWxiYXNlOjAuMjIuNicKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfVVJMX1RSQUlMQkFTRV80MDAwCiAgICB2b2x1bWVzOgogICAgICAtICd0cmFpbGJhc2UtZGF0YTovYXBwL3RyYWlsZGVwb3QnCg==", + "tags": [ + "trailbase", + "backend", + "saas", + "mobile", + "api" + ], + "category": "backend", + "logo": "svgs/trailbase.svg", + "minversion": "0.0.0", + "port": "4000" + }, "transmission": { "documentation": "https://docs.linuxserver.io/images/docker-transmission/?utm_source=coolify.io", "slogan": "Fast, easy, and free BitTorrent client.", @@ -4719,7 +4810,7 @@ "wireguard-easy": { "documentation": "https://github.com/wg-easy/wg-easy?utm_source=coolify.io", "slogan": "The easiest way to run WireGuard VPN + Web-based Admin UI.", - "compose": "c2VydmljZXM6CiAgd2ctZWFzeToKICAgIGltYWdlOiAnZ2hjci5pby93Zy1lYXN5L3dnLWVhc3k6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9VUkxfV0lSRUdVQVJERUFTWV81MTgyMQogICAgICAtICdXR19IT1NUPSR7U0VSVklDRV9VUkxfV0lSRUdVQVJERUFTWX0nCiAgICAgIC0gJ0xBTkc9JHtMQU5HOi1lbn0nCiAgICAgIC0gV0dfUE9SVD01MTgyMAogICAgICAtICdfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX0FETUlOfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3dnLWVhc3k6L2V0Yy93aXJlZ3VhcmQnCiAgICBwb3J0czoKICAgICAgLSAnNTE4MjA6NTE4MjAvdWRwJwogICAgY2FwX2FkZDoKICAgICAgLSBORVRfQURNSU4KICAgICAgLSBTWVNfTU9EVUxFCiAgICBzeXNjdGxzOgogICAgICAtIG5ldC5pcHY0LmNvbmYuYWxsLnNyY192YWxpZF9tYXJrPTEKICAgICAgLSBuZXQuaXB2NC5pcF9mb3J3YXJkPTEKICAgIGVudHJ5cG9pbnQ6CiAgICAgIC0gL2Jpbi9iYXNoCiAgICAgIC0gJy1jJwogICAgICAtICJldmFsIFwid2dwdyAnJHtTRVJWSUNFX1BBU1NXT1JEX0FETUlOfScgPiAvcGFzcy1oYXNoXCJcbmV2YWwgXCIkKGNhdCAvcGFzcy1oYXNoKSBkdW1iLWluaXQgbm9kZSBzZXJ2ZXIuanNcIlxuIgo=", + "compose": "c2VydmljZXM6CiAgd2ctZWFzeToKICAgIGltYWdlOiAnZ2hjci5pby93Zy1lYXN5L3dnLWVhc3k6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9VUkxfV0lSRUdVQVJERUFTWV81MTgyMQogICAgICAtICdXR19IT1NUPSR7U0VSVklDRV9GUUROX1dJUkVHVUFSREVBU1l9JwogICAgICAtICdMQU5HPSR7TEFORzotZW59JwogICAgICAtIFdHX1BPUlQ9NTE4MjAKICAgICAgLSAnX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9BRE1JTn0nCiAgICB2b2x1bWVzOgogICAgICAtICd3Zy1lYXN5Oi9ldGMvd2lyZWd1YXJkJwogICAgcG9ydHM6CiAgICAgIC0gJzUxODIwOjUxODIwL3VkcCcKICAgIGNhcF9hZGQ6CiAgICAgIC0gTkVUX0FETUlOCiAgICAgIC0gU1lTX01PRFVMRQogICAgc3lzY3RsczoKICAgICAgLSBuZXQuaXB2NC5jb25mLmFsbC5zcmNfdmFsaWRfbWFyaz0xCiAgICAgIC0gbmV0LmlwdjQuaXBfZm9yd2FyZD0xCiAgICBlbnRyeXBvaW50OgogICAgICAtIC9iaW4vYmFzaAogICAgICAtICctYycKICAgICAgLSAiZXZhbCBcIndncHcgJyR7U0VSVklDRV9QQVNTV09SRF9BRE1JTn0nID4gL3Bhc3MtaGFzaFwiXG5ldmFsIFwiJChjYXQgL3Bhc3MtaGFzaCkgZHVtYi1pbml0IG5vZGUgc2VydmVyLmpzXCJcbiIK", "tags": [ "wireguard", "vpn", diff --git a/templates/service-templates.json b/templates/service-templates.json index 89b8044dd..b9dc75ebd 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -580,6 +580,21 @@ "logo": "svgs/cloudflared.svg", "minversion": "0.0.0" }, + "cloudreve": { + "documentation": "https://docs.cloudreve.org/?utm_source=coolify.io", + "slogan": "A self-hosted file management and sharing system.", + "compose": "c2VydmljZXM6CiAgY2xvdWRyZXZlOgogICAgaW1hZ2U6ICdjbG91ZHJldmUvY2xvdWRyZXZlOjQuMTAuMScKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9DTE9VRFJFVkVfNTIxMgogICAgICAtIENSX0NPTkZfRGF0YWJhc2UuVHlwZT1wb3N0Z3JlcwogICAgICAtIENSX0NPTkZfRGF0YWJhc2UuSG9zdD1wb3N0Z3JlcwogICAgICAtICdDUl9DT05GX0RhdGFiYXNlLlVzZXI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdDUl9DT05GX0RhdGFiYXNlLlBhc3N3b3JkPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ0NSX0NPTkZfRGF0YWJhc2UuTmFtZT0ke1BPU1RHUkVTX0RCOi1jbG91ZHJldmUtZGJ9JwogICAgICAtIENSX0NPTkZfRGF0YWJhc2UuUG9ydD01NDMyCiAgICAgIC0gJ0NSX0NPTkZfUmVkaXMuU2VydmVyPXJlZGlzOjYzNzknCiAgICAgIC0gJ0NSX0NPTkZfUmVkaXMuUGFzc3dvcmQ9JHtTRVJWSUNFX1BBU1NXT1JEX1JFRElTfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2Nsb3VkcmV2ZS1kYXRhOi9jbG91ZHJldmUvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBuYwogICAgICAgIC0gJy16JwogICAgICAgIC0gbG9jYWxob3N0CiAgICAgICAgLSAnNTIxMicKICAgICAgaW50ZXJ2YWw6IDIwcwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMwogICAgZGVwZW5kc19vbjoKICAgICAgcG9zdGdyZXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICBwb3N0Z3JlczoKICAgIGltYWdlOiAncG9zdGdyZXM6MTgtYWxwaW5lJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1jbG91ZHJldmUtZGJ9JwogICAgdm9sdW1lczoKICAgICAgLSAncG9zdGdyZXMtZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLVUgJCR7UE9TVEdSRVNfVVNFUn0gLWQgJCR7UE9TVEdSRVNfREJ9JwogICAgICBpbnRlcnZhbDogMTBzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDUKICByZWRpczoKICAgIGltYWdlOiAncmVkaXM6Ny1hbHBpbmUnCiAgICBjb21tYW5kOiAncmVkaXMtc2VydmVyIC0tcmVxdWlyZXBhc3MgJHtTRVJWSUNFX1BBU1NXT1JEX1JFRElTfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3JlZGlzLWRhdGE6L2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSAnLWEnCiAgICAgICAgLSAnJHtTRVJWSUNFX1BBU1NXT1JEX1JFRElTfScKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1Cg==", + "tags": [ + "file sharing", + "cloud storage", + "self-hosted", + "open-source" + ], + "category": "storage", + "logo": "svgs/cloudreve.svg", + "minversion": "0.0.0", + "port": "5212" + }, "cockpit": { "documentation": "https://getcockpit.com/documentation/?utm_source=coolify.io", "slogan": "Cockpit is a headless content platform that is lightweight, fast and ready for takeoff.", @@ -1073,6 +1088,21 @@ "minversion": "0.0.0", "port": "8080" }, + "esphome": { + "documentation": "https://esphome.io/guides/getting_started_command_line/?utm_source=coolify.io", + "slogan": "Smart Home Made Simple.", + "compose": "c2VydmljZXM6CiAgZXNwaG9tZToKICAgIGltYWdlOiAnZ2hjci5pby9lc3Bob21lL2VzcGhvbWU6MjAyNS4xMi40JwogICAgdm9sdW1lczoKICAgICAgLSAnZXNwX2NvbmZpZzovY29uZmlnJwogICAgICAtICcvZXRjL2xvY2FsdGltZTovZXRjL2xvY2FsdGltZTpybycKICAgIHByaXZpbGVnZWQ6IHRydWUKICAgIG5ldHdvcmtfbW9kZTogaG9zdAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0VTUEhPTUVfNjA1MgogICAgICAtICdVU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9BRE1JTn0nCiAgICAgIC0gJ1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9BRE1JTn0nCg==", + "tags": [ + "home", + "smart", + "assistant", + "microcontroller" + ], + "category": "automation", + "logo": "svgs/esphome.svg", + "minversion": "0.0.0", + "port": "6052" + }, "evolution-api": { "documentation": "https://doc.evolution-api.com/v2/en/get-started/introduction?utm_source=coolify.io", "slogan": "Multi-platform messaging (whatsapp and more) integration API", @@ -1766,6 +1796,21 @@ "logo": "svgs/grocy.svg", "minversion": "0.0.0" }, + "hatchet": { + "documentation": "https://docs.hatchet.run/self-hosting/docker-compose?utm_source=coolify.io", + "slogan": "Hatchet is a high-throughput, low-latency computing service. It's built on an open-source, fault-tolerant queue, allowing work to be delivered as fast as your system can handle", + "compose": "c2VydmljZXM6CiAgaGF0Y2hldC1kYXNoYm9hcmQ6CiAgICBpbWFnZTogJ2doY3IuaW8vaGF0Y2hldC1kZXYvaGF0Y2hldC9oYXRjaGV0LWRhc2hib2FyZDpsYXRlc3QnCiAgICBjb21tYW5kOiAnc2ggLi9lbnRyeXBvaW50LnNoIC0tY29uZmlnIC9oYXRjaGV0L2NvbmZpZycKICAgIGVudmlyb25tZW50OgogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzOjU0MzIvJFBPU1RHUkVTX0RCJwogICAgICAtIFNFUlZJQ0VfRlFETl9IQVRDSEVUXzgwCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3JlczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICByYWJiaXRtcToKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBzZXR1cC1jb25maWc6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2NvbXBsZXRlZF9zdWNjZXNzZnVsbHkKICAgICAgbWlncmF0aW9uOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9jb21wbGV0ZWRfc3VjY2Vzc2Z1bGx5CiAgICB2b2x1bWVzOgogICAgICAtICdoYXRjaGV0LWNlcnRzOi9oYXRjaGV0L2NlcnRzJwogICAgICAtICdoYXRjaGV0LWNvbmZpZzovaGF0Y2hldC9jb25maWcnCiAgaGF0Y2hldC1lbmdpbmU6CiAgICBpbWFnZTogJ2doY3IuaW8vaGF0Y2hldC1kZXYvaGF0Y2hldC9oYXRjaGV0LWVuZ2luZTpsYXRlc3QnCiAgICBjb21tYW5kOiAnL2hhdGNoZXQvaGF0Y2hldC1lbmdpbmUgLS1jb25maWcgL2hhdGNoZXQvY29uZmlnJwogICAgcmVzdGFydDogb24tZmFpbHVyZQogICAgZGVwZW5kc19vbjoKICAgICAgcG9zdGdyZXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmFiYml0bXE6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgc2V0dXAtY29uZmlnOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9jb21wbGV0ZWRfc3VjY2Vzc2Z1bGx5CiAgICAgIG1pZ3JhdGlvbjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfY29tcGxldGVkX3N1Y2Nlc3NmdWxseQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcG9zdGdyZXM6NTQzMi8kUE9TVEdSRVNfREInCiAgICAgIC0gJ1NFUlZFUl9HUlBDX0JJTkRfQUREUkVTUz0ke1NFUlZFUl9HUlBDX0JJTkRfQUREUkVTUzotMC4wLjAuMH0nCiAgICAgIC0gJ1NFUlZFUl9HUlBDX0lOU0VDVVJFPSR7U0VSVkVSX0dSUENfSU5TRUNVUkU6LXR9JwogICAgdm9sdW1lczoKICAgICAgLSAnaGF0Y2hldC1jZXJ0czovaGF0Y2hldC9jZXJ0cycKICAgICAgLSAnaGF0Y2hldC1jb25maWc6L2hhdGNoZXQvY29uZmlnJwogIHBvc3RncmVzOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNi1hbHBpbmUnCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0Z3Jlc3FsLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUE9TVEdSRVNfVVNFUj0kU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotaGF0Y2hldH0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLVUgJCR7UE9TVEdSRVNfVVNFUn0gLWQgJCR7UE9TVEdSRVNfREJ9JwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcmFiYml0bXE6CiAgICBpbWFnZTogJ3JhYmJpdG1xOjMtbWFuYWdlbWVudCcKICAgIGhvc3RuYW1lOiByYWJiaXRtcQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX1JBQkJJVE1RXzE1NjcyCiAgICAgIC0gUkFCQklUTVFfREVGQVVMVF9VU0VSPSRTRVJWSUNFX1VTRVJfUkFCQklUTVEKICAgICAgLSBSQUJCSVRNUV9ERUZBVUxUX1BBU1M9JFNFUlZJQ0VfUEFTU1dPUkRfUkFCQklUTVEKICAgICAgLSAnUE9SVD0ke1JBQkJJVE1RX1BPUlQ6LTU2NzJ9JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6ICdyYWJiaXRtcS1kaWFnbm9zdGljcyAtcSBwaW5nJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMzBzCiAgICAgIHJldHJpZXM6IDEwCiAgICB2b2x1bWVzOgogICAgICAtICdyYWJiaXRtcS1kYXRhOi92YXIvbGliL3JhYmJpdG1xLycKICBtaWdyYXRpb246CiAgICBpbWFnZTogJ2doY3IuaW8vaGF0Y2hldC1kZXYvaGF0Y2hldC9oYXRjaGV0LW1pZ3JhdGU6bGF0ZXN0JwogICAgY29tbWFuZDogL2hhdGNoZXQvaGF0Y2hldC1taWdyYXRlCiAgICByZXN0YXJ0OiAnbm8nCiAgICBleGNsdWRlX2Zyb21faGM6IHRydWUKICAgIGVudmlyb25tZW50OgogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzOjU0MzIvJFBPU1RHUkVTX0RCJwogICAgZGVwZW5kc19vbjoKICAgICAgcG9zdGdyZXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICBzZXR1cC1jb25maWc6CiAgICBpbWFnZTogJ2doY3IuaW8vaGF0Y2hldC1kZXYvaGF0Y2hldC9oYXRjaGV0LWFkbWluOmxhdGVzdCcKICAgIGNvbW1hbmQ6ICcvaGF0Y2hldC9oYXRjaGV0LWFkbWluIHF1aWNrc3RhcnQgLS1za2lwIGNlcnRzIC0tZ2VuZXJhdGVkLWNvbmZpZy1kaXIgL2hhdGNoZXQvY29uZmlnIC0tb3ZlcndyaXRlPWZhbHNlJwogICAgcmVzdGFydDogJ25vJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcG9zdGdyZXM6NTQzMi8kUE9TVEdSRVNfREInCiAgICAgIC0gJ1NFUlZFUl9UQVNLUVVFVUVfUkFCQklUTVFfVVJMPWFtcXA6Ly8kU0VSVklDRV9VU0VSX1JBQkJJVE1ROiRTRVJWSUNFX1BBU1NXT1JEX1JBQkJJVE1RQHJhYmJpdG1xOjU2NzIvJwogICAgICAtICdTRVJWRVJfQVVUSF9DT09LSUVfRE9NQUlOPSR7U0VSVkVSX0FVVEhfQ09PS0lFX0RPTUFJTjotbG9jYWxob3N0OjgwODB9JwogICAgICAtICdTRVJWRVJfQVVUSF9DT09LSUVfSU5TRUNVUkU9JHtTRVJWRVJfQVVUSF9DT09LSUVfSU5TRUNVUkU6LXR9JwogICAgICAtICdTRVJWRVJfR1JQQ19CSU5EX0FERFJFU1M9JHtTRVJWRVJfR1JQQ19CSU5EX0FERFJFU1M6LTAuMC4wLjB9JwogICAgICAtICdTRVJWRVJfR1JQQ19JTlNFQ1VSRT0ke1NFUlZFUl9HUlBDX0lOU0VDVVJFOi10fScKICAgICAgLSAnU0VSVkVSX0dSUENfQlJPQURDQVNUX0FERFJFU1M9JHtTRVJWRVJfR1JQQ19CUk9BRENBU1RfQUREUkVTUzotbG9jYWxob3N0OjcwNzd9JwogICAgICAtIFNFUlZFUl9ERUZBVUxUX0VOR0lORV9WRVJTSU9OPVYxCiAgICAgIC0gJ1NFUlZFUl9JTlRFUk5BTF9DTElFTlRfSU5URVJOQUxfR1JQQ19CUk9BRENBU1RfQUREUkVTUz0ke1NFUlZFUl9JTlRFUk5BTF9DTElFTlRfSU5URVJOQUxfR1JQQ19CUk9BRENBU1RfQUREUkVTUzotaGF0Y2hldC1lbmdpbmU6NzA3N30nCiAgICB2b2x1bWVzOgogICAgICAtICdoYXRjaGV0X2NlcnRzOi9oYXRjaGV0L2NlcnRzJwogICAgICAtICdoYXRjaGV0X2NvbmZpZzovaGF0Y2hldC9jb25maWcnCiAgICBkZXBlbmRzX29uOgogICAgICBtaWdyYXRpb246CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2NvbXBsZXRlZF9zdWNjZXNzZnVsbHkKICAgICAgcmFiYml0bXE6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcG9zdGdyZXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkK", + "tags": [ + "ai-agents", + "background-tasks", + "data-pipelines", + "scheduling" + ], + "category": null, + "logo": "svgs/hatchet.svg", + "minversion": "0.0.0", + "port": "80" + }, "heimdall": { "documentation": "https://github.com/linuxserver/Heimdall?utm_source=coolify.io", "slogan": "Heimdall is a dashboard for managing and organizing your server applications.", @@ -1862,7 +1907,7 @@ "hoppscotch": { "documentation": "https://docs.hoppscotch.io?utm_source=coolify.io", "slogan": "The Open Source API Development Platform", - "compose": "c2VydmljZXM6CiAgYmFja2VuZDoKICAgIGltYWdlOiAnaG9wcHNjb3RjaC9ob3Bwc2NvdGNoOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9IT1BQU0NPVENIXzgwCiAgICAgIC0gJ1ZJVEVfQUxMT1dFRF9BVVRIX1BST1ZJREVSUz0ke1ZJVEVfQUxMT1dFRF9BVVRIX1BST1ZJREVSUzotR09PR0xFLEdJVEhVQixNSUNST1NPRlQsRU1BSUx9JwogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QGhvcHBzY290Y2gtZGI6NTQzMi8ke1BPU1RHUkVTX0RCfScKICAgICAgLSAnSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSAnVE9LRU5fU0FMVF9DT01QTEVYSVRZPSR7VE9LRU5fU0FMVF9DT01QTEVYSVRZOi0xMH0nCiAgICAgIC0gJ01BR0lDX0xJTktfVE9LRU5fVkFMSURJVFk9JHtNQUdJQ19MSU5LX1RPS0VOX1ZBTElESVRZOi0zfScKICAgICAgLSAnUkVGUkVTSF9UT0tFTl9WQUxJRElUWT0ke1JFRlJFU0hfVE9LRU5fVkFMSURJVFk6LTYwNDgwMDAwMH0nCiAgICAgIC0gJ0FDQ0VTU19UT0tFTl9WQUxJRElUWT0ke0FDQ0VTU19UT0tFTl9WQUxJRElUWTotODY0MDAwMDB9JwogICAgICAtICdTRVNTSU9OX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfU0VDUkVUfScKICAgICAgLSAnQUxMT1dfU0VDVVJFX0NPT0tJRVM9JHtBTExPV19TRUNVUkVfQ09PS0lFUzotdHJ1ZX0nCiAgICAgIC0gJ0RBVEFfRU5DUllQVElPTl9LRVk9JHtEQVRBX0VOQ1JZUFRJT05fS0VZOi1tdXN0YmVleGFjdHJ5MzJjaGFyYWN0ZXJsaWtldGhhdH0nCiAgICAgIC0gJ1JFRElSRUNUX1VSTD0ke1NFUlZJQ0VfRlFETl9IT1BQU0NPVENIfScKICAgICAgLSAnV0hJVEVMSVNURURfT1JJR0lOUz0ke1NFUlZJQ0VfRlFETl9IT1BQU0NPVENIfS9iYWNrZW5kLCR7U0VSVklDRV9GUUROX0hPUFBTQ09UQ0h9LCR7U0VSVklDRV9GUUROX0hPUFBTQ09UQ0h9L2FkbWluJwogICAgICAtICdHT09HTEVfQ0xJRU5UX0lEPSR7R09PR0xFX0NMSUVOVF9JRDotKioqKip9JwogICAgICAtICdHT09HTEVfQ0xJRU5UX1NFQ1JFVD0ke0dPT0dMRV9DTElFTlRfU0VDUkVUOi0qKioqKn0nCiAgICAgIC0gJ0dPT0dMRV9DQUxMQkFDS19VUkw9JHtTRVJWSUNFX0ZRRE5fSE9QUFNDT1RDSH0vYmFja2VuZC92MS9hdXRoL2dvb2dsZS9jYWxsYmFjaycKICAgICAgLSAnR09PR0xFX1NDT1BFPWVtYWlsLHByb2ZpbGUnCiAgICAgIC0gJ0dJVEhVQl9DTElFTlRfSUQ9JHtHSVRIVUJfQ0xJRU5UX0lEOi0qKioqKn0nCiAgICAgIC0gJ0dJVEhVQl9DTElFTlRfU0VDUkVUPSR7R0lUSFVCX0NMSUVOVF9TRUNSRVQ6LSoqKioqfScKICAgICAgLSAnR0lUSFVCX0NBTExCQUNLX1VSTD0ke1NFUlZJQ0VfRlFETl9IT1BQU0NPVENIfS9iYWNrZW5kL3YxL2F1dGgvZ2l0aHViL2NhbGxiYWNrJwogICAgICAtICdHSVRIVUJfU0NPUEU9dXNlcjplbWFpbCcKICAgICAgLSAnTUlDUk9TT0ZUX0NMSUVOVF9JRD0ke01JQ1JPU09GVF9DTElFTlRfSUQ6LSoqKioqfScKICAgICAgLSAnTUlDUk9TT0ZUX0NMSUVOVF9TRUNSRVQ9JHtNSUNST1NPRlRfQ0xJRU5UX1NFQ1JFVDotKioqKip9JwogICAgICAtICdNSUNST1NPRlRfQ0FMTEJBQ0tfVVJMPSR7U0VSVklDRV9GUUROX0hPUFBTQ09UQ0h9L2JhY2tlbmQvdjEvYXV0aC9taWNyb3NvZnQvY2FsbGJhY2snCiAgICAgIC0gTUlDUk9TT0ZUX1NDT1BFPXVzZXIucmVhZAogICAgICAtIE1JQ1JPU09GVF9URU5BTlQ9Y29tbW9uCiAgICAgIC0gJ01BSUxFUl9TTVRQX0VOQUJMRT0ke01BSUxFUl9TTVRQX0VOQUJMRTotZmFsc2V9JwogICAgICAtICdNQUlMRVJfVVNFX0NVU1RPTV9DT05GSUdTPSR7TUFJTEVSX1VTRV9DVVNUT01fQ09ORklHUzotdHJ1ZX0nCiAgICAgIC0gJ01BSUxFUl9BRERSRVNTX0ZST009JHtNQUlMRVJfQUREUkVTU19GUk9NOi11c2VyQGV4YW1wbGUuY29tfScKICAgICAgLSAnTUFJTEVSX1NNVFBfVVJMPSR7TUFJTEVSX1NNVFBfVVJMOi1zbXRwc191cmx9JwogICAgICAtICdNQUlMRVJfU01UUF9IT1NUPSR7TUFJTEVSX1NNVFBfSE9TVDotc210cC5leGFtcGxlLmNvbX0nCiAgICAgIC0gJ01BSUxFUl9TTVRQX1BPUlQ9JHtNQUlMRVJfU01UUF9QT1JUOi00NjV9JwogICAgICAtICdNQUlMRVJfU01UUF9TRUNVUkU9JHtNQUlMRVJfU01UUF9TRUNVUkU6LXRydWV9JwogICAgICAtICdNQUlMRVJfU01UUF9VU0VSPSR7TUFJTEVSX1NNVFBfVVNFUjotdXNlckBleGFtcGxlLmNvbX0nCiAgICAgIC0gJ01BSUxFUl9TTVRQX1BBU1NXT1JEPSR7TUFJTEVSX1NNVFBfUEFTU1dPUkQ6LW1haWxwYXNzfScKICAgICAgLSAnTUFJTEVSX1RMU19SRUpFQ1RfVU5BVVRIT1JJWkVEPSR7TUFJTEVSX1RMU19SRUpFQ1RfVU5BVVRIT1JJWkVEOi1mYWxzZX0nCiAgICAgIC0gJ1JBVEVfTElNSVRfVFRMPSR7UkFURV9MSU1JVF9UVEw6LTYwfScKICAgICAgLSAnUkFURV9MSU1JVF9NQVg9JHtSQVRFX0xJTUlUX01BWDotMTAwfScKICAgICAgLSAnVklURV9CQVNFX1VSTD0ke1NFUlZJQ0VfRlFETl9IT1BQU0NPVENIfScKICAgICAgLSAnVklURV9TSE9SVENPREVfQkFTRV9VUkw9JHtTRVJWSUNFX0ZRRE5fSE9QUFNDT1RDSH0nCiAgICAgIC0gJ1ZJVEVfQURNSU5fVVJMPSR7U0VSVklDRV9GUUROX0hPUFBTQ09UQ0h9L2FkbWluJwogICAgICAtICdWSVRFX0JBQ0tFTkRfR1FMX1VSTD0ke1NFUlZJQ0VfRlFETl9IT1BQU0NPVENIfS9iYWNrZW5kL2dyYXBocWwnCiAgICAgIC0gJ1ZJVEVfQkFDS0VORF9XU19VUkw9d3NzOi8vJHtTRVJWSUNFX0ZRRE5fSE9QUFNDT1RDSH0vYmFja2VuZC9ncmFwaHFsJwogICAgICAtICdWSVRFX0JBQ0tFTkRfQVBJX1VSTD0ke1NFUlZJQ0VfRlFETl9IT1BQU0NPVENIfS9iYWNrZW5kL3YxJwogICAgICAtICdWSVRFX0FQUF9UT1NfTElOSz1odHRwczovL2RvY3MuaG9wcHNjb3RjaC5pby9zdXBwb3J0L3Rlcm1zJwogICAgICAtICdWSVRFX0FQUF9QUklWQUNZX1BPTElDWV9MSU5LPWh0dHBzOi8vZG9jcy5ob3Bwc2NvdGNoLmlvL3N1cHBvcnQvcHJpdmFjeScKICAgICAgLSBFTkFCTEVfU1VCUEFUSF9CQVNFRF9BQ0NFU1M9dHJ1ZQogICAgZGVwZW5kc19vbjoKICAgICAgZGItbWlncmF0aW9uOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9jb21wbGV0ZWRfc3VjY2Vzc2Z1bGx5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3dnZXQgLXFPLSBodHRwOi8vMTI3LjAuMC4xOjgwLycKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIGhvcHBzY290Y2gtZGI6CiAgICBpbWFnZTogJ3Bvc3RncmVzOmxhdGVzdCcKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Bvc3RncmVzX2RhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1ob3Bwc2NvdGNofScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtaCBsb2NhbGhvc3QgLVUgJCR7UE9TVEdSRVNfVVNFUn0gLWQgJCR7UE9TVEdSRVNfREJ9JwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDEwCiAgZGItbWlncmF0aW9uOgogICAgZXhjbHVkZV9mcm9tX2hjOiB0cnVlCiAgICBpbWFnZTogJ2hvcHBzY290Y2gvaG9wcHNjb3RjaDpsYXRlc3QnCiAgICBkZXBlbmRzX29uOgogICAgICBob3Bwc2NvdGNoLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBjb21tYW5kOiAncG5weCBwcmlzbWEgbWlncmF0ZSBkZXBsb3knCiAgICByZXN0YXJ0OiBvbi1mYWlsdXJlCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LWhvcHBzY290Y2h9JwogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXM6Ly8ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU306JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUBob3Bwc2NvdGNoLWRiOjU0MzIvJHtQT1NUR1JFU19EQjotaG9wcHNjb3RjaH0nCg==", + "compose": "c2VydmljZXM6CiAgYmFja2VuZDoKICAgIGltYWdlOiAnaG9wcHNjb3RjaC9ob3Bwc2NvdGNoOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9IT1BQU0NPVENIXzgwCiAgICAgIC0gJ1ZJVEVfQUxMT1dFRF9BVVRIX1BST1ZJREVSUz0ke1ZJVEVfQUxMT1dFRF9BVVRIX1BST1ZJREVSUzotR09PR0xFLEdJVEhVQixNSUNST1NPRlQsRU1BSUx9JwogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QGhvcHBzY290Y2gtZGI6NTQzMi8ke1BPU1RHUkVTX0RCfScKICAgICAgLSAnREFUQV9FTkNSWVBUSU9OX0tFWT0ke1NFUlZJQ0VfQkFTRTY0X0RBVEFFTkNSWVBUSU9OS0VZfScKICAgICAgLSAnV0hJVEVMSVNURURfT1JJR0lOUz0ke1NFUlZJQ0VfRlFETl9IT1BQU0NPVENIfS9iYWNrZW5kLCR7U0VSVklDRV9GUUROX0hPUFBTQ09UQ0h9LCR7U0VSVklDRV9GUUROX0hPUFBTQ09UQ0h9L2FkbWluJwogICAgICAtICdNQUlMRVJfVVNFX0NVU1RPTV9DT05GSUdTPSR7TUFJTEVSX1VTRV9DVVNUT01fQ09ORklHUzotdHJ1ZX0nCiAgICAgIC0gJ1ZJVEVfQkFTRV9VUkw9JHtTRVJWSUNFX0ZRRE5fSE9QUFNDT1RDSH0nCiAgICAgIC0gJ1ZJVEVfU0hPUlRDT0RFX0JBU0VfVVJMPSR7U0VSVklDRV9GUUROX0hPUFBTQ09UQ0h9JwogICAgICAtICdWSVRFX0FETUlOX1VSTD0ke1NFUlZJQ0VfRlFETl9IT1BQU0NPVENIfS9hZG1pbicKICAgICAgLSAnVklURV9CQUNLRU5EX0dRTF9VUkw9JHtTRVJWSUNFX0ZRRE5fSE9QUFNDT1RDSH0vYmFja2VuZC9ncmFwaHFsJwogICAgICAtICdWSVRFX0JBQ0tFTkRfV1NfVVJMPXdzczovLyR7U0VSVklDRV9GUUROX0hPUFBTQ09UQ0h9L2JhY2tlbmQvZ3JhcGhxbCcKICAgICAgLSAnVklURV9CQUNLRU5EX0FQSV9VUkw9JHtTRVJWSUNFX0ZRRE5fSE9QUFNDT1RDSH0vYmFja2VuZC92MScKICAgICAgLSAnVklURV9BUFBfVE9TX0xJTks9aHR0cHM6Ly9kb2NzLmhvcHBzY290Y2guaW8vc3VwcG9ydC90ZXJtcycKICAgICAgLSAnVklURV9BUFBfUFJJVkFDWV9QT0xJQ1lfTElOSz1odHRwczovL2RvY3MuaG9wcHNjb3RjaC5pby9zdXBwb3J0L3ByaXZhY3knCiAgICAgIC0gRU5BQkxFX1NVQlBBVEhfQkFTRURfQUNDRVNTPXRydWUKICAgIGRlcGVuZHNfb246CiAgICAgIGRiLW1pZ3JhdGlvbjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfY29tcGxldGVkX3N1Y2Nlc3NmdWxseQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICd3Z2V0IC1xTy0gaHR0cDovLzEyNy4wLjAuMTo4MC8nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICBob3Bwc2NvdGNoLWRiOgogICAgaW1hZ2U6ICdwb3N0Z3JlczpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0Z3Jlc19kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotaG9wcHNjb3RjaH0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLWggbG9jYWxob3N0IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxMAogIGRiLW1pZ3JhdGlvbjoKICAgIGV4Y2x1ZGVfZnJvbV9oYzogdHJ1ZQogICAgaW1hZ2U6ICdob3Bwc2NvdGNoL2hvcHBzY290Y2g6bGF0ZXN0JwogICAgZGVwZW5kc19vbjoKICAgICAgaG9wcHNjb3RjaC1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgY29tbWFuZDogJ3BucHggcHJpc21hIG1pZ3JhdGUgZGVwbG95JwogICAgcmVzdGFydDogb24tZmFpbHVyZQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1ob3Bwc2NvdGNofScKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AaG9wcHNjb3RjaC1kYjo1NDMyLyR7UE9TVEdSRVNfREI6LWhvcHBzY290Y2h9Jwo=", "tags": [ "api", "development", @@ -2687,7 +2732,7 @@ "mosquitto": { "documentation": "https://mosquitto.org/documentation/?utm_source=coolify.io", "slogan": "Mosquitto is lightweight and suitable for use on all devices, from low-power single-board computers to full servers.", - "compose": "c2VydmljZXM6CiAgbW9zcXVpdHRvOgogICAgaW1hZ2U6IGVjbGlwc2UtbW9zcXVpdHRvCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTU9TUVVJVFRPXzE4ODMKICAgICAgLSAnTVFUVF9VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9NT1NRVUlUVE99JwogICAgICAtICdNUVRUX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NT1NRVUlUVE99JwogICAgICAtICdSRVFVSVJFX0NFUlRJRklDQVRFPSR7UkVRVUlSRV9DRVJUSUZJQ0FURTotZmFsc2V9JwogICAgICAtICdBTExPV19BTk9OWU1PVVM9JHtBTExPV19BTk9OWU1PVVM6LXRydWV9JwogICAgdm9sdW1lczoKICAgICAgLSAnbW9zcXVpdHRvLWNvbmZpZzovbW9zcXVpdHRvL2NvbmZpZycKICAgICAgLSAnbW9zcXVpdHRvLWNlcnRzOi9jZXJ0cycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnZXhpdCAwJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgICBlbnRyeXBvaW50OiAic2ggLWMgXCIgaWYgWyAnJFJFUVVJUkVfQ0VSVElGSUNBVEUnID0gJ3RydWUnIF07IHRoZW4gZWNobyAnbGlzdGVuZXIgODg4MycgPiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiAmJiBlY2hvICdjYWZpbGUgL2NlcnRzL2NhLmNydCcgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgJiYgZWNobyAnY2VydGZpbGUgL2NlcnRzL3NlcnZlci5jcnQnID4+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mICYmIGVjaG8gJ2tleWZpbGUgIC9jZXJ0cy9zZXJ2ZXIua2V5JyA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZjsgZWxzZSBlY2hvICdsaXN0ZW5lciAxODgzJyA+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mOyBmaSAmJiBlY2hvICdyZXF1aXJlX2NlcnRpZmljYXRlICckUkVRVUlSRV9DRVJUSUZJQ0FURSA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiAmJiBlY2hvICdhbGxvd19hbm9ueW1vdXMgJyRBTExPV19BTk9OWU1PVVMgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmY7IGlmIFsgLW4gJyRTRVJWSUNFX1VTRVJfTU9TUVVJVFRPJyBdICYmIFsgLW4gJyRTRVJWSUNFX1BBU1NXT1JEX01PU1FVSVRUTycgXTsgdGhlbiBlY2hvICdwYXNzd29yZF9maWxlIC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkcycgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgJiYgdG91Y2ggL21vc3F1aXR0by9jb25maWcvcGFzc3dvcmRzICYmIGNobW9kIDA3MDAgL21vc3F1aXR0by9jb25maWcvcGFzc3dvcmRzICYmIGNob3duIHJvb3Q6cm9vdCAvbW9zcXVpdHRvL2NvbmZpZy9wYXNzd29yZHMgJiYgbW9zcXVpdHRvX3Bhc3N3ZCAtYiAtYyAvbW9zcXVpdHRvL2NvbmZpZy9wYXNzd29yZHMgJFNFUlZJQ0VfVVNFUl9NT1NRVUlUVE8gJFNFUlZJQ0VfUEFTU1dPUkRfTU9TUVVJVFRPICYmIGNob3duIG1vc3F1aXR0bzptb3NxdWl0dG8gL21vc3F1aXR0by9jb25maWcvcGFzc3dvcmRzOyBmaSAmJiBleGVjIG1vc3F1aXR0byAtYyAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiBcIiIKICAgIGxhYmVsczoKICAgICAgLSB0cmFlZmlrLnRjcC5yb3V0ZXJzLm1xdHQuZW50cnlwb2ludHM9bXF0dAogICAgICAtIHRyYWVmaWsudGNwLnJvdXRlcnMubXF0dHMuZW50cnlwb2ludHM9bXF0dHMK", + "compose": "c2VydmljZXM6CiAgbW9zcXVpdHRvOgogICAgaW1hZ2U6IGVjbGlwc2UtbW9zcXVpdHRvCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTU9TUVVJVFRPXzE4ODMKICAgICAgLSAnTVFUVF9VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9NT1NRVUlUVE99JwogICAgICAtICdNUVRUX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NT1NRVUlUVE99JwogICAgICAtICdSRVFVSVJFX0NFUlRJRklDQVRFPSR7UkVRVUlSRV9DRVJUSUZJQ0FURTotZmFsc2V9JwogICAgICAtICdBTExPV19BTk9OWU1PVVM9JHtBTExPV19BTk9OWU1PVVM6LXRydWV9JwogICAgdm9sdW1lczoKICAgICAgLSAnLi9tb3NxdWl0dG8vY29uZmlnOi9tb3NxdWl0dG8vY29uZmlnJwogICAgICAtICcuL2NlcnRzOi9jZXJ0cycKICAgIHBvcnRzOgogICAgICAtICc4ODgzOjg4ODMnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ2V4aXQgMCcKICAgICAgaW50ZXJ2YWw6IDMwcwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMwogICAgZW50cnlwb2ludDogInNoIC1jIFwiIGlmIFsgJyRSRVFVSVJFX0NFUlRJRklDQVRFJyA9ICd0cnVlJyBdOyB0aGVuIGVjaG8gJ2xpc3RlbmVyIDg4ODMnID4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgJiYgZWNobyAnY2FmaWxlIC9jZXJ0cy9jYS5jcnQnID4+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mICYmIGVjaG8gJ2NlcnRmaWxlIC9jZXJ0cy9zZXJ2ZXIuY3J0JyA+PiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZiAmJiBlY2hvICdrZXlmaWxlICAvY2VydHMvc2VydmVyLmtleScgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmY7IGVsc2UgZWNobyAnbGlzdGVuZXIgMTg4MycgPiAvbW9zcXVpdHRvL2NvbmZpZy9tb3NxdWl0dG8uY29uZjsgZmkgJiYgZWNobyAncmVxdWlyZV9jZXJ0aWZpY2F0ZSAnJFJFUVVJUkVfQ0VSVElGSUNBVEUgPj4gL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgJiYgZWNobyAnYWxsb3dfYW5vbnltb3VzICckQUxMT1dfQU5PTllNT1VTID4+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mOyBpZiBbIC1uICckU0VSVklDRV9VU0VSX01PU1FVSVRUTycgXSAmJiBbIC1uICckU0VSVklDRV9QQVNTV09SRF9NT1NRVUlUVE8nIF07IHRoZW4gZWNobyAncGFzc3dvcmRfZmlsZSAvbW9zcXVpdHRvL2NvbmZpZy9wYXNzd29yZHMnID4+IC9tb3NxdWl0dG8vY29uZmlnL21vc3F1aXR0by5jb25mICYmIHRvdWNoIC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkcyAmJiBjaG1vZCAwNzAwIC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkcyAmJiBjaG93biByb290OnJvb3QgL21vc3F1aXR0by9jb25maWcvcGFzc3dvcmRzICYmIG1vc3F1aXR0b19wYXNzd2QgLWIgLWMgL21vc3F1aXR0by9jb25maWcvcGFzc3dvcmRzICRTRVJWSUNFX1VTRVJfTU9TUVVJVFRPICRTRVJWSUNFX1BBU1NXT1JEX01PU1FVSVRUTyAmJiBjaG93biBtb3NxdWl0dG86bW9zcXVpdHRvIC9tb3NxdWl0dG8vY29uZmlnL3Bhc3N3b3JkczsgZmkgJiYgZXhlYyBtb3NxdWl0dG8gLWMgL21vc3F1aXR0by9jb25maWcvbW9zcXVpdHRvLmNvbmYgXCIiCiAgICBsYWJlbHM6CiAgICAgIC0gdHJhZWZpay50Y3Aucm91dGVycy5tcXR0LmVudHJ5cG9pbnRzPW1xdHQKICAgICAgLSB0cmFlZmlrLnRjcC5yb3V0ZXJzLm1xdHRzLmVudHJ5cG9pbnRzPW1xdHRzCg==", "tags": [ "mosquitto", "mqtt", @@ -3536,7 +3581,7 @@ "postiz": { "documentation": "https://docs.postiz.com?utm_source=coolify.io", "slogan": "Open source social media scheduling tool.", - "compose": "c2VydmljZXM6CiAgcG9zdGl6OgogICAgaW1hZ2U6ICdnaGNyLmlvL2dpdHJvb21ocS9wb3N0aXotYXBwOnYyLjEwLjEnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fUE9TVElaXzUwMDAKICAgICAgLSAnTUFJTl9VUkw9JHtTRVJWSUNFX0ZRRE5fUE9TVElafScKICAgICAgLSAnRlJPTlRFTkRfVVJMPSR7U0VSVklDRV9GUUROX1BPU1RJWn0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0JBQ0tFTkRfVVJMPSR7U0VSVklDRV9GUUROX1BPU1RJWn0vYXBpJwogICAgICAtICdKV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1RTRUNSRVR9JwogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovL3Bvc3RncmVzOiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMfUBwb3N0Z3Jlczo1NDMyLyR7UE9TVEdSRVNRTF9EQVRBQkFTRTotcG9zdGl6LWRifScKICAgICAgLSAnUkVESVNfVVJMPXJlZGlzOi8vZGVmYXVsdDoke1NFUlZJQ0VfUEFTU1dPUkRfUkVESVN9QHJlZGlzOjYzNzknCiAgICAgIC0gJ0JBQ0tFTkRfSU5URVJOQUxfVVJMPWh0dHA6Ly9sb2NhbGhvc3Q6MzAwMCcKICAgICAgLSAnQ0xPVURGTEFSRV9BQ0NPVU5UX0lEPSR7Q0xPVURGTEFSRV9BQ0NPVU5UX0lEfScKICAgICAgLSAnQ0xPVURGTEFSRV9BQ0NFU1NfS0VZPSR7Q0xPVURGTEFSRV9BQ0NFU1NfS0VZfScKICAgICAgLSAnQ0xPVURGTEFSRV9TRUNSRVRfQUNDRVNTX0tFWT0ke0NMT1VERkxBUkVfU0VDUkVUX0FDQ0VTU19LRVl9JwogICAgICAtICdDTE9VREZMQVJFX0JVQ0tFVE5BTUU9JHtDTE9VREZMQVJFX0JVQ0tFVE5BTUV9JwogICAgICAtICdDTE9VREZMQVJFX0JVQ0tFVF9VUkw9JHtDTE9VREZMQVJFX0JVQ0tFVF9VUkx9JwogICAgICAtICdDTE9VREZMQVJFX1JFR0lPTj0ke0NMT1VERkxBUkVfUkVHSU9OfScKICAgICAgLSAnU1RPUkFHRV9QUk9WSURFUj0ke1NUT1JBR0VfUFJPVklERVI6LWxvY2FsfScKICAgICAgLSAnVVBMT0FEX0RJUkVDVE9SWT0ke1VQTE9BRF9ESVJFQ1RPUlk6LS91cGxvYWRzfScKICAgICAgLSAnTkVYVF9QVUJMSUNfVVBMT0FEX0RJUkVDVE9SWT0ke05FWFRfUFVCTElDX1VQTE9BRF9ESVJFQ1RPUlk6LS91cGxvYWRzfScKICAgICAgLSAnTkVYVF9QVUJMSUNfVVBMT0FEX1NUQVRJQ19ESVJFQ1RPUlk9JHtORVhUX1BVQkxJQ19VUExPQURfU1RBVElDX0RJUkVDVE9SWX0nCiAgICAgIC0gJ1JFU0VORF9BUElfS0VZPSR7UkVTRU5EX0FQSV9LRVl9JwogICAgICAtICdFTUFJTF9GUk9NX0FERFJFU1M9JHtFTUFJTF9GUk9NX0FERFJFU1N9JwogICAgICAtICdFTUFJTF9GUk9NX05BTUU9JHtFTUFJTF9GUk9NX05BTUV9JwogICAgICAtICdFTUFJTF9QUk9WSURFUj0ke0VNQUlMX1BST1ZJREVSfScKICAgICAgLSAnWF9BUElfS0VZPSR7U0VSVklDRV9YX0FQSX0nCiAgICAgIC0gJ1hfQVBJX1NFQ1JFVD0ke1NFUlZJQ0VfWF9TRUNSRVR9JwogICAgICAtICdMSU5LRURJTl9DTElFTlRfSUQ9JHtTRVJWSUNFX0xJTktFRElOX0lEfScKICAgICAgLSAnTElOS0VESU5fQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfTElOS0VESU5fU0VDUkVUfScKICAgICAgLSAnUkVERElUX0NMSUVOVF9JRD0ke1NFUlZJQ0VfUkVERElUX0FQSX0nCiAgICAgIC0gJ1JFRERJVF9DTElFTlRfU0VDUkVUPSR7U0VSVklDRV9SRURESVRfU0VDUkVUfScKICAgICAgLSAnR0lUSFVCX0NMSUVOVF9JRD0ke1NFUlZJQ0VfR0lUSFVCX0lEfScKICAgICAgLSAnR0lUSFVCX0NMSUVOVF9TRUNSRVQ9JHtTRVJWSUNFX0dJVEhVQl9TRUNSRVR9JwogICAgICAtICdUSFJFQURTX0FQUF9JRD0ke1NFUlZJQ0VfVEhSRUFEU19JRH0nCiAgICAgIC0gJ1RIUkVBRFNfQVBQX1NFQ1JFVD0ke1NFUlZJQ0VfVEhSRUFEU19TRUNSRVR9JwogICAgICAtICdGQUNFQk9PS19BUFBfSUQ9JHtTRVJWSUNFX0ZBQ0VCT09LX0lEfScKICAgICAgLSAnRkFDRUJPT0tfQVBQX1NFQ1JFVD0ke1NFUlZJQ0VfRkFDRUJPT0tfU0VDUkVUfScKICAgICAgLSAnWU9VVFVCRV9DTElFTlRfSUQ9JHtTRVJWSUNFX1lPVVRVQkVfSUR9JwogICAgICAtICdZT1VUVUJFX0NMSUVOVF9TRUNSRVQ9JHtTRVJWSUNFX1lPVVRVQkVfU0VDUkVUfScKICAgICAgLSAnVElLVE9LX0NMSUVOVF9JRD0ke1NFUlZJQ0VfVElLVE9LX0lEfScKICAgICAgLSAnVElLVE9LX0NMSUVOVF9TRUNSRVQ9JHtTRVJWSUNFX1RJS1RPS19TRUNSRVR9JwogICAgICAtICdQSU5URVJFU1RfQ0xJRU5UX0lEPSR7U0VSVklDRV9QSU5URVJFU1RfSUR9JwogICAgICAtICdQSU5URVJFU1RfQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfUElOVEVSRVNUX1NFQ1JFVH0nCiAgICAgIC0gJ0RSSUJCQkxFX0NMSUVOVF9JRD0ke1NFUlZJQ0VfRFJJQkJMRV9JRH0nCiAgICAgIC0gJ0RSSUJCQkxFX0NMSUVOVF9TRUNSRVQ9JHtTRVJWSUNFX0RSSUJCTEVfU0VDUkVUfScKICAgICAgLSAnRElTQ09SRF9DTElFTlRfSUQ9JHtTRVJWSUNFX0RJU0NPUkRfSUR9JwogICAgICAtICdESVNDT1JEX0NMSUVOVF9TRUNSRVQ9JHtTRVJWSUNFX0RJU0NPUkRfU0VDUkVUfScKICAgICAgLSAnRElTQ09SRF9CT1RfVE9LRU5fSUQ9JHtTRVJWSUNFX0RJU0NPUkRfVE9LRU59JwogICAgICAtICdTTEFDS19JRD0ke1NFUlZJQ0VfU0xBQ0tfSUR9JwogICAgICAtICdTTEFDS19TRUNSRVQ9JHtTRVJWSUNFX1NMQUNLX1NFQ1JFVH0nCiAgICAgIC0gJ1NMQUNLX1NJR05JTkdfU0VDUkVUPSR7U0xBQ0tfU0lHTklOR19TRUNSRVR9JwogICAgICAtICdNQVNUT0RPTl9DTElFTlRfSUQ9JHtTRVJWSUNFX01BU1RPRE9OX0lEfScKICAgICAgLSAnTUFTVE9ET05fQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfTUFTVE9ET05fU0VDUkVUfScKICAgICAgLSAnQkVFSElJVkVfQVBJX0tFWT0ke1NFUlZJQ0VfQkVFSElJVkVfS0VZfScKICAgICAgLSAnQkVFSElJVkVfUFVCTElDQVRJT05fSUQ9JHtTRVJWSUNFX0JFRUhJSVZFX1BVQklEfScKICAgICAgLSAnT1BFTkFJX0FQSV9LRVk9JHtTRVJWSUNFX09QRU5BSV9LRVl9JwogICAgICAtICdORVhUX1BVQkxJQ19ESVNDT1JEX1NVUFBPUlQ9JHtORVhUX1BVQkxJQ19ESVNDT1JEX1NVUFBPUlR9JwogICAgICAtICdORVhUX1BVQkxJQ19QT0xPVE5PPSR7TkVYVF9QVUJMSUNfUE9MT1ROT30nCiAgICAgIC0gSVNfR0VORVJBTD10cnVlCiAgICAgIC0gJ05YX0FERF9QTFVHSU5TPSR7TlhfQUREX1BMVUdJTlM6LWZhbHNlfScKICAgICAgLSAnTk9UX1NFQ1VSRUQ9JHtOT1RfU0VDVVJFRDotZmFsc2V9JwogICAgICAtICdGRUVfQU1PVU5UPSR7RkVFX0FNT1VOVDotMC4wNX0nCiAgICAgIC0gJ1NUUklQRV9QVUJMSVNIQUJMRV9LRVk9JHtTVFJJUEVfUFVCTElTSEFCTEVfS0VZfScKICAgICAgLSAnU1RSSVBFX1NFQ1JFVF9LRVk9JHtTVFJJUEVfU0VDUkVUX0tFWX0nCiAgICAgIC0gJ1NUUklQRV9TSUdOSU5HX0tFWT0ke1NUUklQRV9TSUdOSU5HX0tFWX0nCiAgICAgIC0gJ1NUUklQRV9TSUdOSU5HX0tFWV9DT05ORUNUPSR7U1RSSVBFX1NJR05JTkdfS0VZX0NPTk5FQ1R9JwogICAgdm9sdW1lczoKICAgICAgLSAncG9zdGl6X2NvbmZpZzovY29uZmlnLycKICAgICAgLSAncG9zdGl6X3VwbG9hZHM6L3VwbG9hZHMvJwogICAgZGVwZW5kc19vbjoKICAgICAgcG9zdGdyZXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnd2dldCAtcU8tIGh0dHA6Ly8xMjcuMC4wLjE6NTAwMC8nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICBwb3N0Z3JlczoKICAgIGltYWdlOiAncG9zdGdyZXM6MTQuNScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Bvc3Rpel9wb3N0Z3Jlc3FsX2RhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUE9TVEdSRVNfVVNFUj1wb3N0Z3JlcwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNRTH0nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNRTF9EQVRBQkFTRTotcG9zdGl6LWRifScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQjotcG9zdGl6LWRifScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczo3LjInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUkVESVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1JFRElTfScKICAgIGNvbW1hbmQ6ICdyZWRpcy1zZXJ2ZXIgLS1yZXF1aXJlcGFzcyAke1NFUlZJQ0VfUEFTU1dPUkRfUkVESVN9JwogICAgdm9sdW1lczoKICAgICAgLSAncG9zdGl6X3JlZGlzX2RhdGE6L2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSAnLWEnCiAgICAgICAgLSAnJHtTRVJWSUNFX1BBU1NXT1JEX1JFRElTfScKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAyMAo=", + "compose": "c2VydmljZXM6CiAgcG9zdGl6OgogICAgaW1hZ2U6ICdnaGNyLmlvL2dpdHJvb21ocS9wb3N0aXotYXBwOnYyLjEwLjEnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fUE9TVElaXzUwMDAKICAgICAgLSAnTUFJTl9VUkw9JHtTRVJWSUNFX0ZRRE5fUE9TVElafScKICAgICAgLSAnRlJPTlRFTkRfVVJMPSR7U0VSVklDRV9GUUROX1BPU1RJWn0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0JBQ0tFTkRfVVJMPSR7U0VSVklDRV9GUUROX1BPU1RJWn0vYXBpJwogICAgICAtICdKV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1RTRUNSRVR9JwogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovL3Bvc3RncmVzOiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMfUBwb3N0Z3Jlczo1NDMyLyR7UE9TVEdSRVNRTF9EQVRBQkFTRTotcG9zdGl6LWRifScKICAgICAgLSAnUkVESVNfVVJMPXJlZGlzOi8vZGVmYXVsdDoke1NFUlZJQ0VfUEFTU1dPUkRfUkVESVN9QHJlZGlzOjYzNzknCiAgICAgIC0gJ0JBQ0tFTkRfSU5URVJOQUxfVVJMPWh0dHA6Ly9sb2NhbGhvc3Q6MzAwMCcKICAgICAgLSAnQ0xPVURGTEFSRV9BQ0NPVU5UX0lEPSR7Q0xPVURGTEFSRV9BQ0NPVU5UX0lEfScKICAgICAgLSAnQ0xPVURGTEFSRV9BQ0NFU1NfS0VZPSR7Q0xPVURGTEFSRV9BQ0NFU1NfS0VZfScKICAgICAgLSAnQ0xPVURGTEFSRV9TRUNSRVRfQUNDRVNTX0tFWT0ke0NMT1VERkxBUkVfU0VDUkVUX0FDQ0VTU19LRVl9JwogICAgICAtICdDTE9VREZMQVJFX0JVQ0tFVE5BTUU9JHtDTE9VREZMQVJFX0JVQ0tFVE5BTUV9JwogICAgICAtICdDTE9VREZMQVJFX0JVQ0tFVF9VUkw9JHtDTE9VREZMQVJFX0JVQ0tFVF9VUkx9JwogICAgICAtICdDTE9VREZMQVJFX1JFR0lPTj0ke0NMT1VERkxBUkVfUkVHSU9OfScKICAgICAgLSAnU1RPUkFHRV9QUk9WSURFUj0ke1NUT1JBR0VfUFJPVklERVI6LWxvY2FsfScKICAgICAgLSAnVVBMT0FEX0RJUkVDVE9SWT0ke1VQTE9BRF9ESVJFQ1RPUlk6LS91cGxvYWRzfScKICAgICAgLSAnTkVYVF9QVUJMSUNfVVBMT0FEX0RJUkVDVE9SWT0ke05FWFRfUFVCTElDX1VQTE9BRF9ESVJFQ1RPUlk6LS91cGxvYWRzfScKICAgICAgLSAnTkVYVF9QVUJMSUNfVVBMT0FEX1NUQVRJQ19ESVJFQ1RPUlk9JHtORVhUX1BVQkxJQ19VUExPQURfU1RBVElDX0RJUkVDVE9SWX0nCiAgICAgIC0gJ1JFU0VORF9BUElfS0VZPSR7UkVTRU5EX0FQSV9LRVl9JwogICAgICAtICdFTUFJTF9GUk9NX0FERFJFU1M9JHtFTUFJTF9GUk9NX0FERFJFU1N9JwogICAgICAtICdFTUFJTF9GUk9NX05BTUU9JHtFTUFJTF9GUk9NX05BTUV9JwogICAgICAtICdFTUFJTF9QUk9WSURFUj0ke0VNQUlMX1BST1ZJREVSfScKICAgICAgLSAnWF9BUElfS0VZPSR7U0VSVklDRV9YX0FQSX0nCiAgICAgIC0gJ1hfQVBJX1NFQ1JFVD0ke1NFUlZJQ0VfWF9TRUNSRVR9JwogICAgICAtICdMSU5LRURJTl9DTElFTlRfSUQ9JHtTRVJWSUNFX0xJTktFRElOX0lEfScKICAgICAgLSAnTElOS0VESU5fQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfTElOS0VESU5fU0VDUkVUfScKICAgICAgLSAnUkVERElUX0NMSUVOVF9JRD0ke1NFUlZJQ0VfUkVERElUX0FQSX0nCiAgICAgIC0gJ1JFRERJVF9DTElFTlRfU0VDUkVUPSR7U0VSVklDRV9SRURESVRfU0VDUkVUfScKICAgICAgLSAnR0lUSFVCX0NMSUVOVF9JRD0ke1NFUlZJQ0VfR0lUSFVCX0lEfScKICAgICAgLSAnR0lUSFVCX0NMSUVOVF9TRUNSRVQ9JHtTRVJWSUNFX0dJVEhVQl9TRUNSRVR9JwogICAgICAtICdUSFJFQURTX0FQUF9JRD0ke1NFUlZJQ0VfVEhSRUFEU19JRH0nCiAgICAgIC0gJ1RIUkVBRFNfQVBQX1NFQ1JFVD0ke1NFUlZJQ0VfVEhSRUFEU19TRUNSRVR9JwogICAgICAtICdGQUNFQk9PS19BUFBfSUQ9JHtTRVJWSUNFX0ZBQ0VCT09LX0lEfScKICAgICAgLSAnRkFDRUJPT0tfQVBQX1NFQ1JFVD0ke1NFUlZJQ0VfRkFDRUJPT0tfU0VDUkVUfScKICAgICAgLSAnWU9VVFVCRV9DTElFTlRfSUQ9JHtTRVJWSUNFX1lPVVRVQkVfSUR9JwogICAgICAtICdZT1VUVUJFX0NMSUVOVF9TRUNSRVQ9JHtTRVJWSUNFX1lPVVRVQkVfU0VDUkVUfScKICAgICAgLSAnVElLVE9LX0NMSUVOVF9JRD0ke1NFUlZJQ0VfVElLVE9LX0lEfScKICAgICAgLSAnVElLVE9LX0NMSUVOVF9TRUNSRVQ9JHtTRVJWSUNFX1RJS1RPS19TRUNSRVR9JwogICAgICAtICdQSU5URVJFU1RfQ0xJRU5UX0lEPSR7U0VSVklDRV9QSU5URVJFU1RfSUR9JwogICAgICAtICdQSU5URVJFU1RfQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfUElOVEVSRVNUX1NFQ1JFVH0nCiAgICAgIC0gJ0RSSUJCQkxFX0NMSUVOVF9JRD0ke1NFUlZJQ0VfRFJJQkJMRV9JRH0nCiAgICAgIC0gJ0RSSUJCQkxFX0NMSUVOVF9TRUNSRVQ9JHtTRVJWSUNFX0RSSUJCTEVfU0VDUkVUfScKICAgICAgLSAnRElTQ09SRF9DTElFTlRfSUQ9JHtTRVJWSUNFX0RJU0NPUkRfSUR9JwogICAgICAtICdESVNDT1JEX0NMSUVOVF9TRUNSRVQ9JHtTRVJWSUNFX0RJU0NPUkRfU0VDUkVUfScKICAgICAgLSAnRElTQ09SRF9CT1RfVE9LRU5fSUQ9JHtTRVJWSUNFX0RJU0NPUkRfVE9LRU59JwogICAgICAtICdTTEFDS19JRD0ke1NFUlZJQ0VfU0xBQ0tfSUR9JwogICAgICAtICdTTEFDS19TRUNSRVQ9JHtTRVJWSUNFX1NMQUNLX1NFQ1JFVH0nCiAgICAgIC0gJ1NMQUNLX1NJR05JTkdfU0VDUkVUPSR7U0xBQ0tfU0lHTklOR19TRUNSRVR9JwogICAgICAtICdNQVNUT0RPTl9DTElFTlRfSUQ9JHtTRVJWSUNFX01BU1RPRE9OX0lEfScKICAgICAgLSAnTUFTVE9ET05fQ0xJRU5UX1NFQ1JFVD0ke1NFUlZJQ0VfTUFTVE9ET05fU0VDUkVUfScKICAgICAgLSAnSU5TVEFHUkFNX0FQUF9JRD0ke0lOU1RBR1JBTV9BUFBfSUR9JwogICAgICAtICdJTlNUQUdSQU1fQVBQX1NFQ1JFVD0ke0lOU1RBR1JBTV9BUFBfU0VDUkVUfScKICAgICAgLSAnQkVFSElJVkVfQVBJX0tFWT0ke1NFUlZJQ0VfQkVFSElJVkVfS0VZfScKICAgICAgLSAnQkVFSElJVkVfUFVCTElDQVRJT05fSUQ9JHtTRVJWSUNFX0JFRUhJSVZFX1BVQklEfScKICAgICAgLSAnT1BFTkFJX0FQSV9LRVk9JHtTRVJWSUNFX09QRU5BSV9LRVl9JwogICAgICAtICdORVhUX1BVQkxJQ19ESVNDT1JEX1NVUFBPUlQ9JHtORVhUX1BVQkxJQ19ESVNDT1JEX1NVUFBPUlR9JwogICAgICAtICdORVhUX1BVQkxJQ19QT0xPVE5PPSR7TkVYVF9QVUJMSUNfUE9MT1ROT30nCiAgICAgIC0gSVNfR0VORVJBTD10cnVlCiAgICAgIC0gJ05YX0FERF9QTFVHSU5TPSR7TlhfQUREX1BMVUdJTlM6LWZhbHNlfScKICAgICAgLSAnTk9UX1NFQ1VSRUQ9JHtOT1RfU0VDVVJFRDotZmFsc2V9JwogICAgICAtICdGRUVfQU1PVU5UPSR7RkVFX0FNT1VOVDotMC4wNX0nCiAgICAgIC0gJ1NUUklQRV9QVUJMSVNIQUJMRV9LRVk9JHtTVFJJUEVfUFVCTElTSEFCTEVfS0VZfScKICAgICAgLSAnU1RSSVBFX1NFQ1JFVF9LRVk9JHtTVFJJUEVfU0VDUkVUX0tFWX0nCiAgICAgIC0gJ1NUUklQRV9TSUdOSU5HX0tFWT0ke1NUUklQRV9TSUdOSU5HX0tFWX0nCiAgICAgIC0gJ1NUUklQRV9TSUdOSU5HX0tFWV9DT05ORUNUPSR7U1RSSVBFX1NJR05JTkdfS0VZX0NPTk5FQ1R9JwogICAgdm9sdW1lczoKICAgICAgLSAncG9zdGl6X2NvbmZpZzovY29uZmlnLycKICAgICAgLSAncG9zdGl6X3VwbG9hZHM6L3VwbG9hZHMvJwogICAgZGVwZW5kc19vbjoKICAgICAgcG9zdGdyZXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnd2dldCAtcU8tIGh0dHA6Ly8xMjcuMC4wLjE6NTAwMC8nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICBwb3N0Z3JlczoKICAgIGltYWdlOiAncG9zdGdyZXM6MTQuNScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Bvc3Rpel9wb3N0Z3Jlc3FsX2RhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUE9TVEdSRVNfVVNFUj1wb3N0Z3JlcwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNRTH0nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNRTF9EQVRBQkFTRTotcG9zdGl6LWRifScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQjotcG9zdGl6LWRifScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczo3LjInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUkVESVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1JFRElTfScKICAgIGNvbW1hbmQ6ICdyZWRpcy1zZXJ2ZXIgLS1yZXF1aXJlcGFzcyAke1NFUlZJQ0VfUEFTU1dPUkRfUkVESVN9JwogICAgdm9sdW1lczoKICAgICAgLSAncG9zdGl6X3JlZGlzX2RhdGE6L2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSAnLWEnCiAgICAgICAgLSAnJHtTRVJWSUNFX1BBU1NXT1JEX1JFRElTfScKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAyMAo=", "tags": [ "post everywhere", "social media", @@ -3903,6 +3948,22 @@ "minversion": "0.0.0", "port": "7376" }, + "sftpgo": { + "documentation": "https://docs.sftpgo.com/2.7/?utm_source=coolify.io", + "slogan": "SFTPGo is an event-driven SFTP, FTP/S, HTTP/S and WebDAV server.", + "compose": "c2VydmljZXM6CiAgc2Z0cGdvOgogICAgaW1hZ2U6ICdnaGNyLmlvL2RyYWtrYW4vc2Z0cGdvOnYyLjctYWxwaW5lJwogICAgcG9ydHM6CiAgICAgIC0gJzIyMjI6MjIyMicKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9TRlRQR09fODA4MAogICAgICAtIFNGVFBHT19EQVRBX1BST1ZJREVSX19EUklWRVI9cG9zdGdyZXNxbAogICAgICAtICdTRlRQR09fREFUQV9QUk9WSURFUl9fQ09OTkVDVElPTl9TVFJJTkc9cG9zdGdyZXNxbDovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfNjRfUE9TVEdSRVN9QHBvc3RncmVzcWw6NTQzMi8ke1BPU1RHUkVTX0RBVEFCQVNFOi1zZnRwZ28tZGJ9JwogICAgICAtIFNGVFBHT19TRlRQRF9fQklORElOR1NfXzBfX1BPUlQ9MjAyMgogICAgICAtICdTRlRQR09fTE9HX0xFVkVMPSR7TE9HX0xFVkVMOi1pbmZvfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnd2dldCAtcU8tIGh0dHA6Ly8xMjcuMC4wLjE6ODA4MC8nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzcWw6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3NmdHBnby1kYXRhOi9zcnYvc2Z0cGdvL2RhdGEnCiAgICAgIC0gJ3NmdHBnby1rZXlzOi92YXIvbGliL3NmdHBnbycKICBwb3N0Z3Jlc3FsOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNy1hbHBpbmUnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF82NF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREFUQUJBU0U6LXNmdHBnby1kYn0nCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0Z3Jlc3FsLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAyMAo=", + "tags": [ + "sftpgo", + "sftp", + "ftp", + "file", + "webdav" + ], + "category": null, + "logo": "svgs/sftpgo.png", + "minversion": "0.0.0", + "port": "8080" + }, "shlink": { "documentation": "https://shlink.io/?utm_source=coolify.io", "slogan": "The definitive self-hosted URL shortener", @@ -3940,6 +4001,20 @@ "minversion": "0.0.0", "port": "8080" }, + "silverbullet": { + "documentation": "https://v2.silverbullet.md/Install/Configuration?utm_source=coolify.io", + "slogan": "SilverBullet is a tool to develop, organize, and structure your personal knowledge and to make it universally accessible across all your devices.", + "compose": "c2VydmljZXM6CiAgc2lsdmVyYnVsbGV0OgogICAgaW1hZ2U6ICdnaGNyLmlvL3NpbHZlcmJ1bGxldG1kL3NpbHZlcmJ1bGxldDp2MicKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9TSUxWRVJCVUxMRVRfMzAwMAogICAgICAtICdTQl9VU0VSPSR7U0VSVklDRV9VU0VSX1NJTFZFUkJVTExFVH06JHtTRVJWSUNFX1BBU1NXT1JEX1NJTFZFUkJVTExFVH0nCiAgICB2b2x1bWVzOgogICAgICAtICdzaWx2ZXJidWxsZXQtc3BhY2U6L3NwYWNlJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICctLXF1aWV0JwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6MzAwMCcKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiA1Cg==", + "tags": [ + "note-taking", + "markdown", + "pkm" + ], + "category": null, + "logo": "svgs/silverbullet.png", + "minversion": "0.0.0", + "port": "3000" + }, "siyuan": { "documentation": "https://github.com/siyuan-note/siyuan?utm_source=coolify.io", "slogan": "A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang.", @@ -4282,6 +4357,22 @@ "minversion": "0.0.0", "port": "8082" }, + "trailbase": { + "documentation": "https://trailbase.io/?utm_source=coolify.io", + "slogan": "A blazingly fast Rust/SQLite/Wasmtime app server with type-safe APIs", + "compose": "c2VydmljZXM6CiAgdHJhaWxiYXNlOgogICAgaW1hZ2U6ICd0cmFpbGJhc2UvdHJhaWxiYXNlOjAuMjIuNicKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9UUkFJTEJBU0VfNDAwMAogICAgdm9sdW1lczoKICAgICAgLSAndHJhaWxiYXNlLWRhdGE6L2FwcC90cmFpbGRlcG90Jwo=", + "tags": [ + "trailbase", + "backend", + "saas", + "mobile", + "api" + ], + "category": "backend", + "logo": "svgs/trailbase.svg", + "minversion": "0.0.0", + "port": "4000" + }, "transmission": { "documentation": "https://docs.linuxserver.io/images/docker-transmission/?utm_source=coolify.io", "slogan": "Fast, easy, and free BitTorrent client.", From aeef97f295d42df368dbc66950b226291b7971a9 Mon Sep 17 00:00:00 2001 From: Yassir <53705290+YaRissi@users.noreply.github.com> Date: Tue, 6 Jan 2026 12:52:32 +0100 Subject: [PATCH 009/191] fix(docs): api docs for bulk env update response (#7714) --- app/Http/Controllers/Api/ApplicationsController.php | 6 ++---- openapi.json | 11 ++++------- openapi.yaml | 6 +++--- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index 3b6f67b1f..06f16e715 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -2696,10 +2696,8 @@ class ApplicationsController extends Controller new OA\MediaType( mediaType: 'application/json', schema: new OA\Schema( - type: 'object', - properties: [ - 'message' => ['type' => 'string', 'example' => 'Environment variables updated.'], - ] + type: 'array', + items: new OA\Items(ref: '#/components/schemas/EnvironmentVariable') ) ), ] diff --git a/openapi.json b/openapi.json index 571720d40..b7ad90111 100644 --- a/openapi.json +++ b/openapi.json @@ -3009,13 +3009,10 @@ "content": { "application\/json": { "schema": { - "properties": { - "message": { - "type": "string", - "example": "Environment variables updated." - } - }, - "type": "object" + "type": "array", + "items": { + "$ref": "#\/components\/schemas\/EnvironmentVariable" + } } } } diff --git a/openapi.yaml b/openapi.yaml index 896b97b9e..137b01c00 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -1915,9 +1915,9 @@ paths: content: application/json: schema: - properties: - message: { type: string, example: 'Environment variables updated.' } - type: object + type: array + items: + $ref: '#/components/schemas/EnvironmentVariable' '401': $ref: '#/components/responses/401' '400': From caca421e2e74ae32a9d836def7bfa1e842a912c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=8F=94=EF=B8=8F=20Peak?= <122374094+peaklabs-dev@users.noreply.github.com> Date: Tue, 6 Jan 2026 13:44:46 +0100 Subject: [PATCH 010/191] fix: db public port instant save and simplify if condition (#7883) --- .../Project/Database/Clickhouse/General.php | 15 +++++++-------- .../Project/Database/Dragonfly/General.php | 15 +++++++-------- app/Livewire/Project/Database/Keydb/General.php | 15 +++++++-------- app/Livewire/Project/Database/Mariadb/General.php | 15 ++++++++------- app/Livewire/Project/Database/Mongodb/General.php | 15 ++++++++------- app/Livewire/Project/Database/Mysql/General.php | 15 ++++++++------- .../Project/Database/Postgresql/General.php | 15 ++++++++------- app/Livewire/Project/Database/Redis/General.php | 15 +++++++-------- 8 files changed, 60 insertions(+), 60 deletions(-) diff --git a/app/Livewire/Project/Database/Clickhouse/General.php b/app/Livewire/Project/Database/Clickhouse/General.php index c4a7983b8..7ad453fd5 100644 --- a/app/Livewire/Project/Database/Clickhouse/General.php +++ b/app/Livewire/Project/Database/Clickhouse/General.php @@ -168,21 +168,20 @@ class General extends Component return; } - if ($this->isPublic) { - if (! str($this->database->status)->startsWith('running')) { - $this->dispatch('error', 'Database must be started to be publicly accessible.'); - $this->isPublic = false; + if ($this->isPublic && ! str($this->database->status)->startsWith('running')) { + $this->dispatch('error', 'Database must be started to be publicly accessible.'); + $this->isPublic = false; - return; - } + return; + } + $this->syncData(true); + if ($this->isPublic) { StartDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is now publicly accessible.'); } else { StopDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is no longer publicly accessible.'); } - $this->dbUrlPublic = $this->database->external_db_url; - $this->syncData(true); } catch (\Throwable $e) { $this->isPublic = ! $this->isPublic; $this->syncData(true); diff --git a/app/Livewire/Project/Database/Dragonfly/General.php b/app/Livewire/Project/Database/Dragonfly/General.php index 9052a4749..4e325b9ee 100644 --- a/app/Livewire/Project/Database/Dragonfly/General.php +++ b/app/Livewire/Project/Database/Dragonfly/General.php @@ -178,21 +178,20 @@ class General extends Component return; } - if ($this->isPublic) { - if (! str($this->database->status)->startsWith('running')) { - $this->dispatch('error', 'Database must be started to be publicly accessible.'); - $this->isPublic = false; + if ($this->isPublic && ! str($this->database->status)->startsWith('running')) { + $this->dispatch('error', 'Database must be started to be publicly accessible.'); + $this->isPublic = false; - return; - } + return; + } + $this->syncData(true); + if ($this->isPublic) { StartDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is now publicly accessible.'); } else { StopDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is no longer publicly accessible.'); } - $this->dbUrlPublic = $this->database->external_db_url; - $this->syncData(true); } catch (\Throwable $e) { $this->isPublic = ! $this->isPublic; $this->syncData(true); diff --git a/app/Livewire/Project/Database/Keydb/General.php b/app/Livewire/Project/Database/Keydb/General.php index 6d21988e7..f02aa6674 100644 --- a/app/Livewire/Project/Database/Keydb/General.php +++ b/app/Livewire/Project/Database/Keydb/General.php @@ -185,21 +185,20 @@ class General extends Component return; } - if ($this->isPublic) { - if (! str($this->database->status)->startsWith('running')) { - $this->dispatch('error', 'Database must be started to be publicly accessible.'); - $this->isPublic = false; + if ($this->isPublic && ! str($this->database->status)->startsWith('running')) { + $this->dispatch('error', 'Database must be started to be publicly accessible.'); + $this->isPublic = false; - return; - } + return; + } + $this->syncData(true); + if ($this->isPublic) { StartDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is now publicly accessible.'); } else { StopDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is no longer publicly accessible.'); } - $this->dbUrlPublic = $this->database->external_db_url; - $this->syncData(true); } catch (\Throwable $e) { $this->isPublic = ! $this->isPublic; $this->syncData(true); diff --git a/app/Livewire/Project/Database/Mariadb/General.php b/app/Livewire/Project/Database/Mariadb/General.php index 3bffc0bef..74658e2a4 100644 --- a/app/Livewire/Project/Database/Mariadb/General.php +++ b/app/Livewire/Project/Database/Mariadb/General.php @@ -232,22 +232,23 @@ class General extends Component return; } - if ($this->isPublic) { - if (! str($this->database->status)->startsWith('running')) { - $this->dispatch('error', 'Database must be started to be publicly accessible.'); - $this->isPublic = false; + if ($this->isPublic && ! str($this->database->status)->startsWith('running')) { + $this->dispatch('error', 'Database must be started to be publicly accessible.'); + $this->isPublic = false; - return; - } + return; + } + $this->syncData(true); + if ($this->isPublic) { StartDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is now publicly accessible.'); } else { StopDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is no longer publicly accessible.'); } - $this->syncData(true); } catch (\Throwable $e) { $this->isPublic = ! $this->isPublic; + $this->syncData(true); return handleError($e, $this); } diff --git a/app/Livewire/Project/Database/Mongodb/General.php b/app/Livewire/Project/Database/Mongodb/General.php index 5c0465c22..9f34b73d5 100644 --- a/app/Livewire/Project/Database/Mongodb/General.php +++ b/app/Livewire/Project/Database/Mongodb/General.php @@ -235,22 +235,23 @@ class General extends Component return; } - if ($this->isPublic) { - if (! str($this->database->status)->startsWith('running')) { - $this->dispatch('error', 'Database must be started to be publicly accessible.'); - $this->isPublic = false; + if ($this->isPublic && ! str($this->database->status)->startsWith('running')) { + $this->dispatch('error', 'Database must be started to be publicly accessible.'); + $this->isPublic = false; - return; - } + return; + } + $this->syncData(true); + if ($this->isPublic) { StartDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is now publicly accessible.'); } else { StopDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is no longer publicly accessible.'); } - $this->syncData(true); } catch (\Throwable $e) { $this->isPublic = ! $this->isPublic; + $this->syncData(true); return handleError($e, $this); } diff --git a/app/Livewire/Project/Database/Mysql/General.php b/app/Livewire/Project/Database/Mysql/General.php index 5ac34299c..86b109251 100644 --- a/app/Livewire/Project/Database/Mysql/General.php +++ b/app/Livewire/Project/Database/Mysql/General.php @@ -239,22 +239,23 @@ class General extends Component return; } - if ($this->isPublic) { - if (! str($this->database->status)->startsWith('running')) { - $this->dispatch('error', 'Database must be started to be publicly accessible.'); - $this->isPublic = false; + if ($this->isPublic && ! str($this->database->status)->startsWith('running')) { + $this->dispatch('error', 'Database must be started to be publicly accessible.'); + $this->isPublic = false; - return; - } + return; + } + $this->syncData(true); + if ($this->isPublic) { StartDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is now publicly accessible.'); } else { StopDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is no longer publicly accessible.'); } - $this->syncData(true); } catch (\Throwable $e) { $this->isPublic = ! $this->isPublic; + $this->syncData(true); return handleError($e, $this); } diff --git a/app/Livewire/Project/Database/Postgresql/General.php b/app/Livewire/Project/Database/Postgresql/General.php index 84e34c145..e24674315 100644 --- a/app/Livewire/Project/Database/Postgresql/General.php +++ b/app/Livewire/Project/Database/Postgresql/General.php @@ -286,22 +286,23 @@ class General extends Component return; } - if ($this->isPublic) { - if (! str($this->database->status)->startsWith('running')) { - $this->dispatch('error', 'Database must be started to be publicly accessible.'); - $this->isPublic = false; + if ($this->isPublic && ! str($this->database->status)->startsWith('running')) { + $this->dispatch('error', 'Database must be started to be publicly accessible.'); + $this->isPublic = false; - return; - } + return; + } + $this->syncData(true); + if ($this->isPublic) { StartDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is now publicly accessible.'); } else { StopDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is no longer publicly accessible.'); } - $this->syncData(true); } catch (\Throwable $e) { $this->isPublic = ! $this->isPublic; + $this->syncData(true); return handleError($e, $this); } diff --git a/app/Livewire/Project/Database/Redis/General.php b/app/Livewire/Project/Database/Redis/General.php index f96f5d30e..08bcdc343 100644 --- a/app/Livewire/Project/Database/Redis/General.php +++ b/app/Livewire/Project/Database/Redis/General.php @@ -225,21 +225,20 @@ class General extends Component return; } - if ($this->isPublic) { - if (! str($this->database->status)->startsWith('running')) { - $this->dispatch('error', 'Database must be started to be publicly accessible.'); - $this->isPublic = false; + if ($this->isPublic && ! str($this->database->status)->startsWith('running')) { + $this->dispatch('error', 'Database must be started to be publicly accessible.'); + $this->isPublic = false; - return; - } + return; + } + $this->syncData(true); + if ($this->isPublic) { StartDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is now publicly accessible.'); } else { StopDatabaseProxy::run($this->database); $this->dispatch('success', 'Database is no longer publicly accessible.'); } - $this->dbUrlPublic = $this->database->external_db_url; - $this->syncData(true); } catch (\Throwable $e) { $this->isPublic = ! $this->isPublic; $this->syncData(true); From a5537119b974b57da33e3ec77f9c8a9388e7a883 Mon Sep 17 00:00:00 2001 From: Alexzvn Date: Tue, 6 Jan 2026 20:14:56 +0700 Subject: [PATCH 011/191] fix(ui): empty network destinations when cloning a resource (#7309) --- .../views/livewire/project/shared/resource-operations.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/livewire/project/shared/resource-operations.blade.php b/resources/views/livewire/project/shared/resource-operations.blade.php index 3d850f542..573f70ba0 100644 --- a/resources/views/livewire/project/shared/resource-operations.blade.php +++ b/resources/views/livewire/project/shared/resource-operations.blade.php @@ -23,7 +23,7 @@ ], ), ], - ), + )->values(), ), projects: @js( $projects->map( From 2332e88a2e117a331211df51909fcc2ff748e870 Mon Sep 17 00:00:00 2001 From: Sarthak Shrivastava Date: Tue, 6 Jan 2026 19:38:23 +0530 Subject: [PATCH 012/191] feat(service): add nocobase template (#7347) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 🏔️ Peak <122374094+peaklabs-dev@users.noreply.github.com> --- public/svgs/nocobase.png | Bin 0 -> 38056 bytes templates/compose/nocobase.yaml | 38 ++++++++++++++++++++++++ templates/service-templates-latest.json | 15 ++++++++++ templates/service-templates.json | 15 ++++++++++ 4 files changed, 68 insertions(+) create mode 100644 public/svgs/nocobase.png create mode 100644 templates/compose/nocobase.yaml diff --git a/public/svgs/nocobase.png b/public/svgs/nocobase.png new file mode 100644 index 0000000000000000000000000000000000000000..4133901ef327b514beccc899f459f2ecb031684c GIT binary patch literal 38056 zcmeEuc{r5s|L>z!kw^=&rrnYyvXg{9Ns6*BB_w-eX{@7&LbMQtAr*x|c3DGY8?sEu zzKkV=VKA0+-_P{@{Jz)u>->4Hb8=l>9{1eK`~71b>0+R3#OL6BV+G}W#m z$o6LVk8v9qc_mYY1;2JUYZ_t@goz#gV?bWTa)7}cD}xKx7cQJc7{MRgkUb2W5eD!C z|8X&FMSouh&j7Ta;2+%QKfeJf5!;b1U_?wp zT#Vr<{h0ymfF%4G7Z(#_NTBbyv4J3)66iZNZ%2^L|Md*EK+Y>WRv`#KazX8^-o4mg zofW&v`B}>|zpr^H@p5iD{AcWsj$@2If>``#x(c)FpCPgTOy~dioPVdY{(H{9(}Vv# z=iljn$)ZE~7cDvte|77RY5lcCIuL&y#9s#i5cnH>=xXpcRMT-l{$>z#ApYiCbR7OV zh`$a3An>=upsT^(g6xku{Oce8I*7jx;;)1F|GQ&jzc^i8;BeZuGG*)ve^Y?o@h1W9 zhgq!NYQ^rzH{!l`!uW;C8~+)1?Z}C;Uo1hEA-TD}ZKrUO4FBnvZTU~*ONRYFoiCMt z8)bi|p$_K%Q9yXX&&4v>9Zk4QBofOusFedcloIfFIkzZO1{}qCokF3E+U0jEt}e|c zQH()%6}NjzJGpgy$d3t5EOzF7x;i(vdfDX>uX)XoODh%jt})Thur<3s#Cd&l{1)o3G`Ag^OP2T@QQ*r=$ehpl#TYcuc9<7FVJMSemf^=ub$%YqirG zW3psw^k|=H5?ua_3F@mwRKcEbyV+m&lw86nLQ;H-(|5rA_=R_7Hb z%h=!smxAV<`btZ-O_-PYzALs~eOgJxE9;)>9C906_(IAs*EIv(dF1Hl)^XRBH9rVw z<)hp2%kv8^ZtF8;8-#W0Bhs8VBwS(#U>=Q^xDxgHkGW7iDpC=N&>x8x3WTqat3r$NAnv@T{1p}EP=`Ss<2gWxAJKs6~dVMa6auGZ^de#--gfHN2⩔GRwfpZxBUhw!4q8Rahw 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 Date: Tue, 6 Jan 2026 15:50:55 +0100 Subject: [PATCH 013/191] feat(api): allow to escape special characters in labels (#7886) --- .../Api/ApplicationsController.php | 43 +++++++++++++++++-- bootstrap/helpers/api.php | 2 + openapi.json | 35 +++++++++++++++ openapi.yaml | 28 ++++++++++++ 4 files changed, 105 insertions(+), 3 deletions(-) diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index 06f16e715..b7e9ac6ff 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -193,6 +193,7 @@ class ApplicationsController extends Controller 'connect_to_docker_network' => ['type' => 'boolean', 'description' => 'The flag to connect the service to the predefined Docker network.'], 'force_domain_override' => ['type' => 'boolean', 'description' => 'Force domain usage even if conflicts are detected. Default is false.'], 'autogenerate_domain' => ['type' => 'boolean', 'default' => true, 'description' => 'If true and domains is empty, auto-generate a domain using the server\'s wildcard domain or sslip.io fallback. Default: true.'], + 'is_container_label_escape_enabled' => ['type' => 'boolean', 'default' => true, 'description' => 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.'], ], ) ), @@ -344,6 +345,7 @@ class ApplicationsController extends Controller 'connect_to_docker_network' => ['type' => 'boolean', 'description' => 'The flag to connect the service to the predefined Docker network.'], 'force_domain_override' => ['type' => 'boolean', 'description' => 'Force domain usage even if conflicts are detected. Default is false.'], 'autogenerate_domain' => ['type' => 'boolean', 'default' => true, 'description' => 'If true and domains is empty, auto-generate a domain using the server\'s wildcard domain or sslip.io fallback. Default: true.'], + 'is_container_label_escape_enabled' => ['type' => 'boolean', 'default' => true, 'description' => 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.'], ], ) ), @@ -495,6 +497,7 @@ class ApplicationsController extends Controller 'connect_to_docker_network' => ['type' => 'boolean', 'description' => 'The flag to connect the service to the predefined Docker network.'], 'force_domain_override' => ['type' => 'boolean', 'description' => 'Force domain usage even if conflicts are detected. Default is false.'], 'autogenerate_domain' => ['type' => 'boolean', 'default' => true, 'description' => 'If true and domains is empty, auto-generate a domain using the server\'s wildcard domain or sslip.io fallback. Default: true.'], + 'is_container_label_escape_enabled' => ['type' => 'boolean', 'default' => true, 'description' => 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.'], ], ) ), @@ -630,6 +633,7 @@ class ApplicationsController extends Controller 'connect_to_docker_network' => ['type' => 'boolean', 'description' => 'The flag to connect the service to the predefined Docker network.'], 'force_domain_override' => ['type' => 'boolean', 'description' => 'Force domain usage even if conflicts are detected. Default is false.'], 'autogenerate_domain' => ['type' => 'boolean', 'default' => true, 'description' => 'If true and domains is empty, auto-generate a domain using the server\'s wildcard domain or sslip.io fallback. Default: true.'], + 'is_container_label_escape_enabled' => ['type' => 'boolean', 'default' => true, 'description' => 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.'], ], ) ), @@ -762,6 +766,7 @@ class ApplicationsController extends Controller 'connect_to_docker_network' => ['type' => 'boolean', 'description' => 'The flag to connect the service to the predefined Docker network.'], 'force_domain_override' => ['type' => 'boolean', 'description' => 'Force domain usage even if conflicts are detected. Default is false.'], 'autogenerate_domain' => ['type' => 'boolean', 'default' => true, 'description' => 'If true and domains is empty, auto-generate a domain using the server\'s wildcard domain or sslip.io fallback. Default: true.'], + 'is_container_label_escape_enabled' => ['type' => 'boolean', 'default' => true, 'description' => 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.'], ], ) ), @@ -856,6 +861,7 @@ class ApplicationsController extends Controller 'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'], 'connect_to_docker_network' => ['type' => 'boolean', 'description' => 'The flag to connect the service to the predefined Docker network.'], 'force_domain_override' => ['type' => 'boolean', 'description' => 'Force domain usage even if conflicts are detected. Default is false.'], + 'is_container_label_escape_enabled' => ['type' => 'boolean', 'default' => true, 'description' => 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.'], ], ) ), @@ -932,7 +938,7 @@ class ApplicationsController extends Controller if ($return instanceof \Illuminate\Http\JsonResponse) { return $return; } - $allowedFields = ['project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'private_key_uuid', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'redirect', 'github_app_uuid', 'instant_deploy', 'dockerfile', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'watch_paths', 'use_build_server', 'static_image', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network', 'force_domain_override', 'autogenerate_domain']; + $allowedFields = ['project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'private_key_uuid', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'redirect', 'github_app_uuid', 'instant_deploy', 'dockerfile', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'watch_paths', 'use_build_server', 'static_image', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network', 'force_domain_override', 'autogenerate_domain', 'is_container_label_escape_enabled']; $validator = customApiValidator($request->all(), [ 'name' => 'string|max:255', @@ -977,6 +983,7 @@ class ApplicationsController extends Controller $isStatic = $request->is_static; $connectToDockerNetwork = $request->connect_to_docker_network; $customNginxConfiguration = $request->custom_nginx_configuration; + $isContainerLabelEscapeEnabled = $request->boolean('is_container_label_escape_enabled', true); if (! is_null($customNginxConfiguration)) { if (! isBase64Encoded($customNginxConfiguration)) { @@ -1093,6 +1100,10 @@ class ApplicationsController extends Controller $application->settings->is_build_server_enabled = $useBuildServer; $application->settings->save(); } + if (isset($isContainerLabelEscapeEnabled)) { + $application->settings->is_container_label_escape_enabled = $isContainerLabelEscapeEnabled; + $application->settings->save(); + } $application->refresh(); // Auto-generate domain if requested and no custom domain provided if ($autogenerateDomain && blank($fqdn)) { @@ -1259,6 +1270,10 @@ class ApplicationsController extends Controller $application->settings->is_build_server_enabled = $useBuildServer; $application->settings->save(); } + if (isset($isContainerLabelEscapeEnabled)) { + $application->settings->is_container_label_escape_enabled = $isContainerLabelEscapeEnabled; + $application->settings->save(); + } if ($application->settings->is_container_label_readonly_enabled) { $application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n"); $application->save(); @@ -1393,6 +1408,10 @@ class ApplicationsController extends Controller $application->settings->is_build_server_enabled = $useBuildServer; $application->settings->save(); } + if (isset($isContainerLabelEscapeEnabled)) { + $application->settings->is_container_label_escape_enabled = $isContainerLabelEscapeEnabled; + $application->settings->save(); + } if ($application->settings->is_container_label_readonly_enabled) { $application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n"); $application->save(); @@ -1492,6 +1511,10 @@ class ApplicationsController extends Controller $application->settings->is_build_server_enabled = $useBuildServer; $application->settings->save(); } + if (isset($isContainerLabelEscapeEnabled)) { + $application->settings->is_container_label_escape_enabled = $isContainerLabelEscapeEnabled; + $application->settings->save(); + } if ($application->settings->is_container_label_readonly_enabled) { $application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n"); $application->save(); @@ -1590,6 +1613,10 @@ class ApplicationsController extends Controller $application->settings->is_build_server_enabled = $useBuildServer; $application->settings->save(); } + if (isset($isContainerLabelEscapeEnabled)) { + $application->settings->is_container_label_escape_enabled = $isContainerLabelEscapeEnabled; + $application->settings->save(); + } if ($application->settings->is_container_label_readonly_enabled) { $application->custom_labels = str(implode('|coolify|', generateLabelsApplication($application)))->replace('|coolify|', "\n"); $application->save(); @@ -1617,7 +1644,7 @@ class ApplicationsController extends Controller 'domains' => data_get($application, 'fqdn'), ]))->setStatusCode(201); } elseif ($type === 'dockercompose') { - $allowedFields = ['project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'instant_deploy', 'docker_compose_raw', 'force_domain_override']; + $allowedFields = ['project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'instant_deploy', 'docker_compose_raw', 'force_domain_override', 'is_container_label_escape_enabled']; $extraFields = array_diff(array_keys($request->all()), $allowedFields); if ($validator->fails() || ! empty($extraFields)) { @@ -1681,6 +1708,9 @@ class ApplicationsController extends Controller $service->server_id = $server->id; $service->destination_id = $destination->id; $service->destination_type = $destination->getMorphClass(); + if (isset($isContainerLabelEscapeEnabled)) { + $service->is_container_label_escape_enabled = $isContainerLabelEscapeEnabled; + } $service->save(); $service->parse(isNew: true); @@ -2047,6 +2077,7 @@ class ApplicationsController extends Controller 'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'], 'connect_to_docker_network' => ['type' => 'boolean', 'description' => 'The flag to connect the service to the predefined Docker network.'], 'force_domain_override' => ['type' => 'boolean', 'description' => 'Force domain usage even if conflicts are detected. Default is false.'], + 'is_container_label_escape_enabled' => ['type' => 'boolean', 'default' => true, 'description' => 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.'], ], ) ), @@ -2132,7 +2163,7 @@ class ApplicationsController extends Controller $this->authorize('update', $application); $server = $application->destination->server; - $allowedFields = ['name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'redirect', 'instant_deploy', 'use_build_server', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network', 'force_domain_override']; + $allowedFields = ['name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'redirect', 'instant_deploy', 'use_build_server', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network', 'force_domain_override', 'is_container_label_escape_enabled']; $validationRules = [ 'name' => 'string|max:255', @@ -2313,6 +2344,7 @@ class ApplicationsController extends Controller $isStatic = $request->is_static; $connectToDockerNetwork = $request->connect_to_docker_network; $useBuildServer = $request->use_build_server; + $isContainerLabelEscapeEnabled = $request->boolean('is_container_label_escape_enabled'); if (isset($useBuildServer)) { $application->settings->is_build_server_enabled = $useBuildServer; @@ -2329,6 +2361,11 @@ class ApplicationsController extends Controller $application->settings->save(); } + if ($request->has('is_container_label_escape_enabled')) { + $application->settings->is_container_label_escape_enabled = $isContainerLabelEscapeEnabled; + $application->settings->save(); + } + removeUnnecessaryFieldsFromRequest($request); $data = $request->all(); diff --git a/bootstrap/helpers/api.php b/bootstrap/helpers/api.php index 84bde5393..d9d6f40d8 100644 --- a/bootstrap/helpers/api.php +++ b/bootstrap/helpers/api.php @@ -135,6 +135,7 @@ function sharedDataApplications() 'docker_compose_domains' => 'array|nullable', 'docker_compose_custom_start_command' => 'string|nullable', 'docker_compose_custom_build_command' => 'string|nullable', + 'is_container_label_escape_enabled' => 'boolean', ]; } @@ -179,4 +180,5 @@ function removeUnnecessaryFieldsFromRequest(Request $request) $request->offsetUnset('is_static'); $request->offsetUnset('force_domain_override'); $request->offsetUnset('autogenerate_domain'); + $request->offsetUnset('is_container_label_escape_enabled'); } diff --git a/openapi.json b/openapi.json index b7ad90111..9bbae8154 100644 --- a/openapi.json +++ b/openapi.json @@ -366,6 +366,11 @@ "type": "boolean", "default": true, "description": "If true and domains is empty, auto-generate a domain using the server's wildcard domain or sslip.io fallback. Default: true." + }, + "is_container_label_escape_enabled": { + "type": "boolean", + "default": true, + "description": "Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off." } }, "type": "object" @@ -781,6 +786,11 @@ "type": "boolean", "default": true, "description": "If true and domains is empty, auto-generate a domain using the server's wildcard domain or sslip.io fallback. Default: true." + }, + "is_container_label_escape_enabled": { + "type": "boolean", + "default": true, + "description": "Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off." } }, "type": "object" @@ -1196,6 +1206,11 @@ "type": "boolean", "default": true, "description": "If true and domains is empty, auto-generate a domain using the server's wildcard domain or sslip.io fallback. Default: true." + }, + "is_container_label_escape_enabled": { + "type": "boolean", + "default": true, + "description": "Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off." } }, "type": "object" @@ -1540,6 +1555,11 @@ "type": "boolean", "default": true, "description": "If true and domains is empty, auto-generate a domain using the server's wildcard domain or sslip.io fallback. Default: true." + }, + "is_container_label_escape_enabled": { + "type": "boolean", + "default": true, + "description": "Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off." } }, "type": "object" @@ -1867,6 +1887,11 @@ "type": "boolean", "default": true, "description": "If true and domains is empty, auto-generate a domain using the server's wildcard domain or sslip.io fallback. Default: true." + }, + "is_container_label_escape_enabled": { + "type": "boolean", + "default": true, + "description": "Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off." } }, "type": "object" @@ -2028,6 +2053,11 @@ "force_domain_override": { "type": "boolean", "description": "Force domain usage even if conflicts are detected. Default is false." + }, + "is_container_label_escape_enabled": { + "type": "boolean", + "default": true, + "description": "Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off." } }, "type": "object" @@ -2549,6 +2579,11 @@ "force_domain_override": { "type": "boolean", "description": "Force domain usage even if conflicts are detected. Default is false." + }, + "is_container_label_escape_enabled": { + "type": "boolean", + "default": true, + "description": "Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off." } }, "type": "object" diff --git a/openapi.yaml b/openapi.yaml index 137b01c00..4a68857fb 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -269,6 +269,10 @@ paths: type: boolean default: true description: "If true and domains is empty, auto-generate a domain using the server's wildcard domain or sslip.io fallback. Default: true." + is_container_label_escape_enabled: + type: boolean + default: true + description: 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.' type: object responses: '201': @@ -539,6 +543,10 @@ paths: type: boolean default: true description: "If true and domains is empty, auto-generate a domain using the server's wildcard domain or sslip.io fallback. Default: true." + is_container_label_escape_enabled: + type: boolean + default: true + description: 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.' type: object responses: '201': @@ -809,6 +817,10 @@ paths: type: boolean default: true description: "If true and domains is empty, auto-generate a domain using the server's wildcard domain or sslip.io fallback. Default: true." + is_container_label_escape_enabled: + type: boolean + default: true + description: 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.' type: object responses: '201': @@ -1026,6 +1038,10 @@ paths: type: boolean default: true description: "If true and domains is empty, auto-generate a domain using the server's wildcard domain or sslip.io fallback. Default: true." + is_container_label_escape_enabled: + type: boolean + default: true + description: 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.' type: object responses: '201': @@ -1234,6 +1250,10 @@ paths: type: boolean default: true description: "If true and domains is empty, auto-generate a domain using the server's wildcard domain or sslip.io fallback. Default: true." + is_container_label_escape_enabled: + type: boolean + default: true + description: 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.' type: object responses: '201': @@ -1318,6 +1338,10 @@ paths: force_domain_override: type: boolean description: 'Force domain usage even if conflicts are detected. Default is false.' + is_container_label_escape_enabled: + type: boolean + default: true + description: 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.' type: object responses: '201': @@ -1658,6 +1682,10 @@ paths: force_domain_override: type: boolean description: 'Force domain usage even if conflicts are detected. Default is false.' + is_container_label_escape_enabled: + type: boolean + default: true + description: 'Escape special characters in labels. By default, $ (and other chars) is escaped. So if you write $ in the labels, it will be saved as $$. If you want to use env variables inside the labels, turn this off.' type: object responses: '200': From 3af456cd356690d83a46d0eecc17de406c43b907 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Tue, 6 Jan 2026 16:18:37 +0100 Subject: [PATCH 014/191] chore: remove raw sql from env relationship - raw sql should not be used whenever possible - using sql to order on the relationship environment_variables() causes custom sorting to break or be additionally complicated --- app/Models/Application.php | 10 +--------- app/Models/Service.php | 10 +--------- app/Models/StandaloneClickhouse.php | 10 +--------- app/Models/StandaloneDragonfly.php | 10 +--------- app/Models/StandaloneKeydb.php | 10 +--------- app/Models/StandaloneMariadb.php | 10 +--------- app/Models/StandaloneMongodb.php | 10 +--------- app/Models/StandaloneMysql.php | 10 +--------- app/Models/StandalonePostgresql.php | 10 +--------- app/Models/StandaloneRedis.php | 10 +--------- 10 files changed, 10 insertions(+), 90 deletions(-) diff --git a/app/Models/Application.php b/app/Models/Application.php index 2eab8df20..59b46f7e7 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -845,15 +845,7 @@ class Application extends BaseModel public function environment_variables() { return $this->morphMany(EnvironmentVariable::class, 'resourceable') - ->where('is_preview', false) - ->orderByRaw(" - CASE - WHEN is_required = true THEN 1 - WHEN LOWER(key) LIKE 'service_%' THEN 2 - ELSE 3 - END, - LOWER(key) ASC - "); + ->where('is_preview', false); } public function runtime_environment_variables() diff --git a/app/Models/Service.php b/app/Models/Service.php index f28b7b635..93f274241 100644 --- a/app/Models/Service.php +++ b/app/Models/Service.php @@ -1458,15 +1458,7 @@ class Service extends BaseModel public function environment_variables() { - return $this->morphMany(EnvironmentVariable::class, 'resourceable') - ->orderByRaw(" - CASE - WHEN is_required = true THEN 1 - WHEN LOWER(key) LIKE 'service_%' THEN 2 - ELSE 3 - END, - LOWER(key) ASC - "); + return $this->morphMany(EnvironmentVariable::class, 'resourceable'); } public function workdir() diff --git a/app/Models/StandaloneClickhouse.php b/app/Models/StandaloneClickhouse.php index ee8a27162..86323db8c 100644 --- a/app/Models/StandaloneClickhouse.php +++ b/app/Models/StandaloneClickhouse.php @@ -295,15 +295,7 @@ class StandaloneClickhouse extends BaseModel public function environment_variables() { - return $this->morphMany(EnvironmentVariable::class, 'resourceable') - ->orderByRaw(" - CASE - WHEN LOWER(key) LIKE 'service_%' THEN 1 - WHEN is_required = true AND (value IS NULL OR value = '') THEN 2 - ELSE 3 - END, - LOWER(key) ASC - "); + return $this->morphMany(EnvironmentVariable::class, 'resourceable'); } public function runtime_environment_variables() diff --git a/app/Models/StandaloneDragonfly.php b/app/Models/StandaloneDragonfly.php index 051a95a80..4db7866b7 100644 --- a/app/Models/StandaloneDragonfly.php +++ b/app/Models/StandaloneDragonfly.php @@ -324,14 +324,6 @@ class StandaloneDragonfly extends BaseModel public function environment_variables() { - return $this->morphMany(EnvironmentVariable::class, 'resourceable') - ->orderByRaw(" - CASE - WHEN LOWER(key) LIKE 'service_%' THEN 1 - WHEN is_required = true AND (value IS NULL OR value = '') THEN 2 - ELSE 3 - END, - LOWER(key) ASC - "); + return $this->morphMany(EnvironmentVariable::class, 'resourceable'); } } diff --git a/app/Models/StandaloneKeydb.php b/app/Models/StandaloneKeydb.php index 6cd51edce..f23499608 100644 --- a/app/Models/StandaloneKeydb.php +++ b/app/Models/StandaloneKeydb.php @@ -324,14 +324,6 @@ class StandaloneKeydb extends BaseModel public function environment_variables() { - return $this->morphMany(EnvironmentVariable::class, 'resourceable') - ->orderByRaw(" - CASE - WHEN LOWER(key) LIKE 'service_%' THEN 1 - WHEN is_required = true AND (value IS NULL OR value = '') THEN 2 - ELSE 3 - END, - LOWER(key) ASC - "); + return $this->morphMany(EnvironmentVariable::class, 'resourceable'); } } diff --git a/app/Models/StandaloneMariadb.php b/app/Models/StandaloneMariadb.php index f312473be..e7ba75b67 100644 --- a/app/Models/StandaloneMariadb.php +++ b/app/Models/StandaloneMariadb.php @@ -289,15 +289,7 @@ class StandaloneMariadb extends BaseModel public function environment_variables() { - return $this->morphMany(EnvironmentVariable::class, 'resourceable') - ->orderByRaw(" - CASE - WHEN LOWER(key) LIKE 'service_%' THEN 1 - WHEN is_required = true AND (value IS NULL OR value = '') THEN 2 - ELSE 3 - END, - LOWER(key) ASC - "); + return $this->morphMany(EnvironmentVariable::class, 'resourceable'); } public function runtime_environment_variables() diff --git a/app/Models/StandaloneMongodb.php b/app/Models/StandaloneMongodb.php index d2d8fef12..d6de5874c 100644 --- a/app/Models/StandaloneMongodb.php +++ b/app/Models/StandaloneMongodb.php @@ -349,14 +349,6 @@ class StandaloneMongodb extends BaseModel public function environment_variables() { - return $this->morphMany(EnvironmentVariable::class, 'resourceable') - ->orderByRaw(" - CASE - WHEN LOWER(key) LIKE 'service_%' THEN 1 - WHEN is_required = true AND (value IS NULL OR value = '') THEN 2 - ELSE 3 - END, - LOWER(key) ASC - "); + return $this->morphMany(EnvironmentVariable::class, 'resourceable'); } } diff --git a/app/Models/StandaloneMysql.php b/app/Models/StandaloneMysql.php index c27b2a679..98a5cab77 100644 --- a/app/Models/StandaloneMysql.php +++ b/app/Models/StandaloneMysql.php @@ -328,14 +328,6 @@ class StandaloneMysql extends BaseModel public function environment_variables() { - return $this->morphMany(EnvironmentVariable::class, 'resourceable') - ->orderByRaw(" - CASE - WHEN LOWER(key) LIKE 'service_%' THEN 1 - WHEN is_required = true AND (value IS NULL OR value = '') THEN 2 - ELSE 3 - END, - LOWER(key) ASC - "); + return $this->morphMany(EnvironmentVariable::class, 'resourceable'); } } diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php index 73b00742a..be86438fe 100644 --- a/app/Models/StandalonePostgresql.php +++ b/app/Models/StandalonePostgresql.php @@ -323,15 +323,7 @@ class StandalonePostgresql extends BaseModel public function environment_variables() { - return $this->morphMany(EnvironmentVariable::class, 'resourceable') - ->orderByRaw(" - CASE - WHEN LOWER(key) LIKE 'service_%' THEN 1 - WHEN is_required = true AND (value IS NULL OR value = '') THEN 2 - ELSE 3 - END, - LOWER(key) ASC - "); + return $this->morphMany(EnvironmentVariable::class, 'resourceable'); } public function isBackupSolutionAvailable() diff --git a/app/Models/StandaloneRedis.php b/app/Models/StandaloneRedis.php index 46e8da434..e906bbb81 100644 --- a/app/Models/StandaloneRedis.php +++ b/app/Models/StandaloneRedis.php @@ -374,14 +374,6 @@ class StandaloneRedis extends BaseModel public function environment_variables() { - return $this->morphMany(EnvironmentVariable::class, 'resourceable') - ->orderByRaw(" - CASE - WHEN LOWER(key) LIKE 'service_%' THEN 1 - WHEN is_required = true AND (value IS NULL OR value = '') THEN 2 - ELSE 3 - END, - LOWER(key) ASC - "); + return $this->morphMany(EnvironmentVariable::class, 'resourceable'); } } From 8ba30d75ead1d95a41d17c3d825fd95f24559aef Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Tue, 6 Jan 2026 16:19:38 +0100 Subject: [PATCH 015/191] refactor: move all env sorting to one place --- .../Shared/EnvironmentVariable/All.php | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/app/Livewire/Project/Shared/EnvironmentVariable/All.php b/app/Livewire/Project/Shared/EnvironmentVariable/All.php index 07938d9d0..55e388b78 100644 --- a/app/Livewire/Project/Shared/EnvironmentVariable/All.php +++ b/app/Livewire/Project/Shared/EnvironmentVariable/All.php @@ -63,20 +63,30 @@ class All extends Component public function getEnvironmentVariablesProperty() { - if ($this->is_env_sorting_enabled === false) { - return $this->resource->environment_variables()->orderBy('order')->get(); + $query = $this->resource->environment_variables() + ->orderByRaw("CASE WHEN is_required = true AND (value IS NULL OR value = '') THEN 0 ELSE 1 END"); + + if ($this->is_env_sorting_enabled) { + $query->orderBy('key'); + } else { + $query->orderBy('order'); } - return $this->resource->environment_variables; + return $query->get(); } public function getEnvironmentVariablesPreviewProperty() { - if ($this->is_env_sorting_enabled === false) { - return $this->resource->environment_variables_preview()->orderBy('order')->get(); + $query = $this->resource->environment_variables_preview() + ->orderByRaw("CASE WHEN is_required = true AND (value IS NULL OR value = '') THEN 0 ELSE 1 END"); + + if ($this->is_env_sorting_enabled) { + $query->orderBy('key'); + } else { + $query->orderBy('order'); } - return $this->resource->environment_variables_preview; + return $query->get(); } public function getDevView() From 40778ad44d8f665c33c1803abe1a119ae653daf5 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Tue, 6 Jan 2026 23:10:38 +0100 Subject: [PATCH 016/191] fix(service): budibase worker envs --- templates/compose/budibase.yaml | 4 ++-- templates/service-templates-latest.json | 2 +- templates/service-templates.json | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/compose/budibase.yaml b/templates/compose/budibase.yaml index ac40406c8..9b7258438 100644 --- a/templates/compose/budibase.yaml +++ b/templates/compose/budibase.yaml @@ -43,8 +43,8 @@ services: - SELF_HOSTED=1 - PORT=4003 - CLUSTER_PORT=10000 - - API_ENCRYPTION_KEY=$SERVICE_BASE64_64_BUDIBASE - - JWT_SECRET=$SERVICE_BASE64_64_BUDIBASE + - API_ENCRYPTION_KEY=$SERVICE_BASE64_64_BUDIBASEAPI + - JWT_SECRET=$SERVICE_BASE64_64_BUDIBASEJWT - MINIO_ACCESS_KEY=$SERVICE_USER_MINIO - MINIO_SECRET_KEY=$SERVICE_PASSWORD_MINIO - MINIO_URL=http://minio-service:9000 diff --git a/templates/service-templates-latest.json b/templates/service-templates-latest.json index 0e2b7bf2b..4a2c59f09 100644 --- a/templates/service-templates-latest.json +++ b/templates/service-templates-latest.json @@ -313,7 +313,7 @@ "budibase": { "documentation": "https://docs.budibase.com/docs/docker-compose?utm_source=coolify.io", "slogan": "Low code platform for building business apps and workflows in minutes. Supports PostgreSQL, MySQL, MSSQL, MongoDB, Rest API, Docker, K8s, and more.", - "compose": "c2VydmljZXM6CiAgYXBwLXNlcnZpY2U6CiAgICBpbWFnZTogYnVkaWJhc2UuZG9ja2VyLnNjYXJmLnNoL2J1ZGliYXNlL2FwcHMKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFTEZfSE9TVEVEPTEKICAgICAgLSAnQ09VQ0hfREJfVVJMPWh0dHA6Ly8kU0VSVklDRV9VU0VSX0NPVUNIREI6JFNFUlZJQ0VfUEFTU1dPUkRfQ09VQ0hEQkBjb3VjaGRiLXNlcnZpY2U6NTk4NCcKICAgICAgLSAnV09SS0VSX1VSTD1odHRwOi8vd29ya2VyLXNlcnZpY2U6NDAwMycKICAgICAgLSAnTUlOSU9fVVJMPWh0dHA6Ly9taW5pby1zZXJ2aWNlOjkwMDAnCiAgICAgIC0gTUlOSU9fQUNDRVNTX0tFWT0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtIElOVEVSTkFMX0FQSV9LRVk9JFNFUlZJQ0VfQkFTRTY0XzEyOF9CVURJQkFTRQogICAgICAtICdCVURJQkFTRV9FTlZJUk9OTUVOVD0ke0JVRElCQVNFX0VOVklST05NRU5UOi1QUk9EVUNUSU9OfScKICAgICAgLSBQT1JUPTQwMDIKICAgICAgLSBBUElfRU5DUllQVElPTl9LRVk9JFNFUlZJQ0VfQkFTRTY0XzY0X0JVRElCQVNFQVBJCiAgICAgIC0gRU5DUllQVElPTl9LRVk9JFNFUlZJQ0VfQkFTRTY0XzY0X0JVRElCQVNFCiAgICAgIC0gSldUX1NFQ1JFVD0kU0VSVklDRV9CQVNFNjRfNjRfQlVESUJBU0VKV1QKICAgICAgLSBMT0dfTEVWRUw9aW5mbwogICAgICAtICdFTkFCTEVfQU5BTFlUSUNTPSR7RU5BQkxFX0FOQUxZVElDUzotdHJ1ZX0nCiAgICAgIC0gJ1JFRElTX1VSTD1yZWRpcy1zZXJ2aWNlOjYzNzknCiAgICAgIC0gUkVESVNfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUkVESVMKICAgICAgLSBCQl9BRE1JTl9VU0VSX0VNQUlMPQogICAgICAtIEJCX0FETUlOX1VTRVJfUEFTU1dPUkQ9CiAgICBkZXBlbmRzX29uOgogICAgICAtIHdvcmtlci1zZXJ2aWNlCiAgICAgIC0gcmVkaXMtc2VydmljZQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICctcU8tJwogICAgICAgIC0gJ2h0dHA6Ly9sb2NhbGhvc3Q6NDAwMi9oZWFsdGgnCiAgICAgIGludGVydmFsOiAxNXMKICAgICAgdGltZW91dDogMTVzCiAgICAgIHJldHJpZXM6IDUKICAgICAgc3RhcnRfcGVyaW9kOiAxMHMKICB3b3JrZXItc2VydmljZToKICAgIGltYWdlOiBidWRpYmFzZS5kb2NrZXIuc2NhcmYuc2gvYnVkaWJhc2Uvd29ya2VyCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRUxGX0hPU1RFRD0xCiAgICAgIC0gUE9SVD00MDAzCiAgICAgIC0gQ0xVU1RFUl9QT1JUPTEwMDAwCiAgICAgIC0gQVBJX0VOQ1JZUFRJT05fS0VZPSRTRVJWSUNFX0JBU0U2NF82NF9CVURJQkFTRQogICAgICAtIEpXVF9TRUNSRVQ9JFNFUlZJQ0VfQkFTRTY0XzY0X0JVRElCQVNFCiAgICAgIC0gTUlOSU9fQUNDRVNTX0tFWT0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdNSU5JT19VUkw9aHR0cDovL21pbmlvLXNlcnZpY2U6OTAwMCcKICAgICAgLSAnQVBQU19VUkw9aHR0cDovL2FwcC1zZXJ2aWNlOjQwMDInCiAgICAgIC0gQ09VQ0hfREJfVVNFUk5BTUU9JFNFUlZJQ0VfVVNFUl9DT1VDSERCCiAgICAgIC0gQ09VQ0hfREJfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfQ09VQ0hEQgogICAgICAtICdDT1VDSF9EQl9VUkw9aHR0cDovLyRTRVJWSUNFX1VTRVJfQ09VQ0hEQjokU0VSVklDRV9QQVNTV09SRF9DT1VDSERCQGNvdWNoZGItc2VydmljZTo1OTg0JwogICAgICAtIElOVEVSTkFMX0FQSV9LRVk9JFNFUlZJQ0VfQkFTRTY0XzEyOF9CVURJQkFTRQogICAgICAtICdSRURJU19VUkw9cmVkaXMtc2VydmljZTo2Mzc5JwogICAgICAtIFJFRElTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1JFRElTCiAgICBkZXBlbmRzX29uOgogICAgICAtIHJlZGlzLXNlcnZpY2UKICAgICAgLSBtaW5pby1zZXJ2aWNlCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gd2dldAogICAgICAgIC0gJy0tc3BpZGVyJwogICAgICAgIC0gJy1xTy0nCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo0MDAzL2hlYWx0aCcKICAgICAgaW50ZXJ2YWw6IDE1cwogICAgICB0aW1lb3V0OiAxNXMKICAgICAgcmV0cmllczogNQogICAgICBzdGFydF9wZXJpb2Q6IDEwcwogIG1pbmlvLXNlcnZpY2U6CiAgICBpbWFnZTogJ2doY3IuaW8vY29vbGxhYnNpby9taW5pbzpSRUxFQVNFLjIwMjUtMTAtMTVUMTctMjktNTVaJwogICAgdm9sdW1lczoKICAgICAgLSAnbWluaW9fZGF0YTovZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtIE1JTklPX1JPT1RfVVNFUj0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtIE1JTklPX0JST1dTRVI9b2ZmCiAgICBjb21tYW5kOiAnc2VydmVyIC9kYXRhIC0tY29uc29sZS1hZGRyZXNzICI6OTAwMSInCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gbWMKICAgICAgICAtIHJlYWR5CiAgICAgICAgLSBsb2NhbAogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcHJveHktc2VydmljZToKICAgIGltYWdlOiBidWRpYmFzZS9wcm94eQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9VUkxfQlVESUJBU0VfMTAwMDAKICAgICAgLSBQUk9YWV9SQVRFX0xJTUlUX1dFQkhPT0tTX1BFUl9TRUNPTkQ9MTAKICAgICAgLSBQUk9YWV9SQVRFX0xJTUlUX0FQSV9QRVJfU0VDT05EPTIwCiAgICAgIC0gJ0FQUFNfVVBTVFJFQU1fVVJMPWh0dHA6Ly9hcHAtc2VydmljZTo0MDAyJwogICAgICAtICdXT1JLRVJfVVBTVFJFQU1fVVJMPWh0dHA6Ly93b3JrZXItc2VydmljZTo0MDAzJwogICAgICAtICdNSU5JT19VUFNUUkVBTV9VUkw9aHR0cDovL21pbmlvLXNlcnZpY2U6OTAwMCcKICAgICAgLSAnQ09VQ0hEQl9VUFNUUkVBTV9VUkw9aHR0cDovL2NvdWNoZGItc2VydmljZTo1OTg0JwogICAgICAtICdXQVRDSFRPV0VSX1VQU1RSRUFNX1VSTD1odHRwOi8vd2F0Y2h0b3dlci1zZXJ2aWNlOjgwODAnCiAgICAgIC0gUkVTT0xWRVI9MTI3LjAuMC4xMQogICAgZGVwZW5kc19vbjoKICAgICAgLSBtaW5pby1zZXJ2aWNlCiAgICAgIC0gd29ya2VyLXNlcnZpY2UKICAgICAgLSBhcHAtc2VydmljZQogICAgICAtIGNvdWNoZGItc2VydmljZQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjEwMDAwLycKICAgICAgaW50ZXJ2YWw6IDE1cwogICAgICB0aW1lb3V0OiAxNXMKICAgICAgcmV0cmllczogNQogICAgICBzdGFydF9wZXJpb2Q6IDEwcwogIGNvdWNoZGItc2VydmljZToKICAgIGltYWdlOiBidWRpYmFzZS9jb3VjaGRiCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBDT1VDSERCX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX0NPVUNIREIKICAgICAgLSBDT1VDSERCX1VTRVI9JFNFUlZJQ0VfVVNFUl9DT1VDSERCCiAgICAgIC0gVEFSR0VUQlVJTEQ9ZG9ja2VyLWNvbXBvc2UKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo1OTg0LycKICAgICAgaW50ZXJ2YWw6IDE1cwogICAgICB0aW1lb3V0OiAxNXMKICAgICAgcmV0cmllczogNQogICAgICBzdGFydF9wZXJpb2Q6IDEwcwogICAgdm9sdW1lczoKICAgICAgLSAnY291Y2hkYjNfZGF0YTovb3B0L2NvdWNoZGIvZGF0YScKICByZWRpcy1zZXJ2aWNlOgogICAgaW1hZ2U6IHJlZGlzCiAgICBjb21tYW5kOiAncmVkaXMtc2VydmVyIC0tcmVxdWlyZXBhc3MgIiRTRVJWSUNFX1BBU1NXT1JEX1JFRElTIicKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3JlZGlzX2RhdGE6L2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSAnLWEnCiAgICAgICAgLSAkU0VSVklDRV9QQVNTV09SRF9SRURJUwogICAgICAgIC0gcGluZwogICAgICBpbnRlcnZhbDogMTVzCiAgICAgIHRpbWVvdXQ6IDE1cwogICAgICByZXRyaWVzOiA1CiAgICAgIHN0YXJ0X3BlcmlvZDogMTBzCiAgd2F0Y2h0b3dlci1zZXJ2aWNlOgogICAgcmVzdGFydDogYWx3YXlzCiAgICBpbWFnZTogY29udGFpbnJyci93YXRjaHRvd2VyCiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgIGNvbW1hbmQ6ICctLWRlYnVnIC0taHR0cC1hcGktdXBkYXRlIGJiYXBwcyBiYndvcmtlciBiYnByb3h5JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gV0FUQ0hUT1dFUl9IVFRQX0FQST10cnVlCiAgICAgIC0gV0FUQ0hUT1dFUl9IVFRQX0FQSV9UT0tFTj0kU0VSVklDRV9QQVNTV09SRF9XQVRDSFRPV0VSCiAgICAgIC0gV0FUQ0hUT1dFUl9DTEVBTlVQPXRydWUKICAgIGxhYmVsczoKICAgICAgLSBjb20uY2VudHVyeWxpbmtsYWJzLndhdGNodG93ZXIuZW5hYmxlPWZhbHNlCiAgICBleGNsdWRlX2Zyb21faGM6IHRydWUK", + "compose": "c2VydmljZXM6CiAgYXBwLXNlcnZpY2U6CiAgICBpbWFnZTogYnVkaWJhc2UuZG9ja2VyLnNjYXJmLnNoL2J1ZGliYXNlL2FwcHMKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFTEZfSE9TVEVEPTEKICAgICAgLSAnQ09VQ0hfREJfVVJMPWh0dHA6Ly8kU0VSVklDRV9VU0VSX0NPVUNIREI6JFNFUlZJQ0VfUEFTU1dPUkRfQ09VQ0hEQkBjb3VjaGRiLXNlcnZpY2U6NTk4NCcKICAgICAgLSAnV09SS0VSX1VSTD1odHRwOi8vd29ya2VyLXNlcnZpY2U6NDAwMycKICAgICAgLSAnTUlOSU9fVVJMPWh0dHA6Ly9taW5pby1zZXJ2aWNlOjkwMDAnCiAgICAgIC0gTUlOSU9fQUNDRVNTX0tFWT0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtIElOVEVSTkFMX0FQSV9LRVk9JFNFUlZJQ0VfQkFTRTY0XzEyOF9CVURJQkFTRQogICAgICAtICdCVURJQkFTRV9FTlZJUk9OTUVOVD0ke0JVRElCQVNFX0VOVklST05NRU5UOi1QUk9EVUNUSU9OfScKICAgICAgLSBQT1JUPTQwMDIKICAgICAgLSBBUElfRU5DUllQVElPTl9LRVk9JFNFUlZJQ0VfQkFTRTY0XzY0X0JVRElCQVNFQVBJCiAgICAgIC0gRU5DUllQVElPTl9LRVk9JFNFUlZJQ0VfQkFTRTY0XzY0X0JVRElCQVNFCiAgICAgIC0gSldUX1NFQ1JFVD0kU0VSVklDRV9CQVNFNjRfNjRfQlVESUJBU0VKV1QKICAgICAgLSBMT0dfTEVWRUw9aW5mbwogICAgICAtICdFTkFCTEVfQU5BTFlUSUNTPSR7RU5BQkxFX0FOQUxZVElDUzotdHJ1ZX0nCiAgICAgIC0gJ1JFRElTX1VSTD1yZWRpcy1zZXJ2aWNlOjYzNzknCiAgICAgIC0gUkVESVNfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUkVESVMKICAgICAgLSBCQl9BRE1JTl9VU0VSX0VNQUlMPQogICAgICAtIEJCX0FETUlOX1VTRVJfUEFTU1dPUkQ9CiAgICBkZXBlbmRzX29uOgogICAgICAtIHdvcmtlci1zZXJ2aWNlCiAgICAgIC0gcmVkaXMtc2VydmljZQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICctcU8tJwogICAgICAgIC0gJ2h0dHA6Ly9sb2NhbGhvc3Q6NDAwMi9oZWFsdGgnCiAgICAgIGludGVydmFsOiAxNXMKICAgICAgdGltZW91dDogMTVzCiAgICAgIHJldHJpZXM6IDUKICAgICAgc3RhcnRfcGVyaW9kOiAxMHMKICB3b3JrZXItc2VydmljZToKICAgIGltYWdlOiBidWRpYmFzZS5kb2NrZXIuc2NhcmYuc2gvYnVkaWJhc2Uvd29ya2VyCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRUxGX0hPU1RFRD0xCiAgICAgIC0gUE9SVD00MDAzCiAgICAgIC0gQ0xVU1RFUl9QT1JUPTEwMDAwCiAgICAgIC0gQVBJX0VOQ1JZUFRJT05fS0VZPSRTRVJWSUNFX0JBU0U2NF82NF9CVURJQkFTRUFQSQogICAgICAtIEpXVF9TRUNSRVQ9JFNFUlZJQ0VfQkFTRTY0XzY0X0JVRElCQVNFSldUCiAgICAgIC0gTUlOSU9fQUNDRVNTX0tFWT0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdNSU5JT19VUkw9aHR0cDovL21pbmlvLXNlcnZpY2U6OTAwMCcKICAgICAgLSAnQVBQU19VUkw9aHR0cDovL2FwcC1zZXJ2aWNlOjQwMDInCiAgICAgIC0gQ09VQ0hfREJfVVNFUk5BTUU9JFNFUlZJQ0VfVVNFUl9DT1VDSERCCiAgICAgIC0gQ09VQ0hfREJfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfQ09VQ0hEQgogICAgICAtICdDT1VDSF9EQl9VUkw9aHR0cDovLyRTRVJWSUNFX1VTRVJfQ09VQ0hEQjokU0VSVklDRV9QQVNTV09SRF9DT1VDSERCQGNvdWNoZGItc2VydmljZTo1OTg0JwogICAgICAtIElOVEVSTkFMX0FQSV9LRVk9JFNFUlZJQ0VfQkFTRTY0XzEyOF9CVURJQkFTRQogICAgICAtICdSRURJU19VUkw9cmVkaXMtc2VydmljZTo2Mzc5JwogICAgICAtIFJFRElTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1JFRElTCiAgICBkZXBlbmRzX29uOgogICAgICAtIHJlZGlzLXNlcnZpY2UKICAgICAgLSBtaW5pby1zZXJ2aWNlCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gd2dldAogICAgICAgIC0gJy0tc3BpZGVyJwogICAgICAgIC0gJy1xTy0nCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo0MDAzL2hlYWx0aCcKICAgICAgaW50ZXJ2YWw6IDE1cwogICAgICB0aW1lb3V0OiAxNXMKICAgICAgcmV0cmllczogNQogICAgICBzdGFydF9wZXJpb2Q6IDEwcwogIG1pbmlvLXNlcnZpY2U6CiAgICBpbWFnZTogJ2doY3IuaW8vY29vbGxhYnNpby9taW5pbzpSRUxFQVNFLjIwMjUtMTAtMTVUMTctMjktNTVaJwogICAgdm9sdW1lczoKICAgICAgLSAnbWluaW9fZGF0YTovZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtIE1JTklPX1JPT1RfVVNFUj0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtIE1JTklPX0JST1dTRVI9b2ZmCiAgICBjb21tYW5kOiAnc2VydmVyIC9kYXRhIC0tY29uc29sZS1hZGRyZXNzICI6OTAwMSInCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gbWMKICAgICAgICAtIHJlYWR5CiAgICAgICAgLSBsb2NhbAogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcHJveHktc2VydmljZToKICAgIGltYWdlOiBidWRpYmFzZS9wcm94eQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9VUkxfQlVESUJBU0VfMTAwMDAKICAgICAgLSBQUk9YWV9SQVRFX0xJTUlUX1dFQkhPT0tTX1BFUl9TRUNPTkQ9MTAKICAgICAgLSBQUk9YWV9SQVRFX0xJTUlUX0FQSV9QRVJfU0VDT05EPTIwCiAgICAgIC0gJ0FQUFNfVVBTVFJFQU1fVVJMPWh0dHA6Ly9hcHAtc2VydmljZTo0MDAyJwogICAgICAtICdXT1JLRVJfVVBTVFJFQU1fVVJMPWh0dHA6Ly93b3JrZXItc2VydmljZTo0MDAzJwogICAgICAtICdNSU5JT19VUFNUUkVBTV9VUkw9aHR0cDovL21pbmlvLXNlcnZpY2U6OTAwMCcKICAgICAgLSAnQ09VQ0hEQl9VUFNUUkVBTV9VUkw9aHR0cDovL2NvdWNoZGItc2VydmljZTo1OTg0JwogICAgICAtICdXQVRDSFRPV0VSX1VQU1RSRUFNX1VSTD1odHRwOi8vd2F0Y2h0b3dlci1zZXJ2aWNlOjgwODAnCiAgICAgIC0gUkVTT0xWRVI9MTI3LjAuMC4xMQogICAgZGVwZW5kc19vbjoKICAgICAgLSBtaW5pby1zZXJ2aWNlCiAgICAgIC0gd29ya2VyLXNlcnZpY2UKICAgICAgLSBhcHAtc2VydmljZQogICAgICAtIGNvdWNoZGItc2VydmljZQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjEwMDAwLycKICAgICAgaW50ZXJ2YWw6IDE1cwogICAgICB0aW1lb3V0OiAxNXMKICAgICAgcmV0cmllczogNQogICAgICBzdGFydF9wZXJpb2Q6IDEwcwogIGNvdWNoZGItc2VydmljZToKICAgIGltYWdlOiBidWRpYmFzZS9jb3VjaGRiCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBDT1VDSERCX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX0NPVUNIREIKICAgICAgLSBDT1VDSERCX1VTRVI9JFNFUlZJQ0VfVVNFUl9DT1VDSERCCiAgICAgIC0gVEFSR0VUQlVJTEQ9ZG9ja2VyLWNvbXBvc2UKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo1OTg0LycKICAgICAgaW50ZXJ2YWw6IDE1cwogICAgICB0aW1lb3V0OiAxNXMKICAgICAgcmV0cmllczogNQogICAgICBzdGFydF9wZXJpb2Q6IDEwcwogICAgdm9sdW1lczoKICAgICAgLSAnY291Y2hkYjNfZGF0YTovb3B0L2NvdWNoZGIvZGF0YScKICByZWRpcy1zZXJ2aWNlOgogICAgaW1hZ2U6IHJlZGlzCiAgICBjb21tYW5kOiAncmVkaXMtc2VydmVyIC0tcmVxdWlyZXBhc3MgIiRTRVJWSUNFX1BBU1NXT1JEX1JFRElTIicKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3JlZGlzX2RhdGE6L2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSAnLWEnCiAgICAgICAgLSAkU0VSVklDRV9QQVNTV09SRF9SRURJUwogICAgICAgIC0gcGluZwogICAgICBpbnRlcnZhbDogMTVzCiAgICAgIHRpbWVvdXQ6IDE1cwogICAgICByZXRyaWVzOiA1CiAgICAgIHN0YXJ0X3BlcmlvZDogMTBzCiAgd2F0Y2h0b3dlci1zZXJ2aWNlOgogICAgcmVzdGFydDogYWx3YXlzCiAgICBpbWFnZTogY29udGFpbnJyci93YXRjaHRvd2VyCiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgIGNvbW1hbmQ6ICctLWRlYnVnIC0taHR0cC1hcGktdXBkYXRlIGJiYXBwcyBiYndvcmtlciBiYnByb3h5JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gV0FUQ0hUT1dFUl9IVFRQX0FQST10cnVlCiAgICAgIC0gV0FUQ0hUT1dFUl9IVFRQX0FQSV9UT0tFTj0kU0VSVklDRV9QQVNTV09SRF9XQVRDSFRPV0VSCiAgICAgIC0gV0FUQ0hUT1dFUl9DTEVBTlVQPXRydWUKICAgIGxhYmVsczoKICAgICAgLSBjb20uY2VudHVyeWxpbmtsYWJzLndhdGNodG93ZXIuZW5hYmxlPWZhbHNlCiAgICBleGNsdWRlX2Zyb21faGM6IHRydWUK", "tags": [ "budibase", "low-code", diff --git a/templates/service-templates.json b/templates/service-templates.json index fe6298e92..78337fe89 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -313,7 +313,7 @@ "budibase": { "documentation": "https://docs.budibase.com/docs/docker-compose?utm_source=coolify.io", "slogan": "Low code platform for building business apps and workflows in minutes. Supports PostgreSQL, MySQL, MSSQL, MongoDB, Rest API, Docker, K8s, and more.", - "compose": "c2VydmljZXM6CiAgYXBwLXNlcnZpY2U6CiAgICBpbWFnZTogYnVkaWJhc2UuZG9ja2VyLnNjYXJmLnNoL2J1ZGliYXNlL2FwcHMKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFTEZfSE9TVEVEPTEKICAgICAgLSAnQ09VQ0hfREJfVVJMPWh0dHA6Ly8kU0VSVklDRV9VU0VSX0NPVUNIREI6JFNFUlZJQ0VfUEFTU1dPUkRfQ09VQ0hEQkBjb3VjaGRiLXNlcnZpY2U6NTk4NCcKICAgICAgLSAnV09SS0VSX1VSTD1odHRwOi8vd29ya2VyLXNlcnZpY2U6NDAwMycKICAgICAgLSAnTUlOSU9fVVJMPWh0dHA6Ly9taW5pby1zZXJ2aWNlOjkwMDAnCiAgICAgIC0gTUlOSU9fQUNDRVNTX0tFWT0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtIElOVEVSTkFMX0FQSV9LRVk9JFNFUlZJQ0VfQkFTRTY0XzEyOF9CVURJQkFTRQogICAgICAtICdCVURJQkFTRV9FTlZJUk9OTUVOVD0ke0JVRElCQVNFX0VOVklST05NRU5UOi1QUk9EVUNUSU9OfScKICAgICAgLSBQT1JUPTQwMDIKICAgICAgLSBBUElfRU5DUllQVElPTl9LRVk9JFNFUlZJQ0VfQkFTRTY0XzY0X0JVRElCQVNFQVBJCiAgICAgIC0gRU5DUllQVElPTl9LRVk9JFNFUlZJQ0VfQkFTRTY0XzY0X0JVRElCQVNFCiAgICAgIC0gSldUX1NFQ1JFVD0kU0VSVklDRV9CQVNFNjRfNjRfQlVESUJBU0VKV1QKICAgICAgLSBMT0dfTEVWRUw9aW5mbwogICAgICAtICdFTkFCTEVfQU5BTFlUSUNTPSR7RU5BQkxFX0FOQUxZVElDUzotdHJ1ZX0nCiAgICAgIC0gJ1JFRElTX1VSTD1yZWRpcy1zZXJ2aWNlOjYzNzknCiAgICAgIC0gUkVESVNfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUkVESVMKICAgICAgLSBCQl9BRE1JTl9VU0VSX0VNQUlMPQogICAgICAtIEJCX0FETUlOX1VTRVJfUEFTU1dPUkQ9CiAgICBkZXBlbmRzX29uOgogICAgICAtIHdvcmtlci1zZXJ2aWNlCiAgICAgIC0gcmVkaXMtc2VydmljZQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICctcU8tJwogICAgICAgIC0gJ2h0dHA6Ly9sb2NhbGhvc3Q6NDAwMi9oZWFsdGgnCiAgICAgIGludGVydmFsOiAxNXMKICAgICAgdGltZW91dDogMTVzCiAgICAgIHJldHJpZXM6IDUKICAgICAgc3RhcnRfcGVyaW9kOiAxMHMKICB3b3JrZXItc2VydmljZToKICAgIGltYWdlOiBidWRpYmFzZS5kb2NrZXIuc2NhcmYuc2gvYnVkaWJhc2Uvd29ya2VyCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRUxGX0hPU1RFRD0xCiAgICAgIC0gUE9SVD00MDAzCiAgICAgIC0gQ0xVU1RFUl9QT1JUPTEwMDAwCiAgICAgIC0gQVBJX0VOQ1JZUFRJT05fS0VZPSRTRVJWSUNFX0JBU0U2NF82NF9CVURJQkFTRQogICAgICAtIEpXVF9TRUNSRVQ9JFNFUlZJQ0VfQkFTRTY0XzY0X0JVRElCQVNFCiAgICAgIC0gTUlOSU9fQUNDRVNTX0tFWT0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdNSU5JT19VUkw9aHR0cDovL21pbmlvLXNlcnZpY2U6OTAwMCcKICAgICAgLSAnQVBQU19VUkw9aHR0cDovL2FwcC1zZXJ2aWNlOjQwMDInCiAgICAgIC0gQ09VQ0hfREJfVVNFUk5BTUU9JFNFUlZJQ0VfVVNFUl9DT1VDSERCCiAgICAgIC0gQ09VQ0hfREJfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfQ09VQ0hEQgogICAgICAtICdDT1VDSF9EQl9VUkw9aHR0cDovLyRTRVJWSUNFX1VTRVJfQ09VQ0hEQjokU0VSVklDRV9QQVNTV09SRF9DT1VDSERCQGNvdWNoZGItc2VydmljZTo1OTg0JwogICAgICAtIElOVEVSTkFMX0FQSV9LRVk9JFNFUlZJQ0VfQkFTRTY0XzEyOF9CVURJQkFTRQogICAgICAtICdSRURJU19VUkw9cmVkaXMtc2VydmljZTo2Mzc5JwogICAgICAtIFJFRElTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1JFRElTCiAgICBkZXBlbmRzX29uOgogICAgICAtIHJlZGlzLXNlcnZpY2UKICAgICAgLSBtaW5pby1zZXJ2aWNlCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gd2dldAogICAgICAgIC0gJy0tc3BpZGVyJwogICAgICAgIC0gJy1xTy0nCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo0MDAzL2hlYWx0aCcKICAgICAgaW50ZXJ2YWw6IDE1cwogICAgICB0aW1lb3V0OiAxNXMKICAgICAgcmV0cmllczogNQogICAgICBzdGFydF9wZXJpb2Q6IDEwcwogIG1pbmlvLXNlcnZpY2U6CiAgICBpbWFnZTogJ2doY3IuaW8vY29vbGxhYnNpby9taW5pbzpSRUxFQVNFLjIwMjUtMTAtMTVUMTctMjktNTVaJwogICAgdm9sdW1lczoKICAgICAgLSAnbWluaW9fZGF0YTovZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtIE1JTklPX1JPT1RfVVNFUj0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtIE1JTklPX0JST1dTRVI9b2ZmCiAgICBjb21tYW5kOiAnc2VydmVyIC9kYXRhIC0tY29uc29sZS1hZGRyZXNzICI6OTAwMSInCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gbWMKICAgICAgICAtIHJlYWR5CiAgICAgICAgLSBsb2NhbAogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcHJveHktc2VydmljZToKICAgIGltYWdlOiBidWRpYmFzZS9wcm94eQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0JVRElCQVNFXzEwMDAwCiAgICAgIC0gUFJPWFlfUkFURV9MSU1JVF9XRUJIT09LU19QRVJfU0VDT05EPTEwCiAgICAgIC0gUFJPWFlfUkFURV9MSU1JVF9BUElfUEVSX1NFQ09ORD0yMAogICAgICAtICdBUFBTX1VQU1RSRUFNX1VSTD1odHRwOi8vYXBwLXNlcnZpY2U6NDAwMicKICAgICAgLSAnV09SS0VSX1VQU1RSRUFNX1VSTD1odHRwOi8vd29ya2VyLXNlcnZpY2U6NDAwMycKICAgICAgLSAnTUlOSU9fVVBTVFJFQU1fVVJMPWh0dHA6Ly9taW5pby1zZXJ2aWNlOjkwMDAnCiAgICAgIC0gJ0NPVUNIREJfVVBTVFJFQU1fVVJMPWh0dHA6Ly9jb3VjaGRiLXNlcnZpY2U6NTk4NCcKICAgICAgLSAnV0FUQ0hUT1dFUl9VUFNUUkVBTV9VUkw9aHR0cDovL3dhdGNodG93ZXItc2VydmljZTo4MDgwJwogICAgICAtIFJFU09MVkVSPTEyNy4wLjAuMTEKICAgIGRlcGVuZHNfb246CiAgICAgIC0gbWluaW8tc2VydmljZQogICAgICAtIHdvcmtlci1zZXJ2aWNlCiAgICAgIC0gYXBwLXNlcnZpY2UKICAgICAgLSBjb3VjaGRiLXNlcnZpY2UKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDoxMDAwMC8nCiAgICAgIGludGVydmFsOiAxNXMKICAgICAgdGltZW91dDogMTVzCiAgICAgIHJldHJpZXM6IDUKICAgICAgc3RhcnRfcGVyaW9kOiAxMHMKICBjb3VjaGRiLXNlcnZpY2U6CiAgICBpbWFnZTogYnVkaWJhc2UvY291Y2hkYgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gQ09VQ0hEQl9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9DT1VDSERCCiAgICAgIC0gQ09VQ0hEQl9VU0VSPSRTRVJWSUNFX1VTRVJfQ09VQ0hEQgogICAgICAtIFRBUkdFVEJVSUxEPWRvY2tlci1jb21wb3NlCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly9sb2NhbGhvc3Q6NTk4NC8nCiAgICAgIGludGVydmFsOiAxNXMKICAgICAgdGltZW91dDogMTVzCiAgICAgIHJldHJpZXM6IDUKICAgICAgc3RhcnRfcGVyaW9kOiAxMHMKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2NvdWNoZGIzX2RhdGE6L29wdC9jb3VjaGRiL2RhdGEnCiAgcmVkaXMtc2VydmljZToKICAgIGltYWdlOiByZWRpcwogICAgY29tbWFuZDogJ3JlZGlzLXNlcnZlciAtLXJlcXVpcmVwYXNzICIkU0VSVklDRV9QQVNTV09SRF9SRURJUyInCiAgICB2b2x1bWVzOgogICAgICAtICdyZWRpc19kYXRhOi9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHJlZGlzLWNsaQogICAgICAgIC0gJy1hJwogICAgICAgIC0gJFNFUlZJQ0VfUEFTU1dPUkRfUkVESVMKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDE1cwogICAgICB0aW1lb3V0OiAxNXMKICAgICAgcmV0cmllczogNQogICAgICBzdGFydF9wZXJpb2Q6IDEwcwogIHdhdGNodG93ZXItc2VydmljZToKICAgIHJlc3RhcnQ6IGFsd2F5cwogICAgaW1hZ2U6IGNvbnRhaW5ycnIvd2F0Y2h0b3dlcgogICAgdm9sdW1lczoKICAgICAgLSAnL3Zhci9ydW4vZG9ja2VyLnNvY2s6L3Zhci9ydW4vZG9ja2VyLnNvY2snCiAgICBjb21tYW5kOiAnLS1kZWJ1ZyAtLWh0dHAtYXBpLXVwZGF0ZSBiYmFwcHMgYmJ3b3JrZXIgYmJwcm94eScKICAgIGVudmlyb25tZW50OgogICAgICAtIFdBVENIVE9XRVJfSFRUUF9BUEk9dHJ1ZQogICAgICAtIFdBVENIVE9XRVJfSFRUUF9BUElfVE9LRU49JFNFUlZJQ0VfUEFTU1dPUkRfV0FUQ0hUT1dFUgogICAgICAtIFdBVENIVE9XRVJfQ0xFQU5VUD10cnVlCiAgICBsYWJlbHM6CiAgICAgIC0gY29tLmNlbnR1cnlsaW5rbGFicy53YXRjaHRvd2VyLmVuYWJsZT1mYWxzZQogICAgZXhjbHVkZV9mcm9tX2hjOiB0cnVlCg==", + "compose": "c2VydmljZXM6CiAgYXBwLXNlcnZpY2U6CiAgICBpbWFnZTogYnVkaWJhc2UuZG9ja2VyLnNjYXJmLnNoL2J1ZGliYXNlL2FwcHMKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFTEZfSE9TVEVEPTEKICAgICAgLSAnQ09VQ0hfREJfVVJMPWh0dHA6Ly8kU0VSVklDRV9VU0VSX0NPVUNIREI6JFNFUlZJQ0VfUEFTU1dPUkRfQ09VQ0hEQkBjb3VjaGRiLXNlcnZpY2U6NTk4NCcKICAgICAgLSAnV09SS0VSX1VSTD1odHRwOi8vd29ya2VyLXNlcnZpY2U6NDAwMycKICAgICAgLSAnTUlOSU9fVVJMPWh0dHA6Ly9taW5pby1zZXJ2aWNlOjkwMDAnCiAgICAgIC0gTUlOSU9fQUNDRVNTX0tFWT0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtIElOVEVSTkFMX0FQSV9LRVk9JFNFUlZJQ0VfQkFTRTY0XzEyOF9CVURJQkFTRQogICAgICAtICdCVURJQkFTRV9FTlZJUk9OTUVOVD0ke0JVRElCQVNFX0VOVklST05NRU5UOi1QUk9EVUNUSU9OfScKICAgICAgLSBQT1JUPTQwMDIKICAgICAgLSBBUElfRU5DUllQVElPTl9LRVk9JFNFUlZJQ0VfQkFTRTY0XzY0X0JVRElCQVNFQVBJCiAgICAgIC0gRU5DUllQVElPTl9LRVk9JFNFUlZJQ0VfQkFTRTY0XzY0X0JVRElCQVNFCiAgICAgIC0gSldUX1NFQ1JFVD0kU0VSVklDRV9CQVNFNjRfNjRfQlVESUJBU0VKV1QKICAgICAgLSBMT0dfTEVWRUw9aW5mbwogICAgICAtICdFTkFCTEVfQU5BTFlUSUNTPSR7RU5BQkxFX0FOQUxZVElDUzotdHJ1ZX0nCiAgICAgIC0gJ1JFRElTX1VSTD1yZWRpcy1zZXJ2aWNlOjYzNzknCiAgICAgIC0gUkVESVNfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUkVESVMKICAgICAgLSBCQl9BRE1JTl9VU0VSX0VNQUlMPQogICAgICAtIEJCX0FETUlOX1VTRVJfUEFTU1dPUkQ9CiAgICBkZXBlbmRzX29uOgogICAgICAtIHdvcmtlci1zZXJ2aWNlCiAgICAgIC0gcmVkaXMtc2VydmljZQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICctcU8tJwogICAgICAgIC0gJ2h0dHA6Ly9sb2NhbGhvc3Q6NDAwMi9oZWFsdGgnCiAgICAgIGludGVydmFsOiAxNXMKICAgICAgdGltZW91dDogMTVzCiAgICAgIHJldHJpZXM6IDUKICAgICAgc3RhcnRfcGVyaW9kOiAxMHMKICB3b3JrZXItc2VydmljZToKICAgIGltYWdlOiBidWRpYmFzZS5kb2NrZXIuc2NhcmYuc2gvYnVkaWJhc2Uvd29ya2VyCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRUxGX0hPU1RFRD0xCiAgICAgIC0gUE9SVD00MDAzCiAgICAgIC0gQ0xVU1RFUl9QT1JUPTEwMDAwCiAgICAgIC0gQVBJX0VOQ1JZUFRJT05fS0VZPSRTRVJWSUNFX0JBU0U2NF82NF9CVURJQkFTRUFQSQogICAgICAtIEpXVF9TRUNSRVQ9JFNFUlZJQ0VfQkFTRTY0XzY0X0JVRElCQVNFSldUCiAgICAgIC0gTUlOSU9fQUNDRVNTX0tFWT0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fU0VDUkVUX0tFWT0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtICdNSU5JT19VUkw9aHR0cDovL21pbmlvLXNlcnZpY2U6OTAwMCcKICAgICAgLSAnQVBQU19VUkw9aHR0cDovL2FwcC1zZXJ2aWNlOjQwMDInCiAgICAgIC0gQ09VQ0hfREJfVVNFUk5BTUU9JFNFUlZJQ0VfVVNFUl9DT1VDSERCCiAgICAgIC0gQ09VQ0hfREJfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfQ09VQ0hEQgogICAgICAtICdDT1VDSF9EQl9VUkw9aHR0cDovLyRTRVJWSUNFX1VTRVJfQ09VQ0hEQjokU0VSVklDRV9QQVNTV09SRF9DT1VDSERCQGNvdWNoZGItc2VydmljZTo1OTg0JwogICAgICAtIElOVEVSTkFMX0FQSV9LRVk9JFNFUlZJQ0VfQkFTRTY0XzEyOF9CVURJQkFTRQogICAgICAtICdSRURJU19VUkw9cmVkaXMtc2VydmljZTo2Mzc5JwogICAgICAtIFJFRElTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1JFRElTCiAgICBkZXBlbmRzX29uOgogICAgICAtIHJlZGlzLXNlcnZpY2UKICAgICAgLSBtaW5pby1zZXJ2aWNlCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gd2dldAogICAgICAgIC0gJy0tc3BpZGVyJwogICAgICAgIC0gJy1xTy0nCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo0MDAzL2hlYWx0aCcKICAgICAgaW50ZXJ2YWw6IDE1cwogICAgICB0aW1lb3V0OiAxNXMKICAgICAgcmV0cmllczogNQogICAgICBzdGFydF9wZXJpb2Q6IDEwcwogIG1pbmlvLXNlcnZpY2U6CiAgICBpbWFnZTogJ2doY3IuaW8vY29vbGxhYnNpby9taW5pbzpSRUxFQVNFLjIwMjUtMTAtMTVUMTctMjktNTVaJwogICAgdm9sdW1lczoKICAgICAgLSAnbWluaW9fZGF0YTovZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtIE1JTklPX1JPT1RfVVNFUj0kU0VSVklDRV9VU0VSX01JTklPCiAgICAgIC0gTUlOSU9fUk9PVF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NSU5JTwogICAgICAtIE1JTklPX0JST1dTRVI9b2ZmCiAgICBjb21tYW5kOiAnc2VydmVyIC9kYXRhIC0tY29uc29sZS1hZGRyZXNzICI6OTAwMSInCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gbWMKICAgICAgICAtIHJlYWR5CiAgICAgICAgLSBsb2NhbAogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcHJveHktc2VydmljZToKICAgIGltYWdlOiBidWRpYmFzZS9wcm94eQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0JVRElCQVNFXzEwMDAwCiAgICAgIC0gUFJPWFlfUkFURV9MSU1JVF9XRUJIT09LU19QRVJfU0VDT05EPTEwCiAgICAgIC0gUFJPWFlfUkFURV9MSU1JVF9BUElfUEVSX1NFQ09ORD0yMAogICAgICAtICdBUFBTX1VQU1RSRUFNX1VSTD1odHRwOi8vYXBwLXNlcnZpY2U6NDAwMicKICAgICAgLSAnV09SS0VSX1VQU1RSRUFNX1VSTD1odHRwOi8vd29ya2VyLXNlcnZpY2U6NDAwMycKICAgICAgLSAnTUlOSU9fVVBTVFJFQU1fVVJMPWh0dHA6Ly9taW5pby1zZXJ2aWNlOjkwMDAnCiAgICAgIC0gJ0NPVUNIREJfVVBTVFJFQU1fVVJMPWh0dHA6Ly9jb3VjaGRiLXNlcnZpY2U6NTk4NCcKICAgICAgLSAnV0FUQ0hUT1dFUl9VUFNUUkVBTV9VUkw9aHR0cDovL3dhdGNodG93ZXItc2VydmljZTo4MDgwJwogICAgICAtIFJFU09MVkVSPTEyNy4wLjAuMTEKICAgIGRlcGVuZHNfb246CiAgICAgIC0gbWluaW8tc2VydmljZQogICAgICAtIHdvcmtlci1zZXJ2aWNlCiAgICAgIC0gYXBwLXNlcnZpY2UKICAgICAgLSBjb3VjaGRiLXNlcnZpY2UKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDoxMDAwMC8nCiAgICAgIGludGVydmFsOiAxNXMKICAgICAgdGltZW91dDogMTVzCiAgICAgIHJldHJpZXM6IDUKICAgICAgc3RhcnRfcGVyaW9kOiAxMHMKICBjb3VjaGRiLXNlcnZpY2U6CiAgICBpbWFnZTogYnVkaWJhc2UvY291Y2hkYgogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gQ09VQ0hEQl9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9DT1VDSERCCiAgICAgIC0gQ09VQ0hEQl9VU0VSPSRTRVJWSUNFX1VTRVJfQ09VQ0hEQgogICAgICAtIFRBUkdFVEJVSUxEPWRvY2tlci1jb21wb3NlCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly9sb2NhbGhvc3Q6NTk4NC8nCiAgICAgIGludGVydmFsOiAxNXMKICAgICAgdGltZW91dDogMTVzCiAgICAgIHJldHJpZXM6IDUKICAgICAgc3RhcnRfcGVyaW9kOiAxMHMKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2NvdWNoZGIzX2RhdGE6L29wdC9jb3VjaGRiL2RhdGEnCiAgcmVkaXMtc2VydmljZToKICAgIGltYWdlOiByZWRpcwogICAgY29tbWFuZDogJ3JlZGlzLXNlcnZlciAtLXJlcXVpcmVwYXNzICIkU0VSVklDRV9QQVNTV09SRF9SRURJUyInCiAgICB2b2x1bWVzOgogICAgICAtICdyZWRpc19kYXRhOi9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHJlZGlzLWNsaQogICAgICAgIC0gJy1hJwogICAgICAgIC0gJFNFUlZJQ0VfUEFTU1dPUkRfUkVESVMKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDE1cwogICAgICB0aW1lb3V0OiAxNXMKICAgICAgcmV0cmllczogNQogICAgICBzdGFydF9wZXJpb2Q6IDEwcwogIHdhdGNodG93ZXItc2VydmljZToKICAgIHJlc3RhcnQ6IGFsd2F5cwogICAgaW1hZ2U6IGNvbnRhaW5ycnIvd2F0Y2h0b3dlcgogICAgdm9sdW1lczoKICAgICAgLSAnL3Zhci9ydW4vZG9ja2VyLnNvY2s6L3Zhci9ydW4vZG9ja2VyLnNvY2snCiAgICBjb21tYW5kOiAnLS1kZWJ1ZyAtLWh0dHAtYXBpLXVwZGF0ZSBiYmFwcHMgYmJ3b3JrZXIgYmJwcm94eScKICAgIGVudmlyb25tZW50OgogICAgICAtIFdBVENIVE9XRVJfSFRUUF9BUEk9dHJ1ZQogICAgICAtIFdBVENIVE9XRVJfSFRUUF9BUElfVE9LRU49JFNFUlZJQ0VfUEFTU1dPUkRfV0FUQ0hUT1dFUgogICAgICAtIFdBVENIVE9XRVJfQ0xFQU5VUD10cnVlCiAgICBsYWJlbHM6CiAgICAgIC0gY29tLmNlbnR1cnlsaW5rbGFicy53YXRjaHRvd2VyLmVuYWJsZT1mYWxzZQogICAgZXhjbHVkZV9mcm9tX2hjOiB0cnVlCg==", "tags": [ "budibase", "low-code", From cc53e9476e3cc6b00ce5353a458ab1e17ca948b1 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Wed, 7 Jan 2026 14:57:13 +0100 Subject: [PATCH 017/191] fix(docker): add fallback for Docker Swarm container labels --- app/Actions/Docker/GetContainersStatus.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/Actions/Docker/GetContainersStatus.php b/app/Actions/Docker/GetContainersStatus.php index 3631cca24..c8e3162c0 100644 --- a/app/Actions/Docker/GetContainersStatus.php +++ b/app/Actions/Docker/GetContainersStatus.php @@ -145,6 +145,12 @@ class GetContainersStatus $this->applicationContainerStatuses->put($applicationId, collect()); } $containerName = data_get($labels, 'com.docker.compose.service'); + // Fallback for Docker Swarm which uses different labels + if (! $containerName && $this->server->isSwarm()) { + $containerName = data_get($labels, 'coolify.serviceName') + ?? data_get($labels, 'coolify.name') + ?? data_get($labels, 'com.docker.stack.namespace'); + } if ($containerName) { $this->applicationContainerStatuses->get($applicationId)->put($containerName, $containerStatus); } From 7a305fd2cd6866de28c7ff094c66bb8b182d3e7e Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Wed, 7 Jan 2026 15:23:48 +0100 Subject: [PATCH 018/191] fix: prevent timing attack in GitLab webhook token validation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace insecure !== operator with hash_equals() for constant-time string comparison when validating GitLab webhook tokens. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- app/Http/Controllers/Webhook/Gitlab.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Http/Controllers/Webhook/Gitlab.php b/app/Http/Controllers/Webhook/Gitlab.php index 5b8dd5686..34a5266ca 100644 --- a/app/Http/Controllers/Webhook/Gitlab.php +++ b/app/Http/Controllers/Webhook/Gitlab.php @@ -100,7 +100,7 @@ class Gitlab extends Controller } foreach ($applications as $application) { $webhook_secret = data_get($application, 'manual_webhook_secret_gitlab'); - if ($webhook_secret !== $x_gitlab_token) { + if (! hash_equals($webhook_secret ?? '', $x_gitlab_token ?? '')) { $return_payloads->push([ 'application' => $application->name, 'status' => 'failed', From 06f477461079af8768d0e6ff6150e88fb8bca821 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Victor=20Can=C3=B4?= Date: Wed, 7 Jan 2026 15:01:32 -0300 Subject: [PATCH 019/191] feat(service): upgrade trigger template to v4 (#7808) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 🏔️ Peak <122374094+peaklabs-dev@users.noreply.github.com> --- public/svgs/trigger.avif | Bin 6465 -> 0 bytes .../trigger-with-external-database.yaml | 37 --- templates/compose/trigger.yaml | 275 +++++++++++------- templates/service-templates-latest.json | 37 +-- templates/service-templates.json | 37 +-- 5 files changed, 191 insertions(+), 195 deletions(-) delete mode 100644 public/svgs/trigger.avif delete mode 100644 templates/compose/trigger-with-external-database.yaml diff --git a/public/svgs/trigger.avif b/public/svgs/trigger.avif deleted file mode 100644 index 66500da9f9ee4bb382ddef5ddc8379186be215e7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6465 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 z 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 diff --git a/templates/compose/trigger-with-external-database.yaml b/templates/compose/trigger-with-external-database.yaml deleted file mode 100644 index 706d07067..000000000 --- a/templates/compose/trigger-with-external-database.yaml +++ /dev/null @@ -1,37 +0,0 @@ -# documentation: https://trigger.dev -# slogan: The open source Background Jobs framework for TypeScript -# category: automation -# tags: trigger.dev, background jobs, typescript, trigger, jobs, cron, scheduler -# logo: svgs/trigger.png -# port: 3000 - -services: - trigger: - image: ghcr.io/triggerdotdev/trigger.dev:main - environment: - - SERVICE_URL_TRIGGER_3000 - - LOGIN_ORIGIN=$SERVICE_URL_TRIGGER - - APP_ORIGIN=$SERVICE_URL_TRIGGER - - MAGIC_LINK_SECRET=$SERVICE_PASSWORD_32_MAGIC - - ENCRYPTION_KEY=$SERVICE_PASSWORD_32_ENCRYPTION - - SESSION_SECRET=$SERVICE_PASSWORD_32_SESSION - - DATABASE_URL=${DATABASE_URL:?} - - DIRECT_URL=${DATABASE_URL:?} - - RUNTIME_PLATFORM=docker-compose - - NODE_ENV=production - - AUTH_GITHUB_CLIENT_ID=${AUTH_GITHUB_CLIENT_ID} - - AUTH_GITHUB_CLIENT_SECRET=${AUTH_GITHUB_CLIENT_SECRET} - - RESEND_API_KEY=${RESEND_API_KEY} - - FROM_EMAIL=${FROM_EMAIL} - - REPLY_TO_EMAIL=${REPLY_TO_EMAIL} - - REDIS_HOST=${REDIS_HOST} - - REDIS_PORT=${REDIS_PORT} - - REDIS_USERNAME=${REDIS_USERNAME} - - REDIS_PASSWORD=${REDIS_PASSWORD} - - REDIS_TLS_DISABLED=${REDIS_TLS_DISABLED:-true} - - healthcheck: - test: "timeout 10s bash -c ':> /dev/tcp/127.0.0.1/3000' || exit 1" - interval: 10s - timeout: 5s - retries: 5 diff --git a/templates/compose/trigger.yaml b/templates/compose/trigger.yaml index be385ecc7..c46b88634 100644 --- a/templates/compose/trigger.yaml +++ b/templates/compose/trigger.yaml @@ -1,58 +1,82 @@ -# documentation: https://trigger.dev -# slogan: The open source Background Jobs framework for TypeScript +# documentation: https://trigger.dev/docs/self-hosting/overview +# slogan: The open source background jobs platform for developers # category: automation -# tags: trigger.dev, background jobs, typescript, trigger, jobs, cron, scheduler +# tags: background-jobs, typescript, javascript, scheduling, workflows, automation, tasks, queues # logo: svgs/trigger.png # port: 3000 -x-common-env: &common-env - REMIX_APP_PORT: 3000 - NODE_ENV: production - RUNTIME_PLATFORM: docker-compose - V3_ENABLED: true - INTERNAL_OTEL_TRACE_DISABLED: 1 - INTERNAL_OTEL_TRACE_LOGGING_ENABLED: 0 - POSTGRES_USER: $SERVICE_USER_POSTGRES - POSTGRES_PASSWORD: $SERVICE_PASSWORD_POSTGRES - POSTGRES_DB: ${POSTGRES_DB:-trigger} - MAGIC_LINK_SECRET: $SERVICE_PASSWORD_32_MAGIC - SESSION_SECRET: $SERVICE_PASSWORD_32_SESSION - ENCRYPTION_KEY: $SERVICE_PASSWORD_32_ENCRYPTION - PROVIDER_SECRET: $SERVICE_PASSWORD_64_PROVIDER - COORDINATOR_SECRET: $SERVICE_PASSWORD_64_COORDINATOR - DATABASE_HOST: postgresql:5432 - DATABASE_URL: postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB?sslmode=disable - DIRECT_URL: postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB?sslmode=disable - REDIS_HOST: redis - REDIS_PORT: 6379 - REDIS_TLS_DISABLED: true - COORDINATOR_HOST: 127.0.0.1 - COORDINATOR_PORT: 9020 - WHITELISTED_EMAILS: "" - ADMIN_EMAILS: "" - DEFAULT_ORG_EXECUTION_CONCURRENCY_LIMIT: 300 - DEFAULT_ENV_EXECUTION_CONCURRENCY_LIMIT: 100 - DEPLOY_REGISTRY_HOST: docker.io - DEPLOY_REGISTRY_NAMESPACE: trigger - REGISTRY_HOST: ${DEPLOY_REGISTRY_HOST} - REGISTRY_NAMESPACE: ${DEPLOY_REGISTRY_NAMESPACE} - AUTH_GITHUB_CLIENT_ID: ${AUTH_GITHUB_CLIENT_ID} - AUTH_GITHUB_CLIENT_SECRET: ${AUTH_GITHUB_CLIENT_SECRET} - RESEND_API_KEY: ${RESEND_API_KEY} - FROM_EMAIL: ${FROM_EMAIL} - REPLY_TO_EMAIL: ${REPLY_TO_EMAIL} - LOGIN_ORIGIN: $SERVICE_URL_TRIGGER_3000 - APP_ORIGIN: $SERVICE_URL_TRIGGER_3000 - DEV_OTEL_EXPORTER_OTLP_ENDPOINT: $SERVICE_URL_TRIGGER_3000/otel - OTEL_EXPORTER_OTLP_ENDPOINT: $SERVICE_URL_TRIGGER_3000/otel - ELECTRIC_ORIGIN: http://electric:3000 - services: trigger: - image: ghcr.io/triggerdotdev/trigger.dev:v3 + image: ghcr.io/triggerdotdev/trigger.dev:v4.3.0 + # Root user is required for bootstrap and shared volume permissions + # See: https://github.com/triggerdotdev/trigger.dev/blob/main/hosting/docker/webapp/docker-compose.yml + user: root + command: | + sh -c "chown -R node:node /home/node/shared && exec ./scripts/entrypoint.sh" environment: - SERVICE_URL_TRIGGER_3000: "" - <<: *common-env + - SERVICE_URL_TRIGGER_3000 + - APP_ORIGIN=${SERVICE_URL_TRIGGER_3000} + - LOGIN_ORIGIN=${SERVICE_URL_TRIGGER_3000} + - API_ORIGIN=${SERVICE_URL_TRIGGER_3000} + - SESSION_SECRET=${SERVICE_PASSWORD_64_SESSION} + - MAGIC_LINK_SECRET=${SERVICE_PASSWORD_64_MAGICLINK} + - ENCRYPTION_KEY=${SERVICE_PASSWORD_ENCRYPTIONKEY} + - MANAGED_WORKER_SECRET=${SERVICE_PASSWORD_64_WORKERSECRET} + - TRIGGER_WORKER_TOKEN=${TRIGGER_WORKER_TOKEN} + - NODE_ENV=production + - APP_LOG_LEVEL=info + - DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql:5432/${POSTGRES_DB:-trigger-db}?schema=public&sslmode=disable + - DIRECT_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql:5432/${POSTGRES_DB:-trigger-db}?schema=public&sslmode=disable + - REDIS_HOST=redis + - REDIS_PORT=6379 + - REDIS_TLS_DISABLED=true + - ELECTRIC_ORIGIN=http://electric:3000 + - DEV_OTEL_EXPORTER_OTLP_ENDPOINT=${DEV_OTEL_EXPORTER_OTLP_ENDPOINT:-} + - DEPLOY_REGISTRY_HOST=${DEPLOY_REGISTRY_HOST:-ghcr.io} + - DEPLOY_REGISTRY_PROTOCOL=${DEPLOY_REGISTRY_PROTOCOL:-https} + - DEPLOY_REGISTRY_NAMESPACE=${DEPLOY_REGISTRY_NAMESPACE:-trigger} + - V4_DEPLOY_REGISTRY_NAMESPACE=${DEPLOY_REGISTRY_NAMESPACE:-trigger} + - OBJECT_STORE_BASE_URL=${OBJECT_STORE_BASE_URL} + - OBJECT_STORE_ACCESS_KEY_ID=${OBJECT_STORE_ACCESS_KEY_ID} + - OBJECT_STORE_SECRET_ACCESS_KEY=${OBJECT_STORE_SECRET_ACCESS_KEY} + - CLICKHOUSE_URL=http://${SERVICE_USER_CLICKHOUSE}:${SERVICE_PASSWORD_64_CLICKHOUSE}@clickhouse:8123?secure=false + - CLICKHOUSE_LOG_LEVEL=info + - RUN_REPLICATION_ENABLED=1 + - RUN_REPLICATION_CLICKHOUSE_URL=http://${SERVICE_USER_CLICKHOUSE}:${SERVICE_PASSWORD_64_CLICKHOUSE}@clickhouse:8123 + - RUN_REPLICATION_LOG_LEVEL=info + - TRIGGER_BOOTSTRAP_ENABLED=1 + - TRIGGER_BOOTSTRAP_WORKER_GROUP_NAME=bootstrap + - TRIGGER_BOOTSTRAP_WORKER_TOKEN_PATH=/home/node/shared/worker_token + - DEFAULT_ORG_EXECUTION_CONCURRENCY_LIMIT=${DEFAULT_ORG_EXECUTION_CONCURRENCY_LIMIT:-300} + - DEFAULT_ENV_EXECUTION_CONCURRENCY_LIMIT=${DEFAULT_ENV_EXECUTION_CONCURRENCY_LIMIT:-100} + - AUTH_GITHUB_CLIENT_ID=${AUTH_GITHUB_CLIENT_ID:-} + - AUTH_GITHUB_CLIENT_SECRET=${AUTH_GITHUB_CLIENT_SECRET:-} + - EMAIL_TRANSPORT=${EMAIL_TRANSPORT:-smtp} + - RESEND_API_KEY=${RESEND_API_KEY} + - SMTP_HOST=${SMTP_HOST} + - SMTP_PORT=${SMTP_PORT} + - SMTP_USER=${SMTP_USER} + - SMTP_PASSWORD=${SMTP_PASSWORD} + - SMTP_SECURE=${SMTP_SECURE} + - FROM_EMAIL=${FROM_EMAIL} + - REPLY_TO_EMAIL=${REPLY_TO_EMAIL} + - WHITELISTED_EMAILS=${WHITELISTED_EMAILS} + - ADMIN_EMAILS=${ADMIN_EMAILS} + - GRACEFUL_SHUTDOWN_TIMEOUT=1000 + - INTERNAL_OTEL_TRACE_LOGGING_ENABLED=${INTERNAL_OTEL_TRACE_LOGGING_ENABLED:-0} + - TRIGGER_TELEMETRY_DISABLED=${TRIGGER_TELEMETRY_DISABLED:-true} + volumes: + - shared-data:/home/node/shared + healthcheck: + test: + - CMD + - node + - "-e" + - "require('http').get('http://127.0.0.1:3000/healthcheck',(r)=>process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1))" + interval: 10s + timeout: 5s + retries: 5 + start_period: 10s depends_on: postgresql: condition: service_healthy @@ -60,87 +84,130 @@ services: condition: service_healthy electric: condition: service_healthy + clickhouse: + condition: service_healthy + + supervisor: + image: ghcr.io/triggerdotdev/supervisor:v4.3.0 + user: root + command: | + sh -c "chown -R node:node /home/node/shared && exec /usr/bin/dumb-init -- pnpm run --filter supervisor start" + environment: + - TRIGGER_API_URL=http://trigger:3000 + - OTEL_EXPORTER_OTLP_ENDPOINT=http://trigger:3000/otel + - TRIGGER_WORKER_TOKEN=${TRIGGER_WORKER_TOKEN:-file:///home/node/shared/worker_token} + - MANAGED_WORKER_SECRET=${SERVICE_PASSWORD_64_WORKERSECRET} + - TRIGGER_WORKLOAD_API_DOMAIN=${TRIGGER_WORKLOAD_API_DOMAIN} + - TRIGGER_WORKLOAD_API_PORT_EXTERNAL=8020 + - DOCKER_HOST=tcp://docker-proxy:2375 + - DOCKER_RUNNER_NETWORKS=${DOCKER_RUNNER_NETWORKS} + - DOCKER_AUTOREMOVE_EXITED_CONTAINERS=${DOCKER_AUTOREMOVE_EXITED_CONTAINERS:-1} + - DOCKER_REGISTRY_URL=https://${DEPLOY_REGISTRY_HOST:-ghcr.io} + - DOCKER_REGISTRY_USERNAME=${DEPLOY_REGISTRY_USERNAME} + - DOCKER_REGISTRY_PASSWORD=${DEPLOY_REGISTRY_PASSWORD} + - ENFORCE_MACHINE_PRESETS=1 + - TRIGGER_DEQUEUE_INTERVAL_MS=1000 + - DEBUG=${SUPERVISOR_DEBUG:-0} + volumes: + - shared-data:/home/node/shared healthcheck: - test: "timeout 10s bash -c ':> /dev/tcp/127.0.0.1/3000' || exit 1" + test: + - CMD + - node + - "-e" + - "require('http').get('http://127.0.0.1:8020/health',(r)=>process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1))" interval: 10s timeout: 5s retries: 5 - - electric: - image: electricsql/electric - environment: - <<: *common-env depends_on: - postgresql: + trigger: + condition: service_healthy + docker-proxy: condition: service_healthy - healthcheck: - test: - - CMD-SHELL - - pwd - redis: - image: "redis:7" + docker-proxy: + image: tecnativa/docker-socket-proxy:v0.4.2 + volumes: + - /var/run/docker.sock:/var/run/docker.sock:ro environment: - - ALLOW_EMPTY_PASSWORD=yes + - LOG_LEVEL=info + - POST=${POST:-1} + - CONTAINERS=${CONTAINERS:-1} + - IMAGES=${IMAGES:-1} + - INFO=${INFO:-1} + - NETWORKS=${NETWORKS:-1} + - AUTH=${AUTH:-1} + - DISTRIBUTION=${DISTRIBUTION:-1} healthcheck: test: - CMD-SHELL - - "redis-cli -h localhost -p 6379 ping" - interval: 5s + - nc -z 127.0.0.1 2375 || exit 1 + interval: 30s timeout: 5s - retries: 3 - volumes: - - redis-data:/data + retries: 5 + postgresql: image: postgres:16-alpine + command: + - "-c" + - wal_level=logical + environment: + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB:-trigger-db} volumes: - postgresql-data:/var/lib/postgresql/data - environment: - <<: *common-env - command: - - -c - - wal_level=logical healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s timeout: 20s retries: 10 - docker-provider: - image: ghcr.io/triggerdotdev/provider/docker:v3 - platform: linux/amd64 + redis: + image: redis:7-alpine volumes: - - /var/run/docker.sock:/var/run/docker.sock - user: root - depends_on: - trigger: - condition: service_healthy + - redis-data:/data + healthcheck: + test: + - CMD + - redis-cli + - ping + interval: 10s + timeout: 5s + retries: 5 + + electric: + image: electricsql/electric:1.2.9 environment: - <<: *common-env - PLATFORM_HOST: trigger - PLATFORM_WS_PORT: 3000 - SECURE_CONNECTION: "false" - PLATFORM_SECRET: $SERVICE_PASSWORD_64_PROVIDER - HTTP_SERVER_PORT: 9020 - coordinator: - image: ghcr.io/triggerdotdev/coordinator:v3 - platform: linux/amd64 + - DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql:5432/${POSTGRES_DB:-trigger-db}?sslmode=disable + - ELECTRIC_SECRET=${SERVICE_PASSWORD_64_ELECTRIC} + - ELECTRIC_USAGE_REPORTING=false + healthcheck: + test: + - CMD + - curl + - "-f" + - "http://localhost:3000/v1/health" + interval: 10s + timeout: 5s + retries: 5 + depends_on: + postgresql: + condition: service_healthy + + clickhouse: + image: clickhouse/clickhouse-server:25.8 + environment: + - CLICKHOUSE_USER=${SERVICE_USER_CLICKHOUSE} + - CLICKHOUSE_PASSWORD=${SERVICE_PASSWORD_64_CLICKHOUSE} + - CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1 volumes: - - /var/run/docker.sock:/var/run/docker.sock - user: root - ports: - - '127.0.0.1:9020:9020' - depends_on: - trigger: - condition: service_healthy - environment: - <<: *common-env - PLATFORM_HOST: trigger - PLATFORM_WS_PORT: 3000 - SECURE_CONNECTION: "false" - PLATFORM_SECRET: $SERVICE_PASSWORD_64_COORDINATOR - HTTP_SERVER_PORT: 9020 + - clickhouse-data:/var/lib/clickhouse + - clickhouse-logs:/var/log/clickhouse-server healthcheck: test: - CMD-SHELL - - pwd + - wget --no-verbose --tries=1 --spider http://localhost:8123/ping || exit 1 + interval: 10s + timeout: 5s + retries: 5 diff --git a/templates/service-templates-latest.json b/templates/service-templates-latest.json index 4a2c59f09..d5ed6fd29 100644 --- a/templates/service-templates-latest.json +++ b/templates/service-templates-latest.json @@ -4402,36 +4402,19 @@ "minversion": "0.0.0", "port": "9091" }, - "trigger-with-external-database": { - "documentation": "https://trigger.dev?utm_source=coolify.io", - "slogan": "The open source Background Jobs framework for TypeScript", - "compose": "c2VydmljZXM6CiAgdHJpZ2dlcjoKICAgIGltYWdlOiAnZ2hjci5pby90cmlnZ2VyZG90ZGV2L3RyaWdnZXIuZGV2Om1haW4nCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX1VSTF9UUklHR0VSXzMwMDAKICAgICAgLSBMT0dJTl9PUklHSU49JFNFUlZJQ0VfVVJMX1RSSUdHRVIKICAgICAgLSBBUFBfT1JJR0lOPSRTRVJWSUNFX1VSTF9UUklHR0VSCiAgICAgIC0gTUFHSUNfTElOS19TRUNSRVQ9JFNFUlZJQ0VfUEFTU1dPUkRfMzJfTUFHSUMKICAgICAgLSBFTkNSWVBUSU9OX0tFWT0kU0VSVklDRV9QQVNTV09SRF8zMl9FTkNSWVBUSU9OCiAgICAgIC0gU0VTU0lPTl9TRUNSRVQ9JFNFUlZJQ0VfUEFTU1dPUkRfMzJfU0VTU0lPTgogICAgICAtICdEQVRBQkFTRV9VUkw9JHtEQVRBQkFTRV9VUkw6P30nCiAgICAgIC0gJ0RJUkVDVF9VUkw9JHtEQVRBQkFTRV9VUkw6P30nCiAgICAgIC0gUlVOVElNRV9QTEFURk9STT1kb2NrZXItY29tcG9zZQogICAgICAtIE5PREVfRU5WPXByb2R1Y3Rpb24KICAgICAgLSAnQVVUSF9HSVRIVUJfQ0xJRU5UX0lEPSR7QVVUSF9HSVRIVUJfQ0xJRU5UX0lEfScKICAgICAgLSAnQVVUSF9HSVRIVUJfQ0xJRU5UX1NFQ1JFVD0ke0FVVEhfR0lUSFVCX0NMSUVOVF9TRUNSRVR9JwogICAgICAtICdSRVNFTkRfQVBJX0tFWT0ke1JFU0VORF9BUElfS0VZfScKICAgICAgLSAnRlJPTV9FTUFJTD0ke0ZST01fRU1BSUx9JwogICAgICAtICdSRVBMWV9UT19FTUFJTD0ke1JFUExZX1RPX0VNQUlMfScKICAgICAgLSAnUkVESVNfSE9TVD0ke1JFRElTX0hPU1R9JwogICAgICAtICdSRURJU19QT1JUPSR7UkVESVNfUE9SVH0nCiAgICAgIC0gJ1JFRElTX1VTRVJOQU1FPSR7UkVESVNfVVNFUk5BTUV9JwogICAgICAtICdSRURJU19QQVNTV09SRD0ke1JFRElTX1BBU1NXT1JEfScKICAgICAgLSAnUkVESVNfVExTX0RJU0FCTEVEPSR7UkVESVNfVExTX0RJU0FCTEVEOi10cnVlfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OiAidGltZW91dCAxMHMgYmFzaCAtYyAnOj4gL2Rldi90Y3AvMTI3LjAuMC4xLzMwMDAnIHx8IGV4aXQgMSIKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1Cg==", - "tags": [ - "trigger.dev", - "background jobs", - "typescript", - "trigger", - "jobs", - "cron", - "scheduler" - ], - "category": "automation", - "logo": "svgs/trigger.png", - "minversion": "0.0.0", - "port": "3000" - }, "trigger": { - "documentation": "https://trigger.dev?utm_source=coolify.io", - "slogan": "The open source Background Jobs framework for TypeScript", - "compose": "eC1jb21tb24tZW52OgogIFJFTUlYX0FQUF9QT1JUOiAzMDAwCiAgTk9ERV9FTlY6IHByb2R1Y3Rpb24KICBSVU5USU1FX1BMQVRGT1JNOiBkb2NrZXItY29tcG9zZQogIFYzX0VOQUJMRUQ6IHRydWUKICBJTlRFUk5BTF9PVEVMX1RSQUNFX0RJU0FCTEVEOiAxCiAgSU5URVJOQUxfT1RFTF9UUkFDRV9MT0dHSU5HX0VOQUJMRUQ6IDAKICBQT1NUR1JFU19VU0VSOiAkU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgUE9TVEdSRVNfUEFTU1dPUkQ6ICRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgUE9TVEdSRVNfREI6ICcke1BPU1RHUkVTX0RCOi10cmlnZ2VyfScKICBNQUdJQ19MSU5LX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfTUFHSUMKICBTRVNTSU9OX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfU0VTU0lPTgogIEVOQ1JZUFRJT05fS0VZOiAkU0VSVklDRV9QQVNTV09SRF8zMl9FTkNSWVBUSU9OCiAgUFJPVklERVJfU0VDUkVUOiAkU0VSVklDRV9QQVNTV09SRF82NF9QUk9WSURFUgogIENPT1JESU5BVE9SX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfNjRfQ09PUkRJTkFUT1IKICBEQVRBQkFTRV9IT1NUOiAncG9zdGdyZXNxbDo1NDMyJwogIERBVEFCQVNFX1VSTDogJ3Bvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0Bwb3N0Z3Jlc3FsOjU0MzIvJFBPU1RHUkVTX0RCP3NzbG1vZGU9ZGlzYWJsZScKICBESVJFQ1RfVVJMOiAncG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzcWw6NTQzMi8kUE9TVEdSRVNfREI/c3NsbW9kZT1kaXNhYmxlJwogIFJFRElTX0hPU1Q6IHJlZGlzCiAgUkVESVNfUE9SVDogNjM3OQogIFJFRElTX1RMU19ESVNBQkxFRDogdHJ1ZQogIENPT1JESU5BVE9SX0hPU1Q6IDEyNy4wLjAuMQogIENPT1JESU5BVE9SX1BPUlQ6IDkwMjAKICBXSElURUxJU1RFRF9FTUFJTFM6ICcnCiAgQURNSU5fRU1BSUxTOiAnJwogIERFRkFVTFRfT1JHX0VYRUNVVElPTl9DT05DVVJSRU5DWV9MSU1JVDogMzAwCiAgREVGQVVMVF9FTlZfRVhFQ1VUSU9OX0NPTkNVUlJFTkNZX0xJTUlUOiAxMDAKICBERVBMT1lfUkVHSVNUUllfSE9TVDogZG9ja2VyLmlvCiAgREVQTE9ZX1JFR0lTVFJZX05BTUVTUEFDRTogdHJpZ2dlcgogIFJFR0lTVFJZX0hPU1Q6ICcke0RFUExPWV9SRUdJU1RSWV9IT1NUfScKICBSRUdJU1RSWV9OQU1FU1BBQ0U6ICcke0RFUExPWV9SRUdJU1RSWV9OQU1FU1BBQ0V9JwogIEFVVEhfR0lUSFVCX0NMSUVOVF9JRDogJyR7QVVUSF9HSVRIVUJfQ0xJRU5UX0lEfScKICBBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUOiAnJHtBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUfScKICBSRVNFTkRfQVBJX0tFWTogJyR7UkVTRU5EX0FQSV9LRVl9JwogIEZST01fRU1BSUw6ICcke0ZST01fRU1BSUx9JwogIFJFUExZX1RPX0VNQUlMOiAnJHtSRVBMWV9UT19FTUFJTH0nCiAgTE9HSU5fT1JJR0lOOiAkU0VSVklDRV9VUkxfVFJJR0dFUl8zMDAwCiAgQVBQX09SSUdJTjogJFNFUlZJQ0VfVVJMX1RSSUdHRVJfMzAwMAogIERFVl9PVEVMX0VYUE9SVEVSX09UTFBfRU5EUE9JTlQ6ICRTRVJWSUNFX1VSTF9UUklHR0VSXzMwMDAvb3RlbAogIE9URUxfRVhQT1JURVJfT1RMUF9FTkRQT0lOVDogJFNFUlZJQ0VfVVJMX1RSSUdHRVJfMzAwMC9vdGVsCiAgRUxFQ1RSSUNfT1JJR0lOOiAnaHR0cDovL2VsZWN0cmljOjMwMDAnCnNlcnZpY2VzOgogIHRyaWdnZXI6CiAgICBpbWFnZTogJ2doY3IuaW8vdHJpZ2dlcmRvdGRldi90cmlnZ2VyLmRldjp2MycKICAgIGVudmlyb25tZW50OgogICAgICBTRVJWSUNFX1VSTF9UUklHR0VSXzMwMDA6ICcnCiAgICAgIFJFTUlYX0FQUF9QT1JUOiAzMDAwCiAgICAgIE5PREVfRU5WOiBwcm9kdWN0aW9uCiAgICAgIFJVTlRJTUVfUExBVEZPUk06IGRvY2tlci1jb21wb3NlCiAgICAgIFYzX0VOQUJMRUQ6IHRydWUKICAgICAgSU5URVJOQUxfT1RFTF9UUkFDRV9ESVNBQkxFRDogMQogICAgICBJTlRFUk5BTF9PVEVMX1RSQUNFX0xPR0dJTkdfRU5BQkxFRDogMAogICAgICBQT1NUR1JFU19VU0VSOiAkU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIFBPU1RHUkVTX1BBU1NXT1JEOiAkU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICBQT1NUR1JFU19EQjogJyR7UE9TVEdSRVNfREI6LXRyaWdnZXJ9JwogICAgICBNQUdJQ19MSU5LX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfTUFHSUMKICAgICAgU0VTU0lPTl9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzMyX1NFU1NJT04KICAgICAgRU5DUllQVElPTl9LRVk6ICRTRVJWSUNFX1BBU1NXT1JEXzMyX0VOQ1JZUFRJT04KICAgICAgUFJPVklERVJfU0VDUkVUOiAkU0VSVklDRV9QQVNTV09SRF82NF9QUk9WSURFUgogICAgICBDT09SRElOQVRPUl9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzY0X0NPT1JESU5BVE9SCiAgICAgIERBVEFCQVNFX0hPU1Q6ICdwb3N0Z3Jlc3FsOjU0MzInCiAgICAgIERBVEFCQVNFX1VSTDogJ3Bvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0Bwb3N0Z3Jlc3FsOjU0MzIvJFBPU1RHUkVTX0RCP3NzbG1vZGU9ZGlzYWJsZScKICAgICAgRElSRUNUX1VSTDogJ3Bvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0Bwb3N0Z3Jlc3FsOjU0MzIvJFBPU1RHUkVTX0RCP3NzbG1vZGU9ZGlzYWJsZScKICAgICAgUkVESVNfSE9TVDogcmVkaXMKICAgICAgUkVESVNfUE9SVDogNjM3OQogICAgICBSRURJU19UTFNfRElTQUJMRUQ6IHRydWUKICAgICAgQ09PUkRJTkFUT1JfSE9TVDogMTI3LjAuMC4xCiAgICAgIENPT1JESU5BVE9SX1BPUlQ6IDkwMjAKICAgICAgV0hJVEVMSVNURURfRU1BSUxTOiAnJwogICAgICBBRE1JTl9FTUFJTFM6ICcnCiAgICAgIERFRkFVTFRfT1JHX0VYRUNVVElPTl9DT05DVVJSRU5DWV9MSU1JVDogMzAwCiAgICAgIERFRkFVTFRfRU5WX0VYRUNVVElPTl9DT05DVVJSRU5DWV9MSU1JVDogMTAwCiAgICAgIERFUExPWV9SRUdJU1RSWV9IT1NUOiBkb2NrZXIuaW8KICAgICAgREVQTE9ZX1JFR0lTVFJZX05BTUVTUEFDRTogdHJpZ2dlcgogICAgICBSRUdJU1RSWV9IT1NUOiAnJHtERVBMT1lfUkVHSVNUUllfSE9TVH0nCiAgICAgIFJFR0lTVFJZX05BTUVTUEFDRTogJyR7REVQTE9ZX1JFR0lTVFJZX05BTUVTUEFDRX0nCiAgICAgIEFVVEhfR0lUSFVCX0NMSUVOVF9JRDogJyR7QVVUSF9HSVRIVUJfQ0xJRU5UX0lEfScKICAgICAgQVVUSF9HSVRIVUJfQ0xJRU5UX1NFQ1JFVDogJyR7QVVUSF9HSVRIVUJfQ0xJRU5UX1NFQ1JFVH0nCiAgICAgIFJFU0VORF9BUElfS0VZOiAnJHtSRVNFTkRfQVBJX0tFWX0nCiAgICAgIEZST01fRU1BSUw6ICcke0ZST01fRU1BSUx9JwogICAgICBSRVBMWV9UT19FTUFJTDogJyR7UkVQTFlfVE9fRU1BSUx9JwogICAgICBMT0dJTl9PUklHSU46ICRTRVJWSUNFX1VSTF9UUklHR0VSXzMwMDAKICAgICAgQVBQX09SSUdJTjogJFNFUlZJQ0VfVVJMX1RSSUdHRVJfMzAwMAogICAgICBERVZfT1RFTF9FWFBPUlRFUl9PVExQX0VORFBPSU5UOiAkU0VSVklDRV9VUkxfVFJJR0dFUl8zMDAwL290ZWwKICAgICAgT1RFTF9FWFBPUlRFUl9PVExQX0VORFBPSU5UOiAkU0VSVklDRV9VUkxfVFJJR0dFUl8zMDAwL290ZWwKICAgICAgRUxFQ1RSSUNfT1JJR0lOOiAnaHR0cDovL2VsZWN0cmljOjMwMDAnCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3Jlc3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIGVsZWN0cmljOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDogInRpbWVvdXQgMTBzIGJhc2ggLWMgJzo+IC9kZXYvdGNwLzEyNy4wLjAuMS8zMDAwJyB8fCBleGl0IDEiCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogNQogIGVsZWN0cmljOgogICAgaW1hZ2U6IGVsZWN0cmljc3FsL2VsZWN0cmljCiAgICBlbnZpcm9ubWVudDoKICAgICAgUkVNSVhfQVBQX1BPUlQ6IDMwMDAKICAgICAgTk9ERV9FTlY6IHByb2R1Y3Rpb24KICAgICAgUlVOVElNRV9QTEFURk9STTogZG9ja2VyLWNvbXBvc2UKICAgICAgVjNfRU5BQkxFRDogdHJ1ZQogICAgICBJTlRFUk5BTF9PVEVMX1RSQUNFX0RJU0FCTEVEOiAxCiAgICAgIElOVEVSTkFMX09URUxfVFJBQ0VfTE9HR0lOR19FTkFCTEVEOiAwCiAgICAgIFBPU1RHUkVTX1VTRVI6ICRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgUE9TVEdSRVNfUEFTU1dPUkQ6ICRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIFBPU1RHUkVTX0RCOiAnJHtQT1NUR1JFU19EQjotdHJpZ2dlcn0nCiAgICAgIE1BR0lDX0xJTktfU0VDUkVUOiAkU0VSVklDRV9QQVNTV09SRF8zMl9NQUdJQwogICAgICBTRVNTSU9OX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfU0VTU0lPTgogICAgICBFTkNSWVBUSU9OX0tFWTogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfRU5DUllQVElPTgogICAgICBQUk9WSURFUl9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzY0X1BST1ZJREVSCiAgICAgIENPT1JESU5BVE9SX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfNjRfQ09PUkRJTkFUT1IKICAgICAgREFUQUJBU0VfSE9TVDogJ3Bvc3RncmVzcWw6NTQzMicKICAgICAgREFUQUJBU0VfVVJMOiAncG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzcWw6NTQzMi8kUE9TVEdSRVNfREI/c3NsbW9kZT1kaXNhYmxlJwogICAgICBESVJFQ1RfVVJMOiAncG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzcWw6NTQzMi8kUE9TVEdSRVNfREI/c3NsbW9kZT1kaXNhYmxlJwogICAgICBSRURJU19IT1NUOiByZWRpcwogICAgICBSRURJU19QT1JUOiA2Mzc5CiAgICAgIFJFRElTX1RMU19ESVNBQkxFRDogdHJ1ZQogICAgICBDT09SRElOQVRPUl9IT1NUOiAxMjcuMC4wLjEKICAgICAgQ09PUkRJTkFUT1JfUE9SVDogOTAyMAogICAgICBXSElURUxJU1RFRF9FTUFJTFM6ICcnCiAgICAgIEFETUlOX0VNQUlMUzogJycKICAgICAgREVGQVVMVF9PUkdfRVhFQ1VUSU9OX0NPTkNVUlJFTkNZX0xJTUlUOiAzMDAKICAgICAgREVGQVVMVF9FTlZfRVhFQ1VUSU9OX0NPTkNVUlJFTkNZX0xJTUlUOiAxMDAKICAgICAgREVQTE9ZX1JFR0lTVFJZX0hPU1Q6IGRvY2tlci5pbwogICAgICBERVBMT1lfUkVHSVNUUllfTkFNRVNQQUNFOiB0cmlnZ2VyCiAgICAgIFJFR0lTVFJZX0hPU1Q6ICcke0RFUExPWV9SRUdJU1RSWV9IT1NUfScKICAgICAgUkVHSVNUUllfTkFNRVNQQUNFOiAnJHtERVBMT1lfUkVHSVNUUllfTkFNRVNQQUNFfScKICAgICAgQVVUSF9HSVRIVUJfQ0xJRU5UX0lEOiAnJHtBVVRIX0dJVEhVQl9DTElFTlRfSUR9JwogICAgICBBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUOiAnJHtBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUfScKICAgICAgUkVTRU5EX0FQSV9LRVk6ICcke1JFU0VORF9BUElfS0VZfScKICAgICAgRlJPTV9FTUFJTDogJyR7RlJPTV9FTUFJTH0nCiAgICAgIFJFUExZX1RPX0VNQUlMOiAnJHtSRVBMWV9UT19FTUFJTH0nCiAgICAgIExPR0lOX09SSUdJTjogJFNFUlZJQ0VfVVJMX1RSSUdHRVJfMzAwMAogICAgICBBUFBfT1JJR0lOOiAkU0VSVklDRV9VUkxfVFJJR0dFUl8zMDAwCiAgICAgIERFVl9PVEVMX0VYUE9SVEVSX09UTFBfRU5EUE9JTlQ6ICRTRVJWSUNFX1VSTF9UUklHR0VSXzMwMDAvb3RlbAogICAgICBPVEVMX0VYUE9SVEVSX09UTFBfRU5EUE9JTlQ6ICRTRVJWSUNFX1VSTF9UUklHR0VSXzMwMDAvb3RlbAogICAgICBFTEVDVFJJQ19PUklHSU46ICdodHRwOi8vZWxlY3RyaWM6MzAwMCcKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzcWw6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSBwd2QKICByZWRpczoKICAgIGltYWdlOiAncmVkaXM6NycKICAgIGVudmlyb25tZW50OgogICAgICAtIEFMTE9XX0VNUFRZX1BBU1NXT1JEPXllcwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdyZWRpcy1jbGkgLWggbG9jYWxob3N0IC1wIDYzNzkgcGluZycKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3JlZGlzLWRhdGE6L2RhdGEnCiAgcG9zdGdyZXNxbDoKICAgIGltYWdlOiAncG9zdGdyZXM6MTYtYWxwaW5lJwogICAgdm9sdW1lczoKICAgICAgLSAncG9zdGdyZXNxbC1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICBSRU1JWF9BUFBfUE9SVDogMzAwMAogICAgICBOT0RFX0VOVjogcHJvZHVjdGlvbgogICAgICBSVU5USU1FX1BMQVRGT1JNOiBkb2NrZXItY29tcG9zZQogICAgICBWM19FTkFCTEVEOiB0cnVlCiAgICAgIElOVEVSTkFMX09URUxfVFJBQ0VfRElTQUJMRUQ6IDEKICAgICAgSU5URVJOQUxfT1RFTF9UUkFDRV9MT0dHSU5HX0VOQUJMRUQ6IDAKICAgICAgUE9TVEdSRVNfVVNFUjogJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgICBQT1NUR1JFU19QQVNTV09SRDogJFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICAgICAgUE9TVEdSRVNfREI6ICcke1BPU1RHUkVTX0RCOi10cmlnZ2VyfScKICAgICAgTUFHSUNfTElOS19TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzMyX01BR0lDCiAgICAgIFNFU1NJT05fU0VDUkVUOiAkU0VSVklDRV9QQVNTV09SRF8zMl9TRVNTSU9OCiAgICAgIEVOQ1JZUFRJT05fS0VZOiAkU0VSVklDRV9QQVNTV09SRF8zMl9FTkNSWVBUSU9OCiAgICAgIFBST1ZJREVSX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfNjRfUFJPVklERVIKICAgICAgQ09PUkRJTkFUT1JfU0VDUkVUOiAkU0VSVklDRV9QQVNTV09SRF82NF9DT09SRElOQVRPUgogICAgICBEQVRBQkFTRV9IT1NUOiAncG9zdGdyZXNxbDo1NDMyJwogICAgICBEQVRBQkFTRV9VUkw6ICdwb3N0Z3JlczovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcG9zdGdyZXNxbDo1NDMyLyRQT1NUR1JFU19EQj9zc2xtb2RlPWRpc2FibGUnCiAgICAgIERJUkVDVF9VUkw6ICdwb3N0Z3JlczovLyRTRVJWSUNFX1VTRVJfUE9TVEdSRVM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAcG9zdGdyZXNxbDo1NDMyLyRQT1NUR1JFU19EQj9zc2xtb2RlPWRpc2FibGUnCiAgICAgIFJFRElTX0hPU1Q6IHJlZGlzCiAgICAgIFJFRElTX1BPUlQ6IDYzNzkKICAgICAgUkVESVNfVExTX0RJU0FCTEVEOiB0cnVlCiAgICAgIENPT1JESU5BVE9SX0hPU1Q6IDEyNy4wLjAuMQogICAgICBDT09SRElOQVRPUl9QT1JUOiA5MDIwCiAgICAgIFdISVRFTElTVEVEX0VNQUlMUzogJycKICAgICAgQURNSU5fRU1BSUxTOiAnJwogICAgICBERUZBVUxUX09SR19FWEVDVVRJT05fQ09OQ1VSUkVOQ1lfTElNSVQ6IDMwMAogICAgICBERUZBVUxUX0VOVl9FWEVDVVRJT05fQ09OQ1VSUkVOQ1lfTElNSVQ6IDEwMAogICAgICBERVBMT1lfUkVHSVNUUllfSE9TVDogZG9ja2VyLmlvCiAgICAgIERFUExPWV9SRUdJU1RSWV9OQU1FU1BBQ0U6IHRyaWdnZXIKICAgICAgUkVHSVNUUllfSE9TVDogJyR7REVQTE9ZX1JFR0lTVFJZX0hPU1R9JwogICAgICBSRUdJU1RSWV9OQU1FU1BBQ0U6ICcke0RFUExPWV9SRUdJU1RSWV9OQU1FU1BBQ0V9JwogICAgICBBVVRIX0dJVEhVQl9DTElFTlRfSUQ6ICcke0FVVEhfR0lUSFVCX0NMSUVOVF9JRH0nCiAgICAgIEFVVEhfR0lUSFVCX0NMSUVOVF9TRUNSRVQ6ICcke0FVVEhfR0lUSFVCX0NMSUVOVF9TRUNSRVR9JwogICAgICBSRVNFTkRfQVBJX0tFWTogJyR7UkVTRU5EX0FQSV9LRVl9JwogICAgICBGUk9NX0VNQUlMOiAnJHtGUk9NX0VNQUlMfScKICAgICAgUkVQTFlfVE9fRU1BSUw6ICcke1JFUExZX1RPX0VNQUlMfScKICAgICAgTE9HSU5fT1JJR0lOOiAkU0VSVklDRV9VUkxfVFJJR0dFUl8zMDAwCiAgICAgIEFQUF9PUklHSU46ICRTRVJWSUNFX1VSTF9UUklHR0VSXzMwMDAKICAgICAgREVWX09URUxfRVhQT1JURVJfT1RMUF9FTkRQT0lOVDogJFNFUlZJQ0VfVVJMX1RSSUdHRVJfMzAwMC9vdGVsCiAgICAgIE9URUxfRVhQT1JURVJfT1RMUF9FTkRQT0lOVDogJFNFUlZJQ0VfVVJMX1RSSUdHRVJfMzAwMC9vdGVsCiAgICAgIEVMRUNUUklDX09SSUdJTjogJ2h0dHA6Ly9lbGVjdHJpYzozMDAwJwogICAgY29tbWFuZDoKICAgICAgLSAnLWMnCiAgICAgIC0gd2FsX2xldmVsPWxvZ2ljYWwKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQn0nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICBkb2NrZXItcHJvdmlkZXI6CiAgICBpbWFnZTogJ2doY3IuaW8vdHJpZ2dlcmRvdGRldi9wcm92aWRlci9kb2NrZXI6djMnCiAgICBwbGF0Zm9ybTogbGludXgvYW1kNjQKICAgIHZvbHVtZXM6CiAgICAgIC0gJy92YXIvcnVuL2RvY2tlci5zb2NrOi92YXIvcnVuL2RvY2tlci5zb2NrJwogICAgdXNlcjogcm9vdAogICAgZGVwZW5kc19vbjoKICAgICAgdHJpZ2dlcjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIFJFTUlYX0FQUF9QT1JUOiAzMDAwCiAgICAgIE5PREVfRU5WOiBwcm9kdWN0aW9uCiAgICAgIFJVTlRJTUVfUExBVEZPUk06IGRvY2tlci1jb21wb3NlCiAgICAgIFYzX0VOQUJMRUQ6IHRydWUKICAgICAgSU5URVJOQUxfT1RFTF9UUkFDRV9ESVNBQkxFRDogMQogICAgICBJTlRFUk5BTF9PVEVMX1RSQUNFX0xPR0dJTkdfRU5BQkxFRDogMAogICAgICBQT1NUR1JFU19VU0VSOiAkU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIFBPU1RHUkVTX1BBU1NXT1JEOiAkU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICBQT1NUR1JFU19EQjogJyR7UE9TVEdSRVNfREI6LXRyaWdnZXJ9JwogICAgICBNQUdJQ19MSU5LX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfTUFHSUMKICAgICAgU0VTU0lPTl9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzMyX1NFU1NJT04KICAgICAgRU5DUllQVElPTl9LRVk6ICRTRVJWSUNFX1BBU1NXT1JEXzMyX0VOQ1JZUFRJT04KICAgICAgUFJPVklERVJfU0VDUkVUOiAkU0VSVklDRV9QQVNTV09SRF82NF9QUk9WSURFUgogICAgICBDT09SRElOQVRPUl9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzY0X0NPT1JESU5BVE9SCiAgICAgIERBVEFCQVNFX0hPU1Q6ICdwb3N0Z3Jlc3FsOjU0MzInCiAgICAgIERBVEFCQVNFX1VSTDogJ3Bvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0Bwb3N0Z3Jlc3FsOjU0MzIvJFBPU1RHUkVTX0RCP3NzbG1vZGU9ZGlzYWJsZScKICAgICAgRElSRUNUX1VSTDogJ3Bvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0Bwb3N0Z3Jlc3FsOjU0MzIvJFBPU1RHUkVTX0RCP3NzbG1vZGU9ZGlzYWJsZScKICAgICAgUkVESVNfSE9TVDogcmVkaXMKICAgICAgUkVESVNfUE9SVDogNjM3OQogICAgICBSRURJU19UTFNfRElTQUJMRUQ6IHRydWUKICAgICAgQ09PUkRJTkFUT1JfSE9TVDogMTI3LjAuMC4xCiAgICAgIENPT1JESU5BVE9SX1BPUlQ6IDkwMjAKICAgICAgV0hJVEVMSVNURURfRU1BSUxTOiAnJwogICAgICBBRE1JTl9FTUFJTFM6ICcnCiAgICAgIERFRkFVTFRfT1JHX0VYRUNVVElPTl9DT05DVVJSRU5DWV9MSU1JVDogMzAwCiAgICAgIERFRkFVTFRfRU5WX0VYRUNVVElPTl9DT05DVVJSRU5DWV9MSU1JVDogMTAwCiAgICAgIERFUExPWV9SRUdJU1RSWV9IT1NUOiBkb2NrZXIuaW8KICAgICAgREVQTE9ZX1JFR0lTVFJZX05BTUVTUEFDRTogdHJpZ2dlcgogICAgICBSRUdJU1RSWV9IT1NUOiAnJHtERVBMT1lfUkVHSVNUUllfSE9TVH0nCiAgICAgIFJFR0lTVFJZX05BTUVTUEFDRTogJyR7REVQTE9ZX1JFR0lTVFJZX05BTUVTUEFDRX0nCiAgICAgIEFVVEhfR0lUSFVCX0NMSUVOVF9JRDogJyR7QVVUSF9HSVRIVUJfQ0xJRU5UX0lEfScKICAgICAgQVVUSF9HSVRIVUJfQ0xJRU5UX1NFQ1JFVDogJyR7QVVUSF9HSVRIVUJfQ0xJRU5UX1NFQ1JFVH0nCiAgICAgIFJFU0VORF9BUElfS0VZOiAnJHtSRVNFTkRfQVBJX0tFWX0nCiAgICAgIEZST01fRU1BSUw6ICcke0ZST01fRU1BSUx9JwogICAgICBSRVBMWV9UT19FTUFJTDogJyR7UkVQTFlfVE9fRU1BSUx9JwogICAgICBMT0dJTl9PUklHSU46ICRTRVJWSUNFX1VSTF9UUklHR0VSXzMwMDAKICAgICAgQVBQX09SSUdJTjogJFNFUlZJQ0VfVVJMX1RSSUdHRVJfMzAwMAogICAgICBERVZfT1RFTF9FWFBPUlRFUl9PVExQX0VORFBPSU5UOiAkU0VSVklDRV9VUkxfVFJJR0dFUl8zMDAwL290ZWwKICAgICAgT1RFTF9FWFBPUlRFUl9PVExQX0VORFBPSU5UOiAkU0VSVklDRV9VUkxfVFJJR0dFUl8zMDAwL290ZWwKICAgICAgRUxFQ1RSSUNfT1JJR0lOOiAnaHR0cDovL2VsZWN0cmljOjMwMDAnCiAgICAgIFBMQVRGT1JNX0hPU1Q6IHRyaWdnZXIKICAgICAgUExBVEZPUk1fV1NfUE9SVDogMzAwMAogICAgICBTRUNVUkVfQ09OTkVDVElPTjogJ2ZhbHNlJwogICAgICBQTEFURk9STV9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzY0X1BST1ZJREVSCiAgICAgIEhUVFBfU0VSVkVSX1BPUlQ6IDkwMjAKICBjb29yZGluYXRvcjoKICAgIGltYWdlOiAnZ2hjci5pby90cmlnZ2VyZG90ZGV2L2Nvb3JkaW5hdG9yOnYzJwogICAgcGxhdGZvcm06IGxpbnV4L2FtZDY0CiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgIHVzZXI6IHJvb3QKICAgIHBvcnRzOgogICAgICAtICcxMjcuMC4wLjE6OTAyMDo5MDIwJwogICAgZGVwZW5kc19vbjoKICAgICAgdHJpZ2dlcjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIFJFTUlYX0FQUF9QT1JUOiAzMDAwCiAgICAgIE5PREVfRU5WOiBwcm9kdWN0aW9uCiAgICAgIFJVTlRJTUVfUExBVEZPUk06IGRvY2tlci1jb21wb3NlCiAgICAgIFYzX0VOQUJMRUQ6IHRydWUKICAgICAgSU5URVJOQUxfT1RFTF9UUkFDRV9ESVNBQkxFRDogMQogICAgICBJTlRFUk5BTF9PVEVMX1RSQUNFX0xPR0dJTkdfRU5BQkxFRDogMAogICAgICBQT1NUR1JFU19VU0VSOiAkU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIFBPU1RHUkVTX1BBU1NXT1JEOiAkU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICBQT1NUR1JFU19EQjogJyR7UE9TVEdSRVNfREI6LXRyaWdnZXJ9JwogICAgICBNQUdJQ19MSU5LX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfTUFHSUMKICAgICAgU0VTU0lPTl9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzMyX1NFU1NJT04KICAgICAgRU5DUllQVElPTl9LRVk6ICRTRVJWSUNFX1BBU1NXT1JEXzMyX0VOQ1JZUFRJT04KICAgICAgUFJPVklERVJfU0VDUkVUOiAkU0VSVklDRV9QQVNTV09SRF82NF9QUk9WSURFUgogICAgICBDT09SRElOQVRPUl9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzY0X0NPT1JESU5BVE9SCiAgICAgIERBVEFCQVNFX0hPU1Q6ICdwb3N0Z3Jlc3FsOjU0MzInCiAgICAgIERBVEFCQVNFX1VSTDogJ3Bvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0Bwb3N0Z3Jlc3FsOjU0MzIvJFBPU1RHUkVTX0RCP3NzbG1vZGU9ZGlzYWJsZScKICAgICAgRElSRUNUX1VSTDogJ3Bvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0Bwb3N0Z3Jlc3FsOjU0MzIvJFBPU1RHUkVTX0RCP3NzbG1vZGU9ZGlzYWJsZScKICAgICAgUkVESVNfSE9TVDogcmVkaXMKICAgICAgUkVESVNfUE9SVDogNjM3OQogICAgICBSRURJU19UTFNfRElTQUJMRUQ6IHRydWUKICAgICAgQ09PUkRJTkFUT1JfSE9TVDogMTI3LjAuMC4xCiAgICAgIENPT1JESU5BVE9SX1BPUlQ6IDkwMjAKICAgICAgV0hJVEVMSVNURURfRU1BSUxTOiAnJwogICAgICBBRE1JTl9FTUFJTFM6ICcnCiAgICAgIERFRkFVTFRfT1JHX0VYRUNVVElPTl9DT05DVVJSRU5DWV9MSU1JVDogMzAwCiAgICAgIERFRkFVTFRfRU5WX0VYRUNVVElPTl9DT05DVVJSRU5DWV9MSU1JVDogMTAwCiAgICAgIERFUExPWV9SRUdJU1RSWV9IT1NUOiBkb2NrZXIuaW8KICAgICAgREVQTE9ZX1JFR0lTVFJZX05BTUVTUEFDRTogdHJpZ2dlcgogICAgICBSRUdJU1RSWV9IT1NUOiAnJHtERVBMT1lfUkVHSVNUUllfSE9TVH0nCiAgICAgIFJFR0lTVFJZX05BTUVTUEFDRTogJyR7REVQTE9ZX1JFR0lTVFJZX05BTUVTUEFDRX0nCiAgICAgIEFVVEhfR0lUSFVCX0NMSUVOVF9JRDogJyR7QVVUSF9HSVRIVUJfQ0xJRU5UX0lEfScKICAgICAgQVVUSF9HSVRIVUJfQ0xJRU5UX1NFQ1JFVDogJyR7QVVUSF9HSVRIVUJfQ0xJRU5UX1NFQ1JFVH0nCiAgICAgIFJFU0VORF9BUElfS0VZOiAnJHtSRVNFTkRfQVBJX0tFWX0nCiAgICAgIEZST01fRU1BSUw6ICcke0ZST01fRU1BSUx9JwogICAgICBSRVBMWV9UT19FTUFJTDogJyR7UkVQTFlfVE9fRU1BSUx9JwogICAgICBMT0dJTl9PUklHSU46ICRTRVJWSUNFX1VSTF9UUklHR0VSXzMwMDAKICAgICAgQVBQX09SSUdJTjogJFNFUlZJQ0VfVVJMX1RSSUdHRVJfMzAwMAogICAgICBERVZfT1RFTF9FWFBPUlRFUl9PVExQX0VORFBPSU5UOiAkU0VSVklDRV9VUkxfVFJJR0dFUl8zMDAwL290ZWwKICAgICAgT1RFTF9FWFBPUlRFUl9PVExQX0VORFBPSU5UOiAkU0VSVklDRV9VUkxfVFJJR0dFUl8zMDAwL290ZWwKICAgICAgRUxFQ1RSSUNfT1JJR0lOOiAnaHR0cDovL2VsZWN0cmljOjMwMDAnCiAgICAgIFBMQVRGT1JNX0hPU1Q6IHRyaWdnZXIKICAgICAgUExBVEZPUk1fV1NfUE9SVDogMzAwMAogICAgICBTRUNVUkVfQ09OTkVDVElPTjogJ2ZhbHNlJwogICAgICBQTEFURk9STV9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzY0X0NPT1JESU5BVE9SCiAgICAgIEhUVFBfU0VSVkVSX1BPUlQ6IDkwMjAKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSBwd2QK", + "documentation": "https://trigger.dev/docs/self-hosting/overview?utm_source=coolify.io", + "slogan": "The open source background jobs platform for developers", + "compose": "c2VydmljZXM6CiAgdHJpZ2dlcjoKICAgIGltYWdlOiAnZ2hjci5pby90cmlnZ2VyZG90ZGV2L3RyaWdnZXIuZGV2OnY0LjMuMCcKICAgIHVzZXI6IHJvb3QKICAgIGNvbW1hbmQ6ICJzaCAtYyBcImNob3duIC1SIG5vZGU6bm9kZSAvaG9tZS9ub2RlL3NoYXJlZCAmJiBleGVjIC4vc2NyaXB0cy9lbnRyeXBvaW50LnNoXCJcbiIKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfVVJMX1RSSUdHRVJfMzAwMAogICAgICAtICdBUFBfT1JJR0lOPSR7U0VSVklDRV9VUkxfVFJJR0dFUl8zMDAwfScKICAgICAgLSAnTE9HSU5fT1JJR0lOPSR7U0VSVklDRV9VUkxfVFJJR0dFUl8zMDAwfScKICAgICAgLSAnQVBJX09SSUdJTj0ke1NFUlZJQ0VfVVJMX1RSSUdHRVJfMzAwMH0nCiAgICAgIC0gJ1NFU1NJT05fU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF82NF9TRVNTSU9OfScKICAgICAgLSAnTUFHSUNfTElOS19TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X01BR0lDTElOS30nCiAgICAgIC0gJ0VOQ1JZUFRJT05fS0VZPSR7U0VSVklDRV9QQVNTV09SRF9FTkNSWVBUSU9OS0VZfScKICAgICAgLSAnTUFOQUdFRF9XT1JLRVJfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF82NF9XT1JLRVJTRUNSRVR9JwogICAgICAtICdUUklHR0VSX1dPUktFUl9UT0tFTj0ke1RSSUdHRVJfV09SS0VSX1RPS0VOfScKICAgICAgLSBOT0RFX0VOVj1wcm9kdWN0aW9uCiAgICAgIC0gQVBQX0xPR19MRVZFTD1pbmZvCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AcG9zdGdyZXNxbDo1NDMyLyR7UE9TVEdSRVNfREI6LXRyaWdnZXItZGJ9P3NjaGVtYT1wdWJsaWMmc3NsbW9kZT1kaXNhYmxlJwogICAgICAtICdESVJFQ1RfVVJMPXBvc3RncmVzcWw6Ly8ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU306JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUBwb3N0Z3Jlc3FsOjU0MzIvJHtQT1NUR1JFU19EQjotdHJpZ2dlci1kYn0/c2NoZW1hPXB1YmxpYyZzc2xtb2RlPWRpc2FibGUnCiAgICAgIC0gUkVESVNfSE9TVD1yZWRpcwogICAgICAtIFJFRElTX1BPUlQ9NjM3OQogICAgICAtIFJFRElTX1RMU19ESVNBQkxFRD10cnVlCiAgICAgIC0gJ0VMRUNUUklDX09SSUdJTj1odHRwOi8vZWxlY3RyaWM6MzAwMCcKICAgICAgLSAnREVWX09URUxfRVhQT1JURVJfT1RMUF9FTkRQT0lOVD0ke0RFVl9PVEVMX0VYUE9SVEVSX09UTFBfRU5EUE9JTlQ6LX0nCiAgICAgIC0gJ0RFUExPWV9SRUdJU1RSWV9IT1NUPSR7REVQTE9ZX1JFR0lTVFJZX0hPU1Q6LWdoY3IuaW99JwogICAgICAtICdERVBMT1lfUkVHSVNUUllfUFJPVE9DT0w9JHtERVBMT1lfUkVHSVNUUllfUFJPVE9DT0w6LWh0dHBzfScKICAgICAgLSAnREVQTE9ZX1JFR0lTVFJZX05BTUVTUEFDRT0ke0RFUExPWV9SRUdJU1RSWV9OQU1FU1BBQ0U6LXRyaWdnZXJ9JwogICAgICAtICdWNF9ERVBMT1lfUkVHSVNUUllfTkFNRVNQQUNFPSR7REVQTE9ZX1JFR0lTVFJZX05BTUVTUEFDRTotdHJpZ2dlcn0nCiAgICAgIC0gJ09CSkVDVF9TVE9SRV9CQVNFX1VSTD0ke09CSkVDVF9TVE9SRV9CQVNFX1VSTH0nCiAgICAgIC0gJ09CSkVDVF9TVE9SRV9BQ0NFU1NfS0VZX0lEPSR7T0JKRUNUX1NUT1JFX0FDQ0VTU19LRVlfSUR9JwogICAgICAtICdPQkpFQ1RfU1RPUkVfU0VDUkVUX0FDQ0VTU19LRVk9JHtPQkpFQ1RfU1RPUkVfU0VDUkVUX0FDQ0VTU19LRVl9JwogICAgICAtICdDTElDS0hPVVNFX1VSTD1odHRwOi8vJHtTRVJWSUNFX1VTRVJfQ0xJQ0tIT1VTRX06JHtTRVJWSUNFX1BBU1NXT1JEXzY0X0NMSUNLSE9VU0V9QGNsaWNraG91c2U6ODEyMz9zZWN1cmU9ZmFsc2UnCiAgICAgIC0gQ0xJQ0tIT1VTRV9MT0dfTEVWRUw9aW5mbwogICAgICAtIFJVTl9SRVBMSUNBVElPTl9FTkFCTEVEPTEKICAgICAgLSAnUlVOX1JFUExJQ0FUSU9OX0NMSUNLSE9VU0VfVVJMPWh0dHA6Ly8ke1NFUlZJQ0VfVVNFUl9DTElDS0hPVVNFfToke1NFUlZJQ0VfUEFTU1dPUkRfNjRfQ0xJQ0tIT1VTRX1AY2xpY2tob3VzZTo4MTIzJwogICAgICAtIFJVTl9SRVBMSUNBVElPTl9MT0dfTEVWRUw9aW5mbwogICAgICAtIFRSSUdHRVJfQk9PVFNUUkFQX0VOQUJMRUQ9MQogICAgICAtIFRSSUdHRVJfQk9PVFNUUkFQX1dPUktFUl9HUk9VUF9OQU1FPWJvb3RzdHJhcAogICAgICAtIFRSSUdHRVJfQk9PVFNUUkFQX1dPUktFUl9UT0tFTl9QQVRIPS9ob21lL25vZGUvc2hhcmVkL3dvcmtlcl90b2tlbgogICAgICAtICdERUZBVUxUX09SR19FWEVDVVRJT05fQ09OQ1VSUkVOQ1lfTElNSVQ9JHtERUZBVUxUX09SR19FWEVDVVRJT05fQ09OQ1VSUkVOQ1lfTElNSVQ6LTMwMH0nCiAgICAgIC0gJ0RFRkFVTFRfRU5WX0VYRUNVVElPTl9DT05DVVJSRU5DWV9MSU1JVD0ke0RFRkFVTFRfRU5WX0VYRUNVVElPTl9DT05DVVJSRU5DWV9MSU1JVDotMTAwfScKICAgICAgLSAnQVVUSF9HSVRIVUJfQ0xJRU5UX0lEPSR7QVVUSF9HSVRIVUJfQ0xJRU5UX0lEOi19JwogICAgICAtICdBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUPSR7QVVUSF9HSVRIVUJfQ0xJRU5UX1NFQ1JFVDotfScKICAgICAgLSAnRU1BSUxfVFJBTlNQT1JUPSR7RU1BSUxfVFJBTlNQT1JUOi1zbXRwfScKICAgICAgLSAnUkVTRU5EX0FQSV9LRVk9JHtSRVNFTkRfQVBJX0tFWX0nCiAgICAgIC0gJ1NNVFBfSE9TVD0ke1NNVFBfSE9TVH0nCiAgICAgIC0gJ1NNVFBfUE9SVD0ke1NNVFBfUE9SVH0nCiAgICAgIC0gJ1NNVFBfVVNFUj0ke1NNVFBfVVNFUn0nCiAgICAgIC0gJ1NNVFBfUEFTU1dPUkQ9JHtTTVRQX1BBU1NXT1JEfScKICAgICAgLSAnU01UUF9TRUNVUkU9JHtTTVRQX1NFQ1VSRX0nCiAgICAgIC0gJ0ZST01fRU1BSUw9JHtGUk9NX0VNQUlMfScKICAgICAgLSAnUkVQTFlfVE9fRU1BSUw9JHtSRVBMWV9UT19FTUFJTH0nCiAgICAgIC0gJ1dISVRFTElTVEVEX0VNQUlMUz0ke1dISVRFTElTVEVEX0VNQUlMU30nCiAgICAgIC0gJ0FETUlOX0VNQUlMUz0ke0FETUlOX0VNQUlMU30nCiAgICAgIC0gR1JBQ0VGVUxfU0hVVERPV05fVElNRU9VVD0xMDAwCiAgICAgIC0gJ0lOVEVSTkFMX09URUxfVFJBQ0VfTE9HR0lOR19FTkFCTEVEPSR7SU5URVJOQUxfT1RFTF9UUkFDRV9MT0dHSU5HX0VOQUJMRUQ6LTB9JwogICAgICAtICdUUklHR0VSX1RFTEVNRVRSWV9ESVNBQkxFRD0ke1RSSUdHRVJfVEVMRU1FVFJZX0RJU0FCTEVEOi10cnVlfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3NoYXJlZC1kYXRhOi9ob21lL25vZGUvc2hhcmVkJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIG5vZGUKICAgICAgICAtICctZScKICAgICAgICAtICJyZXF1aXJlKCdodHRwJykuZ2V0KCdodHRwOi8vMTI3LjAuMC4xOjMwMDAvaGVhbHRoY2hlY2snLChyKT0+cHJvY2Vzcy5leGl0KHIuc3RhdHVzQ29kZT09PTIwMD8wOjEpKS5vbignZXJyb3InLCgpPT5wcm9jZXNzLmV4aXQoMSkpIgogICAgICBpbnRlcnZhbDogMTBzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDUKICAgICAgc3RhcnRfcGVyaW9kOiAxMHMKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzcWw6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgZWxlY3RyaWM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgY2xpY2tob3VzZToKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogIHN1cGVydmlzb3I6CiAgICBpbWFnZTogJ2doY3IuaW8vdHJpZ2dlcmRvdGRldi9zdXBlcnZpc29yOnY0LjMuMCcKICAgIHVzZXI6IHJvb3QKICAgIGNvbW1hbmQ6ICJzaCAtYyBcImNob3duIC1SIG5vZGU6bm9kZSAvaG9tZS9ub2RlL3NoYXJlZCAmJiBleGVjIC91c3IvYmluL2R1bWItaW5pdCAtLSBwbnBtIHJ1biAtLWZpbHRlciBzdXBlcnZpc29yIHN0YXJ0XCJcbiIKICAgIGVudmlyb25tZW50OgogICAgICAtICdUUklHR0VSX0FQSV9VUkw9aHR0cDovL3RyaWdnZXI6MzAwMCcKICAgICAgLSAnT1RFTF9FWFBPUlRFUl9PVExQX0VORFBPSU5UPWh0dHA6Ly90cmlnZ2VyOjMwMDAvb3RlbCcKICAgICAgLSAnVFJJR0dFUl9XT1JLRVJfVE9LRU49JHtUUklHR0VSX1dPUktFUl9UT0tFTjotZmlsZTovLy9ob21lL25vZGUvc2hhcmVkL3dvcmtlcl90b2tlbn0nCiAgICAgIC0gJ01BTkFHRURfV09SS0VSX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfNjRfV09SS0VSU0VDUkVUfScKICAgICAgLSAnVFJJR0dFUl9XT1JLTE9BRF9BUElfRE9NQUlOPSR7VFJJR0dFUl9XT1JLTE9BRF9BUElfRE9NQUlOfScKICAgICAgLSBUUklHR0VSX1dPUktMT0FEX0FQSV9QT1JUX0VYVEVSTkFMPTgwMjAKICAgICAgLSAnRE9DS0VSX0hPU1Q9dGNwOi8vZG9ja2VyLXByb3h5OjIzNzUnCiAgICAgIC0gJ0RPQ0tFUl9SVU5ORVJfTkVUV09SS1M9JHtET0NLRVJfUlVOTkVSX05FVFdPUktTfScKICAgICAgLSAnRE9DS0VSX0FVVE9SRU1PVkVfRVhJVEVEX0NPTlRBSU5FUlM9JHtET0NLRVJfQVVUT1JFTU9WRV9FWElURURfQ09OVEFJTkVSUzotMX0nCiAgICAgIC0gJ0RPQ0tFUl9SRUdJU1RSWV9VUkw9aHR0cHM6Ly8ke0RFUExPWV9SRUdJU1RSWV9IT1NUOi1naGNyLmlvfScKICAgICAgLSAnRE9DS0VSX1JFR0lTVFJZX1VTRVJOQU1FPSR7REVQTE9ZX1JFR0lTVFJZX1VTRVJOQU1FfScKICAgICAgLSAnRE9DS0VSX1JFR0lTVFJZX1BBU1NXT1JEPSR7REVQTE9ZX1JFR0lTVFJZX1BBU1NXT1JEfScKICAgICAgLSBFTkZPUkNFX01BQ0hJTkVfUFJFU0VUUz0xCiAgICAgIC0gVFJJR0dFUl9ERVFVRVVFX0lOVEVSVkFMX01TPTEwMDAKICAgICAgLSAnREVCVUc9JHtTVVBFUlZJU09SX0RFQlVHOi0wfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3NoYXJlZC1kYXRhOi9ob21lL25vZGUvc2hhcmVkJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIG5vZGUKICAgICAgICAtICctZScKICAgICAgICAtICJyZXF1aXJlKCdodHRwJykuZ2V0KCdodHRwOi8vMTI3LjAuMC4xOjgwMjAvaGVhbHRoJywocik9PnByb2Nlc3MuZXhpdChyLnN0YXR1c0NvZGU9PT0yMDA/MDoxKSkub24oJ2Vycm9yJywoKT0+cHJvY2Vzcy5leGl0KDEpKSIKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgICBkZXBlbmRzX29uOgogICAgICB0cmlnZ2VyOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIGRvY2tlci1wcm94eToKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogIGRvY2tlci1wcm94eToKICAgIGltYWdlOiAndGVjbmF0aXZhL2RvY2tlci1zb2NrZXQtcHJveHk6djAuNC4yJwogICAgdm9sdW1lczoKICAgICAgLSAnL3Zhci9ydW4vZG9ja2VyLnNvY2s6L3Zhci9ydW4vZG9ja2VyLnNvY2s6cm8nCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBMT0dfTEVWRUw9aW5mbwogICAgICAtICdQT1NUPSR7UE9TVDotMX0nCiAgICAgIC0gJ0NPTlRBSU5FUlM9JHtDT05UQUlORVJTOi0xfScKICAgICAgLSAnSU1BR0VTPSR7SU1BR0VTOi0xfScKICAgICAgLSAnSU5GTz0ke0lORk86LTF9JwogICAgICAtICdORVRXT1JLUz0ke05FVFdPUktTOi0xfScKICAgICAgLSAnQVVUSD0ke0FVVEg6LTF9JwogICAgICAtICdESVNUUklCVVRJT049JHtESVNUUklCVVRJT046LTF9JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICduYyAteiAxMjcuMC4wLjEgMjM3NSB8fCBleGl0IDEnCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogNQogIHBvc3RncmVzcWw6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIGNvbW1hbmQ6CiAgICAgIC0gJy1jJwogICAgICAtIHdhbF9sZXZlbD1sb2dpY2FsCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LXRyaWdnZXItZGJ9JwogICAgdm9sdW1lczoKICAgICAgLSAncG9zdGdyZXNxbC1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkJHtQT1NUR1JFU19VU0VSfSAtZCAkJHtQT1NUR1JFU19EQn0nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICByZWRpczoKICAgIGltYWdlOiAncmVkaXM6Ny1hbHBpbmUnCiAgICB2b2x1bWVzOgogICAgICAtICdyZWRpcy1kYXRhOi9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHJlZGlzLWNsaQogICAgICAgIC0gcGluZwogICAgICBpbnRlcnZhbDogMTBzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDUKICBlbGVjdHJpYzoKICAgIGltYWdlOiAnZWxlY3RyaWNzcWwvZWxlY3RyaWM6MS4yLjknCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzcWw6Ly8ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU306JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUBwb3N0Z3Jlc3FsOjU0MzIvJHtQT1NUR1JFU19EQjotdHJpZ2dlci1kYn0/c3NsbW9kZT1kaXNhYmxlJwogICAgICAtICdFTEVDVFJJQ19TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X0VMRUNUUklDfScKICAgICAgLSBFTEVDVFJJQ19VU0FHRV9SRVBPUlRJTkc9ZmFsc2UKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDozMDAwL3YxL2hlYWx0aCcKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3Jlc3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgY2xpY2tob3VzZToKICAgIGltYWdlOiAnY2xpY2tob3VzZS9jbGlja2hvdXNlLXNlcnZlcjoyNS44JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0NMSUNLSE9VU0VfVVNFUj0ke1NFUlZJQ0VfVVNFUl9DTElDS0hPVVNFfScKICAgICAgLSAnQ0xJQ0tIT1VTRV9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfNjRfQ0xJQ0tIT1VTRX0nCiAgICAgIC0gQ0xJQ0tIT1VTRV9ERUZBVUxUX0FDQ0VTU19NQU5BR0VNRU5UPTEKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2NsaWNraG91c2UtZGF0YTovdmFyL2xpYi9jbGlja2hvdXNlJwogICAgICAtICdjbGlja2hvdXNlLWxvZ3M6L3Zhci9sb2cvY2xpY2tob3VzZS1zZXJ2ZXInCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3dnZXQgLS1uby12ZXJib3NlIC0tdHJpZXM9MSAtLXNwaWRlciBodHRwOi8vbG9jYWxob3N0OjgxMjMvcGluZyB8fCBleGl0IDEnCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogNQo=", "tags": [ - "trigger.dev", - "background jobs", + "background-jobs", "typescript", - "trigger", - "jobs", - "cron", - "scheduler" + "javascript", + "scheduling", + "workflows", + "automation", + "tasks", + "queues" ], "category": "automation", "logo": "svgs/trigger.png", diff --git a/templates/service-templates.json b/templates/service-templates.json index 78337fe89..ce43c5d45 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -4402,36 +4402,19 @@ "minversion": "0.0.0", "port": "9091" }, - "trigger-with-external-database": { - "documentation": "https://trigger.dev?utm_source=coolify.io", - "slogan": "The open source Background Jobs framework for TypeScript", - "compose": "c2VydmljZXM6CiAgdHJpZ2dlcjoKICAgIGltYWdlOiAnZ2hjci5pby90cmlnZ2VyZG90ZGV2L3RyaWdnZXIuZGV2Om1haW4nCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fVFJJR0dFUl8zMDAwCiAgICAgIC0gTE9HSU5fT1JJR0lOPSRTRVJWSUNFX0ZRRE5fVFJJR0dFUgogICAgICAtIEFQUF9PUklHSU49JFNFUlZJQ0VfRlFETl9UUklHR0VSCiAgICAgIC0gTUFHSUNfTElOS19TRUNSRVQ9JFNFUlZJQ0VfUEFTU1dPUkRfMzJfTUFHSUMKICAgICAgLSBFTkNSWVBUSU9OX0tFWT0kU0VSVklDRV9QQVNTV09SRF8zMl9FTkNSWVBUSU9OCiAgICAgIC0gU0VTU0lPTl9TRUNSRVQ9JFNFUlZJQ0VfUEFTU1dPUkRfMzJfU0VTU0lPTgogICAgICAtICdEQVRBQkFTRV9VUkw9JHtEQVRBQkFTRV9VUkw6P30nCiAgICAgIC0gJ0RJUkVDVF9VUkw9JHtEQVRBQkFTRV9VUkw6P30nCiAgICAgIC0gUlVOVElNRV9QTEFURk9STT1kb2NrZXItY29tcG9zZQogICAgICAtIE5PREVfRU5WPXByb2R1Y3Rpb24KICAgICAgLSAnQVVUSF9HSVRIVUJfQ0xJRU5UX0lEPSR7QVVUSF9HSVRIVUJfQ0xJRU5UX0lEfScKICAgICAgLSAnQVVUSF9HSVRIVUJfQ0xJRU5UX1NFQ1JFVD0ke0FVVEhfR0lUSFVCX0NMSUVOVF9TRUNSRVR9JwogICAgICAtICdSRVNFTkRfQVBJX0tFWT0ke1JFU0VORF9BUElfS0VZfScKICAgICAgLSAnRlJPTV9FTUFJTD0ke0ZST01fRU1BSUx9JwogICAgICAtICdSRVBMWV9UT19FTUFJTD0ke1JFUExZX1RPX0VNQUlMfScKICAgICAgLSAnUkVESVNfSE9TVD0ke1JFRElTX0hPU1R9JwogICAgICAtICdSRURJU19QT1JUPSR7UkVESVNfUE9SVH0nCiAgICAgIC0gJ1JFRElTX1VTRVJOQU1FPSR7UkVESVNfVVNFUk5BTUV9JwogICAgICAtICdSRURJU19QQVNTV09SRD0ke1JFRElTX1BBU1NXT1JEfScKICAgICAgLSAnUkVESVNfVExTX0RJU0FCTEVEPSR7UkVESVNfVExTX0RJU0FCTEVEOi10cnVlfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OiAidGltZW91dCAxMHMgYmFzaCAtYyAnOj4gL2Rldi90Y3AvMTI3LjAuMC4xLzMwMDAnIHx8IGV4aXQgMSIKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1Cg==", - "tags": [ - "trigger.dev", - "background jobs", - "typescript", - "trigger", - "jobs", - "cron", - "scheduler" - ], - "category": "automation", - "logo": "svgs/trigger.png", - "minversion": "0.0.0", - "port": "3000" - }, "trigger": { - "documentation": "https://trigger.dev?utm_source=coolify.io", - "slogan": "The open source Background Jobs framework for TypeScript", - "compose": "eC1jb21tb24tZW52OgogIFJFTUlYX0FQUF9QT1JUOiAzMDAwCiAgTk9ERV9FTlY6IHByb2R1Y3Rpb24KICBSVU5USU1FX1BMQVRGT1JNOiBkb2NrZXItY29tcG9zZQogIFYzX0VOQUJMRUQ6IHRydWUKICBJTlRFUk5BTF9PVEVMX1RSQUNFX0RJU0FCTEVEOiAxCiAgSU5URVJOQUxfT1RFTF9UUkFDRV9MT0dHSU5HX0VOQUJMRUQ6IDAKICBQT1NUR1JFU19VU0VSOiAkU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgUE9TVEdSRVNfUEFTU1dPUkQ6ICRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgUE9TVEdSRVNfREI6ICcke1BPU1RHUkVTX0RCOi10cmlnZ2VyfScKICBNQUdJQ19MSU5LX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfTUFHSUMKICBTRVNTSU9OX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfU0VTU0lPTgogIEVOQ1JZUFRJT05fS0VZOiAkU0VSVklDRV9QQVNTV09SRF8zMl9FTkNSWVBUSU9OCiAgUFJPVklERVJfU0VDUkVUOiAkU0VSVklDRV9QQVNTV09SRF82NF9QUk9WSURFUgogIENPT1JESU5BVE9SX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfNjRfQ09PUkRJTkFUT1IKICBEQVRBQkFTRV9IT1NUOiAncG9zdGdyZXNxbDo1NDMyJwogIERBVEFCQVNFX1VSTDogJ3Bvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0Bwb3N0Z3Jlc3FsOjU0MzIvJFBPU1RHUkVTX0RCP3NzbG1vZGU9ZGlzYWJsZScKICBESVJFQ1RfVVJMOiAncG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzcWw6NTQzMi8kUE9TVEdSRVNfREI/c3NsbW9kZT1kaXNhYmxlJwogIFJFRElTX0hPU1Q6IHJlZGlzCiAgUkVESVNfUE9SVDogNjM3OQogIFJFRElTX1RMU19ESVNBQkxFRDogdHJ1ZQogIENPT1JESU5BVE9SX0hPU1Q6IDEyNy4wLjAuMQogIENPT1JESU5BVE9SX1BPUlQ6IDkwMjAKICBXSElURUxJU1RFRF9FTUFJTFM6ICcnCiAgQURNSU5fRU1BSUxTOiAnJwogIERFRkFVTFRfT1JHX0VYRUNVVElPTl9DT05DVVJSRU5DWV9MSU1JVDogMzAwCiAgREVGQVVMVF9FTlZfRVhFQ1VUSU9OX0NPTkNVUlJFTkNZX0xJTUlUOiAxMDAKICBERVBMT1lfUkVHSVNUUllfSE9TVDogZG9ja2VyLmlvCiAgREVQTE9ZX1JFR0lTVFJZX05BTUVTUEFDRTogdHJpZ2dlcgogIFJFR0lTVFJZX0hPU1Q6ICcke0RFUExPWV9SRUdJU1RSWV9IT1NUfScKICBSRUdJU1RSWV9OQU1FU1BBQ0U6ICcke0RFUExPWV9SRUdJU1RSWV9OQU1FU1BBQ0V9JwogIEFVVEhfR0lUSFVCX0NMSUVOVF9JRDogJyR7QVVUSF9HSVRIVUJfQ0xJRU5UX0lEfScKICBBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUOiAnJHtBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUfScKICBSRVNFTkRfQVBJX0tFWTogJyR7UkVTRU5EX0FQSV9LRVl9JwogIEZST01fRU1BSUw6ICcke0ZST01fRU1BSUx9JwogIFJFUExZX1RPX0VNQUlMOiAnJHtSRVBMWV9UT19FTUFJTH0nCiAgTE9HSU5fT1JJR0lOOiAkU0VSVklDRV9GUUROX1RSSUdHRVJfMzAwMAogIEFQUF9PUklHSU46ICRTRVJWSUNFX0ZRRE5fVFJJR0dFUl8zMDAwCiAgREVWX09URUxfRVhQT1JURVJfT1RMUF9FTkRQT0lOVDogJFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAvb3RlbAogIE9URUxfRVhQT1JURVJfT1RMUF9FTkRQT0lOVDogJFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAvb3RlbAogIEVMRUNUUklDX09SSUdJTjogJ2h0dHA6Ly9lbGVjdHJpYzozMDAwJwpzZXJ2aWNlczoKICB0cmlnZ2VyOgogICAgaW1hZ2U6ICdnaGNyLmlvL3RyaWdnZXJkb3RkZXYvdHJpZ2dlci5kZXY6djMnCiAgICBlbnZpcm9ubWVudDoKICAgICAgU0VSVklDRV9GUUROX1RSSUdHRVJfMzAwMDogJycKICAgICAgUkVNSVhfQVBQX1BPUlQ6IDMwMDAKICAgICAgTk9ERV9FTlY6IHByb2R1Y3Rpb24KICAgICAgUlVOVElNRV9QTEFURk9STTogZG9ja2VyLWNvbXBvc2UKICAgICAgVjNfRU5BQkxFRDogdHJ1ZQogICAgICBJTlRFUk5BTF9PVEVMX1RSQUNFX0RJU0FCTEVEOiAxCiAgICAgIElOVEVSTkFMX09URUxfVFJBQ0VfTE9HR0lOR19FTkFCTEVEOiAwCiAgICAgIFBPU1RHUkVTX1VTRVI6ICRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgUE9TVEdSRVNfUEFTU1dPUkQ6ICRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIFBPU1RHUkVTX0RCOiAnJHtQT1NUR1JFU19EQjotdHJpZ2dlcn0nCiAgICAgIE1BR0lDX0xJTktfU0VDUkVUOiAkU0VSVklDRV9QQVNTV09SRF8zMl9NQUdJQwogICAgICBTRVNTSU9OX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfU0VTU0lPTgogICAgICBFTkNSWVBUSU9OX0tFWTogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfRU5DUllQVElPTgogICAgICBQUk9WSURFUl9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzY0X1BST1ZJREVSCiAgICAgIENPT1JESU5BVE9SX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfNjRfQ09PUkRJTkFUT1IKICAgICAgREFUQUJBU0VfSE9TVDogJ3Bvc3RncmVzcWw6NTQzMicKICAgICAgREFUQUJBU0VfVVJMOiAncG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzcWw6NTQzMi8kUE9TVEdSRVNfREI/c3NsbW9kZT1kaXNhYmxlJwogICAgICBESVJFQ1RfVVJMOiAncG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzcWw6NTQzMi8kUE9TVEdSRVNfREI/c3NsbW9kZT1kaXNhYmxlJwogICAgICBSRURJU19IT1NUOiByZWRpcwogICAgICBSRURJU19QT1JUOiA2Mzc5CiAgICAgIFJFRElTX1RMU19ESVNBQkxFRDogdHJ1ZQogICAgICBDT09SRElOQVRPUl9IT1NUOiAxMjcuMC4wLjEKICAgICAgQ09PUkRJTkFUT1JfUE9SVDogOTAyMAogICAgICBXSElURUxJU1RFRF9FTUFJTFM6ICcnCiAgICAgIEFETUlOX0VNQUlMUzogJycKICAgICAgREVGQVVMVF9PUkdfRVhFQ1VUSU9OX0NPTkNVUlJFTkNZX0xJTUlUOiAzMDAKICAgICAgREVGQVVMVF9FTlZfRVhFQ1VUSU9OX0NPTkNVUlJFTkNZX0xJTUlUOiAxMDAKICAgICAgREVQTE9ZX1JFR0lTVFJZX0hPU1Q6IGRvY2tlci5pbwogICAgICBERVBMT1lfUkVHSVNUUllfTkFNRVNQQUNFOiB0cmlnZ2VyCiAgICAgIFJFR0lTVFJZX0hPU1Q6ICcke0RFUExPWV9SRUdJU1RSWV9IT1NUfScKICAgICAgUkVHSVNUUllfTkFNRVNQQUNFOiAnJHtERVBMT1lfUkVHSVNUUllfTkFNRVNQQUNFfScKICAgICAgQVVUSF9HSVRIVUJfQ0xJRU5UX0lEOiAnJHtBVVRIX0dJVEhVQl9DTElFTlRfSUR9JwogICAgICBBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUOiAnJHtBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUfScKICAgICAgUkVTRU5EX0FQSV9LRVk6ICcke1JFU0VORF9BUElfS0VZfScKICAgICAgRlJPTV9FTUFJTDogJyR7RlJPTV9FTUFJTH0nCiAgICAgIFJFUExZX1RPX0VNQUlMOiAnJHtSRVBMWV9UT19FTUFJTH0nCiAgICAgIExPR0lOX09SSUdJTjogJFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAKICAgICAgQVBQX09SSUdJTjogJFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAKICAgICAgREVWX09URUxfRVhQT1JURVJfT1RMUF9FTkRQT0lOVDogJFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAvb3RlbAogICAgICBPVEVMX0VYUE9SVEVSX09UTFBfRU5EUE9JTlQ6ICRTRVJWSUNFX0ZRRE5fVFJJR0dFUl8zMDAwL290ZWwKICAgICAgRUxFQ1RSSUNfT1JJR0lOOiAnaHR0cDovL2VsZWN0cmljOjMwMDAnCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3Jlc3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIGVsZWN0cmljOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDogInRpbWVvdXQgMTBzIGJhc2ggLWMgJzo+IC9kZXYvdGNwLzEyNy4wLjAuMS8zMDAwJyB8fCBleGl0IDEiCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogNQogIGVsZWN0cmljOgogICAgaW1hZ2U6IGVsZWN0cmljc3FsL2VsZWN0cmljCiAgICBlbnZpcm9ubWVudDoKICAgICAgUkVNSVhfQVBQX1BPUlQ6IDMwMDAKICAgICAgTk9ERV9FTlY6IHByb2R1Y3Rpb24KICAgICAgUlVOVElNRV9QTEFURk9STTogZG9ja2VyLWNvbXBvc2UKICAgICAgVjNfRU5BQkxFRDogdHJ1ZQogICAgICBJTlRFUk5BTF9PVEVMX1RSQUNFX0RJU0FCTEVEOiAxCiAgICAgIElOVEVSTkFMX09URUxfVFJBQ0VfTE9HR0lOR19FTkFCTEVEOiAwCiAgICAgIFBPU1RHUkVTX1VTRVI6ICRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgUE9TVEdSRVNfUEFTU1dPUkQ6ICRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIFBPU1RHUkVTX0RCOiAnJHtQT1NUR1JFU19EQjotdHJpZ2dlcn0nCiAgICAgIE1BR0lDX0xJTktfU0VDUkVUOiAkU0VSVklDRV9QQVNTV09SRF8zMl9NQUdJQwogICAgICBTRVNTSU9OX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfU0VTU0lPTgogICAgICBFTkNSWVBUSU9OX0tFWTogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfRU5DUllQVElPTgogICAgICBQUk9WSURFUl9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzY0X1BST1ZJREVSCiAgICAgIENPT1JESU5BVE9SX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfNjRfQ09PUkRJTkFUT1IKICAgICAgREFUQUJBU0VfSE9TVDogJ3Bvc3RncmVzcWw6NTQzMicKICAgICAgREFUQUJBU0VfVVJMOiAncG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzcWw6NTQzMi8kUE9TVEdSRVNfREI/c3NsbW9kZT1kaXNhYmxlJwogICAgICBESVJFQ1RfVVJMOiAncG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzcWw6NTQzMi8kUE9TVEdSRVNfREI/c3NsbW9kZT1kaXNhYmxlJwogICAgICBSRURJU19IT1NUOiByZWRpcwogICAgICBSRURJU19QT1JUOiA2Mzc5CiAgICAgIFJFRElTX1RMU19ESVNBQkxFRDogdHJ1ZQogICAgICBDT09SRElOQVRPUl9IT1NUOiAxMjcuMC4wLjEKICAgICAgQ09PUkRJTkFUT1JfUE9SVDogOTAyMAogICAgICBXSElURUxJU1RFRF9FTUFJTFM6ICcnCiAgICAgIEFETUlOX0VNQUlMUzogJycKICAgICAgREVGQVVMVF9PUkdfRVhFQ1VUSU9OX0NPTkNVUlJFTkNZX0xJTUlUOiAzMDAKICAgICAgREVGQVVMVF9FTlZfRVhFQ1VUSU9OX0NPTkNVUlJFTkNZX0xJTUlUOiAxMDAKICAgICAgREVQTE9ZX1JFR0lTVFJZX0hPU1Q6IGRvY2tlci5pbwogICAgICBERVBMT1lfUkVHSVNUUllfTkFNRVNQQUNFOiB0cmlnZ2VyCiAgICAgIFJFR0lTVFJZX0hPU1Q6ICcke0RFUExPWV9SRUdJU1RSWV9IT1NUfScKICAgICAgUkVHSVNUUllfTkFNRVNQQUNFOiAnJHtERVBMT1lfUkVHSVNUUllfTkFNRVNQQUNFfScKICAgICAgQVVUSF9HSVRIVUJfQ0xJRU5UX0lEOiAnJHtBVVRIX0dJVEhVQl9DTElFTlRfSUR9JwogICAgICBBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUOiAnJHtBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUfScKICAgICAgUkVTRU5EX0FQSV9LRVk6ICcke1JFU0VORF9BUElfS0VZfScKICAgICAgRlJPTV9FTUFJTDogJyR7RlJPTV9FTUFJTH0nCiAgICAgIFJFUExZX1RPX0VNQUlMOiAnJHtSRVBMWV9UT19FTUFJTH0nCiAgICAgIExPR0lOX09SSUdJTjogJFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAKICAgICAgQVBQX09SSUdJTjogJFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAKICAgICAgREVWX09URUxfRVhQT1JURVJfT1RMUF9FTkRQT0lOVDogJFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAvb3RlbAogICAgICBPVEVMX0VYUE9SVEVSX09UTFBfRU5EUE9JTlQ6ICRTRVJWSUNFX0ZRRE5fVFJJR0dFUl8zMDAwL290ZWwKICAgICAgRUxFQ1RSSUNfT1JJR0lOOiAnaHR0cDovL2VsZWN0cmljOjMwMDAnCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3Jlc3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gcHdkCiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOjcnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBBTExPV19FTVBUWV9QQVNTV09SRD15ZXMKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncmVkaXMtY2xpIC1oIGxvY2FsaG9zdCAtcCA2Mzc5IHBpbmcnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiAzCiAgICB2b2x1bWVzOgogICAgICAtICdyZWRpcy1kYXRhOi9kYXRhJwogIHBvc3RncmVzcWw6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Bvc3RncmVzcWwtZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBlbnZpcm9ubWVudDoKICAgICAgUkVNSVhfQVBQX1BPUlQ6IDMwMDAKICAgICAgTk9ERV9FTlY6IHByb2R1Y3Rpb24KICAgICAgUlVOVElNRV9QTEFURk9STTogZG9ja2VyLWNvbXBvc2UKICAgICAgVjNfRU5BQkxFRDogdHJ1ZQogICAgICBJTlRFUk5BTF9PVEVMX1RSQUNFX0RJU0FCTEVEOiAxCiAgICAgIElOVEVSTkFMX09URUxfVFJBQ0VfTE9HR0lOR19FTkFCTEVEOiAwCiAgICAgIFBPU1RHUkVTX1VTRVI6ICRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgUE9TVEdSRVNfUEFTU1dPUkQ6ICRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIFBPU1RHUkVTX0RCOiAnJHtQT1NUR1JFU19EQjotdHJpZ2dlcn0nCiAgICAgIE1BR0lDX0xJTktfU0VDUkVUOiAkU0VSVklDRV9QQVNTV09SRF8zMl9NQUdJQwogICAgICBTRVNTSU9OX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfU0VTU0lPTgogICAgICBFTkNSWVBUSU9OX0tFWTogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfRU5DUllQVElPTgogICAgICBQUk9WSURFUl9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzY0X1BST1ZJREVSCiAgICAgIENPT1JESU5BVE9SX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfNjRfQ09PUkRJTkFUT1IKICAgICAgREFUQUJBU0VfSE9TVDogJ3Bvc3RncmVzcWw6NTQzMicKICAgICAgREFUQUJBU0VfVVJMOiAncG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzcWw6NTQzMi8kUE9TVEdSRVNfREI/c3NsbW9kZT1kaXNhYmxlJwogICAgICBESVJFQ1RfVVJMOiAncG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzcWw6NTQzMi8kUE9TVEdSRVNfREI/c3NsbW9kZT1kaXNhYmxlJwogICAgICBSRURJU19IT1NUOiByZWRpcwogICAgICBSRURJU19QT1JUOiA2Mzc5CiAgICAgIFJFRElTX1RMU19ESVNBQkxFRDogdHJ1ZQogICAgICBDT09SRElOQVRPUl9IT1NUOiAxMjcuMC4wLjEKICAgICAgQ09PUkRJTkFUT1JfUE9SVDogOTAyMAogICAgICBXSElURUxJU1RFRF9FTUFJTFM6ICcnCiAgICAgIEFETUlOX0VNQUlMUzogJycKICAgICAgREVGQVVMVF9PUkdfRVhFQ1VUSU9OX0NPTkNVUlJFTkNZX0xJTUlUOiAzMDAKICAgICAgREVGQVVMVF9FTlZfRVhFQ1VUSU9OX0NPTkNVUlJFTkNZX0xJTUlUOiAxMDAKICAgICAgREVQTE9ZX1JFR0lTVFJZX0hPU1Q6IGRvY2tlci5pbwogICAgICBERVBMT1lfUkVHSVNUUllfTkFNRVNQQUNFOiB0cmlnZ2VyCiAgICAgIFJFR0lTVFJZX0hPU1Q6ICcke0RFUExPWV9SRUdJU1RSWV9IT1NUfScKICAgICAgUkVHSVNUUllfTkFNRVNQQUNFOiAnJHtERVBMT1lfUkVHSVNUUllfTkFNRVNQQUNFfScKICAgICAgQVVUSF9HSVRIVUJfQ0xJRU5UX0lEOiAnJHtBVVRIX0dJVEhVQl9DTElFTlRfSUR9JwogICAgICBBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUOiAnJHtBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUfScKICAgICAgUkVTRU5EX0FQSV9LRVk6ICcke1JFU0VORF9BUElfS0VZfScKICAgICAgRlJPTV9FTUFJTDogJyR7RlJPTV9FTUFJTH0nCiAgICAgIFJFUExZX1RPX0VNQUlMOiAnJHtSRVBMWV9UT19FTUFJTH0nCiAgICAgIExPR0lOX09SSUdJTjogJFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAKICAgICAgQVBQX09SSUdJTjogJFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAKICAgICAgREVWX09URUxfRVhQT1JURVJfT1RMUF9FTkRQT0lOVDogJFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAvb3RlbAogICAgICBPVEVMX0VYUE9SVEVSX09UTFBfRU5EUE9JTlQ6ICRTRVJWSUNFX0ZRRE5fVFJJR0dFUl8zMDAwL290ZWwKICAgICAgRUxFQ1RSSUNfT1JJR0lOOiAnaHR0cDovL2VsZWN0cmljOjMwMDAnCiAgICBjb21tYW5kOgogICAgICAtICctYycKICAgICAgLSB3YWxfbGV2ZWw9bG9naWNhbAogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIGRvY2tlci1wcm92aWRlcjoKICAgIGltYWdlOiAnZ2hjci5pby90cmlnZ2VyZG90ZGV2L3Byb3ZpZGVyL2RvY2tlcjp2MycKICAgIHBsYXRmb3JtOiBsaW51eC9hbWQ2NAogICAgdm9sdW1lczoKICAgICAgLSAnL3Zhci9ydW4vZG9ja2VyLnNvY2s6L3Zhci9ydW4vZG9ja2VyLnNvY2snCiAgICB1c2VyOiByb290CiAgICBkZXBlbmRzX29uOgogICAgICB0cmlnZ2VyOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgUkVNSVhfQVBQX1BPUlQ6IDMwMDAKICAgICAgTk9ERV9FTlY6IHByb2R1Y3Rpb24KICAgICAgUlVOVElNRV9QTEFURk9STTogZG9ja2VyLWNvbXBvc2UKICAgICAgVjNfRU5BQkxFRDogdHJ1ZQogICAgICBJTlRFUk5BTF9PVEVMX1RSQUNFX0RJU0FCTEVEOiAxCiAgICAgIElOVEVSTkFMX09URUxfVFJBQ0VfTE9HR0lOR19FTkFCTEVEOiAwCiAgICAgIFBPU1RHUkVTX1VTRVI6ICRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgUE9TVEdSRVNfUEFTU1dPUkQ6ICRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIFBPU1RHUkVTX0RCOiAnJHtQT1NUR1JFU19EQjotdHJpZ2dlcn0nCiAgICAgIE1BR0lDX0xJTktfU0VDUkVUOiAkU0VSVklDRV9QQVNTV09SRF8zMl9NQUdJQwogICAgICBTRVNTSU9OX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfU0VTU0lPTgogICAgICBFTkNSWVBUSU9OX0tFWTogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfRU5DUllQVElPTgogICAgICBQUk9WSURFUl9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzY0X1BST1ZJREVSCiAgICAgIENPT1JESU5BVE9SX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfNjRfQ09PUkRJTkFUT1IKICAgICAgREFUQUJBU0VfSE9TVDogJ3Bvc3RncmVzcWw6NTQzMicKICAgICAgREFUQUJBU0VfVVJMOiAncG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzcWw6NTQzMi8kUE9TVEdSRVNfREI/c3NsbW9kZT1kaXNhYmxlJwogICAgICBESVJFQ1RfVVJMOiAncG9zdGdyZXM6Ly8kU0VSVklDRV9VU0VSX1BPU1RHUkVTOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQHBvc3RncmVzcWw6NTQzMi8kUE9TVEdSRVNfREI/c3NsbW9kZT1kaXNhYmxlJwogICAgICBSRURJU19IT1NUOiByZWRpcwogICAgICBSRURJU19QT1JUOiA2Mzc5CiAgICAgIFJFRElTX1RMU19ESVNBQkxFRDogdHJ1ZQogICAgICBDT09SRElOQVRPUl9IT1NUOiAxMjcuMC4wLjEKICAgICAgQ09PUkRJTkFUT1JfUE9SVDogOTAyMAogICAgICBXSElURUxJU1RFRF9FTUFJTFM6ICcnCiAgICAgIEFETUlOX0VNQUlMUzogJycKICAgICAgREVGQVVMVF9PUkdfRVhFQ1VUSU9OX0NPTkNVUlJFTkNZX0xJTUlUOiAzMDAKICAgICAgREVGQVVMVF9FTlZfRVhFQ1VUSU9OX0NPTkNVUlJFTkNZX0xJTUlUOiAxMDAKICAgICAgREVQTE9ZX1JFR0lTVFJZX0hPU1Q6IGRvY2tlci5pbwogICAgICBERVBMT1lfUkVHSVNUUllfTkFNRVNQQUNFOiB0cmlnZ2VyCiAgICAgIFJFR0lTVFJZX0hPU1Q6ICcke0RFUExPWV9SRUdJU1RSWV9IT1NUfScKICAgICAgUkVHSVNUUllfTkFNRVNQQUNFOiAnJHtERVBMT1lfUkVHSVNUUllfTkFNRVNQQUNFfScKICAgICAgQVVUSF9HSVRIVUJfQ0xJRU5UX0lEOiAnJHtBVVRIX0dJVEhVQl9DTElFTlRfSUR9JwogICAgICBBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUOiAnJHtBVVRIX0dJVEhVQl9DTElFTlRfU0VDUkVUfScKICAgICAgUkVTRU5EX0FQSV9LRVk6ICcke1JFU0VORF9BUElfS0VZfScKICAgICAgRlJPTV9FTUFJTDogJyR7RlJPTV9FTUFJTH0nCiAgICAgIFJFUExZX1RPX0VNQUlMOiAnJHtSRVBMWV9UT19FTUFJTH0nCiAgICAgIExPR0lOX09SSUdJTjogJFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAKICAgICAgQVBQX09SSUdJTjogJFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAKICAgICAgREVWX09URUxfRVhQT1JURVJfT1RMUF9FTkRQT0lOVDogJFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAvb3RlbAogICAgICBPVEVMX0VYUE9SVEVSX09UTFBfRU5EUE9JTlQ6ICRTRVJWSUNFX0ZRRE5fVFJJR0dFUl8zMDAwL290ZWwKICAgICAgRUxFQ1RSSUNfT1JJR0lOOiAnaHR0cDovL2VsZWN0cmljOjMwMDAnCiAgICAgIFBMQVRGT1JNX0hPU1Q6IHRyaWdnZXIKICAgICAgUExBVEZPUk1fV1NfUE9SVDogMzAwMAogICAgICBTRUNVUkVfQ09OTkVDVElPTjogJ2ZhbHNlJwogICAgICBQTEFURk9STV9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzY0X1BST1ZJREVSCiAgICAgIEhUVFBfU0VSVkVSX1BPUlQ6IDkwMjAKICBjb29yZGluYXRvcjoKICAgIGltYWdlOiAnZ2hjci5pby90cmlnZ2VyZG90ZGV2L2Nvb3JkaW5hdG9yOnYzJwogICAgcGxhdGZvcm06IGxpbnV4L2FtZDY0CiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgIHVzZXI6IHJvb3QKICAgIHBvcnRzOgogICAgICAtICcxMjcuMC4wLjE6OTAyMDo5MDIwJwogICAgZGVwZW5kc19vbjoKICAgICAgdHJpZ2dlcjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIFJFTUlYX0FQUF9QT1JUOiAzMDAwCiAgICAgIE5PREVfRU5WOiBwcm9kdWN0aW9uCiAgICAgIFJVTlRJTUVfUExBVEZPUk06IGRvY2tlci1jb21wb3NlCiAgICAgIFYzX0VOQUJMRUQ6IHRydWUKICAgICAgSU5URVJOQUxfT1RFTF9UUkFDRV9ESVNBQkxFRDogMQogICAgICBJTlRFUk5BTF9PVEVMX1RSQUNFX0xPR0dJTkdfRU5BQkxFRDogMAogICAgICBQT1NUR1JFU19VU0VSOiAkU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIFBPU1RHUkVTX1BBU1NXT1JEOiAkU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICBQT1NUR1JFU19EQjogJyR7UE9TVEdSRVNfREI6LXRyaWdnZXJ9JwogICAgICBNQUdJQ19MSU5LX1NFQ1JFVDogJFNFUlZJQ0VfUEFTU1dPUkRfMzJfTUFHSUMKICAgICAgU0VTU0lPTl9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzMyX1NFU1NJT04KICAgICAgRU5DUllQVElPTl9LRVk6ICRTRVJWSUNFX1BBU1NXT1JEXzMyX0VOQ1JZUFRJT04KICAgICAgUFJPVklERVJfU0VDUkVUOiAkU0VSVklDRV9QQVNTV09SRF82NF9QUk9WSURFUgogICAgICBDT09SRElOQVRPUl9TRUNSRVQ6ICRTRVJWSUNFX1BBU1NXT1JEXzY0X0NPT1JESU5BVE9SCiAgICAgIERBVEFCQVNFX0hPU1Q6ICdwb3N0Z3Jlc3FsOjU0MzInCiAgICAgIERBVEFCQVNFX1VSTDogJ3Bvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0Bwb3N0Z3Jlc3FsOjU0MzIvJFBPU1RHUkVTX0RCP3NzbG1vZGU9ZGlzYWJsZScKICAgICAgRElSRUNUX1VSTDogJ3Bvc3RncmVzOi8vJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUzokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0Bwb3N0Z3Jlc3FsOjU0MzIvJFBPU1RHUkVTX0RCP3NzbG1vZGU9ZGlzYWJsZScKICAgICAgUkVESVNfSE9TVDogcmVkaXMKICAgICAgUkVESVNfUE9SVDogNjM3OQogICAgICBSRURJU19UTFNfRElTQUJMRUQ6IHRydWUKICAgICAgQ09PUkRJTkFUT1JfSE9TVDogMTI3LjAuMC4xCiAgICAgIENPT1JESU5BVE9SX1BPUlQ6IDkwMjAKICAgICAgV0hJVEVMSVNURURfRU1BSUxTOiAnJwogICAgICBBRE1JTl9FTUFJTFM6ICcnCiAgICAgIERFRkFVTFRfT1JHX0VYRUNVVElPTl9DT05DVVJSRU5DWV9MSU1JVDogMzAwCiAgICAgIERFRkFVTFRfRU5WX0VYRUNVVElPTl9DT05DVVJSRU5DWV9MSU1JVDogMTAwCiAgICAgIERFUExPWV9SRUdJU1RSWV9IT1NUOiBkb2NrZXIuaW8KICAgICAgREVQTE9ZX1JFR0lTVFJZX05BTUVTUEFDRTogdHJpZ2dlcgogICAgICBSRUdJU1RSWV9IT1NUOiAnJHtERVBMT1lfUkVHSVNUUllfSE9TVH0nCiAgICAgIFJFR0lTVFJZX05BTUVTUEFDRTogJyR7REVQTE9ZX1JFR0lTVFJZX05BTUVTUEFDRX0nCiAgICAgIEFVVEhfR0lUSFVCX0NMSUVOVF9JRDogJyR7QVVUSF9HSVRIVUJfQ0xJRU5UX0lEfScKICAgICAgQVVUSF9HSVRIVUJfQ0xJRU5UX1NFQ1JFVDogJyR7QVVUSF9HSVRIVUJfQ0xJRU5UX1NFQ1JFVH0nCiAgICAgIFJFU0VORF9BUElfS0VZOiAnJHtSRVNFTkRfQVBJX0tFWX0nCiAgICAgIEZST01fRU1BSUw6ICcke0ZST01fRU1BSUx9JwogICAgICBSRVBMWV9UT19FTUFJTDogJyR7UkVQTFlfVE9fRU1BSUx9JwogICAgICBMT0dJTl9PUklHSU46ICRTRVJWSUNFX0ZRRE5fVFJJR0dFUl8zMDAwCiAgICAgIEFQUF9PUklHSU46ICRTRVJWSUNFX0ZRRE5fVFJJR0dFUl8zMDAwCiAgICAgIERFVl9PVEVMX0VYUE9SVEVSX09UTFBfRU5EUE9JTlQ6ICRTRVJWSUNFX0ZRRE5fVFJJR0dFUl8zMDAwL290ZWwKICAgICAgT1RFTF9FWFBPUlRFUl9PVExQX0VORFBPSU5UOiAkU0VSVklDRV9GUUROX1RSSUdHRVJfMzAwMC9vdGVsCiAgICAgIEVMRUNUUklDX09SSUdJTjogJ2h0dHA6Ly9lbGVjdHJpYzozMDAwJwogICAgICBQTEFURk9STV9IT1NUOiB0cmlnZ2VyCiAgICAgIFBMQVRGT1JNX1dTX1BPUlQ6IDMwMDAKICAgICAgU0VDVVJFX0NPTk5FQ1RJT046ICdmYWxzZScKICAgICAgUExBVEZPUk1fU0VDUkVUOiAkU0VSVklDRV9QQVNTV09SRF82NF9DT09SRElOQVRPUgogICAgICBIVFRQX1NFUlZFUl9QT1JUOiA5MDIwCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gcHdkCg==", + "documentation": "https://trigger.dev/docs/self-hosting/overview?utm_source=coolify.io", + "slogan": "The open source background jobs platform for developers", + "compose": "c2VydmljZXM6CiAgdHJpZ2dlcjoKICAgIGltYWdlOiAnZ2hjci5pby90cmlnZ2VyZG90ZGV2L3RyaWdnZXIuZGV2OnY0LjMuMCcKICAgIHVzZXI6IHJvb3QKICAgIGNvbW1hbmQ6ICJzaCAtYyBcImNob3duIC1SIG5vZGU6bm9kZSAvaG9tZS9ub2RlL3NoYXJlZCAmJiBleGVjIC4vc2NyaXB0cy9lbnRyeXBvaW50LnNoXCJcbiIKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDAKICAgICAgLSAnQVBQX09SSUdJTj0ke1NFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDB9JwogICAgICAtICdMT0dJTl9PUklHSU49JHtTRVJWSUNFX0ZRRE5fVFJJR0dFUl8zMDAwfScKICAgICAgLSAnQVBJX09SSUdJTj0ke1NFUlZJQ0VfRlFETl9UUklHR0VSXzMwMDB9JwogICAgICAtICdTRVNTSU9OX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfNjRfU0VTU0lPTn0nCiAgICAgIC0gJ01BR0lDX0xJTktfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF82NF9NQUdJQ0xJTkt9JwogICAgICAtICdFTkNSWVBUSU9OX0tFWT0ke1NFUlZJQ0VfUEFTU1dPUkRfRU5DUllQVElPTktFWX0nCiAgICAgIC0gJ01BTkFHRURfV09SS0VSX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfNjRfV09SS0VSU0VDUkVUfScKICAgICAgLSAnVFJJR0dFUl9XT1JLRVJfVE9LRU49JHtUUklHR0VSX1dPUktFUl9UT0tFTn0nCiAgICAgIC0gTk9ERV9FTlY9cHJvZHVjdGlvbgogICAgICAtIEFQUF9MT0dfTEVWRUw9aW5mbwogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QHBvc3RncmVzcWw6NTQzMi8ke1BPU1RHUkVTX0RCOi10cmlnZ2VyLWRifT9zY2hlbWE9cHVibGljJnNzbG1vZGU9ZGlzYWJsZScKICAgICAgLSAnRElSRUNUX1VSTD1wb3N0Z3Jlc3FsOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AcG9zdGdyZXNxbDo1NDMyLyR7UE9TVEdSRVNfREI6LXRyaWdnZXItZGJ9P3NjaGVtYT1wdWJsaWMmc3NsbW9kZT1kaXNhYmxlJwogICAgICAtIFJFRElTX0hPU1Q9cmVkaXMKICAgICAgLSBSRURJU19QT1JUPTYzNzkKICAgICAgLSBSRURJU19UTFNfRElTQUJMRUQ9dHJ1ZQogICAgICAtICdFTEVDVFJJQ19PUklHSU49aHR0cDovL2VsZWN0cmljOjMwMDAnCiAgICAgIC0gJ0RFVl9PVEVMX0VYUE9SVEVSX09UTFBfRU5EUE9JTlQ9JHtERVZfT1RFTF9FWFBPUlRFUl9PVExQX0VORFBPSU5UOi19JwogICAgICAtICdERVBMT1lfUkVHSVNUUllfSE9TVD0ke0RFUExPWV9SRUdJU1RSWV9IT1NUOi1naGNyLmlvfScKICAgICAgLSAnREVQTE9ZX1JFR0lTVFJZX1BST1RPQ09MPSR7REVQTE9ZX1JFR0lTVFJZX1BST1RPQ09MOi1odHRwc30nCiAgICAgIC0gJ0RFUExPWV9SRUdJU1RSWV9OQU1FU1BBQ0U9JHtERVBMT1lfUkVHSVNUUllfTkFNRVNQQUNFOi10cmlnZ2VyfScKICAgICAgLSAnVjRfREVQTE9ZX1JFR0lTVFJZX05BTUVTUEFDRT0ke0RFUExPWV9SRUdJU1RSWV9OQU1FU1BBQ0U6LXRyaWdnZXJ9JwogICAgICAtICdPQkpFQ1RfU1RPUkVfQkFTRV9VUkw9JHtPQkpFQ1RfU1RPUkVfQkFTRV9VUkx9JwogICAgICAtICdPQkpFQ1RfU1RPUkVfQUNDRVNTX0tFWV9JRD0ke09CSkVDVF9TVE9SRV9BQ0NFU1NfS0VZX0lEfScKICAgICAgLSAnT0JKRUNUX1NUT1JFX1NFQ1JFVF9BQ0NFU1NfS0VZPSR7T0JKRUNUX1NUT1JFX1NFQ1JFVF9BQ0NFU1NfS0VZfScKICAgICAgLSAnQ0xJQ0tIT1VTRV9VUkw9aHR0cDovLyR7U0VSVklDRV9VU0VSX0NMSUNLSE9VU0V9OiR7U0VSVklDRV9QQVNTV09SRF82NF9DTElDS0hPVVNFfUBjbGlja2hvdXNlOjgxMjM/c2VjdXJlPWZhbHNlJwogICAgICAtIENMSUNLSE9VU0VfTE9HX0xFVkVMPWluZm8KICAgICAgLSBSVU5fUkVQTElDQVRJT05fRU5BQkxFRD0xCiAgICAgIC0gJ1JVTl9SRVBMSUNBVElPTl9DTElDS0hPVVNFX1VSTD1odHRwOi8vJHtTRVJWSUNFX1VTRVJfQ0xJQ0tIT1VTRX06JHtTRVJWSUNFX1BBU1NXT1JEXzY0X0NMSUNLSE9VU0V9QGNsaWNraG91c2U6ODEyMycKICAgICAgLSBSVU5fUkVQTElDQVRJT05fTE9HX0xFVkVMPWluZm8KICAgICAgLSBUUklHR0VSX0JPT1RTVFJBUF9FTkFCTEVEPTEKICAgICAgLSBUUklHR0VSX0JPT1RTVFJBUF9XT1JLRVJfR1JPVVBfTkFNRT1ib290c3RyYXAKICAgICAgLSBUUklHR0VSX0JPT1RTVFJBUF9XT1JLRVJfVE9LRU5fUEFUSD0vaG9tZS9ub2RlL3NoYXJlZC93b3JrZXJfdG9rZW4KICAgICAgLSAnREVGQVVMVF9PUkdfRVhFQ1VUSU9OX0NPTkNVUlJFTkNZX0xJTUlUPSR7REVGQVVMVF9PUkdfRVhFQ1VUSU9OX0NPTkNVUlJFTkNZX0xJTUlUOi0zMDB9JwogICAgICAtICdERUZBVUxUX0VOVl9FWEVDVVRJT05fQ09OQ1VSUkVOQ1lfTElNSVQ9JHtERUZBVUxUX0VOVl9FWEVDVVRJT05fQ09OQ1VSUkVOQ1lfTElNSVQ6LTEwMH0nCiAgICAgIC0gJ0FVVEhfR0lUSFVCX0NMSUVOVF9JRD0ke0FVVEhfR0lUSFVCX0NMSUVOVF9JRDotfScKICAgICAgLSAnQVVUSF9HSVRIVUJfQ0xJRU5UX1NFQ1JFVD0ke0FVVEhfR0lUSFVCX0NMSUVOVF9TRUNSRVQ6LX0nCiAgICAgIC0gJ0VNQUlMX1RSQU5TUE9SVD0ke0VNQUlMX1RSQU5TUE9SVDotc210cH0nCiAgICAgIC0gJ1JFU0VORF9BUElfS0VZPSR7UkVTRU5EX0FQSV9LRVl9JwogICAgICAtICdTTVRQX0hPU1Q9JHtTTVRQX0hPU1R9JwogICAgICAtICdTTVRQX1BPUlQ9JHtTTVRQX1BPUlR9JwogICAgICAtICdTTVRQX1VTRVI9JHtTTVRQX1VTRVJ9JwogICAgICAtICdTTVRQX1BBU1NXT1JEPSR7U01UUF9QQVNTV09SRH0nCiAgICAgIC0gJ1NNVFBfU0VDVVJFPSR7U01UUF9TRUNVUkV9JwogICAgICAtICdGUk9NX0VNQUlMPSR7RlJPTV9FTUFJTH0nCiAgICAgIC0gJ1JFUExZX1RPX0VNQUlMPSR7UkVQTFlfVE9fRU1BSUx9JwogICAgICAtICdXSElURUxJU1RFRF9FTUFJTFM9JHtXSElURUxJU1RFRF9FTUFJTFN9JwogICAgICAtICdBRE1JTl9FTUFJTFM9JHtBRE1JTl9FTUFJTFN9JwogICAgICAtIEdSQUNFRlVMX1NIVVRET1dOX1RJTUVPVVQ9MTAwMAogICAgICAtICdJTlRFUk5BTF9PVEVMX1RSQUNFX0xPR0dJTkdfRU5BQkxFRD0ke0lOVEVSTkFMX09URUxfVFJBQ0VfTE9HR0lOR19FTkFCTEVEOi0wfScKICAgICAgLSAnVFJJR0dFUl9URUxFTUVUUllfRElTQUJMRUQ9JHtUUklHR0VSX1RFTEVNRVRSWV9ESVNBQkxFRDotdHJ1ZX0nCiAgICB2b2x1bWVzOgogICAgICAtICdzaGFyZWQtZGF0YTovaG9tZS9ub2RlL3NoYXJlZCcKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBub2RlCiAgICAgICAgLSAnLWUnCiAgICAgICAgLSAicmVxdWlyZSgnaHR0cCcpLmdldCgnaHR0cDovLzEyNy4wLjAuMTozMDAwL2hlYWx0aGNoZWNrJywocik9PnByb2Nlc3MuZXhpdChyLnN0YXR1c0NvZGU9PT0yMDA/MDoxKSkub24oJ2Vycm9yJywoKT0+cHJvY2Vzcy5leGl0KDEpKSIKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgICAgIHN0YXJ0X3BlcmlvZDogMTBzCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3Jlc3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIGVsZWN0cmljOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIGNsaWNraG91c2U6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICBzdXBlcnZpc29yOgogICAgaW1hZ2U6ICdnaGNyLmlvL3RyaWdnZXJkb3RkZXYvc3VwZXJ2aXNvcjp2NC4zLjAnCiAgICB1c2VyOiByb290CiAgICBjb21tYW5kOiAic2ggLWMgXCJjaG93biAtUiBub2RlOm5vZGUgL2hvbWUvbm9kZS9zaGFyZWQgJiYgZXhlYyAvdXNyL2Jpbi9kdW1iLWluaXQgLS0gcG5wbSBydW4gLS1maWx0ZXIgc3VwZXJ2aXNvciBzdGFydFwiXG4iCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnVFJJR0dFUl9BUElfVVJMPWh0dHA6Ly90cmlnZ2VyOjMwMDAnCiAgICAgIC0gJ09URUxfRVhQT1JURVJfT1RMUF9FTkRQT0lOVD1odHRwOi8vdHJpZ2dlcjozMDAwL290ZWwnCiAgICAgIC0gJ1RSSUdHRVJfV09SS0VSX1RPS0VOPSR7VFJJR0dFUl9XT1JLRVJfVE9LRU46LWZpbGU6Ly8vaG9tZS9ub2RlL3NoYXJlZC93b3JrZXJfdG9rZW59JwogICAgICAtICdNQU5BR0VEX1dPUktFUl9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X1dPUktFUlNFQ1JFVH0nCiAgICAgIC0gJ1RSSUdHRVJfV09SS0xPQURfQVBJX0RPTUFJTj0ke1RSSUdHRVJfV09SS0xPQURfQVBJX0RPTUFJTn0nCiAgICAgIC0gVFJJR0dFUl9XT1JLTE9BRF9BUElfUE9SVF9FWFRFUk5BTD04MDIwCiAgICAgIC0gJ0RPQ0tFUl9IT1NUPXRjcDovL2RvY2tlci1wcm94eToyMzc1JwogICAgICAtICdET0NLRVJfUlVOTkVSX05FVFdPUktTPSR7RE9DS0VSX1JVTk5FUl9ORVRXT1JLU30nCiAgICAgIC0gJ0RPQ0tFUl9BVVRPUkVNT1ZFX0VYSVRFRF9DT05UQUlORVJTPSR7RE9DS0VSX0FVVE9SRU1PVkVfRVhJVEVEX0NPTlRBSU5FUlM6LTF9JwogICAgICAtICdET0NLRVJfUkVHSVNUUllfVVJMPWh0dHBzOi8vJHtERVBMT1lfUkVHSVNUUllfSE9TVDotZ2hjci5pb30nCiAgICAgIC0gJ0RPQ0tFUl9SRUdJU1RSWV9VU0VSTkFNRT0ke0RFUExPWV9SRUdJU1RSWV9VU0VSTkFNRX0nCiAgICAgIC0gJ0RPQ0tFUl9SRUdJU1RSWV9QQVNTV09SRD0ke0RFUExPWV9SRUdJU1RSWV9QQVNTV09SRH0nCiAgICAgIC0gRU5GT1JDRV9NQUNISU5FX1BSRVNFVFM9MQogICAgICAtIFRSSUdHRVJfREVRVUVVRV9JTlRFUlZBTF9NUz0xMDAwCiAgICAgIC0gJ0RFQlVHPSR7U1VQRVJWSVNPUl9ERUJVRzotMH0nCiAgICB2b2x1bWVzOgogICAgICAtICdzaGFyZWQtZGF0YTovaG9tZS9ub2RlL3NoYXJlZCcKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBub2RlCiAgICAgICAgLSAnLWUnCiAgICAgICAgLSAicmVxdWlyZSgnaHR0cCcpLmdldCgnaHR0cDovLzEyNy4wLjAuMTo4MDIwL2hlYWx0aCcsKHIpPT5wcm9jZXNzLmV4aXQoci5zdGF0dXNDb2RlPT09MjAwPzA6MSkpLm9uKCdlcnJvcicsKCk9PnByb2Nlc3MuZXhpdCgxKSkiCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogNQogICAgZGVwZW5kc19vbjoKICAgICAgdHJpZ2dlcjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBkb2NrZXItcHJveHk6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICBkb2NrZXItcHJveHk6CiAgICBpbWFnZTogJ3RlY25hdGl2YS9kb2NrZXItc29ja2V0LXByb3h5OnYwLjQuMicKICAgIHZvbHVtZXM6CiAgICAgIC0gJy92YXIvcnVuL2RvY2tlci5zb2NrOi92YXIvcnVuL2RvY2tlci5zb2NrOnJvJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gTE9HX0xFVkVMPWluZm8KICAgICAgLSAnUE9TVD0ke1BPU1Q6LTF9JwogICAgICAtICdDT05UQUlORVJTPSR7Q09OVEFJTkVSUzotMX0nCiAgICAgIC0gJ0lNQUdFUz0ke0lNQUdFUzotMX0nCiAgICAgIC0gJ0lORk89JHtJTkZPOi0xfScKICAgICAgLSAnTkVUV09SS1M9JHtORVRXT1JLUzotMX0nCiAgICAgIC0gJ0FVVEg9JHtBVVRIOi0xfScKICAgICAgLSAnRElTVFJJQlVUSU9OPSR7RElTVFJJQlVUSU9OOi0xfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnbmMgLXogMTI3LjAuMC4xIDIzNzUgfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDUKICBwb3N0Z3Jlc3FsOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNi1hbHBpbmUnCiAgICBjb21tYW5kOgogICAgICAtICctYycKICAgICAgLSB3YWxfbGV2ZWw9bG9naWNhbAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi10cmlnZ2VyLWRifScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Bvc3RncmVzcWwtZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLVUgJCR7UE9TVEdSRVNfVVNFUn0gLWQgJCR7UE9TVEdSRVNfREJ9JwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOjctYWxwaW5lJwogICAgdm9sdW1lczoKICAgICAgLSAncmVkaXMtZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgZWxlY3RyaWM6CiAgICBpbWFnZTogJ2VsZWN0cmljc3FsL2VsZWN0cmljOjEuMi45JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AcG9zdGdyZXNxbDo1NDMyLyR7UE9TVEdSRVNfREI6LXRyaWdnZXItZGJ9P3NzbG1vZGU9ZGlzYWJsZScKICAgICAgLSAnRUxFQ1RSSUNfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF82NF9FTEVDVFJJQ30nCiAgICAgIC0gRUxFQ1RSSUNfVVNBR0VfUkVQT1JUSU5HPWZhbHNlCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly9sb2NhbGhvc3Q6MzAwMC92MS9oZWFsdGgnCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogNQogICAgZGVwZW5kc19vbjoKICAgICAgcG9zdGdyZXNxbDoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogIGNsaWNraG91c2U6CiAgICBpbWFnZTogJ2NsaWNraG91c2UvY2xpY2tob3VzZS1zZXJ2ZXI6MjUuOCcKICAgIGVudmlyb25tZW50OgogICAgICAtICdDTElDS0hPVVNFX1VTRVI9JHtTRVJWSUNFX1VTRVJfQ0xJQ0tIT1VTRX0nCiAgICAgIC0gJ0NMSUNLSE9VU0VfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X0NMSUNLSE9VU0V9JwogICAgICAtIENMSUNLSE9VU0VfREVGQVVMVF9BQ0NFU1NfTUFOQUdFTUVOVD0xCiAgICB2b2x1bWVzOgogICAgICAtICdjbGlja2hvdXNlLWRhdGE6L3Zhci9saWIvY2xpY2tob3VzZScKICAgICAgLSAnY2xpY2tob3VzZS1sb2dzOi92YXIvbG9nL2NsaWNraG91c2Utc2VydmVyJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICd3Z2V0IC0tbm8tdmVyYm9zZSAtLXRyaWVzPTEgLS1zcGlkZXIgaHR0cDovL2xvY2FsaG9zdDo4MTIzL3BpbmcgfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogMTBzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDUK", "tags": [ - "trigger.dev", - "background jobs", + "background-jobs", "typescript", - "trigger", - "jobs", - "cron", - "scheduler" + "javascript", + "scheduling", + "workflows", + "automation", + "tasks", + "queues" ], "category": "automation", "logo": "svgs/trigger.png", From ccda7db54f9fe8f98f52f3c2d336dbe2503a03a9 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Wed, 7 Jan 2026 19:06:12 +0100 Subject: [PATCH 020/191] fix(service): supabase studio fails to load schemas --- templates/compose/supabase.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/templates/compose/supabase.yaml b/templates/compose/supabase.yaml index f6cb7897a..f265e3f09 100644 --- a/templates/compose/supabase.yaml +++ b/templates/compose/supabase.yaml @@ -280,7 +280,7 @@ services: config: hide_credentials: true supabase-studio: - image: supabase/studio:2025.12.17-sha-43f4f7f + image: supabase/studio:2026.01.07-sha-037e5f9 healthcheck: test: [ @@ -299,6 +299,8 @@ services: - HOSTNAME=0.0.0.0 - STUDIO_PG_META_URL=http://supabase-meta:8080 - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_HOST=${POSTGRES_HOST:-supabase-db} + - CURRENT_CLI_VERSION=2.67.1 - DEFAULT_ORGANIZATION_NAME=${STUDIO_DEFAULT_ORGANIZATION:-Default Organization} - DEFAULT_PROJECT_NAME=${STUDIO_DEFAULT_PROJECT:-Default Project} From 54a834e04288fc792c3856b52795974e2fe1cb22 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Wed, 7 Jan 2026 19:15:16 +0100 Subject: [PATCH 021/191] fix(git): trigger deployments when watch_paths is empty --- app/Http/Controllers/Webhook/Gitea.php | 2 +- app/Http/Controllers/Webhook/Github.php | 4 ++-- app/Http/Controllers/Webhook/Gitlab.php | 2 +- app/Jobs/ProcessGithubPullRequestWebhook.php | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/Webhook/Gitea.php b/app/Http/Controllers/Webhook/Gitea.php index b46db0b59..a9d65eae6 100644 --- a/app/Http/Controllers/Webhook/Gitea.php +++ b/app/Http/Controllers/Webhook/Gitea.php @@ -90,7 +90,7 @@ class Gitea extends Controller if ($x_gitea_event === 'push') { if ($application->isDeployable()) { $is_watch_path_triggered = $application->isWatchPathsTriggered($changed_files); - if ($is_watch_path_triggered || is_null($application->watch_paths)) { + if ($is_watch_path_triggered || blank($application->watch_paths)) { $deployment_uuid = new Cuid2; $result = queue_application_deployment( application: $application, diff --git a/app/Http/Controllers/Webhook/Github.php b/app/Http/Controllers/Webhook/Github.php index 8c912731f..e5a5b746e 100644 --- a/app/Http/Controllers/Webhook/Github.php +++ b/app/Http/Controllers/Webhook/Github.php @@ -101,7 +101,7 @@ class Github extends Controller if ($x_github_event === 'push') { if ($application->isDeployable()) { $is_watch_path_triggered = $application->isWatchPathsTriggered($changed_files); - if ($is_watch_path_triggered || is_null($application->watch_paths)) { + if ($is_watch_path_triggered || blank($application->watch_paths)) { $deployment_uuid = new Cuid2; $result = queue_application_deployment( application: $application, @@ -284,7 +284,7 @@ class Github extends Controller if ($x_github_event === 'push') { if ($application->isDeployable()) { $is_watch_path_triggered = $application->isWatchPathsTriggered($changed_files); - if ($is_watch_path_triggered || is_null($application->watch_paths)) { + if ($is_watch_path_triggered || blank($application->watch_paths)) { $deployment_uuid = new Cuid2; $result = queue_application_deployment( application: $application, diff --git a/app/Http/Controllers/Webhook/Gitlab.php b/app/Http/Controllers/Webhook/Gitlab.php index 34a5266ca..08e5d7162 100644 --- a/app/Http/Controllers/Webhook/Gitlab.php +++ b/app/Http/Controllers/Webhook/Gitlab.php @@ -122,7 +122,7 @@ class Gitlab extends Controller if ($x_gitlab_event === 'push') { if ($application->isDeployable()) { $is_watch_path_triggered = $application->isWatchPathsTriggered($changed_files); - if ($is_watch_path_triggered || is_null($application->watch_paths)) { + if ($is_watch_path_triggered || blank($application->watch_paths)) { $deployment_uuid = new Cuid2; $result = queue_application_deployment( application: $application, diff --git a/app/Jobs/ProcessGithubPullRequestWebhook.php b/app/Jobs/ProcessGithubPullRequestWebhook.php index 6c2f8e75c..041cd812c 100644 --- a/app/Jobs/ProcessGithubPullRequestWebhook.php +++ b/app/Jobs/ProcessGithubPullRequestWebhook.php @@ -107,7 +107,7 @@ class ProcessGithubPullRequestWebhook implements ShouldBeEncrypted, ShouldQueue // Apply watch path filtering $is_watch_path_triggered = $application->isWatchPathsTriggered($changed_files); - if (! $is_watch_path_triggered && ! is_null($application->watch_paths)) { + if (! $is_watch_path_triggered && ! blank($application->watch_paths)) { return; } From 233c79f5981f4779f2ed67f46a0feab1a5e2d97a Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 8 Jan 2026 16:29:08 +0100 Subject: [PATCH 022/191] fix(backup): database restores with custom db name --- app/Livewire/Project/Database/Import.php | 30 ++++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/app/Livewire/Project/Database/Import.php b/app/Livewire/Project/Database/Import.php index 2077ad66c..946368a39 100644 --- a/app/Livewire/Project/Database/Import.php +++ b/app/Livewire/Project/Database/Import.php @@ -147,7 +147,7 @@ class Import extends Component public ?int $activityId = null; - public string $postgresqlRestoreCommand = 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB'; + public string $postgresqlRestoreCommand = 'pg_restore -U $POSTGRES_USER -d ${POSTGRES_DB:\${POSTGRES_USER:-postgres}}'; public string $mysqlRestoreCommand = 'mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE'; @@ -231,10 +231,10 @@ for pid in $(mariadb -u root -p$MARIADB_ROOT_PASSWORD -N -e "SELECT id FROM info mariadb -u root -p$MARIADB_ROOT_PASSWORD -e "KILL $pid" 2>/dev/null || true done && \ mariadb -u root -p$MARIADB_ROOT_PASSWORD -N -e "SELECT CONCAT('DROP DATABASE IF EXISTS \`',schema_name,'\`;') FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema','sys');" | mariadb -u root -p$MARIADB_ROOT_PASSWORD && \ -mariadb -u root -p$MARIADB_ROOT_PASSWORD -e "CREATE DATABASE IF NOT EXISTS \`default\`;" && \ -(gunzip -cf $tmpPath 2>/dev/null || cat $tmpPath) | sed -e '/^CREATE DATABASE/d' -e '/^USE \`mysql\`/d' | mariadb -u root -p$MARIADB_ROOT_PASSWORD default +mariadb -u root -p$MARIADB_ROOT_PASSWORD -e "CREATE DATABASE IF NOT EXISTS \`${MARIADB_DATABASE:-default}\`;" && \ +(gunzip -cf $tmpPath 2>/dev/null || cat $tmpPath) | sed -e '/^CREATE DATABASE/d' -e '/^USE \`mysql\`/d' | mariadb -u root -p$MARIADB_ROOT_PASSWORD ${MARIADB_DATABASE:-default} EOD; - $this->restoreCommandText = $this->mariadbRestoreCommand.' && (gunzip -cf 2>/dev/null || cat ) | mariadb -u root -p$MARIADB_ROOT_PASSWORD default'; + $this->restoreCommandText = $this->mariadbRestoreCommand.' && (gunzip -cf 2>/dev/null || cat ) | mariadb -u root -p$MARIADB_ROOT_PASSWORD ${MARIADB_DATABASE:-default}'; } else { $this->mariadbRestoreCommand = 'mariadb -u $MARIADB_USER -p$MARIADB_PASSWORD $MARIADB_DATABASE'; } @@ -247,10 +247,10 @@ for pid in $(mysql -u root -p$MYSQL_ROOT_PASSWORD -N -e "SELECT id FROM informat mysql -u root -p$MYSQL_ROOT_PASSWORD -e "KILL $pid" 2>/dev/null || true done && \ mysql -u root -p$MYSQL_ROOT_PASSWORD -N -e "SELECT CONCAT('DROP DATABASE IF EXISTS \`',schema_name,'\`;') FROM information_schema.schemata WHERE schema_name NOT IN ('information_schema','mysql','performance_schema','sys');" | mysql -u root -p$MYSQL_ROOT_PASSWORD && \ -mysql -u root -p$MYSQL_ROOT_PASSWORD -e "CREATE DATABASE IF NOT EXISTS \`default\`;" && \ -(gunzip -cf $tmpPath 2>/dev/null || cat $tmpPath) | sed -e '/^CREATE DATABASE/d' -e '/^USE \`mysql\`/d' | mysql -u root -p$MYSQL_ROOT_PASSWORD default +mysql -u root -p$MYSQL_ROOT_PASSWORD -e "CREATE DATABASE IF NOT EXISTS \`${MYSQL_DATABASE:-default}\`;" && \ +(gunzip -cf $tmpPath 2>/dev/null || cat $tmpPath) | sed -e '/^CREATE DATABASE/d' -e '/^USE \`mysql\`/d' | mysql -u root -p$MYSQL_ROOT_PASSWORD ${MYSQL_DATABASE:-default} EOD; - $this->restoreCommandText = $this->mysqlRestoreCommand.' && (gunzip -cf 2>/dev/null || cat ) | mysql -u root -p$MYSQL_ROOT_PASSWORD default'; + $this->restoreCommandText = $this->mysqlRestoreCommand.' && (gunzip -cf 2>/dev/null || cat ) | mysql -u root -p$MYSQL_ROOT_PASSWORD ${MYSQL_DATABASE:-default}'; } else { $this->mysqlRestoreCommand = 'mysql -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE'; } @@ -259,13 +259,13 @@ EOD; case 'postgresql': if ($value === true) { $this->postgresqlRestoreCommand = <<<'EOD' -psql -U $POSTGRES_USER -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname IS NOT NULL AND pid <> pg_backend_pid()" && \ -psql -U $POSTGRES_USER -t -c "SELECT datname FROM pg_database WHERE NOT datistemplate" | xargs -I {} dropdb -U $POSTGRES_USER --if-exists {} && \ -createdb -U $POSTGRES_USER postgres +psql -U ${POSTGRES_USER} -c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname IS NOT NULL AND pid <> pg_backend_pid()" && \ +psql -U ${POSTGRES_USER} -t -c "SELECT datname FROM pg_database WHERE NOT datistemplate" | xargs -I {} dropdb -U ${POSTGRES_USER} --if-exists {} && \ +createdb -U ${POSTGRES_USER} ${POSTGRES_DB:\${POSTGRES_USER:-postgres}} EOD; - $this->restoreCommandText = $this->postgresqlRestoreCommand.' && (gunzip -cf 2>/dev/null || cat ) | psql -U $POSTGRES_USER postgres'; + $this->restoreCommandText = $this->postgresqlRestoreCommand.' && (gunzip -cf 2>/dev/null || cat ) | psql -U ${POSTGRES_USER} -d ${POSTGRES_DB:\${POSTGRES_USER:-postgres}}'; } else { - $this->postgresqlRestoreCommand = 'pg_restore -U $POSTGRES_USER -d $POSTGRES_DB'; + $this->postgresqlRestoreCommand = 'pg_restore -U ${POSTGRES_USER} -d ${POSTGRES_DB:\${POSTGRES_USER:-postgres}}'; } break; } @@ -739,7 +739,7 @@ EOD; case 'mariadb': $restoreCommand = $this->mariadbRestoreCommand; if ($this->dumpAll) { - $restoreCommand .= " && (gunzip -cf {$tmpPath} 2>/dev/null || cat {$tmpPath}) | mariadb -u root -p\$MARIADB_ROOT_PASSWORD"; + $restoreCommand .= " && (gunzip -cf {$tmpPath} 2>/dev/null || cat {$tmpPath}) | mariadb -u root -p\$MARIADB_ROOT_PASSWORD \${MARIADB_DATABASE:-default}"; } else { $restoreCommand .= " < {$tmpPath}"; } @@ -748,7 +748,7 @@ EOD; case 'mysql': $restoreCommand = $this->mysqlRestoreCommand; if ($this->dumpAll) { - $restoreCommand .= " && (gunzip -cf {$tmpPath} 2>/dev/null || cat {$tmpPath}) | mysql -u root -p\$MYSQL_ROOT_PASSWORD"; + $restoreCommand .= " && (gunzip -cf {$tmpPath} 2>/dev/null || cat {$tmpPath}) | mysql -u root -p\$MYSQL_ROOT_PASSWORD \${MYSQL_DATABASE:-default}"; } else { $restoreCommand .= " < {$tmpPath}"; } @@ -757,7 +757,7 @@ EOD; case 'postgresql': $restoreCommand = $this->postgresqlRestoreCommand; if ($this->dumpAll) { - $restoreCommand .= " && (gunzip -cf {$tmpPath} 2>/dev/null || cat {$tmpPath}) | psql -U \$POSTGRES_USER postgres"; + $restoreCommand .= " && (gunzip -cf {$tmpPath} 2>/dev/null || cat {$tmpPath}) | psql -U \${POSTGRES_USER} -d \${POSTGRES_DB:\${POSTGRES_USER:-postgres}}"; } else { $restoreCommand .= " {$tmpPath}"; } From 895c6b0e9a3ad849ec4853fa59dd5482bfa366cd Mon Sep 17 00:00:00 2001 From: Vincent Baeten Date: Thu, 8 Jan 2026 17:22:43 +0100 Subject: [PATCH 023/191] feat(service): add redmine template (#6429) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 🏔️ Peak <122374094+peaklabs-dev@users.noreply.github.com> --- public/svgs/redmine.svg | 22 ++++++++++++++++ templates/compose/redmine.yaml | 48 ++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 public/svgs/redmine.svg create mode 100644 templates/compose/redmine.yaml diff --git a/public/svgs/redmine.svg b/public/svgs/redmine.svg new file mode 100644 index 000000000..5c7bd0f2b --- /dev/null +++ b/public/svgs/redmine.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/templates/compose/redmine.yaml b/templates/compose/redmine.yaml new file mode 100644 index 000000000..23fe07bbe --- /dev/null +++ b/templates/compose/redmine.yaml @@ -0,0 +1,48 @@ +# documentation: https://www.redmine.org/ +# slogan: Redmine is a flexible project management web application. Written using the Ruby on Rails framework, it is cross-platform and cross-database. +# tags: redmine,project management +# logo: svgs/redmine.svg +# port: 3000 + +services: + redmine: + image: redmine:6-alpine + environment: + - SERVICE_FQDN_REDMINE_3000 + - SECRET_KEY_BASE=${SERVICE_PASSWORD_64_REDMINE} + - REDMINE_DB_POSTGRES=postgresql + - REDMINE_DB_PORT=5432 + - REDMINE_DB_USERNAME=${SERVICE_USER_POSTGRES} + - REDMINE_DB_PASSWORD=${SERVICE_PASSWORD_64_POSTGRES} + - REDMINE_DB_DATABASE=${POSTGRES_DATABASE:-redmine-db} + healthcheck: + test: + - CMD-SHELL + - "wget -qO- http://127.0.0.1:3000/" + interval: 5s + timeout: 5s + retries: 5 + volumes: + - redmine-config:/usr/src/redmine/config + - redmine-files:/usr/src/redmine/files + - redmine-themes:/usr/src/redmine/themes + - redmine-plugins:/usr/src/redmine/plugins + depends_on: + postgresql: + condition: service_healthy + + postgresql: + image: postgres:17-alpine + environment: + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_64_POSTGRES} + - POSTGRES_DB=${POSTGRES_DATABASE:-redmine-db} + volumes: + - postgresql-data:/var/lib/postgresql/data + healthcheck: + test: + - CMD-SHELL + - "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}" + interval: 5s + timeout: 5s + retries: 5 From 582afc1c8bb318072502d5e98b0320b4a86306d7 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik <37010174+vitabaks@users.noreply.github.com> Date: Thu, 8 Jan 2026 19:58:15 +0300 Subject: [PATCH 024/191] feat(service): add autobase template (#6299) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 🏔️ Peak <122374094+peaklabs-dev@users.noreply.github.com> --- CHANGELOG.md | 12824 ++++++++++++++++++------------ public/svgs/autobase.svg | 3 + templates/compose/autobase.yaml | 59 + 3 files changed, 8015 insertions(+), 4871 deletions(-) create mode 100644 public/svgs/autobase.svg create mode 100644 templates/compose/autobase.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c890e3ba..dc4c054c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,794 +6,7 @@ All notable changes to this project will be documented in this file. ### 🚀 Features -- Use tags in update -- New update process (#115) -- VaultWarden service -- Www <-> non-www redirection for apps -- Www <-> non-www redirection -- Follow logs -- Generate www & non-www SSL certs -- Basic password reset form -- Scan for lock files and set right commands -- Public port range (WIP) -- Ports range -- Random subdomain for demo -- Random domain for services -- Astro buildpack -- 11ty buildpack -- Registration page -- Languagetool service -- Send version with update request -- Service secrets -- Webhooks inititate all applications with the correct branch -- Check ssl for new apps/services first -- Autodeploy pause -- Install pnpm into docker image if pnpm lock file is used -- Add PHP modules -- Use compose instead of normal docker cmd -- Be able to redeploy PRs -- Add n8n.io service -- Add update kuma service -- Ghost service -- Initial python support -- Add loading on register button -- *(dev)* Allow windows users to use pnpm dev -- MeiliSearch service -- Add abilitry to paste env files -- Wordpress on-demand SFTP -- Finalize on-demand sftp for wp -- PHP Composer support -- Working on-demand sftp to wp data -- Admin team sees everything -- Able to change service version/tag -- Basic white labeled version -- Able to modify database passwords -- Add persistent storage for services -- Multiply dockerfile locations for docker buildpack -- Testing fluentd logging driver -- Fluentbit investigation -- Initial deno support -- Deno DB migration -- Show exited containers on UI & better UX -- Query container state periodically -- Install svelte-18n and init setup -- Umami service -- Coolify auto-updater -- Autoupdater -- Select base image for buildpacks -- Hasura as a service -- Gzip compression -- Laravel buildpack is working! -- Laravel -- Fider service -- Database and services logs -- DNS check settings for SSL generation -- Cancel builds! -- Basic server usage on dashboard -- Show usage trends -- Usage on dashboard -- Custom script path for Plausible -- WP could have custom db -- Python image selection -- PageLoader -- Database + service usage -- Ability to change deployment type for nextjs -- Ability to change deployment type for nuxtjs -- Gitpod ready code(almost) -- Add Docker buildpack exposed port setting -- Custom port for git instances -- Gitpod integration -- Init moodle and separate stuffs to shared package -- Moodle init -- Remote docker engine init -- Working on remote docker engine -- Rde -- Remote docker engine -- Ipv4 and ipv6 -- Contributors -- Add arch to database -- Stop preview deployment -- Persistent storage for all services -- Cleanup clickhouse db -- Init heroku buildpacks -- Databases on ARM -- Mongodb arm support -- New dashboard -- Appwrite service -- Heroku deployments -- Deploy bots (no domains) -- Custom dns servers -- Import public repos (wip) -- Public repo deployment -- Force rebuild + env.PORT for port + public repo build -- Add GlitchTip service -- Searxng service -- *(ui)* Rework home UI and with responsive design -- New service - weblate -- Restart application -- Show elapsed time on running builds -- Github allow fual branches -- Gitlab dual branch -- Taiga -- *(routes)* Rework ui from login and register page -- Add traefik acme json to coolify container -- Database secrets -- New servers view -- Add queue reset button -- Previewapplications init -- PreviewApplications finalized -- Fluentbit -- Show remote servers -- *(layout)* Added drawer when user is in mobile -- Re-apply ui improves -- *(ui)* Improve header of pages -- *(styles)* Make header css component -- *(routes)* Improve ui for apps, databases and services logs -- Add migration button to appwrite -- Custom certificate -- Ssl cert on traefik config -- Refresh resource status on dashboard -- Ssl certificate sets custom ssl for applications -- System-wide github apps -- Cleanup unconfigured applications -- Cleanup unconfigured services and databases -- Docker compose support -- Docker compose -- Docker compose -- Monitoring by container -- Initial support for specific git commit -- Add default to latest commit and support for gitlab -- Redirect catch-all rule -- Rollback coolify -- Only show expose if no proxy conf defined in template -- Custom/private docker registries -- Use registry for building -- Docker registries working -- Custom docker compose file location in repo -- Save doNotTrackData to db -- Add default sentry -- Do not track in settings -- System wide git out of beta -- Custom previewseparator -- Sentry frontend -- Able to host static/php sites on arm -- Save application data before deploying -- SimpleDockerfile deployment -- Able to push image to docker registry -- Revert to remote image -- *(api)* Name label -- Add Openblocks icon -- Adding icon for whoogle -- *(ui)* Add libretranslate service icon -- Handle invite_only plausible analytics -- Init h2c (http2/grpc) support -- Http + h2c paralel -- Github raw icon url -- Remove svg support -- Add host path to any container -- Able to control multiplexing -- Add runRemoteCommandSync -- Github repo with deployment key -- Add persistent volumes -- Debuggable executeNow commands -- Add private gh repos -- Delete gh app -- Installation/update github apps -- Auto-deploy -- Deploy key based deployments -- Resource limits -- Long running queue with 1 hour of timeout -- Add arm build to dev -- Disk cleanup threshold by server -- Notify user of disk cleanup init -- Pricing plans ans subs -- Add s3 storages -- Init postgresql database -- Add backup notifications -- Dockerfile build pack -- Cloud -- Force password reset + waitlist -- Send internal notification to discord -- Monitor server connection -- Invite by email from waitlist -- Rolling update -- Add resend as transactional emails -- Send request in cloud -- Add discord notifications -- Public database -- Telegram topics separation -- Developer view for env variables -- Cache team settings -- Generate public key from private keys -- Able to invite more people at once -- Trial -- Dynamic trial period -- Ssh-agent instead of filesystem based ssh keys -- New container status checks -- Generate ssh key -- Sentry add email for better support -- Healthcheck for apps -- Add cloudflare tunnel support -- Services -- Image tag for services -- Container logs -- Reset root password -- Attach Coolify defined networks to services -- Delete resource command -- Multiselect removable resources -- Disable service, required version -- Basedir / monorepo initial support -- Init version of any git deployment -- Deploy private repo with ssh key -- Add email verification for cloud -- Able to deploy docker images -- Add dockerfile location -- Proxy logs on the ui -- Add custom redis conf -- Use docker login credentials from server -- Able to customize docker labels on applications -- Show if config is not applied -- Standalone mongodb -- Cloning project -- Api tokens + deploy webhook -- Start all kinds of things -- Simple search functionality -- Mysql, mariadb -- Lock environment variables -- Download local backups -- Improve deployment time by a lot -- Deployment logs fullscreen -- Service database backups -- Make service databases public -- Log drain (wip) -- Enable/disable log drain by service -- Log drainer container check -- Add docker engine support install script to rhel based systems -- Save timestamp configuration for logs -- Custom log drain endpoints -- Auto-restart tcp proxies for databases -- Execute command in container -- Autoupdate env during seed -- Disable autoupdate -- Randomly sleep between executions -- Pull latest images for services -- Custom docker compose commands -- Add environment description + able to change name -- Raw docker compose deployments -- Add www-non-www redirects to traefik -- Import backups -- Search between resources -- Move resources between projects / environments -- Clone any resource -- Shared environments -- Concurrent builds / server -- Able to deploy multiple resources with webhook -- Add PR comments -- Dashboard live deployment view -- Added manual webhook support for bitbucket -- Add initial support for custom docker run commands -- Cleanup unreachable servers -- Tags and tag deploy webhooks -- Clone to env -- Multi deployments -- Cleanup queue -- Magic for traefik redirectregex in services -- Revalidate server -- Disable gzip compression on service applications -- Save github app permission locally -- Minversion for services -- Able to add dynamic configurations from proxy dashboard -- Custom server limit -- Delay container/server jobs -- Add static ipv4 ipv6 support -- Server disabled by overflow -- Preview deployment logs -- Collect webhooks during maintenance -- Logs and execute commands with several servers -- Domains api endpoint -- Resources api endpoint -- Team api endpoint -- Add deployment details to deploy endpoint -- Add deployments api -- Experimental caddy support -- Dynamic configuration for caddy -- Reset password -- Show resources on source page -- Able to run scheduler/horizon programatically -- Change page width -- Watch paths -- Able to make rsa/ed ssh keys -- *(application)* Update submodules after git checkout -- Add amazon linux 2023 -- Upload large backups -- Edit domains easier for compose -- Able to delete configuration from server -- Configuration checker for all resources -- Allow tab in textarea -- Dynamic mux time -- Literal env variables -- Lazy load stuffs + tell user if compose based deployments have missing envs -- Can edit file/dir volumes from ui in compose based apps -- Upgrade Appwrite service template to 1.5 -- Upgrade Appwrite service template to 1.5 -- Add db name to backup notifications -- Initial datalist -- Update service contribution docs URL -- The final pricing plan, pay-as-you-go -- Add container name to network aliases in ApplicationDeploymentJob -- Add lazy loading for images in General.php and improve Docker Compose file handling in Application.php -- Experimental sentinel -- Start Sentinel on servers. -- Pull new sentinel image and restart container -- Init metrics -- Add AdminRemoveUser command to remove users from the database -- Adding new COOLIFY_ variables -- Save commit message and better view on deployments -- Toggle label escaping mechanism -- Shows the latest deployment commit + message on status -- New manual update process + remove next_channel -- Add lastDeploymentInfo and lastDeploymentLink props to breadcrumbs and status components -- Sort envs alphabetically and creation date -- Improve sorting of environment variables in the All component -- Update healthcheck test in StartMongodb action -- Add pull_request_id filter to get_last_successful_deployment method in Application model -- Add hc logs to healthchecks -- Add SerpAPI as a Github Sponsor -- Admin view for deleting users -- Scheduled task failed notification -- If the time seems too long it remains at 0s -- Improve Docker Engine start logic in ServerStatusJob -- If proxy stopped manually, it won't start back again -- Exclude_from_hc magic -- Gitea manual webhooks -- Add container logs in case the container does not start healthy -- Handle incomplete expired subscriptions in Stripe webhook -- Add more persistent storage types -- Add PHP memory limit environment variable to docker-compose.prod.yml -- Add manual update option to UpdateCoolify handle method -- Add port configuration for Vaultwarden service -- Able to change database passwords on the UI. It won't sync to the database. -- Able to add several domains to compose based previews -- Add bounty program link to bug report template -- Add titles -- Db proxy logs -- Easily redirect between www-and-non-www domains -- Add logos for new sponsors -- Add homepage template -- Update homepage.yaml with environment variables and volumes -- Spanish translation -- Cancelling a deployment will check if new could be started. -- Add supaguide logo to donations section -- Nixpacks now could reach local dbs internally -- Add Tigris logo to other/logos directory -- COOLIFY_CONTAINER_NAME predefined variable -- Charts -- Sentinel + charts -- Container metrics -- Add high priority queue -- Add metrics warning for servers without Sentinel enabled -- Add blacksmith logo to donations section -- Preselect server and destination if only one found -- More api endpoints -- Add API endpoint to update application by UUID -- Update statusnook logo filename in compose template -- Local fonts -- More API endpoints -- Bulk env update api endpoint -- Update server settings metrics history days to 7 -- New app API endpoint -- Private gh deployments through api -- Lots of api endpoints -- Api api api api api api -- Rename CloudCleanupSubs to CloudCleanupSubscriptions -- Early fraud warning webhook -- Improve internal notification message for early fraud warning webhook -- Add schema for uuid property in app update response -- Cleanup unused docker networks from proxy -- Compose parser v2 -- Display time interval for rollback images -- Add security and storage access key env to twenty template -- Add new logo for Latitude -- Enable legacy model binding in Livewire configuration -- Improve error handling in loadComposeFile method -- Add readonly labels -- Preserve git repository -- Force cleanup server -- Create/delete project endpoints -- Add patch request to projects -- Add server api endpoints -- Add branddev logo to README.md -- Update API endpoint summaries -- Update Caddy button label in proxy.blade.php -- Check custom internal name through server's applications. -- New server check job -- Delete team in cloud without subscription -- Coolify init should cleanup stuck networks in proxy -- Add manual update check functionality to settings page -- Update auto update and update check frequencies in settings -- Update Upgrade component to check for latest version of Coolify -- Improve homepage service template -- Support map fields in Directus -- Labels by proxy type -- Able to generate only the required labels for resources -- Preserve git repository with advanced file storages -- Added Windmill template -- Added Budibase template -- Add shm-size for custom docker commands -- Add custom docker container options to all databases -- Able to select different postgres database -- Add new logos for jobscollider and hostinger -- Order scheduled task executions -- Add Code Server environment variables to Service model -- Add coolify build env variables to building phase -- Add new logos for GlueOps, Ubicloud, Juxtdigital, Saasykit, and Massivegrid -- Add new logos for GlueOps, Ubicloud, Juxtdigital, Saasykit, and Massivegrid -- Update server_settings table to force docker cleanup -- Update Docker Compose file with DB_URL environment variable -- Refactor shared.php to improve environment variable handling -- Expose project description in API response -- Add elixir finetunes to the deployment job -- Make coolify full width by default -- Fully functional terminal for command center -- Custom terminal host -- Add buddy logo -- Add nullable constraint to 'fingerprint' column in private_keys table -- *(api)* Add an endpoint to execute a command -- *(api)* Add endpoint to execute a command -- Add ContainerStatusTypes enum for managing container status -- Allow specify use_build_server when creating/updating an application -- Add support for `use_build_server` in API endpoints for creating/updating applications -- Add Mixpost template -- Update resource deletion job to allow configurable options through API -- Add query parameters for deleting configurations, volumes, docker cleanup, and connected networks -- Add command to check application deployment queue -- Support Hetzner S3 -- Handle HTTPS domain in ConfigureCloudflareTunnels -- Backup all databases for mysql,mariadb,postgresql -- Restart service without pulling the latest image -- Add strapi template -- Add it-tools service template and logo -- Add homarr service tamplate and logo -- Add Argilla service configuration to Service model -- Add Invoice Ninja service configuration to Service model -- Project search on frontend -- Add ollama service with open webui and logo -- Update setType method to use slug value for type -- Refactor setType method to use slug value for type -- Refactor setType method to use slug value for type -- Add Supertokens template -- Add easyappointments service template -- Add dozzle template -- Adds forgejo service with runners -- Add Mautic 4 and 5 to service templates -- Add keycloak template -- Add onedev template -- Improve search functionality in project selection -- Add customHelper to stack-form -- Add cloudbeaver template -- Add ntfy template -- Add qbittorrent template -- Add Homebox template -- Add owncloud service and logo -- Add immich service -- Auto generate url -- Refactored to work with coolify auto env vars -- Affine service template and logo -- Add LibreTranslate template -- Open version in a new tab -- Add Transmission template -- Add transmission healhcheck -- Add zipline template -- Dify template -- Required envs -- Add EdgeDB -- Show warning if people would like to use sslip with https -- Add is shared to env variables -- Variabel sync and support shared vars -- Add notification settings to server_disk_usage -- Add coder service tamplate and logo -- Debug mode for sentinel -- Add jitsi template -- Add --gpu support for custom docker command -- Add Firefox template -- Add template for Wiki.js -- Add upgrade logs to /data/coolify/source -- Custom nginx configuration for static deployments + fix 404 redirects in nginx conf -- Check local horizon scheduler deployments -- Add internal api docs to /docs/api with auth -- Add proxy type change to create/update apis -- Add MacOS template -- Add Windows template -- *(service)* :sparkles: add mealie -- Add hex magic env var -- Add deploy-only token permission -- Able to deploy without cache on every commit -- Update private key nam with new slug as well -- Allow disabling default redirect, set status to 503 -- Add TLS configuration for default redirect in Server model -- Slack notifications -- Introduce root permission -- Able to download schedule task logs -- Migrate old email notification settings from the teams table -- Migrate old discord notification settings from the teams table -- Migrate old telegram notification settings from the teams table -- Add slack notifications to a new table -- Enable success messages again -- Use new notification stuff inside team model -- Some more notification settings and better defaults -- New email notification settings -- New shared function name `is_transactional_emails_enabled()` -- New shared notifications functions -- Email Notification Settings Model -- Telegram notification settings Model -- Discord notification settings Model -- Slack notification settings Model -- New Discord notification UI -- New Slack notification UI -- New telegram UI -- Use new notification event names -- Always sent notifications -- Scheduled task success notification -- Notification trait -- Get discord Webhook form new table -- Get Slack Webhook form new table -- Use new table or instance settings for email -- Use new place for settings and topic IDs for telegram -- Encrypt instance email settings -- Use encryption in instance settings model -- Scheduled task success and failure notifications -- Add docker cleanup success and failure notification settings columns -- UI for docker cleanup success and failure notification -- Docker cleanup email views -- Docker cleanup success and failure notification files -- Scheduled task success email -- Send new docker cleanup notifications -- :passport_control: integrate Authentik authentication with Coolify -- *(notification)* Add Pushover -- Add seeder command and configuration for database seeding -- Add new password magic env with symbols -- Add documenso service -- New ServerReachabilityChanged event -- Use new ServerReachabilityChanged event instead of isDirty -- Add infomaniak oauth -- Add server disk usage check frequency -- Add environment_uuid support and update API documentation -- Add service/resource/project labels -- Add coolify.environment label -- Add database subtype -- Migrate to new encryption options -- New encryption options -- Able to import full db backups for pg/mysql/mariadb -- Restore backup from server file -- Docker volume data cloning -- Move volume data cloning to a Job -- Volume cloning for ResourceOperations -- Remote server volume cloning -- Add horizon server details to queue -- Enhance horizon:manage command with worker restart check -- Add is_coolify_host to the server api responses -- DB migration for Backup retention -- UI for backup retention settings -- New global s3 and local backup deletion function -- Use new backup deletion functions -- Add calibre-web service -- Add actual-budget service -- Add rallly service -- Template for Gotenberg, a Docker-powered stateless API for PDF files -- Enhance import command options with additional guidance and improved checkbox label -- Purify for better sanitization -- Move docker cleanup to its own tab -- DB and Model for docker cleanup executions -- DockerCleanupExecutions relationship -- DockerCleanupDone event -- Get command and output for logs from CleanupDocker -- New sidebar menu and order -- Docker cleanup executions UI -- Add execution log to dockerCleanupJob -- Improve deployment UI -- Root user envs and seeding -- Email, username and password validation when they are set via envs -- Improved error handling and log output -- Add root user configuration variables to production environment -- Add log file check message in upgrade script for better troubleshooting -- Add root user details to install script -- *(core)* Wip version of coolify.json -- *(core)* Add SOURCE_COMMIT variable to build environment in ApplicationDeploymentJob -- *(service)* Update affine.yaml with AI environment variables (#4918) -- *(service)* Add new service Flipt (#4875) -- *(docs)* Update tech stack -- *(terminal)* Show terminal unavailable if the container does not have a shell on the global terminal UI -- *(ui)* Improve deployment UI -- *(template)* Add Open Web UI -- *(templates)* Add Open Web UI service template -- *(ui)* Update GitHub source creation advanced section label -- *(core)* Add dynamic label reset for application settings -- *(ui)* Conditionally enable advanced application settings based on label readonly status -- *(env)* Added COOLIFY_RESOURCE_UUID environment variable -- *(vite)* Add Cloudflare async script and style tag attributes -- *(meta)* Add comprehensive SEO and social media meta tags -- *(core)* Add name to default proxy configuration -- Add application api route -- Container logs -- Remove ansi color from log -- Add lines query parameter -- *(changelog)* Add git cliff for automatic changelog generation -- *(workflows)* Improve changelog generation and workflows -- *(ui)* Add periodic status checking for services -- *(deployment)* Ensure private key is stored in filesystem before deployment -- *(slack)* Show message title in notification previews (#5063) -- *(i18n)* Add Arabic translations (#4991) -- *(i18n)* Add French translations (#4992) -- *(services)* Update `service-templates.json` -- *(ui)* Add top padding to pricing plans view -- *(core)* Add error logging and cron parsing to docker/server schedules -- *(core)* Prevent using servers with existing resources as build servers -- *(ui)* Add textarea switching option in service compose editor -- *(ui)* Add wire:key to two-step confirmation settings -- *(database)* Add index to scheduled task executions for improved query performance -- *(database)* Add index to scheduled database backup executions -- *(billing)* Add Stripe past due subscription status tracking -- *(ui)* Add past due subscription warning banner -- *(service)* Neon -- *(migration)* Add `ssl_certificates` table and model -- *(migration)* Add ssl setting to `standalone_postgresqls` table -- *(ui)* Add ssl settings to Postgres ui -- *(db)* Add ssl mode to Postgres URLs -- *(db)* Setup ssl during Postgres start -- *(migration)* Encrypt local file volumes content and paths -- *(ssl)* Ssl generation helper -- *(ssl)* Migrate to `ECC`certificates using `secp521r1` -- *(ssl)* Improve SSL helper -- *(ssl)* Add a Coolify CA Certificate to all servers -- *(seeder)* Call CA SSL seeder in prod and dev -- *(ssl)* Add Coolify CA Certificate when adding a new server -- *(installer)* Create CA folder during installation -- *(ssl)* Improve SSL helper -- *(ssl)* Use new improved helper for SSL generation -- *(ui)* Add CA cert UI -- *(ui)* New copy button component -- *(ui)* Use new copy button component everywhere -- *(ui)* Improve server advanced view -- *(migration)* Add CN and alternative names to DB -- *(databases)* Add CA SSL crt location to Postgres URLs -- *(ssl)* Improve ssl generation -- *(ssl)* Regenerate SSL certs job -- *(ssl)* Regenerate certificate and valid until UI -- *(ssl)* Regenerate CA cert and all other certs logic -- *(ssl)* Add full MySQL SSL Support -- *(ssl)* Add full MariaDB SSL support -- *(ssl)* Add `openssl.conf` to configure SSL extension properly -- *(ssl)* Improve SSL generation and security a lot -- *(ssl)* Check for SSL renewal twice daily -- *(ssl)* Add SSL relationships to all DBs -- Add full SSL support to MongoDB -- *(ssl)* Fix some issues and improve ssl generation helper -- *(ssl)* Ability to create `.pem` certs and add `clientAuth` to `extendedKeyUsage` -- *(ssl)* New modes for MongoDB and get `caCert` and `mountPath` correctly -- *(ssl)* Full SSL support for Redis -- New mode implementation for MongoDB -- *(ssl)* Improve Redis and remove modes -- Full SSL support for DrangonflyDB -- SSL notification -- *(github-source)* Enhance GitHub App configuration with manual and private key support -- *(ui)* Improve GitHub repository selection and styling -- *(database)* Implement two-step confirmation for database deletion -- *(assets)* Add new SVG logo for Coolify -- *(install)* Enhance Docker address pool configuration and validation -- *(install)* Improve Docker address pool management and service restart logic -- *(install)* Add missing env variable to install script -- *(LocalFileVolume)* Add binary file detection and update UI logic -- *(templates)* Change glance for v0.7 -- *(templates)* Add Freescout service template -- *(service)* Add Evolution API template -- *(service)* Add evolution-api and neon-ws-proxy templates -- *(svg)* Add coolify and evolution-api SVG logos -- *(api)* Add api to create custom services -- *(api)* Separate create and one-click routes -- *(api)* Update Services api routes and handlers -- *(api)* Unify service creation endpoint and enhance validation -- *(notifications)* Add discord ping functionality and settings -- *(user)* Implement session deletion on password reset -- *(github)* Enhance repository loading and validation in applications -- *(database)* Disable MongoDB SSL by default in migration -- *(database)* Add CA certificate generation for database servers -- *(application)* Add SPA configuration and update Nginx generation logic -- *(deployments)* Add list application deployments api route -- *(deploy)* Add pull request ID parameter to deploy endpoint -- *(api)* Add pull request ID parameter to applications endpoint -- *(api)* Add endpoints for retrieving application logs and deployments -- *(lang)* Added Norwegian language (#5280) -- *(dep)* Bump all dependencies -- *(lang)* Added Azerbaijani language updated turkish language. (#5497) -- *(lang)* Added Portuguese from Brazil language (#5500) -- *(lang)* Add Indonesian language translations (#5513) -- *(api)* Update OpenAPI spec for services (#5448) -- *(proxy)* Enhance proxy handling and port conflict detection -- *(Deploy)* Add info dispatch for proxy check initiation -- *(EnvironmentVariable)* Add handling for Redis credentials in the environment variable component -- *(EnvironmentVariable)* Implement protection for critical environment variables and enhance deletion logic -- *(Application)* Add networkAliases attribute for handling network aliases as JSON or comma-separated values -- *(GithubApp)* Update default events to include 'pull_request' and streamline event handling -- *(CleanupDocker)* Add support for realtime image management in Docker cleanup process -- *(Deployment)* Enhance queue_application_deployment to handle existing deployments and return appropriate status messages -- *(SourceManagement)* Add functionality to change Git source and display current source in the application settings -- *(OpenApi)* Enhance OpenAPI specifications by adding UUID parameters for application, project, and service updates; improve deployment listing with pagination parameters; update command signature for OpenApi generation -- *(subscription)* Enhance subscription management with loading states and Stripe status checks -- Add HTTP Basic Authentication -- *(readme)* Add new sponsors Supadata AI and WZ-IT to the README -- *(core)* Enable magic env variables for compose based applications -- *(deployment)* Add repository_project_id handling for private GitHub apps and clean up unused Caddy label logic -- *(api)* Enhance OpenAPI specifications with token variable and additional key attributes -- *(docker)* Add HTTP Basic Authentication support and enhance hostname parsing in Docker run conversion -- *(api)* Add HTTP Basic Authentication fields to OpenAPI specifications and enhance PrivateKey model descriptions -- *(README)* Add InterviewPal sponsorship link and corresponding SVG icon -- *(migration)* Add 'is_migrated' and 'custom_type' columns to service_applications and service_databases tables -- *(backup)* Implement custom database type selection and enhance scheduled backups management -- *(README)* Add Gozunga and Macarne to sponsors list -- *(redis)* Add scheduled cleanup command for Redis keys and enhance cleanup logic -- *(core)* Add 'postmarketos' to supported OS list -- *(service)* Add memos service template (#5032) -- *(ui)* Upgrade to Tailwind v4 (#5710) -- *(service)* Add Navidrome service template (#5022) -- *(service)* Add Passbolt service (#5769) -- *(service)* Add Vert service (#5663) -- *(service)* Add Ryot service (#5232) -- *(service)* Add Marimo service (#5559) -- *(service)* Add Diun service (#5113) -- *(service)* Add Observium service (#5613) -- *(service)* Add Leantime service (#5792) -- *(service)* Add Limesurvey service (#5751) -- *(service)* Add Paymenter service (#5809) -- *(service)* Add CodiMD service (#4867) -- *(modal)* Add dispatchAction property to confirmation modal -- *(security)* Implement server patching functionality -- *(service)* Add Typesense service (#5643) -- *(service)* Add Yamtrack service (#5845) -- *(service)* Add PG Back Web service (#5079) -- *(service)* Update Maybe service and adjust it for the new release (#5795) -- *(oauth)* Set redirect uri as optional and add default value (#5760) -- *(service)* Add apache superset service (#4891) -- *(service)* Add One Time Secret service (#5650) -- *(service)* Add Seafile service (#5817) -- *(service)* Add Netbird-Client service (#5873) -- *(service)* Add OrangeHRM and Grist services (#5212) -- *(rules)* Add comprehensive documentation for Coolify architecture and development practices for AI tools, especially for cursor -- *(server)* Implement server patch check notifications -- *(api)* Add latest query param to Service restart API (#5881) -- *(api)* Add connect_to_docker_network setting to App creation API (#5691) -- *(routes)* Restrict backup download access to team admins and owners -- *(destination)* Update confirmation modal text and add persistent storage warning for server deployment -- *(terminal-access)* Implement terminal access control for servers and containers, including UI updates and backend logic -- *(ca-certificate)* Add CA certificate management functionality with UI integration and routing -- *(security-patches)* Add update check initialization and enhance notification messaging in UI -- *(previews)* Add force deploy without cache functionality and update deploy method to accept force rebuild parameter -- *(security-patterns)* Expand sensitive patterns list to include additional security-related variables -- *(database-backup)* Add MongoDB credential extraction and backup handling to DatabaseBackupJob -- *(activity-monitor)* Implement auto-scrolling functionality and dynamic content observation for improved user experience -- *(utf8-handling)* Implement UTF-8 sanitization for command outputs and enhance error handling in logs processing -- *(navbar)* Add Traefik dashboard availability check and server IP handling; refactor dynamic configurations loading -- *(proxy-dashboard)* Implement ProxyDashboardCacheService to manage Traefik dashboard cache; clear cache on configuration changes and proxy actions -- *(terminal-connection)* Enhance terminal connection handling with auto-connect feature and improved status messaging -- *(terminal)* Implement resize handling with ResizeObserver for improved terminal responsiveness -- *(migration)* Add is_sentinel_enabled column to server_settings with default true -- *(seeder)* Dispatch StartProxy action for each server in ProductionSeeder -- *(seeder)* Add CheckAndStartSentinelJob dispatch for each server in ProductionSeeder -- *(seeder)* Conditionally dispatch StartProxy action based on proxy check result -- *(service)* Update Changedetection template (#5937) -- *(service)* Add Miniflux service (#5843) -- *(service)* Add Pingvin Share service (#5969) -- *(auth)* Add Discord OAuth Provider (#5552) -- *(auth)* Add Clerk OAuth Provider (#5553) -- *(auth)* Add Zitadel OAuth Provider (#5490) -- *(core)* Set custom API rate limit (#5984) -- *(service)* Enhance service status handling and UI updates -- *(cleanup)* Add functionality to delete teams with no members or servers in CleanupStuckedResources command -- *(ui)* Add heart icon and enhance popup messaging for sponsorship support -- *(settings)* Add sponsorship popup toggle and corresponding database migration -- *(migrations)* Add optimized indexes to activity_log for improved query performance -- *(template)* Added excalidraw (#6095) -- *(template)* Add excalidraw service configuration with documentation and tags -- *(scheduling)* Add command to manually run scheduled database backups and tasks with options for chunking, delays, and dry runs +- Add Autobase service template - *(scheduling)* Add frequency filter option for manual execution of scheduled jobs - *(logging)* Implement scheduled logs command and enhance backup/task scheduling with cron checks - *(logging)* Add frequency filters for scheduled logs command to support hourly, daily, weekly, and monthly job views @@ -868,7 +81,7 @@ All notable changes to this project will be documented in this file. - *(policies)* Add EnvironmentVariablePolicy for managing environment variables ( it was missing ) - *(domains)* Implement domain conflict detection and user confirmation modal across application components - *(domains)* Add force_domain_override option and enhance domain conflict detection responses -- Add Ente Photos service template +- Improve detection of special network modes - *(command)* Add option to sync GitHub releases to BunnyCDN and refactor sync logic - *(ui)* Display current version in settings dropdown and update UI accordingly - *(settings)* Add option to restrict PR deployments to repository members and contributors @@ -903,7 +116,6 @@ All notable changes to this project will be documented in this file. - *(search)* Enable query logging for global search caching - *(environment)* Add dynamic checkbox options for environment variable settings based on user permissions and variable types - *(redaction)* Implement sensitive information redaction in logs and commands -- Improve detection of special network modes - *(api)* Add endpoint to update backup configuration by UUID and backup ID; modify response to include backup id - *(databases)* Enhance backup management API with new endpoints and improved data handling - *(github)* Add GitHub app management endpoints @@ -917,6 +129,7 @@ All notable changes to this project will be documented in this file. - *(private-key-refresh)* Add refresh dispatch on private key update and connection check - *(comments)* Add automated comments for labeled pull requests to guide documentation updates - *(comments)* Ping PR author +- Add Ente Photos service template - *(add-watch-paths-for-services)* Show watch paths field for docker compose applications - *(application)* Implement order-based pattern matching for watch paths with negation support - *(github)* Enhance Docker Compose input fields for better user experience @@ -1170,2590 +383,17 @@ All notable changes to this project will be documented in this file. - *(service)* Upgrade docker registry template (#7034) - *(service)* Add esphome template (#6532) - *(service)* Add hatchet template (#6711) -- *(service)* Improve sftpgo +- *(service)* Add sftpgo template (#6415) +- *(service)* Add cloudreve template (#6774) +- *(service)* Add silverbullet template (#6425) +- *(ui)* Add port mapping format to helper and fix typo +- *(service)* Add nocobase template (#7347) +- *(api)* Allow to escape special characters in labels (#7886) +- *(service)* Upgrade trigger template to v4 (#7808) +- *(service)* Add redmine template (#6429) ### 🐛 Bug Fixes -- Secrets join -- ENV variables set differently -- Capture non-error as error -- Only delete id.rsa in case of it exists -- Status is not available yet -- Docker Engine bug related to live-restore and IPs -- Version -- PreventDefault on a button, thats all -- Haproxy check should not throw error -- Delete all build files -- Cleanup images -- More error handling in proxy configuration + cleanups -- Local static assets -- Check sentry -- Typo -- Package.json -- Build secrets should be visible in runtime -- New secret should have default values -- Validate secrets -- Truncate git clone errors -- Branch used does not throw error -- Typo -- Error handling -- Stopping service without proxy -- Coolify proxy start -- Window error in SSR -- GitHub sync PR's -- Load more button -- Small fixes -- Typo -- Error with follow logs -- IsDomainConfigured -- TransactionIds -- Coolify image cleanup -- Cleanup every 10 mins -- Cleanup images -- Add no user redis to uri -- Secure cookie disabled by default -- Buggy svelte-kit-cookie-session -- Login issues -- SSL app off -- Local docker host -- Typo -- Lets encrypt -- Remove SSL with stop -- SSL off for services -- Grr -- Running state css -- Minor fixes -- Remove force SSL when doing let's encrypt request -- GhToken in session now -- Random port for certbot -- Follow icon -- Plausible volume fixed -- Database connection strings -- Gitlab webhooks fixed -- If DNS not found, do not redirect -- Github token -- Move tokens from session to cookie/store -- Email is lowercased in login -- Lowercase email everywhere -- Use normal docker-compose in dev -- Random network name for demo -- Settings fqdn grr -- Revert default network -- Http for demo, oops -- Docker scanner -- Improvement on image pulls -- Coolify image pulls -- Remove wrong/stuck proxy configurations -- Always use a buildpack -- Add icons for eleventy + astro -- Fix proxy every 10 secs -- Do not remove coolify proxy -- Update version -- Be sure .env exists -- Missing fqdn for services -- Default npm command -- Add coolify-image label for build images -- Cleanup old images, > 3 days -- Better proxy check -- Ssl + sslrenew -- Null proxyhash on restart -- Reconfigure proxy on restart -- Update process -- Reload proxy on ssl cert -- Volume name -- Update process -- Check when a container is running -- Reload haproxy if new cert is added -- Cleanup coolify images -- Application state in UI -- Do not error if proxy is not running -- Personal Gitlab repos -- Autodeploy true by default for GH repos -- No cookie found -- Missing session data -- No error if GitSource is missing -- No webhook secret found? -- Basedir for dockerfiles -- Better queue system + more support on monorepos -- Remove build logs in case of app removed -- Cleanup old builds -- Only cleanup same app -- Add nginx + htaccess files -- Skip ssl cert in case of error -- Volumes -- Cleanup only 2 hours+ old images -- Ghost logo size -- Ghost icon, remove console.log -- List ghost services -- Reload window on settings saved -- Persistent storage on webhooks -- Add license -- Space in repo names -- Gitlab repo url -- No need to dashify anymore -- Registration enabled/disabled -- Add PROTO headers -- Haproxy errors -- Build variables -- Use NodeJS for sveltekit for now -- Ignore coolify proxy error for now -- Python no wsgi -- If user not found -- Rename envs to secrets -- Infinite loop on www domains -- No need to paste clear text env for previews -- Build log fix attempt #1 -- Small UI fix on logs -- Lets await! -- Async progress -- Remove console.log -- Build log -- UI -- Gitlab & Github urls -- Secrets build/runtime coudl be changed after save -- Default configuration -- *(php)* If .htaccess file found use apache -- Add default webhook domain for n8n -- Add git lfs while deploying -- Try to update build status several times -- Update stucked builds -- Update stucked builds on startup -- Revert seed -- Lame fixing -- Remove asyncUntil -- Add openssl to image -- Permission issues -- On-demand sFTP for wp -- Fix for fix haha -- Do not pull latest image -- Updated db versions -- Only show proxy for admin team -- Team view for root team -- Do not trigger >1 webhooks on GitLab -- Possible fix for spikes in CPU usage -- Last commit -- Www or not-www, that's the question -- Fix for the fix that fixes the fix -- Ton of updates for users/teams -- Small typo -- Unique storage paths -- Self-hosted GitLab URL -- No line during buildLog -- Html/apiUrls cannot end with / -- Typo -- Missing buildpack -- Enable https for Ghost -- Postgres root passwor shown and set -- Able to change postgres user password from ui -- DB Connecting string generator -- Missing install repositories GitHub -- Return own and other sources better -- Show config missing on sources -- Remove unnecessary save button haha -- Update dockerfile -- Haproxy build stuffs -- Proxy -- Types -- Invitations -- Timeout values -- Cleanup images older than a day -- Meilisearch service -- Load all branches, not just the first 30 -- ProjectID for Github -- DNS check before creating SSL cert -- Try catch me -- Restart policy for resources -- No permission on first registration -- Reverting postgres password for now -- Destinations to HAProxy -- Register should happen if coolify proxy cannot be started -- GitLab typo -- Remove system wide pw reset -- Postgres root pw is pw field -- Teams view -- Improved tcp proxy monitoring for databases/ftp -- Add HTTP proxy checks -- Loading of new destinations -- Better performance for cleanup images -- Remove proxy container in case of dependent container is down -- Restart local docker coolify proxy in case of something happens to it -- Id of service container -- Switch from bitnami/redis to normal redis -- Use redis-alpine -- Wordpress extra config -- Stop sFTP connection on wp stop -- Change user's id in sftp wp instance -- Use arm based certbot on arm -- Buildlog line number is not string -- Application logs paginated -- Switch to stream on applications logs -- Scroll to top for logs -- Pull new images for services all the time it's started. -- White-labeled custom logo -- Application logs -- Deno configurations -- Text on deno buildpack -- Correct branch shown in build logs -- Vscode permission fix -- I18n -- Locales -- Application logs is not reversed and queried better -- Do not activate i18n for now -- GitHub token cleanup on team switch -- No logs found -- Code cleanups -- Reactivate posgtres password -- Contribution guide -- Simplify list services -- Contribution -- Contribution guide -- Contribution guide -- Packagemanager finder -- Unami svg size -- Team switching moved to IAM menu -- Always use IP address for webhooks -- Remove unnecessary test endpoint -- UI -- Migration -- Fider envs -- Checking low disk space -- Build image -- Update autoupdate env variable -- Renew certificates -- Webhook build images -- Missing node versions -- ExposedPorts -- Logos for dbs -- Do not run SSL renew in development -- Check domain for coolify before saving -- Remove debug info -- Cancel jobs -- Cancel old builds in database -- Better DNS check to prevent errors -- Check DNS in prod only -- DNS check -- Disable sentry for now -- Cancel -- Sentry -- No image for Docker buildpack -- Default packagemanager -- Server usage only shown for root team -- Expose ports for services -- UI -- Navbar UI -- UI -- UI -- Remove RC python -- UI -- UI -- UI -- Default Python package -- WP custom db -- UI -- Gastby buildpack -- Service checks -- Remove console.log -- Traefik -- Remove debug things -- WIP Traefik -- Proxy for http -- PR deployments view -- Minio urls + domain checks -- Remove gh token on git source changes -- Do not fetch app state in case of missconfiguration -- Demo instance save domain instantly -- Instant save on demo instance -- New source canceled view -- Lint errors in database services -- Otherfqdns -- Host key verification -- Ftp connection -- GitHub fixes -- TrustProxy -- Force restart proxy -- Only restart coolify proxy in case of version prior to 2.9.2 -- Force restart proxy on seeding -- Add GIT ENV variable for submodules -- Recurisve clone instead of submodule -- Versions -- Only reconfigure coolify proxy if its missconfigured -- Demo version forms -- Typo -- Revert gh and gl cloning -- Proxy stop missing argument -- Fider changed an env variable name -- Pnpm command -- Plausible custom script -- Plausible script and middlewares -- Remove console log -- Remove comments -- Traefik middleware -- Persistent nocodb -- Nocodb persistency -- Host and reload for uvicorn -- Remove package-lock -- Be able to change database + service versions -- Lock file -- Seeding -- Forgot that the version bump changed 😅 -- New destination can be created -- Include post -- New destinations -- Domain check -- Domain check -- TrustProxy for Fastify -- Hostname issue -- GitLab pagination load data -- Service domain checker -- Wp missing ftp solution -- Ftp WP issues -- Ftp?! -- Gitpod updates -- Gitpod -- Gitpod -- Wordpress FTP permission issues -- GitLab search fields -- GitHub App button -- GitLab loop on misconfigured source -- Gitpod -- Cleanup less often and can do it manually -- Admin password reset should not timeout -- Message for double branches -- Turn off autodeploy if double branch is configured -- More types for API -- More types -- Do not rebuild in case image exists and sha not changed -- Gitpod urls -- Remove new service start process -- Remove shared dir, deployment does not work -- Gitlab custom url -- Location url for services and apps -- Settings from api -- Selectable destinations -- Gitpod hardcodes -- Typo -- Typo -- Expose port checker -- States and exposed ports -- CleanupStorage -- Remote traefik webhook -- Remote engine ip address -- RemoteipAddress -- Explanation for remote engine url -- Tcp proxy -- Lol -- Webhook -- Dns check for rde -- Gitpod -- Revert last commit -- Dns check -- Dns checker -- Webhook -- Df and more debug -- Webhooks -- Load previews async -- Destination icon -- Pr webhook -- Cache image -- No ssh key found -- Prisma migration + update of docker and stuffs -- Ui -- Ui -- Only 1 ssh-agent is needed -- Reuse ssh connection -- Ssh tunnel -- Dns checking -- Fider BASE_URL set correctly -- Rde local ports -- Empty remote destinations could be removed -- Tips -- Lowercase issues fider -- Tooltip colors -- Update clickhouse configuration -- Cleanup command -- Enterprise Github instance endpoint -- Follow/cancel buttons -- Only remove coolify managed containers -- White-labeled env -- Schema -- Coolify-network on verification -- Cleanup stucked prisma-engines -- Toast -- Secrets -- Cleanup prisma engine if there is more than 1 -- !isARM to isARM -- Enterprise GH link -- Empty buildpack icons -- Debounce dashboard status requests -- Decryption errors -- Postgresql on ARM -- Make it public button -- Loading indicator -- Replace docker compose with docker-compose on CSB -- Dashboard ui -- Create coolify-infra, if it does not exists -- Gitpod conf and heroku buildpacks -- Appwrite -- Autoimport + readme -- Services import -- Heroku icon -- Heroku icon -- Dns button ui -- Bot deployments -- Bots -- AutoUpdater & cleanupStorage jobs -- Revert docker compose version to 2.6.1 -- Trim secrets -- Restart containers on-failure instead of always -- Show that Ghost values could be changed -- Bots without exposed ports -- Missing commas -- ExposedPort is just optional -- Port checker -- Cancel build after 5 seconds -- ExposedPort checker -- Batch secret = -- Dashboard for non-root users -- Stream build logs -- Show build log start/end -- Ui buttons -- Clear queue on cancelling jobs -- Cancelling jobs -- Dashboard for admins -- Never stop deplyo queue -- Build queue system -- High cpu usage -- Worker -- Better worker system -- Secrets decryption -- UI thinkgs -- Delete team while it is active -- Team switching -- Queue cleanup -- Decrypt secrets -- Cleanup build cache as well -- Pr deployments + remove public gits -- Copy all files during install process -- Typo -- Process -- White labeled icon on navbar -- Whitelabeled icon -- Next/nuxt deployment type -- Again -- Pr deployment -- CompareVersions -- Include -- Include -- Gitlab apps -- Oh god Prisma -- Glitchtip things -- Loading state on start -- Ui -- Submodule -- Gitlab webhooks -- UI + refactor -- Exposedport on save -- Appwrite letsencrypt -- Traefik appwrite -- Traefik -- Finally works! :) -- Rename components + remove PR/MR deployment from public repos -- Settings missing id -- Explainer component -- Database name on logs view -- Taiga -- Ssh pid agent name -- Repository link trim -- Fqdn or expose port required -- Service deploymentEnabled -- Expose port is not required -- Remote verification -- Dockerfile -- Debug api logging + gh actions -- Workdir -- Move restart button to settings -- Gitlab webhook -- Use ip address instead of window location -- Use ip instead of window location host -- Service state update -- Add initial DNS servers -- Revert last change with domain check -- Service volume generation -- Minio default env variables -- Add php 8.1/8.2 -- Edgedb ui -- Edgedb stuff -- Edgedb -- Pr previews -- DnsServer formatting -- Settings for service -- Change to execa from utils -- Save search input -- Ispublic status on databases -- Port checkers -- Ui variables -- Glitchtip env to pyhton boolean -- Autoupdater -- Show restarting apps -- Show restarting application & logs -- Remove unnecessary gitlab group name -- Secrets for PR -- Volumes for services -- Build secrets for apps -- Delete resource use window location -- Changing umami image URL to get latest version -- Gitlab importer for public repos -- Show error logs -- Umami init sql -- Plausible analytics actions -- Login -- Dev url -- UpdateMany build logs -- Fallback to db logs -- Fluentbit configuration -- Coolify update -- Fluentbit and logs -- Canceling build -- Logging -- Load more -- Build logs -- Versions of appwrite -- Appwrite?! -- Get building status -- Await -- Await #2 -- Update PR building status -- Appwrite default version 1.0 -- Undead endpoint does not require JWT -- *(routes)* Improve design of application page -- *(routes)* Improve design of git sources page -- *(routes)* Ui from destinations page -- *(routes)* Ui from databases page -- *(routes)* Ui from databases page -- *(routes)* Ui from databases page -- *(routes)* Ui from services page -- *(routes)* More ui tweaks -- *(routes)* More ui tweaks -- *(routes)* More ui tweaks -- *(routes)* More ui tweaks -- *(routes)* Ui from settings page -- *(routes)* Duplicates classes in services page -- *(routes)* Searchbar ui -- Github conflicts -- *(routes)* More ui tweaks -- *(routes)* More ui tweaks -- *(routes)* More ui tweaks -- *(routes)* More ui tweaks -- Ui with headers -- *(routes)* Header of settings page in databases -- *(routes)* Ui from secrets table -- Ui -- Tooltip -- Dropdown -- Ssl certificate distribution -- Db migration -- Multiplex ssh connections -- Able to search with id -- Not found redirect -- Settings db requests -- Error during saving logs -- Consider base directory in heroku bp -- Basedirectory should be empty if null -- Allow basedirectory for heroku -- Stream logs for heroku bp -- Debug log for bp -- Scp without host verification & cert copy -- Base directory & docker bp -- Laravel php chooser -- Multiplex ssh and ssl copy -- Seed new preview secret types -- Error notification -- Empty preview value -- Error notification -- Seed -- Service logs -- Appwrite function network is not the default -- Logs in docker bp -- Able to delete apps in unconfigured state -- Disable development low disk space -- Only log things to console in dev mode -- Do not get status of more than 10 resources defined by category -- BaseDirectory -- Dashboard statuses -- Default buildImage and baseBuildImage -- Initial deploy status -- Show logs better -- Do not start tcp proxy without main container -- Cleanup stucked tcp proxies -- Default 0 pending invitations -- Handle forked repositories -- Typo -- Pr branches -- Fork pr previews -- Remove unnecessary things -- Meilisearch data dir -- Verify and configure remote docker engines -- Add buildkit features -- Nope if you are not logged in -- Do not use npx -- Pure docker based development -- Do not show nope as ip address for dbs -- Add git sha to build args -- Smart search for new services -- Logs for not running containers -- Update docker binaries -- Gh release -- Dev container -- Gitlab auth and compose reload -- Check compose domains in general -- Port required if fqdn is set -- Appwrite v1 missing containers -- Dockerfile -- Pull does not work remotely on huge compose file -- Single container logs and usage with compose -- Secret errors -- Service logs -- Heroku bp -- Expose port is readonly on the wrong condition -- Toast -- Traefik proxy q 10s -- App logs view -- Tooltip -- Toast, rde, webhooks -- Pathprefix -- Load public repos -- Webhook simplified -- Remote webhooks -- Previews wbh -- Webhooks -- Websecure redirect -- Wb for previews -- Pr stopps main deployment -- Preview wbh -- Wh catchall for all -- Remove old minio proxies -- Template files -- Compose icon -- Templates -- Confirm restart service -- Template -- Templates -- Templates -- Plausible analytics things -- Appwrite webhook -- Coolify instance proxy -- Migrate template -- Preview webhooks -- Simplify webhooks -- Remove ghost-mariadb from the list -- More simplified webhooks -- Umami + ghost issues -- Remove contribution docs -- Umami template -- Compose webhooks fixed -- Variable replacements -- Doc links -- For rollback -- N8n and weblate icon -- Expose ports for services -- Wp + mysql on arm -- Show rollback button loading -- No tags error -- Update on mobile -- Dashboard error -- GetTemplates -- Docker compose persistent volumes -- Application persistent storage things -- Volume names for undefined volume names in compose -- Empty secrets on UI -- Ports for services -- Default icon for new services -- IsBot issue -- Local dev api/ws urls -- Wrong template/type -- Gitea icon is svg -- Gh actions -- Gh actions -- Replace $$generate vars -- Webhook traefik -- Exposed ports -- Wrong icons on dashboard -- Escape % in secrets -- Move debug log settings to build logs -- Storage for compose bp + debug on -- Hasura admin secret -- Logs -- Mounts -- Load logs after build failed -- Accept logged and not logged user in /base -- Remote haproxy password/etc -- Remove hardcoded sentry dsn -- Nope in database strings -- 0 destinations redirect after creation -- Seed -- Sentry dsn update -- Dnt -- Ui -- Only visible with publicrepo -- Migrations -- Prevent webhook errors to be logged -- Login error -- Remove beta from systemwide git -- Git checkout -- Remove sentry before migration -- Webhook previewseparator -- Apache on arm -- Update PR/MRs with new previewSeparator -- Static for arm -- Failed builds should not push images -- Turn off autodeploy for simpledockerfiles -- Security hole -- Rde -- Delete resource on dashboard -- Wrong port in case of docker compose -- Public db icon on dashboard -- Cleanup -- Build commands -- Migration file -- Adding missing appwrite volume -- Appwrite tmp volume -- Do not replace secret -- Root user for dbs on arm -- Escape secrets -- Escape env vars -- Envs -- Docker buildpack env -- Secrets with newline -- Secrets -- Add default node_env variable -- Add default node_env variable -- Secrets -- Secrets -- Gh actions -- Duplicate env variables -- Cleanupstorage -- Remove unused imports -- Parsing secrets -- Read-only permission -- Read-only iam -- $ sign in secrets -- Custom gitlab git user -- Add documentation link again -- Remove prefetches -- Doc link -- Temporary disable dns check with dns servers -- Local images for reverting -- Secrets -- Compose file location -- Docker log sequence -- Delete apps with previews -- Do not cleanup compose applications as unconfigured -- Build env variables with docker compose -- Public gh repo reload compose -- Build args docker compose -- Grpc -- Secrets -- Www redirect -- Cleanup function -- Cleanup stucked containers -- Deletion + cleanupStuckedContainers -- Stucked containers -- CleanupStuckedContainers -- CleanupStuckedContainers -- Typos in docs -- Url -- Network in compose files -- Escape new line chars in wp custom configs -- Applications cannot be deleted -- Arm servics -- Base directory not found -- Cannot delete resource when you are not on root team -- Empty port in docker compose -- Set PACK_VERSION to 0.27.0 -- PublishDirectory -- Host volumes -- Replace . & .. & $PWD with ~ -- Handle log format volumes -- Nestjs buildpack -- Show ip address as host in public dbs -- Revert from dockerhub if ghcr.io does not exists -- Logo of CCCareers -- Typo -- Ssh -- Nullable name on deploy_keys -- Enviroments -- Remove dd - oops -- Add inprogress activity -- Application view -- Only set status in case the last command block is finished -- Poll activity -- Small typo -- Show activity on load -- Deployment should fail on error -- Tests -- Version -- Status not needed -- No project redirect -- Gh actions -- Set status -- Seeders -- Do not modify localhost -- Deployment_uuid -> type_uuid -- Read env from config, bc of cache -- Private key change view -- New destination -- Do not update next channel all the time -- Cancel deployment button -- Public repo limit shown + branch should be preselected. -- Better status on ui for apps -- Arm coolify version -- Formatting -- Gh actions -- Show github app secrets -- Do not force next version updates -- Debug log button -- Deployment key based works -- Deployment cancel/debug buttons -- Upgrade button -- Changing static build changes port -- Overwrite default nginx configuration -- Do not overlap docker image names -- Oops -- Found image name -- Name length -- Semicolons encoding by traefik -- Base_dir wip & outputs -- Cleanup docker images -- Nginx try_files -- Master is the default, not main -- No ms in rate limit resets -- Loading after button text -- Default value -- Localhost is usable -- Update docker-compose prod -- Cloud/checkoutid/lms -- Type of license code -- More verbose error -- Version lol -- Update prod compose -- Version -- Remove buggregator from dev -- Able to change localhost's private key -- Readonly input box -- Notifications -- Licensing -- Subscription link -- Migrate db schema for smtp + discord -- Text field -- Null fqdn notifications -- Remove old modal -- Proxy stop/start ui -- Proxy UI -- Empty description -- Input and textarea -- Postgres_username name to not name, lol -- DatabaseBackupJob.php -- No storage -- Backup now button -- Ui + subscription -- Self-hosted -- Make coolify-db backups unique dir -- Limits & server creation page -- Fqdn on apps -- DockerCleanupjob -- Validation -- Webhook endpoint in cloud and no system wide gh app -- Subscriptions -- Password confirmation -- Proxy start job -- Dockerimage jobs are not overlapping -- Sentry bug -- Button loading animation -- Form address -- Show hosted email service, just disable for non pro subs -- Add navbar for source + keys -- Add docker network to build process -- Overlapping apps -- Do not show system wide git on cloud -- Lowercase image names -- Typo -- SaveModel email settings -- Bug -- Db backup job -- Sentry 4459819517 -- Sentry 4451028626 -- Ui -- Retry notifications -- Instance email settings -- Ui -- Test email on for admins or custom smtp -- Coolify already exists should not throw error -- Delete database related things when delete database -- Remove -q from docker compose -- Errors in views -- Only send internal notifcations to enabled channels -- Recovery code -- Email sending error -- Sentry 4469575117 -- Old docker version error -- Errors -- Proxy check, reduce jobs, etc -- Queue after commit -- Remove nixpkgarchive -- Remove nixpkgarchive from ui -- Webhooks should not run if server is not functional -- Server is functional check -- Confirm email before sending -- Help should send cc on email -- Sub type -- Show help modal everywhere -- Forgot password -- Disable dockerfile based healtcheck for now -- Add timeout for ssh commands -- Prevent weird ui bug for validateServer -- Lowercase email in forgot password -- Lower case email on waitlist -- Encrypt jobs -- ProcessWithEnv()->run -- Plus boarding step about Coolify -- SaveConfigurationSync -- Help uri -- Sub for root -- Redirect on server not found -- Ip check -- Uniqueips -- Simply reply to help messages -- Help -- Rate limit -- Collect billing address -- Invitation -- Smtp view -- Ssh-agent revert -- Restarting container state on ui -- Generate new key -- Missing upgrade js -- Team error -- 4.0.0-beta.37 -- Localhost -- Proxy start (if not proxy defined, use Traefik) -- Do not remove localhost in boarding -- Allow non ip address (DNS) -- InstallDocker id not found -- Boarding -- Errors -- Proxy container status -- Proxy configuration saving -- Convert startProxy to action -- Stop/start UI on apps and dbs -- Improve localhost boarding process -- Try to use old docker-compose -- Boarding again -- Send internal notifications of email errors -- Add github app change on new app view -- Delete environment variables on app/db delete -- Save proxy configuration -- Add proxy to network with periodic check -- Proxy connections -- Delete persistent storages on resource deletion -- Prevent overwrite already existing env variables in services -- Mappings -- Sentry issue 4478125289 -- Make sure proxy path created -- StartProxy -- Server validation with cf tunnels -- Only show traefik dashboard if its available -- Services -- Database schema -- Report livewire errors -- Links with path -- Add traefik labels no matter if traefik is selected or not -- Add expose port for containers -- Also check docker socks permission on validation -- Applications with port mappins do a normal update (not rolling update) -- Put back build pack chooser -- Proxy configuration + starter -- Show real storage name on services -- New service template layout -- Containerstatusjob -- Aaaaaaaaaaaaaaaaa -- Services view -- Services -- Manually create network for services -- Disable early updates -- Sslip for localhost -- ContainerStatusJob -- Cannot delete env with available services -- Sync command -- Install script drops an error -- Prevent sync version (it needs an option) -- Instance fqdn setting -- Sentry 4510197209 -- Sentry 4504136641 -- Sentry 4502634789 -- Next helper image -- Service templates -- Sync:bunny -- Update process if server has been renamed -- Reporting handler -- Localhost privatekey update -- Remove private key in case you removed a github app -- Only show manually added private keys on server view -- Show source on all type of applications -- Docker cleanup should be a job by server -- File/dir based volumes are now read from the server -- Respect server fqdn -- If public repository does not have a main branch -- Preselect branc on private repos -- Deploykey branch -- Backups are now working again -- Not found base_branch in git webhooks -- Coolify db backup -- Preview deployments name, status etc -- Services should have destination as well -- Dockerfile expose is not overwritten -- If app settings is not saved to db -- Do not show subscription cancelled noti -- Show real volume names -- Only parse expose in dockerfiles if ports_exposes is empty -- Add uuid to volume names -- New volumes for services should have - instead of _ -- Always pull helper image in dev -- Only show last 1000 lines -- Service status -- If waitlist is disabled, redirect to register -- Add destination to new services -- Predefined content for files -- Move /data to ./_data in dev -- UI -- Show all storages in one place for services -- Ui -- Add _data to vite ignore -- Only use _ in volume names for services -- Volume names in services -- Volume names -- Service logs visible if the whole service stack is not running -- Ui -- Compose magic -- Compose parser updated -- Dev compose files -- Traefik labels for multiport deployments -- Visible version number -- Remove SERVICE_ from deployable compose -- Delete event to deleting -- Move dev data to volumes to prevent permission issues -- Traefik labelling in case of several http and https domain added -- PR deployments use the first fqdn as base -- Email notifications subscription fixed -- Services - do not remove unnecessary things for now -- Decrease max horizon processes to get lower memory usage -- Test emails only available for user owned smtp/resend -- Ui for self-hosted email settings -- Set smtp notifications on by default -- Select branch on other git -- Private repository -- Contribution guide -- Public repository names -- *(create)* Flex wrap on server & network selection -- Better unreachable/revived server statuses -- Able to set base dir for Dockerfile build pack -- Server validation process -- Fqdn could be null -- Small -- Server unreachable count -- Do not reset unreachable count -- Contact docs -- Check connection -- Server saving -- No env goto envs from dashboard -- Goto -- Tcp proxy for dbs -- Database backups -- Only send email if transactional email set -- Backupfailed notification is forced -- Use port exposed for reverse proxy -- Contact link -- Use only ip addresses for servers -- Deleted team and it is the current one -- Add new team button -- Transactional email link -- Dashboard goto link -- Only require registry image in case of dockerimage bp -- Instant save build pack change -- Public git -- Cannot remove localhost -- Check localhost connection -- Send unreachable/revived notifications -- Boarding + verification -- Make sure proxy wont start in NONE mode -- Service check status 10 sec -- IsCloud in production seeder -- Make sure to use IP address -- Dockerfile location feature -- Server ip could be hostname in self-hosted -- Urls should be password fields -- No backup for redis -- Show database logs in case of its not healthy and running -- Proxy check for ports, do not kill anything listening on port 80/443 -- Traefik dashboard ip -- Db labels -- Docker cleanup jobs -- Timeout for instant remote processes -- Dev containerjobs -- Backup database one-by-one. -- Turn off static deployment if you switch buildpacks -- Docker hub URL -- Redis URL generated -- Build image before starting dockerfile buildpacks -- Service status check is a bit better -- Generate fqdn if you deleted a service app, but it requires fqdn -- Cancel any deployments + queue next -- Add internal domain names during build process -- Noindex meta tag -- Show docker build logs -- Only include config.json if its exists and a file -- Always start proxy if not NONE is selected -- Proxy start process -- Setup:dev script & contribution guide -- Do not show configuration changed if config_hash is null -- Add config_hash if its null (old deployments) -- Label generation -- Labels -- Email channel no recepients -- Limit horizon processes to 2 by default -- Add custom port as ssh option to deploy_key based commands -- Remove custom port from git repo url -- ContainerStatus job -- Service docs links -- Add PGUSER to prevent HC warning -- Preselect s3 storage if available -- Port exposes change, shoud regenerate label -- Boarding -- Clone to with the same environment name -- Cleanup stucked resources on start -- Do not allow to delete env if a resource is defined -- Service template generator + appwrite -- Mongodb backup -- Make sure coolfiy network exists on install -- Syncbunny command -- Encrypt mongodb password -- Mongodb healtcheck command -- Rate limit for api + add mariadb + mysql -- Server settings guarded -- Space in build args -- Lock SERVICE_FQDN envs -- If user is invited, that means its email is verified -- Force password reset on invited accounts -- Add ssh options to git ls-remote -- Git ls-remote -- Remove coolify labels from ui -- Missing environment variables prevewi on service -- Invoice.paid should sleep for 5 seconds -- Local dev repo -- Deployments ui -- Dockerfile build pack fix -- Set labels on generate domain -- Network service parse -- Notification url in containerstatusjob -- Gh webhook response 200 to installation_repositories -- Delete destination -- No id found -- Missing $mailMessage -- Set default from/sender names -- No environments -- Telegram text -- Private key not found error -- UI -- Resourcesdelete command -- Port number should be int -- Separate delete with validation of server -- Add nixpacks info -- Remove filter -- Container logs are now followable in full-screen and sorted by timestamp -- Ui for labels -- Ui -- Deletions -- Build_image not found -- Github source view -- Github source view -- Dockercleanupjob should be released back -- Ui -- Local ip address -- Revert workdir to basedir -- Container status jobs for old pr deployments -- Service updates -- *(fider template)* Use the correct docs url -- Fqdn for minio -- Generate service fields -- Mariadb backups -- When to pull image -- Do not allow to enter local ip addresses -- Reset password -- Only report nonruntime errors -- Handle different label formats in services -- Server adding process -- Show defined resources in server tab, so you will know what you need to delete before you can delete the server. -- Lots of regarding git + docker compose deployments -- Pull request build variables -- Double default password length -- Do not remove deployment in case compose based failed -- No container servers -- Sentry issue -- Dockercompose save ./ volumes under /data/coolify -- Server view for link() -- Default value do not overwrite existing env value -- Use official install script with rancher (one will work for sure) -- Add cf tunnel to boarding server view -- Prevent autorefresh of proxy status -- Missing docker image thing -- Add hc for soketi -- Deploy the right compose file -- Bind volumes for compose bp -- Use hc port 80 in case of static build -- Switching to static build -- Container selection -- Service navbar using new realtime events -- Do not create duplicated networks -- Live event -- Service start + event -- Service deletion job -- Double ws connection -- Boarding view -- Do not send telegram noti on intent payment failed -- Database ui is realtime based -- Live mode for github webhooks -- Ui -- Realtime connection popup could be disabled -- Realtime check -- Add new destination -- Proxy logs -- Db status check -- Pusher host -- Add ipv6 -- Realtime connection?! -- Websocket -- Better handling of errors with install script -- Install script parse version -- Only allow to modify in .env file if AUTOUPDATE is set -- Is autoupdate not null -- Run init command after production seeder -- Init -- Comma in traefik custom labels -- Ignore if dynamic config could not be set -- Service env variable ovewritten if it has a default value -- Labelling -- Non-ascii chars in labels -- Labels -- Init script echos -- Update Coolify script -- Null notify -- Check queued deployments as well -- Copy invitation -- Password reset / invitation link requests -- Add catch all route -- Revert random container job delay -- Backup executions view -- Only check server status in container status job -- Improve server status check times -- Handle other types of generated values -- Server checking status -- Ui for adding new destination -- Reset domains on compose file change -- Domains for compose bp -- No action in webhooks -- Add debug output to gitlab webhooks -- Do not push dockerimage -- Add alpha to swarm -- Server not found -- Do not autovalidate server on mount -- Server update schedule -- Swarm support ui -- Server ready -- Get swarm service logs -- Docker compose apps env rewritten -- Storage error on dbs -- Why?! -- Stay tuned -- Cpu limit to float from int -- Add source commit to final envs -- Routing, switch back to old one -- Deploy instead of restart in case swarm is used -- Button title -- Restore falsely deleted coolify-db-backup -- Sub -- Wrong env variable parsing -- Deploy key + docker compose -- Horizon -- Duplicate compose variable -- Set deployment failed if new container is not healthy -- Nixpacks cache -- Only add restart policy if its empty (compose) -- Nixpacks buildpack -- File storage save -- Database env variables -- Healthy status -- Show framework based notification in build logs -- Traefik labels -- Use ip for sslip in dev if remote server is used -- Service labels without ports (unknown ports) -- Sort and rename (unique part) of labels -- Settings menu -- Remove traefik debug in dev mode -- Php pgsql to 8.2 -- Static buildpack should set port 80 -- Update navbar on build_pack change -- Do not include thegameplan.json into build image -- Submit error on postgresql -- Email verification / forgot password -- Escape build envs properly for nixpacks + docker build -- Undead endpoint -- Upload limit on ui -- Save cmd output propely (merge) -- Load profile on remote commands -- Load profile and set envs on remote cmd -- Restart should not update config hash -- Preview deployments with nixpacks -- Cleanup docker stuffs before upgrading -- Service deletion command -- Cpuset limits was determined in a way that apps only used 1 CPU max, ehh, sorry. -- Service stack view -- Change proxy view -- Checkbox click -- Git pull command for deploy key based previews -- Server status job -- Service deletion bug! -- Links -- Redis custom conf -- Sentry error -- Restrict concurrent deployments per server -- Queue -- Change env variable length -- Bitbucket manual deployments -- Webhooks for multiple apps -- Unhealthy deployments should be failed -- Add env variables for wordpress template without database -- Service deletion function -- Service deletion fix -- Dns validation + duplicated fqdns -- Validate server navbar upated -- Regenerate labels on application clone -- Service deletion -- Not able to use other shared envs -- Sentry fix -- Sentry -- Sentry error -- Sentry -- Sentry error -- Create dynamic directory -- Migrate to new modal -- Duplicate domain check -- Tags -- Wrap tags and avoid horizontal overflow -- Stripe webhooks -- Feedback from self-hosted envs to discord -- New menu on navbar -- Make sure resources are deleted in async mode -- Go to prod env from dashboard if there is no other envs defined -- User proper image_tag, if set -- New menu ui -- Lock logdrain configuration when one of them are enabled -- Add docker compose check during server validation -- Get service stack as uuid, not name -- Menu -- Flex wrap deployment previews -- Boolean docker options -- Only add 'networks' key if 'network_mode' is absent -- Cleanup scheduled tasks -- Padding left on input boxes -- Use ls / command instead ls -- Do not add the same server twice -- Only show redeployment required if status is not exited -- Add openbsd ssh server check -- Resources -- Empty build variables -- *(server)* Revalidate server button not showing in server's page -- Fluent bit ident level -- Submodule cloning -- Database status -- Permission change updates from webhook -- Server validation -- Connections being stuck and not processed until proxy restarts -- Use latest image if nothing is specified -- No coolify.yaml found -- Server validation -- Statuses -- Unknown image of service until it is uploaded -- Subscription / plan switch, etc -- Firefly service -- Force enable/disable server in case ultimate package quantity decreases -- Server disabled -- Custom dockerfile location always checked -- Import to mysql and mariadb -- Resource tab not loading if server is not reachable -- Load unmanaged async -- Do not show n/a networsk -- Service container status updates -- Public prs should not be commented -- Pull request deployments + build servers -- Env value generation -- Sentry error -- Service status updated -- Should note delete personal teams -- Make sure to show some buttons -- Sort repositories by name -- Deploy api messages -- Fqdn null in case docker compose bp -- Reload caddy issue -- /realtime endpoint -- Proxy switch -- Service ports for services + caddy -- Failed deployments should send failed email/notification -- Consider custom healthchecks in dockerfile -- Create initial files async -- Docker compose validation -- Duplicate dockerfile -- Multiline env variables -- Server stopped, service page not reachable -- Empty get logs number of lines -- Only escape envs after v239+ -- 0 in env value -- Consistent container name -- Custom ip address should turn off rolling update -- Multiline input -- Raw compose deployment -- Dashboard view if no project found -- Volumes for prs -- Shared env variable parsing -- Compose env has SERVICE, but not defined for Coolify -- Public service database -- Make sure service db proxy restarted -- Restart service db proxies -- Two factor -- Ui for tags -- Update resources view -- Realtime connection check -- Multline env in dev mode -- Scheduled backup for other service databases (supabase) -- PR deployments should not be distributed to 2 servers -- Name/from address required for resend -- Autoupdater -- Async service loads -- Disabled inputs are not trucated -- Duplicated generated fqdns are now working -- Uis -- Ui for cftunnels -- Search services -- Trial users subscription page -- Async public key loading -- Unfunctional server should see resources -- Warning if you use multiple domains for a service -- New github app creation -- Always rebuild Dockerfile / dockerimage buildpacks -- Do not rebuild dockerfile based apps twice -- Make sure if envs are changed, rebuild is needed -- Members cannot manage subscriptions -- IsMember -- Storage layout -- How to update docker-compose, environment variables and fqdns -- Git submodule update -- Unintended left padding on sidebar -- Hashed random delimeter in ssh commands + make sure to remove the delimeter from the command -- Service config hash update -- Redeploy if image not found in restart only mode -- Check each required binaries one-by-one -- Helper image only pulled if required, not every 10 mins -- Make sure that confs when checking if it is changed sorted -- Respect .env file (for default values) -- Remove temporary cloudflared config -- Remove lazy loading until bug figured out -- Rollback feature -- Base64 encode .env -- $ in labels escaped -- .env saved to deployment server, not to build server -- Do no able to delete gh app without deleting resources -- 500 error on edge case -- Able to select server when creating new destination -- N8n template -- Refresh public ips on start -- Move s3 storages to separate view -- Mongo db backup -- Backups -- Autoupdate -- Respect start period and chekc interval for hc -- Parse HEALTHCHECK from dockerfile -- Make s3 name and endpoint required -- Able to update source path for predefined volumes -- Get logs with non-root user -- Mongo 4.0 db backup -- Formbricks image origin -- Add port even if traefik is used -- Typo in tags.blade.php -- Install.sh error -- Env file -- Comment out internal notification in email_verify method -- Confirmation for custom labels -- Change permissions on newly created dirs -- Color for resource operation server and project name -- Only show realtime error on non-cloud instances -- Only allow push and mr gitlab events -- Improve scheduled task adding/removing -- Docker compose dependencies for pr previews -- Properly populating dependencies -- Use commit hash on webhooks -- Commit message length -- Hc from localhost to 127.0.0.1 -- Use rc in hc -- Telegram group chat notifications -- PR deployments have good predefined envs -- Optimize new resource creation -- Show it docker compose has syntax errors -- Wrong time during a failed deployment -- Removal of the failed deployment condition, addition of since started instead of finished time -- Use local versions + service templates and query them every 10 minutes -- Check proxy functionality before removing unnecessary coolify.yaml file and checking Docker Engine -- Show first 20 users only in admin view -- Add subpath for services -- Ghost subdir -- Do not pull templates in dev -- Templates -- Update error message for invalid token to mention invalid signature -- Disable containerStopped job for now -- Disable unreachable/revived notifications for now -- JSON_UNESCAPED_UNICODE -- Add wget to nixpacks builds -- Pre and post deployment commands -- Bitbucket commits link -- Better way to add curl/wget to nixpacks -- Root team able to download backups -- Build server should not have a proxy -- Improve build server functionalities -- Sentry issue -- Sentry -- Sentry error + livewire downgrade -- Sentry -- Sentry -- Sentry error -- Sentry -- Force load services from cdn on reload list -- Do not allow service storage mount point modifications -- Volume adding -- Sync upgrade process -- Publish horizon -- Add missing team model -- Test new upgrade process? -- Throw exception -- Build server dirs not created on main server -- Compose load with non-root user -- Able to redeploy dockerfile based apps without cache -- Compose previews does have env variables -- Fine-tune cdn pulls -- Spamming :D -- Parse docker version better -- Compose issues -- SERVICE_FQDN has source port in it -- Logto service -- Allow invitations via email -- Sort by defined order + fixed typo -- Only ignore volumes with driver_opts -- Check env in args for compose based apps -- Custom docker compose commands, add project dir if needed -- Autoupdate process -- Backup executions view -- Handle previously defined compose previews -- Sort backup executions -- Supabase service, newest versions -- Set default name for Docker volumes if it is null -- Multiline variable should be literal + should be multiline in bash with \ -- Gitlab merge request should close PR -- Multiline build args -- Setup script doesnt link to the correct source code file -- Install.sh do not reinstall packages on arch -- Just restart -- Stripprefix middleware correctly labeled to http -- Bitbucket link -- Compose generator -- Do no truncate repositories wtih domain (git) in it -- In services should edit compose file for volumes and envs -- Handle laravel deployment better -- Db proxy status shown better in the UI -- Show commit message on webhooks + prs -- Metrics parsing -- Charts -- Application custom labels reset after saving -- Static build with new nixpacks build process -- Make server charts one livewire component with one interval selector -- You can now add env variable from ui to services -- Update compose environment with UI defined variables -- Refresh deployable compose without reload -- Remove cloud stripe notifications -- App deployment should be in high queue -- Remove zoom from modals -- Get envs before sortby -- MB is % lol -- Projects with 0 envs -- Run user commands on high prio queue -- Load js locally -- Remove lemon + paddle things -- Run container commands on high priority -- Image logo -- Remove both option for api endpoints. it just makes things complicated -- Cleanup subs in cloud -- Show keydbs/dragonflies/clickhouses -- Only run cloud clean on cloud + remove root team -- Force cleanup on busy servers -- Check domain on new app via api -- Custom container name will be the container name, not just internal network name -- Api updates -- Yaml everywhere -- Add newline character to private key before saving -- Add validation for webhook endpoint selection -- Database input validators -- Remove own app from domain checks -- Return data of app update -- Do not overwrite hardcoded variables if they rely on another variable -- Remove networks when deleting a docker compose based app -- Api -- Always set project name during app deployments -- Remove volumes as well -- Gitea pr previews -- Prevent instance fqdn persisting to other servers dynamic proxy configs -- Better volume cleanups -- Cleanup parameter -- Update redirect URL in unauthenticated exception handler -- Respect top-level configs and secrets -- Service status changed event -- Disable sentinel until a few bugs are fixed -- Service domains and envs are properly updated -- *(reactive-resume)* New healthcheck command for MinIO -- *(MinIO)* New command healthcheck -- Update minio hc in services -- Add validation for missing docker compose file -- Typo in is_literal helper -- Env is_literal helper text typo -- Update docker compose pull command with --policy always -- Plane service template -- Vikunja -- Docmost template -- Drupal -- Improve github source creation -- Tag deployments -- New docker compose parsing -- Handle / in preselecting branches -- Handle custom_internal_name check in ApplicationDeploymentJob.php -- If git limit reached, ignore it and continue with a default selection -- Backup downloads -- Missing input for api endpoint -- Volume detection (dir or file) is fixed -- Supabase -- Create file storage even if content is empty -- Preview deployments should be stopped properly via gh webhook -- Deleting application should delete preview deployments -- Plane service images -- Fix issue with deployment start command in ApplicationDeploymentJob -- Directory will be created by default for compose host mounts -- Restart proxy does not work + status indicator on the UI -- Uuid in api docs type -- Raw compose deployment .env not found -- Api -> application patch endpoint -- Remove pull always when uploading backup to s3 -- Handle array env vars -- Link in task failed job notifications -- Random generated uuid will be full length (not 7 characters) -- Gitlab service -- Gitlab logo -- Bitbucket repository url -- By default volumes that we cannot determine if they are directories or files are treated as directories -- Domain update on services on the UI -- Update SERVICE_FQDN/URL env variables when you change the domain -- Several shared environment variables in one value, parsed correctly -- Members of root team should not see instance admin stuff -- Parse docker composer -- Service env parsing -- Service env variables -- Activity type invalid -- Update env on ui -- Only append docker network if service/app is running -- Remove lazy load from scheduled tasks -- Plausible template -- Service_url should not have a trailing slash -- If usagebefore cannot be determined, cleanup docker with force -- Async remote command -- Only run logdrain if necessary -- Remove network if it is only connected to coolify proxy itself -- Dir mounts should have proper dirs -- File storages (dir/file mount) handled properly -- Do not use port exposes on docker compose buildpacks -- Minecraft server template fixed -- Graceful shutdown -- Stop resources gracefully -- Handle null and empty disk usage in DockerCleanupJob -- Show latest version on manual update view -- Empty string content should be saved as a file -- Update Traefik labels on init -- Add missing middleware for server check job -- Scheduledbackup not found -- Manual update process -- Timezone not updated when systemd is missing -- If volumes + file mounts are defined, should merge them together in the compose file -- All mongo v4 backups should use the different backup command -- Database custom environment variables -- Connect compose apps to the right predefined network -- Docker compose destination network -- Server status when there are multiple servers -- Sync fqdn change on the UI -- Pr build names in case custom name is used -- Application patch request instant_deploy -- Canceling deployment on build server -- Backup of password protected postgresql database -- Docker cleanup job -- Storages with preserved git repository -- Parser parser parser -- New parser only in dev -- Parser parser -- Numberoflines should be number -- Docker cleanup job -- Fix directory and file mount headings in file-storage.blade.php -- Preview fqdn generation -- Revert a few lines -- Service ui sync bug -- Setup script doesn't work on rhel based images with some curl variant already installed -- Let's wait for healthy container during installation and wait an extra 20 seconds (for migrations) -- Infra files -- Log drain only for Applications -- Copy large compose files through scp (not ssh) -- Check if array is associative or not -- Openapi endpoint urls -- Convert environment variables to one format in shared.php -- Logical volumes could be overwritten with new path -- Env variable in value parsed -- Pull coolify image only when the app needs to be updated -- Wrong executions order -- Handle project not found error in environment_details API endpoint -- Deployment running for - without "ago" -- Update helper image pulling logic to only pull if the version is newer -- Parser -- Plunk NEXT_PUBLIC_API_URI -- Reenable overlapping servercheckjob -- Appwrite template + parser -- Don't add `networks` key if `network_mode` is used -- Remove debug statement in shared.php -- Scp through cloudflare -- Delete older versions of the helper image other than the latest one -- Update remoteProcess.php to handle null values in logItem properties -- Disable mux_enabled during server validation -- Move mc command to coolify image from helper -- Keydb. add `:` delimiter for connection string -- Cloudflare tunnel with new multiplexing feature -- Keep-alive ws connections -- Add build.sh to debug logs -- Update Coolify installer -- Terminal -- Generate https for minio -- Install script -- Handle WebSocket connection close in terminal.blade.php -- Able to open terminal to any containers -- Refactor run-command -- If you exit a container manually, it should close the underlying tty as well -- Move terminal to separate view on services -- Only update helper image in DB -- Generated fqdn for SERVICE_FQDN_APP_3000 magic envs -- Proxy status -- Coolify-db should not be in the managed resources -- Store original root key in the original location -- Logto service -- Cloudflared service -- Migrations -- Cloudflare tunnel configuration, ui, etc -- Parser -- Exited services statuses -- Make sure to reload window if app status changes -- Deploy key based deployments -- Proxy fixes -- Proxy -- *(templates)* Filebrowser FQDN env variable -- Handle edge case when build variables and env variables are in different format -- Compose based terminal -- Filebrowser template -- Edit is_build_server_enabled upon creating application on other application type -- Save settings after assigning value -- In dev mode do not ask confirmation on delete -- Mixpost -- Handle deletion of 'hello' in confirmation modal for dev environment -- Remove autofocuses -- Ipv6 scp should use -6 flag -- Cleanup stucked applicationdeploymentqueue -- Realtime watch in development mode -- Able to select root permission easier -- Able to support more database dynamically from Coolify's UI -- Strapi template -- Bitcoin core template -- Api useBuildServer -- Service application view -- Add new supported database images -- Parse proxy config and check the set ports usage -- Update FQDN -- Scheduled backup for services view -- Parser, espacing container labels -- Reset description and subject fields after submitting feedback -- Tag mass redeployments -- Service env orders, application env orders -- Proxy conf in dev -- One-click services -- Use local service-templates in dev -- New services -- Remove not used extra host -- Chatwoot service -- Directus -- Database descriptions -- Update services -- Soketi -- Select server view -- Update mattermost image tag and add default port -- Remove env, change timezone -- Postgres healthcheck -- Azimutt template - still not working haha -- New parser with SERVICE_URL_ envs -- Improve service template readability -- Update password variables in Service model -- Scheduled database server -- Select server view -- Signup -- Application domains should be http and https only -- Validate and sanitize application domains -- Sanitize and validate application domains -- Use correct env variable for invoice ninja password -- Make sure caddy is not removed by cleanup -- Libretranslate -- Do not allow to change number of lines when streaming logs -- Plunk -- No manual timezones -- Helper push -- Format -- Add port metadata and Coolify magic to generate the domain -- Sentinel -- Metrics -- Generate sentinel url -- Only enable Sentinel for new servers -- Is_static through API -- Allow setting standalone redis variables via ENVs (team variables...) -- Check for username separately form password -- Encrypt all existing redis passwords -- Pull helper image on helper_version change -- Redis database user and password -- Able to update ipv4 / ipv6 instance settings -- Metrics for dbs -- Sentinel start fixed -- Validate sentinel custom URL when enabling sentinel -- Should be able to reset labels in read-only mode with manual click -- No sentinel for swarm yet -- Charts ui -- Volume -- Sentinel config changes restarts sentinel -- Disable sentinel for now -- Disable Sentinel temporarily -- Disable Sentinel temporarily for non-dev environments -- Access team's github apps only -- Admins should now invite owner -- Add experimental flag -- GenerateSentinelUrl method -- NumberOfLines could be null -- Login / register view -- Restart sentinel once a day -- Changing private key manually won't trigger a notification -- Grammar for helper -- Fix my own grammar -- Add telescope only in dev mode -- New way to update container statuses -- Only run server storage every 10 mins if sentinel is not active -- Cloud admin view -- Queries in kernel.php -- Lower case emails only -- Change emails to lowercase on init -- Do not error on update email -- Always authenticate with lowercase emails -- Dashboard refactor -- Add min/max length to input/texarea -- Remove livewire legacy from help view -- Remove unnecessary endpoints (magic) -- Transactional email livewire -- Destinations livewire refactor -- Refactor destination/docker view -- Logdrains validation -- Reworded -- Use Auth(), add new db proxy stop event refactor clickhouse view -- Add user/pw to db view -- Sort servers by name -- Keydb view -- Refactor tags view / remove obsolete one -- Send discord/telegram notifications on high job queue -- Server view refresh on validation -- ShowBoarding -- Show docker installation logs & ubuntu 24.10 notification -- Do not overlap servercheckjob -- Server limit check -- Server validation -- Clear route / view -- Only skip docker installation on 24.10 if its not installed -- For --gpus device support -- Db/service start should be on high queue -- Do not stop sentinel on Coolify restart -- Run resourceCheck after new serviceCheckJob -- Mongodb in dev -- Better invitation errors -- Loading indicator for db proxies -- Do not execute gh workflow on template changes -- Only use sentry in cloud -- Update packagejson of coolify-realtime + add lock file -- Update last online with old function -- Seeder should not start sentinel -- Start sentinel on seeder -- Notifications ui -- Disable wire:navigate -- Confirmation Settings css for light mode -- Server wildcard -- Saving resend api key -- Wildcard domain save -- Disable cloudflare tunnel on "localhost" -- Define separate volumes for mattermost service template -- Github app name is too long -- ServerTimezone update -- Trigger.dev db host & sslmode=disable -- Manual update should be executed only once + better UX -- Upgrade.sh -- Missing privateKey -- Show proper error message on invalid Git source -- Convert HTTP to SSH source when using deploy key on GitHub -- Cloud + stripe related -- Terminal view loading in async -- Cool 500 error (thanks hugodos) -- Update schema in code decorator -- Openapi docs -- Add tests for git url converts -- Minio / logto url generation -- Admin view -- Min docker version 26 -- Pull latest service-templates.json on init -- Workflow files for coolify build -- Autocompletes -- Timezone settings validation -- Invalid tz should not prevent other jobs to be executed -- Testing-host should be built locally -- Poll with modal issue -- Terminal opening issue -- If service img not found, use github as a source -- Fallback to local coolify.png -- Gather private ips -- Cf tunnel menu should be visible when server is not validated -- Deployment optimizations -- Init script + optimize laravel -- Default docker engine version + fix install script -- Pull helper image on init -- SPA static site default nginx conf -- Modal-input -- Modal (+ add) on dynamic config was not opening, removed x-cloak -- AUTOUPDATE + checkbox opacity -- Improve helper text for metrics input fields -- Refine helper text for metrics input fields -- If mux conn fails, still use it without mux + save priv key with better logic -- Migration -- Always validate ssh key -- Make sure important jobs/actions are running on high prio queue -- Do not send internal notification for backups and status jobs -- Validateconnection -- View issue -- Heading -- Remove mux cleanup -- Db backup for services -- Version should come from constants + fix stripe webhook error reporting -- Undefined variable -- Remove version.php as everything is coming from constants.php -- Sentry error -- Websocket connections autoreconnect -- Sentry error -- Sentry -- Empty server API response -- Incorrect server API patch response -- Missing `uuid` parameter on server API patch -- Missing `settings` property on servers API -- Move servers API `delete_unused_*` properties -- Servers API returning `port` as a string -> integer -- Only return server uuid on server update -- Service generate includes yml files as well (haha) -- ServercheckJob should run every 5 minutes on cloud -- New resource icons -- Search should be more visible on scroll on new resource -- Logdrain settings -- Ui -- Email should be retried with backoff -- Alpine in body layout -- Application view loading -- Postiz service -- Only able to select the right keys -- Test email should not be required -- A few inputs -- Api endpoint -- Resolve undefined searchInput reference in Alpine.js component -- URL and sync new app name -- Typos and naming -- Client and webhook secret disappear after sync -- Missing `mysql_password` API property -- Incorrect MongoDB init API property -- Old git versions does not have --cone implemented properly -- Don't allow editing traefik config -- Restart proxy -- Dev mode -- Ui -- Display actual values for disk space checks in installer script -- Proxy change behaviour -- Add warning color -- Import NotificationSlack correctly -- Add middleware to new abilities, better ux for selecting permissions, etc. -- Root + read:sensive could read senstive data with a middlewarew -- Always have download logs button on scheduled tasks -- Missing css -- Development image -- Dockerignore -- DB migration error -- Drop all unused smtp columns -- Backward compatibility -- Email notification channel enabled function -- Instance email settins -- Make sure resend is false if SMTP is true and vice versa -- Email Notification saving -- Slack and discord url now uses text filed because encryption makes the url very long -- Notification trait -- Encryption fixes -- Docker cleanup email template -- Add missing deployment notifications to telegram -- New docker cleanup settings are now saved to the DB correctly -- Ui + migrations -- Docker cleanup email notifications -- General notifications does not go through email channel -- Test notifications to only send it to the right channel -- Remove resale_license from db as well -- Nexus service -- Fileflows volume names -- --cone -- Provider error -- Database migration -- Seeder -- Migration call -- Slack helper -- Telegram helper -- Discord helper -- Telegram topic IDs -- Make pushover settings more clear -- Typo in pushover user key -- Use Livewire refresh method and lock properties -- Create pushover settings for existing teams -- Update token permission check from 'write' to 'root' -- Pushover -- Oauth seeder -- Correct heading display for OAuth settings in settings-oauth.blade.php -- Adjust spacing in login form for improved layout -- Services env values should be sensitive -- Documenso -- Dolibarr -- Typo -- Update OauthSettingSeeder to handle new provider definitions and ensure authentik is recreated if missing -- Improve OauthSettingSeeder to correctly delete non-existent providers and ensure proper handling of provider definitions -- Encrypt resend API key in instance settings -- Resend api key is already a text column -- Monaco editor light and dark mode switching -- Service status indicator + oauth saving -- Socialite for azure and authentik -- Saving oauth -- Fallback for copy button -- Copy the right text -- Maybe fallback is now working -- Only show copy button on secure context -- Render html on error page correctly -- Invalid API response on missing project -- Applications API response code + schema -- Applications API writing to unavailable models -- If an init script is renamed the old version is still on the server -- Oauthseeder -- Compose loading seq -- Resource clone name + volume name generation -- Update Dockerfile entrypoint path to /etc/entrypoint.d -- Debug mode -- Unreachable notifications -- Remove duplicated ServerCheckJob call -- Few fixes and use new ServerReachabilityChanged event -- Use serverStatus not just status -- Oauth seeder -- Service ui structure -- Check port 8080 and fallback to 80 -- Refactor database view -- Always use docker cleanup frequency -- Advanced server UI -- Html css -- Fix domain being override when update application -- Use nixpacks predefined build variables, but still could update the default values from Coolify -- Use local monaco-editor instead of Cloudflare -- N8n timezone -- Smtp encryption -- Bind() to 0.0.0.0:80 failed -- Oauth seeder -- Unreachable notifications -- Instance settings migration -- Only encrypt instance email settings if there are any -- Error message -- Update healthcheck and port configurations to use port 8080 -- Compose envs -- Scheduled tasks and backups are executed by server timezone. -- Show backup timezone on the UI -- Disappearing UI after livewire event received -- Add default vector db for anythingllm -- We need XSRF-TOKEN for terminal -- Prevent default link behavior for resource and settings actions in dashboard -- Increase default php memory limit -- Show if only build servers are added to your team -- Update Livewire button click method to use camelCase -- Local dropzonejs -- Import backups due to js stuff should not be navigated -- Install inetutils on Arch Linux -- Use ip in place of hostname from inetutils in arch -- Update import command to append file redirection for database restoration -- Ui bug on pw confirmation -- Exclude system and computed fields from model replication -- Service cloning on a separate server -- Application cloning -- `Undefined variable $fs_path` for databases -- Service and database cloning and label generation -- Labels and URL generation when cloning -- Clone naming for different database data volumes -- Implement all the cloneMe changes for ResourceOperations as well -- Volume and fileStorages cloning -- View text and helpers -- Teable -- Trigger with external db -- Set `EXPERIMENTAL_FEATURES` to false for labelstudio -- Monaco editor disabled state -- Edge case where executions could be null -- Create destination properly -- Getcontainer status should timeout after 30s -- Enable response for temporary unavailability in sentinel push endpoint -- Use timeout in cleanup resources -- Add timeout to sentinel process checks for improved reliability -- Horizon job checker -- Update response message for sentinel push route -- Add own servers on cloud -- Application deployment -- Service update statsu -- If $SERVICE found in the service specific configuration, then search for it in the db -- Instance wide GitHub apps are not available on other teams then the source team -- Function calls -- UI -- Deletion of single backup -- Backup job deletion - delete all backups from s3 and local -- Use new removeOldBackups function -- Retention functions and folder deletion for local backups -- Storage retention setting -- Db without s3 should still backup -- Wording -- `Undefined variable $service` when creating a new service -- Nodebb service -- Calibre-web service -- Rallly and actualbudget service -- Removed container_name -- Added healthcheck for gotenberg template -- Gotenberg -- *(template)* Gotenberg healthcheck, use /health instead of /version -- Use wire:navigate on sidebar -- Use wire:navigate on dashboard -- Use wire:navigate on projects page -- More wire:navigate -- Even more wire:navigate -- Service navigation -- Logs icons everywhere + terminal -- Redis DB should use the new resourceable columns -- Joomla service -- Add back letters to prod password requirement -- Check System and GitHub time and throw and error if it is over 50s out of sync -- Error message and server time getting -- Error rendering -- Render html correctly now -- Indent -- Potential fix for permissions update -- Expiration time claim ('exp') must be a numeric value -- Sanitize html error messages -- Production password rule and cleanup code -- Use json as it is just better than string for huge amount of logs -- Use `wire:navigate` on server sidebar -- Use finished_at for the end time instead of created_at -- Cancelled deployments should not show end and duration time -- Redirect to server index instead of show on error in Advanced and DockerCleanup components -- Disable registration after creating the root user -- RootUserSeeder -- Regex username validation -- Add spacing around echo outputs -- Success message -- Silent return if envs are empty or not set. -- Create the private key before the server in the prod seeder -- Update ProductionSeeder to check for private key instead of server's private key -- *(ui)* Missing underline for docs link in the Swarm section (#4860) -- *(service)* Change chatwoot service postgres image from `postgres:12` to `pgvector/pgvector:pg12` -- Docker image parser -- Add public key attribute to privatekey model -- Correct service update logic in Docker Compose parser -- Update CDN URL in install script to point to nightly version -- *(service)* Add healthcheck to Cloudflared service (#4859) -- Remove wire:navigate from import backups -- *(ui)* Backups link should not redirected to general -- Envs with special chars during build -- *(db)* `finished_at` timestamps are not set for existing deployments -- Load service templates on cloud -- *(email)* Transactional email sending -- *(ui)* Add missing save button for new Docker Cleanup page -- *(ui)* Show preview deployment environment variables -- *(ui)* Show error on terminal if container has no shell (bash/sh) -- *(parser)* Resource URL should only be parsed if there is one -- *(core)* Compose parsing for apps -- *(redis)* Update environment variable keys from standalone_redis_id to resourceable_id -- *(routes)* Local API docs not available on domain or IP -- *(routes)* Local API docs not available on domain or IP -- *(core)* Update application_id references to resourable_id and resourable_type for Nixpacks configuration -- *(core)* Correct spelling of 'resourable' to 'resourceable' in Nixpacks configuration for ApplicationDeploymentJob -- *(ui)* Traefik dashboard url not working -- *(ui)* Proxy status badge flashing during navigation -- *(core)* Update environment variable generation logic in ApplicationDeploymentJob to handle different build packs -- *(env)* Shared variables can not be updated -- *(ui)* Metrics stuck in loading state -- *(ui)* Use `wire:navigate` to navigate to the server settings page -- *(service)* Plunk API & health check endpoint (#4925) -- *(service)* Infinite loading and lag with invoiceninja service (#4876) -- *(service)* Invoiceninja service -- *(workflows)* `Waiting for changes` label should also be considered and improved messages -- *(workflows)* Remove tags only if the PR has been merged into the main branch -- *(terminal)* Terminal shows that it is not available, even though it is -- *(labels)* Docker labels do not generated correctly -- *(helper)* Downgrade Nixpacks to v1.29.0 -- *(labels)* Generate labels when they are empty not when they are already generated -- *(storage)* Hetzner storage buckets not working -- *(ui)* Update database control UI to check server functionality before displaying actions -- *(ui)* Typo in upgrade message -- *(ui)* Cloudflare tunnel configuration should be an info, not a warning -- *(s3)* DigitalOcean storage buckets do not work -- *(ui)* Correct typo in container label helper text -- Disable certain parts if readonly label is turned off -- Cleanup old scheduled_task_executions -- Validate cron expression in Scheduled Task update -- *(core)* Check cron expression on save -- *(database)* Detect more postgres database image types -- *(templates)* Update service templates -- Remove quotes in COOLIFY_CONTAINER_NAME -- *(templates)* Update Trigger.dev service templates with v3 configuration -- *(database)* Adjust MongoDB restore command and import view styling -- *(core)* Improve public repository URL parsing for branch and base directory -- *(core)* Increase HTTP/2 max concurrent streams to 250 (default) -- *(ui)* Update docker compose file helper text to clarify repository modification -- *(ui)* Skip SERVICE_FQDN and SERVICE_URL variables during update -- *(core)* Stopping database is not disabling db proxy -- *(core)* Remove --remove-orphans flag from proxy startup command to prevent other proxy deletions (db) -- *(api)* Domain check when updating domain -- *(ui)* Always redirect to dashboard after team switch -- *(backup)* Escape special characters in database backup commands -- *(core)* Improve deployment failure Slack notification formatting -- *(core)* Update Slack notification formatting to use bold correctly -- *(core)* Enhance Slack deployment success notification formatting -- *(ui)* Simplify service templates loading logic -- *(ui)* Align title and add button vertically in various views -- Handle pullrequest:updated for reliable preview deployments -- *(ui)* Fix typo on team page (#5105) -- Cal.com documentation link give 404 (#5070) -- *(slack)* Notification settings URL in `HighDiskUsage` message (#5071) -- *(ui)* Correct typo in Storage delete dialog (#5061) -- *(lang)* Add missing italian translations (#5057) -- *(service)* Improve duplicati.yaml (#4971) -- *(service)* Links in homepage service (#5002) -- *(service)* Added SMTP credentials to getoutline yaml template file (#5011) -- *(service)* Added `KEY` Variable to Beszel Template (#5021) -- *(cloudflare-tunnels)* Dead links to docs (#5104) -- System-wide GitHub apps (#5114) -- Pull latest image from registry when using build server -- *(deployment)* Improve server selection for deployment cancellation -- *(deployment)* Improve log line rendering and formatting -- *(s3-storage)* Optimize team admin notification query -- *(core)* Improve connection testing with dynamic disk configuration for s3 backups -- *(core)* Update service status refresh event handling -- *(ui)* Adjust polling intervals for database and service status checks -- *(service)* Update Fider service template healthcheck command -- *(core)* Improve server selection error handling in Docker component -- *(core)* Add server functionality check before dispatching container status -- *(ui)* Disable sticky scroll in Monaco editor -- *(ui)* Add literal and multiline env support to services. -- *(services)* Owncloud docs link -- *(template)* Remove db-migration step from `infisical.yaml` (#5209) -- *(service)* Penpot (#5047) -- *(core)* Production dockerfile -- *(ui)* Update storage configuration guidance link -- *(ui)* Set default SMTP encryption to starttls -- *(notifications)* Correct environment URL path in application notifications -- *(config)* Update default PostgreSQL host to coolify-db instead of postgres -- *(docker)* Improve Docker compose file validation process -- *(ui)* Restrict service retrieval to current team -- *(core)* Only validate custom compose files -- *(mail)* Set default mailer to array when not specified -- *(ui)* Correct redirect routes after task deletion -- *(core)* Adding a new server should not try to make the default docker network -- *(core)* Clean up unnecessary files during application image build -- *(core)* Improve label generation and merging for applications and services -- *(billing)* Handle 'past_due' subscription status in Stripe processing -- *(revert)* Label parsing -- *(helpers)* Initialize command variable in parseCommandFromMagicEnvVariable -- *(billing)* Restrict Stripe subscription status update to 'active' only -- *(api)* Docker compose based apps creationg through api -- *(database)* Improve database type detection for Supabase Postgres images -- *(ssl)* Permission of ssl crt and key inside the container -- *(ui)* Make sure file mounts do not showing the encrypted values -- *(ssl)* Make default ssl mode require not verify-full as it does not need a ca cert -- *(ui)* Select component should not always uses title case -- *(db)* SSL certificates table and model -- *(migration)* Ssl certificates table -- *(databases)* Fix database name users new `uuid` instead of DB one -- *(database)* Fix volume and file mounts and naming -- *(migration)* Store subjectAlternativeNames as a json array in the db -- *(ssl)* Make sure the subjectAlternativeNames are unique and stored correctly -- *(ui)* Certificate expiration data is null before starting the DB -- *(deletion)* Fix DB deletion -- *(ssl)* Improve SSL cert file mounts -- *(ssl)* Always create ca crt on disk even if it is already there -- *(ssl)* Use mountPath parameter not a hardcoded path -- *(ssl)* Use 1 instead of on for mysql -- *(ssl)* Do not remove SSL directory -- *(ssl)* Wrong ssl cert is loaded to the server and UI error when regenerating SSL -- *(ssl)* Make sure when regenerating the CA cert it is not overwritten with a server cert -- *(ssl)* Regenerating certs for a specific DB -- *(ssl)* Fix MariaDB and MySQL need CA cert -- *(ssl)* Add mount path to DB to fix regeneration of certs -- *(ssl)* Fix SSL regeneration to sign with CA cert and use mount path -- *(ssl)* Get caCert correctly -- *(ssl)* Remove caCert even if it is a folder by accident -- *(ssl)* Ger caCert and `mountPath` correctly -- *(ui)* Only show Regenerate SSL Certificates button when there is a cert -- *(ssl)* Server id -- *(ssl)* When regenerating SSL certs the cert is not singed with the new CN -- *(ssl)* Adjust ca paths for MySQL -- *(ssl)* Remove mode selection for MariaDB as it is not supported -- *(ssl)* Permission issue with MariDB cert and key and paths -- *(ssl)* Rename Redis mode to verify-ca as it is not verify-full -- *(ui)* Remove unused mode for MongoDB -- *(ssl)* KeyDB port and caCert args are missing -- *(ui)* Enable SSL is not working correctly for KeyDB -- *(ssl)* Add `--tls` arg to DrangflyDB -- *(notification)* Always send SSL notifications -- *(database)* Change default value of enable_ssl to false for multiple tables -- *(ui)* Correct grammatical error in 404 page -- *(seeder)* Update GitHub app name in GithubAppSeeder -- *(plane)* Update APP_RELEASE to v0.25.2 in environment configuration -- *(domain)* Dispatch refreshStatus event after successful domain update -- *(database)* Correct container name generation for service databases -- *(database)* Limit container name length for database proxy -- *(database)* Handle unsupported database types in StartDatabaseProxy -- *(database)* Simplify container name generation in StartDatabaseProxy -- *(install)* Handle potential errors in Docker address pool configuration -- *(backups)* Retention settings -- *(redis)* Set default redis_username for new instances -- *(core)* Improve instantSave logic and error handling -- *(general)* Correct link to framework specific documentation -- *(core)* Redirect healthcheck route for dockercompose applications -- *(api)* Use name from request payload -- *(issue#4746)* Do not use setGitImportSettings inside of generateGitLsRemoteCommands -- Correct some spellings -- *(service)* Replace deprecated credentials env variables on keycloak service -- *(keycloak)* Update keycloak image version to 26.1 -- *(console)* Handle missing root user in password reset command -- *(ssl)* Handle missing CA certificate in SSL regeneration job -- *(copy-button)* Ensure text is safely passed to clipboard -- *(file-storage)* Double save on compose volumes -- *(parser)* Add logging support for applications in services -- Only get apps for the current team -- *(DeployController)* Cast 'pr' query parameter to integer -- *(deploy)* Validate team ID before deployment -- *(wakapi)* Typo in env variables and add some useful variables to wakapi.yaml (#5424) -- *(ui)* Instance Backup settings -- *(docs)* Comment out execute for now -- *(installation)* Mount the docker config -- *(installation)* Path to config file for docker login -- *(service)* Add health check to Bugsink service (#5512) -- *(email)* Emails are not sent in multiple cases -- *(deployments)* Use graceful shutdown instead of `rm` -- *(docs)* Contribute service url (#5517) -- *(proxy)* Proxy restart does not work on domain -- *(ui)* Only show copy button on https -- *(database)* Custom config for MongoDB (#5471) -- *(api)* Used ssh keys can be deleted -- *(email)* Transactional emails not sending -- *(CheckProxy)* Update port conflict check to ensure accurate grep matching -- *(CheckProxy)* Refine port conflict detection with improved grep patterns -- *(CheckProxy)* Enhance port conflict detection by adjusting ss command for better output -- *(api)* Add back validateDataApplications (#5539) -- *(CheckProxy, Status)* Prevent proxy checks when force_stop is active; remove debug statement in General -- *(Status)* Conditionally check proxy status and refresh button based on force_stop state -- *(General)* Change redis_password property to nullable string -- *(DeployController)* Update request handling to use input method and enhance OpenAPI description for deployment endpoint -- *(pre-commit)* Correct input redirection for /dev/tty and add OpenAPI generation command -- *(pricing-plans)* Adjust grid class for improved layout consistency in subscription pricing plans -- *(migrations)* Make stripe_comment field nullable in subscriptions table -- *(mongodb)* Also apply custom config when SSL is enabled -- *(templates)* Correct casing of denoKV references in service templates and YAML files -- *(deployment)* Handle missing destination in deployment process to prevent errors -- *(parser)* Transform associative array labels into key=value format for better compatibility -- *(redis)* Update username and password input handling to clarify database sync requirements -- *(source)* Update connected source display to handle cases with no source connected -- *(application)* Append base directory to git branch URLs for improved path handling -- *(templates)* Correct casing of "denokv" to "denoKV" in service templates JSON -- *(navbar)* Update error message link to use route for environment variables navigation -- Unsend template -- Replace ports with expose -- *(templates)* Update Unsend compose configuration for improved service integration -- *(backup-edit)* Conditionally enable S3 checkbox based on available validated S3 storage -- *(source)* Update no sources found message for clarity -- *(api)* Correct middleware for service update route to ensure proper permissions -- *(api)* Handle JSON response in service creation and update methods for improved error handling -- Add 201 json code to servers validate api response -- *(docker)* Ensure password hashing only occurs when HTTP Basic Authentication is enabled -- *(docker)* Enhance hostname and GPU option validation in Docker run to compose conversion -- *(terminal)* Enhance WebSocket client verification with authorized IPs in terminal server -- *(ApplicationDeploymentJob)* Ensure source is an object before checking GitHub app properties -- *(ui)* Disable livewire navigate feature (causing spam of setInterval()) -- *(ui)* Remove required attribute from image input in service application view -- *(ui)* Change application image validation to be nullable in service application view -- *(Server)* Correct proxy path formatting for Traefik proxy type -- *(service)* Graceful shutdown of old container (#5731) -- *(ServerCheck)* Enhance proxy container check to ensure it is running before proceeding -- *(applications)* Include pull_request_id in deployment queue check to prevent duplicate deployments -- *(database)* Update label for image input field to improve clarity -- *(ServerCheck)* Set default proxy status to 'exited' to handle missing container state -- *(database)* Reduce container stop timeout from 300 to 30 seconds for improved responsiveness -- *(ui)* System theming for charts (#5740) -- *(dev)* Mount points?! -- *(dev)* Proxy mount point -- *(ui)* Allow adding scheduled backups for non-migrated databases -- *(DatabaseBackupJob)* Escape PostgreSQL password in backup command (#5759) -- *(ui)* Correct closing div tag in service index view -- *(select)* Update fallback logo path to use absolute URL for improved reliability -- *(constants)* Adding 'fedora-asahi-remix' as a supported OS (#5646) -- *(authentik)* Update docker-compose configuration for authentik service -- *(api)* Allow nullable destination_uuid (#5683) -- *(service)* Fix documenso startup and mail (#5737) -- *(docker)* Fix production dockerfile -- *(service)* Navidrome service -- *(service)* Passbolt -- *(service)* Add missing ENVs to NTFY service (#5629) -- *(service)* NTFY is behind a proxy -- *(service)* Vert logo and ENVs -- *(service)* Add platform to Observium service -- *(ActivityMonitor)* Prevent multiple event dispatches during polling -- *(service)* Convex ENVs and update image versions (#5827) -- *(service)* Paymenter -- *(ApplicationDeploymentJob)* Ensure correct COOLIFY_FQDN/COOLIFY_URL values (#4719) -- *(service)* Snapdrop no matching manifest error (#5849) -- *(service)* Use the same volume between chatwoot and sidekiq (#5851) -- *(api)* Validate docker_compose_raw input in ApplicationsController -- *(api)* Enhance validation for docker_compose_raw in ApplicationsController -- *(select)* Update PostgreSQL versions and titles in resource selection -- *(database)* Include DatabaseStatusChanged event in activityMonitor dispatch -- *(css)* Tailwind v5 things -- *(service)* Diun ENV for consistency -- *(service)* Memos service name -- *(css)* 8+ issue with new tailwind v4 -- *(css)* `bg-coollabs-gradient` not working anymore -- *(ui)* Add back missing service navbar components -- *(deploy)* Update resource timestamp handling in deploy_resource method -- *(patches)* DNF reboot logic is flipped -- *(deployment)* Correct syntax for else statement in docker compose build command -- *(shared)* Remove unused relation from queryDatabaseByUuidWithinTeam function -- *(deployment)* Correct COOLIFY_URL and COOLIFY_FQDN assignments based on parsing version in preview deployments -- *(docker)* Ensure correct parsing of environment variables by limiting explode to 2 parts -- *(project)* Update selected environment handling to use environment name instead of UUID -- *(ui)* Update server status display and improve server addition layout -- *(service)* Neon WS Proxy service not working on ARM64 (#5887) -- *(server)* Enhance error handling in server patch check notifications -- *(PushServerUpdateJob)* Add null checks before updating application and database statuses -- *(environment-variables)* Update label text for build variable checkboxes to improve clarity -- *(service-management)* Update service stop and restart messages for improved clarity and formatting -- *(preview-form)* Update helper text formatting in preview URL template input for better readability -- *(application-management)* Improve stop messages for application, database, and service to enhance clarity and formatting -- *(application-configuration)* Prevent access to preview deployments for deploy_key applications and update menu visibility accordingly -- *(select-component)* Handle exceptions during parameter retrieval and environment selection in the mount method -- *(previews)* Escape container names in stopContainers method to prevent shell injection vulnerabilities -- *(docker)* Add protection against empty container queries in GetContainersStatus to prevent unnecessary updates -- *(modal-confirmation)* Decode HTML entities in confirmation text to ensure proper display -- *(select-component)* Enhance user interaction by adding cursor styles and disabling selection during processing -- *(deployment-show)* Remove unnecessary fixed positioning for button container to improve layout responsiveness -- *(email-notifications)* Change notify method to notifyNow for immediate test email delivery -- *(service-templates)* Update Convex service configuration to use FQDN variables -- *(database-heading)* Simplify stop database message for clarity -- *(navbar)* Remove unnecessary x-init directive for loading proxy configuration -- *(patches)* Add padding to loading message for better visibility during update checks -- *(terminal-connection)* Improve error handling and stability for auto-connection; enhance component readiness checks and retry logic -- *(terminal)* Add unique wire:key to terminal component for improved reactivity and state management -- *(css)* Adjust utility classes in utilities.css for consistent application of Tailwind directives -- *(css)* Refine utility classes in utilities.css for proper Tailwind directive application -- *(install)* Update Docker installation script to use dynamic OS_TYPE and correct installation URL -- *(cloudflare)* Add error handling to automated Cloudflare configuration script -- *(navbar)* Add error handling for proxy status check to improve user feedback -- *(web)* Update user team retrieval method for consistent authentication handling -- *(cloudflare)* Update refresh method to correctly set Cloudflare tunnel status and improve user notification on IP address update -- *(service)* Update service template for affine and add migration service for improved deployment process -- *(supabase)* Update Supabase service images and healthcheck methods for improved reliability -- *(terminal)* Now it should work -- *(degraded-status)* Remove unnecessary whitespace in badge element for cleaner HTML -- *(routes)* Add name to security route for improved route management -- *(migration)* Update default value handling for is_sentinel_enabled column in server_settings -- *(seeder)* Conditionally dispatch CheckAndStartSentinelJob based on server's sentinel status -- *(service)* Disable healthcheck logging for Gotenberg (#6005) -- *(service)* Joplin volume name (#5930) -- *(server)* Update sentinelUpdatedAt assignment to use server's sentinel_updated_at property -- *(service)* Audiobookshelf healthcheck command (#5993) -- *(service)* Downgrade Evolution API phone version (#5977) -- *(service)* Pingvinshare-with-clamav -- *(ssh)* Scp requires square brackets for ipv6 (#6001) -- *(github)* Changing github app breaks the webhook. it does not anymore -- *(parser)* Improve FQDN generation and update environment variable handling -- *(ui)* Enhance status refresh buttons with loading indicators -- *(ui)* Update confirmation button text for stopping database and service -- *(routes)* Update middleware for deploy route to use 'api.ability:deploy' -- *(ui)* Refine API token creation form and update helper text for clarity -- *(ui)* Adjust layout of deployments section for improved alignment -- *(ui)* Adjust project grid layout and refine server border styling for better visibility -- *(ui)* Update border styling for consistency across components and enhance loading indicators -- *(ui)* Add padding to section headers in settings views for improved spacing -- *(ui)* Reduce gap between input fields in email settings for better alignment -- *(docker)* Conditionally enable gzip compression in Traefik labels based on configuration -- *(parser)* Enable gzip compression conditionally for Pocketbase images and streamline service creation logic -- *(ui)* Update padding for trademarks policy and enhance spacing in advanced settings section -- *(ui)* Correct closing tag for sponsorship link in layout popups -- *(ui)* Refine wording in sponsorship donation prompt in layout popups -- *(ui)* Update navbar icon color and enhance popup layout for sponsorship support -- *(ui)* Add target="_blank" to sponsorship links in layout popups for improved user experience -- *(models)* Refine comment wording in User model for clarity on user deletion criteria -- *(models)* Improve user deletion logic in User model to handle team member roles and prevent deletion if user is alone in root team -- *(ui)* Update wording in sponsorship prompt for clarity and engagement -- *(shared)* Refactor gzip handling for Pocketbase in newParser function for improved clarity -- *(server)* Prepend 'mux_' to UUID in muxFilename method for consistent naming -- *(ui)* Enhance terminal access messaging to clarify server functionality and terminal status -- *(database)* Proxy ssl port if ssl is enabled -- *(terminal)* Ensure shell execution only uses valid shell if available in terminal command -- *(ui)* Improve destination selection description for clarity in resource segregation -- *(jobs)* Update middleware to use expireAfter for WithoutOverlapping in multiple job classes -- Removing eager loading (#6071) -- *(template)* Adjust health check interval and retries for excalidraw service -- *(ui)* Env variable settings wrong order -- *(service)* Ensure configuration changes are properly tracked and dispatched -- *(service)* Update Postiz compose configuration for improved server availability -- *(install.sh)* Use IPV4_PUBLIC_IP variable in output instead of repeated curl -- *(env)* Generate literal env variables better -- *(deployment)* Update x-data initialization in deployment view for improved functionality -- *(deployment)* Enhance COOLIFY_URL and COOLIFY_FQDN variable generation for better compatibility -- *(deployment)* Improve docker-compose domain handling and environment variable generation -- *(deployment)* Refactor domain parsing and environment variable generation using Spatie URL library -- *(deployment)* Update COOLIFY_URL and COOLIFY_FQDN generation to use Spatie URL library for improved accuracy -- *(scheduling)* Change redis cleanup command frequency from hourly to weekly for better resource management -- *(versions)* Update coolify version numbers in versions.json and constants.php to 4.0.0-beta.420.5 and 4.0.0-beta.420.6 -- *(database)* Ensure internal port defaults correctly for unsupported database types in StartDatabaseProxy -- *(git)* Tracking issue due to case sensitivity - *(versions)* Update coolify version numbers in versions.json and constants.php to 4.0.0-beta.420.6 and 4.0.0-beta.420.7 - *(scheduling)* Remove unnecessary padding from scheduled task form layout for improved UI consistency - *(horizon)* Update queue configuration to use environment variable for dynamic queue management @@ -3779,6 +419,7 @@ All notable changes to this project will be documented in this file. - *(application)* Add option to suppress toast notifications when loading compose file - *(git)* Tracking issue due to case sensitivity - *(git)* Tracking issue due to case sensitivity +- *(git)* Tracking issue due to case sensitivity - *(ui)* Delete button width on small screens (#6308) - *(service)* Matrix entrypoint - *(ui)* Add flex-wrap to prevent overflow on small screens (#6307) @@ -4371,397 +1012,28 @@ All notable changes to this project will be documented in this file. - Disable prepared statements for PgBouncer compatibility - Make PgBouncer prepared statement disabling configurable - Make PgBouncer prepared statement disabling configurable (#7876) +- *(service)* Add instagram envs to postiz template (#6424) +- *(service)* Use fqdn for server host in sequin template (#6528) +- *(service)* Wireguard easy host to use fqdn (#7354) +- *(log)* Preserve leading whitespace in logs (#7879) +- *(docs)* Remove environments from projects endpoint +- Instance public ips initialization validation (#7762) +- *(ui)* Instance public ips ui validation +- Cast docker version to int for proper comparison (#7760) +- *(docs)* Api docs for bulk env update response (#7714) +- Db public port instant save and simplify if condition (#7883) +- *(ui)* Empty network destinations when cloning a resource (#7309) +- *(env)* Custom environment variable sorting (#7887) +- *(service)* Budibase worker envs +- *(docker)* Add fallback for Docker Swarm container labels +- Prevent timing attack in GitLab webhook token validation +- GitLab webhook validation (#7899) +- *(service)* Supabase studio fails to load schemas +- *(git)* Trigger deployments when watch_paths is empty +- *(backup)* Database restores with custom db name ### 💼 Other -- Only allow cleanup in production -- Make copy/password visible -- Dns check -- Remote docker engine -- Colorful states -- Application start -- Colors on svelte-select -- Improvements -- Fix -- Better layout for root team -- Fix -- Fixes -- Fix -- Fix -- Fix -- Fix -- Fix -- Fix -- Fix -- Insane amount -- Fix -- Fixes -- Fixes -- Fix -- Fixes -- Fixes -- Show extraconfig if wp is running -- Umami service -- Base image selector -- Laravel -- Appwrite -- Testing WS -- Traefik?! -- Traefik -- Traefik -- Traefik migration -- Traefik -- Traefik -- Traefik -- Notifications and application usage -- *(fix)* Traefik -- Css -- Error message https://github.com/coollabsio/coolify/issues/502 -- Changes -- Settings -- For removing app -- Local ssh port -- Redesign a lot -- Fixes -- Loading indicator for plausible buttons -- Fix -- Fider -- Typing -- Fixes here and there -- Dashboard fine-tunes -- Fine-tune -- Fixes -- Fix -- Dashbord fixes -- Fixes -- Fixes -- Route to the correct path when creating destination from db config -- Fixes -- Change tooltips and info boxes -- Added rc release -- Database_branches -- Login page -- Fix login/register page -- Update devcontainer -- Add debug log -- Fix initial loading icon bg -- Fix loading start/stop db/services -- Dashboard updates and a lot more -- Dashboard updates -- Fix tooltip -- Fix button -- Fix follow button -- Arm should be on next all the time -- Fix plausible -- Fix cleanup button -- Fix buttons -- Responsive! -- Fixes -- Fix git icon -- Dropdown as infobox -- Small logs on mobile -- Improvements -- Fix destination view -- Settings view -- More UI improvements -- Fixes -- Fixes -- Fix -- Fixes -- Beta features -- Fix button -- Service fixes -- Fix basedirectory meaning -- Resource button fix -- Main resource search -- Dev logs -- Loading button -- Fix gitlab importer view -- Small fix -- Beta flag -- Hasura console notification -- Fix -- Fix -- Fixes -- Inprogress version of iam -- Fix indicato -- Iam & settings update -- Send 200 for ping and installation wh -- Settings icon -- Docker-compose support -- Docker compose -- Remove worker jobs -- One less worker thread -- New resource label -- Secrets on apps -- Fix -- Fixes -- Reload compose loading -- Pocketbase release -- Trpc -- Trpc -- Trpc -- Trpc -- Trpc -- Trpc -- Trpc -- Trpc -- Trpc -- Trpc -- Conditional on environment -- Add missing variables -- Trpc -- Trpc -- Trpc -- Trpc -- Trpc -- Trpc -- Trpc -- Extract process handling from async job. -- Extract process handling from async job. -- Extract process handling from async job. -- Extract process handling from async job. -- Extract process handling from async job. -- Extract process handling from async job. -- Extract process handling from async job. -- Persisting data -- Scheduled backups -- Boarding -- Backup existing database -- User should know that the public key -- Services are not availble yet -- Show registered users on waitlist page -- Nixpacksarchive -- Add Plausible analytics -- Global env variables -- Fix -- Trial emails -- Server check instead of app check -- Show trial instead of sub -- Server lost connection -- Services -- Services -- Services -- Ui for services -- Services -- Services -- Services -- Fixes -- Fix typo -- Fixed z-index for version link. -- Add source button -- Fixed z-index for magicbar -- A bit better error -- More visible feedback button -- Update help modal -- Help -- Marketing emails -- Fix previews to preview -- Uptime kume hc updated -- Switch back to /data (volume errors) -- Notifications -- Add shared email option to everyone -- Dockerimage -- Updated dashboard -- Fix -- Fix -- Coolify proxy access logs exposed in dev -- Able to select environment on new resource -- Delete server -- Redis -- Wordpress -- Add helper to service domains -- PAT by team -- Generate services -- Mongodb backup -- Mongodb backup -- Updates -- Fix subs -- New deployment jobs -- Compose based apps -- Swarm -- Swarm -- Swarm -- Swarm -- Disable trial -- Meilisearch -- Broadcast -- 🌮 -- Env vars -- Migrate to livewire 3 -- Fix for comma in labels -- Add image name to service stack + better options visibility -- Swarm -- Swarm -- Send notification email if payment -- New modal component -- Specific about newrelic logdrains -- Updates -- Change + icon to hamburger. -- Redesign -- Redesign -- Run cleanup every day -- Fix -- Fix log outputs -- Automatic cloudflare tunnels -- Backup executions -- Light buttons -- Multiple server view -- New pricing -- Fix allowTab logic -- Use 2 space instead of tab -- Non-root user for remote servers -- Non-root -- Update resource operations view -- Fix tag view -- Fix a few boxes here and there -- Responsive here and there -- Rocketchat -- New services based git apps -- Unnecessary notification -- Update process -- Glances service -- Glances -- Able to update application -- Add basedir + compose file in new compose based apps -- Formbricks template add required CRON_SECRET -- Add required CRON_SECRET to Formbricks template -- Service env parsing -- Actually update timezone on the server -- Cron jobs are executed based on the server timezone -- Server timezone seeder -- Recent backups UI -- Use apt-get instead of apt -- Typo -- Only pull helper image if the version is newer than the one -- Plunk svg -- Pull helper image if not available otherwise s3 backup upload fails -- Set a default server timezone -- Implement SSH Multiplexing -- Enabel mux -- Cleanup stale multiplexing connections -- Remote servers with port and user -- Do not change localhost server name on revalidation -- Release.md file -- SSH Multiplexing on docker desktop on Windows -- Remove labels and assignees on issue close -- Make sure this action is also triggered on PR issue close -- Volumes on development environment -- Clean new volume name for dev volumes -- Persist DBs, services and so on stored in data/coolify -- Add SSH Key fingerprint to DB -- Add a fingerprint to every private key on save, create... -- Make sure invalid private keys can not be added -- Encrypt private SSH keys in the DB -- Add is_sftp and is_server_ssh_key coloums -- New ssh key file name on disk -- Store all keys on disk by default -- Populate SSH key folder -- Populate SSH keys in dev -- Use new function names and logic everywhere -- Create a Multiplexing Helper -- SSH multiplexing -- Remove unused code form multiplexing -- SSH Key cleanup job -- Private key with ID 2 on dev -- Move more functions to the PrivateKey Model -- Add ssh key fingerprint and generate one for existing keys -- ID issues on dev seeders -- Server ID 0 -- Make sure in use private keys are not deleted -- Do not delete SSH Key from disk during server validation error -- UI bug, do not write ssh key to disk in server dialog -- SSH Multiplexing for Jobs -- SSH algorhytm text -- Few multiplexing things -- Clear mux directory -- Multiplexing do not write file manually -- Integrate tow step process in the modal component WIP -- Ability to hide labels -- DB start, stop confirm -- Del init script -- General confirm -- Preview deployments and typos -- Service confirmation -- Confirm file storage -- Stop service confirm -- DB image cleanup -- Confirm ressource operation -- Environment variabel deletion -- Confirm scheduled tasks -- Confirm API token -- Confirm private key -- Confirm server deletion -- Confirm server settings -- Proxy stop and restart confirmation -- GH app deletion confirmation -- Redeploy all confirmation -- User deletion confirmation -- Team deletion confirmation -- Backup job confirmation -- Delete volume confirmation -- More conformations and fixes -- Delete unused private keys button -- Ray error because port is not uncommented -- #3322 deploy DB alterations before updating -- Css issue with advanced settings and remove cf tunnel in onboarding -- New cf tunnel install flow -- Made help text more clear -- Cloudflare tunnel -- Make helper text more clean to use a FQDN and not an URL -- Manual cleanup button and unused volumes and network deletion -- Force helper image removal -- Use the new confirmation flow -- Typo -- Typo in install script -- If API is disabeled do not show API token creation stuff -- Disable API by default -- Add debug bar -- Remove memlock as it caused problems for some users -- Server storage check -- Show backup button on supported db service stacks -- Update helper version -- Outline -- Directus -- Supertokens -- Supertokens json -- Rabbitmq -- Easyappointments -- Soketi -- Dozzle -- Windmill -- Coolify.json -- Keycloak -- Other DB options for freshrss -- Nextcloud MariaDB and MySQL versions -- Add peppermint -- Loggy -- Add UI for redis password and username -- Wireguard-easy template -- Https://github.com/coollabsio/coolify/issues/4186 -- Separate resources by type in projects view -- Improve s3 add view -- Caddy docker labels do not honor "strip prefix" option -- Test rename GitHub app -- Checkmate service and fix prowlar slogan (too long) -- Arrrrr -- Dep -- Docker dep -- Trigger.dev templates - wrong key length issue -- Trigger.dev template - missing ports and wrong env usage -- Trigger.dev template - fixed otel config -- Trigger.dev template - fixed otel config -- Trigger.dev template - fixed port config -- Bump all dependencies (#5216) -- Bump Coolify to 4.0.0-beta.398 -- Bump Coolify to 4.0.0-beta.400 -- *(migration)* Add SSL fields to database tables -- SSL Support for KeyDB -- Add missing UUID to openapi spec -- Add missing openapi items to PrivateKey -- Adjust Workflows for v5 (#5689) -- Add support for postmarketOS (#5608) -- *(core)* Simplify events for app/db/service status changes - *(settings-dropdown)* Add icons to buttons for improved UI in settings dropdown - *(ui)* Introduce task for simplifying resource operations UI by replacing boxes with dropdown selections to enhance user experience and streamline interactions - Allow deploy from container image hash @@ -4838,426 +1110,6 @@ All notable changes to this project will be documented in this file. ### 🚜 Refactor -- Code -- Env variable generator -- Service logs are now on one page -- Application status changed realtime -- Custom labels -- Clone project -- Compose file and install script -- Add SCHEDULER environment variable to StartSentinel.php -- Update edit-domain form in project service view -- Add Huly services to compose file -- Remove redundant heading in backup settings page -- Add isBuildServer method to Server model -- Update docker network creation in ApplicationDeploymentJob -- Update destination.blade.php to add group class for better styling -- Applicationdeploymentjob -- Improve code structure in ApplicationDeploymentJob.php -- Remove unnecessary debug statement in ApplicationDeploymentJob.php -- Remove unnecessary debug statements and improve code structure in RunRemoteProcess.php and ApplicationDeploymentJob.php -- Remove unnecessary logging statements from UpdateCoolify -- Update storage form inputs in show.blade.php -- Improve Docker Compose parsing for services -- Remove unnecessary port appending in updateCompose function -- Remove unnecessary form class in profile index.blade.php -- Update form layout in invite-link.blade.php -- Add log entry when starting new application deployment -- Improve Docker Compose parsing for services -- Update Docker Compose parsing for services -- Update slogan in shlink.yaml -- Improve display of deployment time in index.blade.php -- Remove commented out code for clearing Ray logs -- Update save_environment_variables method to use application's environment_variables instead of environment_variables_preview -- Append utm_source parameter to documentation URL -- Update save_environment_variables method to use application's environment_variables instead of environment_variables_preview -- Update deployment previews heading to "Deployments" -- Remove unused variables and improve code readability -- Initialize null properties in Github Change component -- Improve pre and post deployment command inputs -- Improve handling of Docker volumes in parseDockerComposeFile function -- Replaces duplications in code with a single function -- Update text color for stderr output in deployment show view -- Update text color for stderr output in deployment show view -- Remove debug code for saving environment variables -- Update Docker build commands for better performance and flexibility -- Update image sizes and add new logos to README.md -- Update README.md with new logos and fix styling -- Update shared.php to use correct key for retrieving sentinel version -- Update container name assignment in Application model -- Remove commented code for docker container removal -- Update Application model to include getDomainsByUuid method -- Update Project/Show component to sort environments by created_at -- Update profile index view to display 2FA QR code in a centered container -- Update dashboard.blade.php to use project's default environment for redirection -- Update gitCommitLink method to handle null values in source.html_url -- Update docker-compose generation to use multi-line literal block -- Update Service model's saveComposeConfigs method -- Add default environment to Service model's saveComposeConfigs method -- Improve handling of default environment in Service model's saveComposeConfigs method -- Remove commented out code in Service model's saveComposeConfigs method -- Update stack-form.blade.php to include wire:target attribute for submit button -- Update code to use str() instead of Str::of() for string manipulation -- Improve formatting and readability of source.blade.php -- Add is_build_time property to nixpacks_php_fallback_path and nixpacks_php_root_dir -- Simplify code for retrieving subscription in Stripe webhook -- Add force parameter to StartProxy handle method -- Comment out unused code for network cleanup -- Reset default labels when docker_compose_domains is modified -- Webhooks view -- Tags view -- Only get instanceSettings once from db -- Update Dockerfile to set CI environment variable to true -- Remove unnecessary code in AppServiceProvider.php -- Update Livewire configuration views -- Update Webhooks.php to use nullable type for webhook URLs -- Add lazy loading to tags in Livewire configuration view -- Update metrics.blade.php to improve alert message clarity -- Update version numbers to 4.0.0-beta.312 -- Update version numbers to 4.0.0-beta.314 -- Remove unused code and fix storage form layout -- Update Docker Compose build command to include --pull flag -- Update DockerCleanupJob to handle nullable usageBefore property -- Server status job and docker cleanup job -- Update DockerCleanupJob to use server settings for force cleanup -- Update DockerCleanupJob to use server settings for force cleanup -- Disable health check for Rust applications during deployment -- Update CleanupDatabase.php to adjust keep_days based on environment -- Adjust keep_days in CleanupDatabase.php based on environment -- Remove commented out code for cleaning up networks in CleanupDocker.php -- Update livewire polling interval in heading.blade.php -- Remove unused code for checking server status in Heading.php -- Simplify log drain installation in ServerCheckJob -- Remove unnecessary debug statement in ServerCheckJob -- Simplify log drain installation and stop log drain if necessary -- Cleanup unnecessary dynamic proxy configuration in Init command -- Remove unnecessary debug statement in ApplicationDeploymentJob -- Update timeout for graceful_shutdown_container in ApplicationDeploymentJob -- Remove unused code and optimize CheckForUpdatesJob -- Update ProxyTypes enum values to use TRAEFIK instead of TRAEFIK_V2 -- Update Traefik labels on init and cleanup unnecessary dynamic proxy configuration -- Update StandalonePostgresql database initialization and backup handling -- Update cron expressions and add helper text for scheduled tasks -- Update Server model getContainers method to use collect() for containers and containerReplicates -- Import ProxyTypes enum and use TRAEFIK instead of TRAEFIK_V2 -- Update event listeners in Show components -- Refresh application to get latest database changes -- Update RabbitMQ configuration to use environment variable for port -- Remove debug statement in parseDockerComposeFile function -- ParseServiceVolumes -- Update OpenApi command to generate documentation -- Remove unnecessary server status check in destination view -- Remove unnecessary admin user email and password in budibase.yaml -- Improve saving of custom internal name in Advanced.php -- Add conditional check for volumes in generate_compose_file() -- Improve storage mount forms in add.blade.php -- Load environment variables based on resource type in sortEnvironmentVariables() -- Remove unnecessary network cleanup in Init.php -- Remove unnecessary environment variable checks in parseDockerComposeFile() -- Add null check for docker_compose_raw in parseCompose() -- Update dockerComposeParser to use YAML data from $yaml instead of $compose -- Convert service variables to key-value pairs in parseDockerComposeFile function -- Update database service name from mariadb to mysql -- Remove unnecessary code in DatabaseBackupJob and BackupExecutions -- Update Docker Compose parsing function to convert service variables to key-value pairs -- Update Docker Compose parsing function to convert service variables to key-value pairs -- Remove unused server timezone seeder and related code -- Remove unused server timezone seeder and related code -- Remove unused PullCoolifyImageJob from schedule -- Update parse method in Advanced, All, ApplicationPreview, General, and ApplicationDeploymentJob classes -- Remove commented out code for getIptables() in Dashboard.php -- Update .env file path in install.sh script -- Update SELF_HOSTED environment variable in docker-compose.prod.yml -- Remove unnecessary code for creating coolify network in upgrade.sh -- Update environment variable handling in StartClickhouse.php and ApplicationDeploymentJob.php -- Improve handling of COOLIFY_URL in shared.php -- Update build_args property type in ApplicationDeploymentJob -- Update background color of sponsor section in README.md -- Update Docker Compose location handling in PublicGitRepository -- Upgrade process of Coolify -- Improve handling of server timezones in scheduled backups and tasks -- Improve handling of server timezones in scheduled backups and tasks -- Improve handling of server timezones in scheduled backups and tasks -- Update cleanup schedule to run daily at midnight -- Skip returning volume if driver type is cifs or nfs -- Improve environment variable handling in shared.php -- Improve handling of environment variable merging in upgrade script -- Remove unnecessary code in ExecuteContainerCommand.php -- Improve Docker network connection command in StartService.php -- Terminal / run command -- Add authorization check in ExecuteContainerCommand mount method -- Remove unnecessary code in Terminal.php -- Remove unnecessary code in Terminal.blade.php -- Update WebSocket connection initialization in terminal.blade.php -- Remove unnecessary console.log statements in terminal.blade.php -- Update Docker cleanup label in Heading.php and Navbar.php -- Remove commented out code in Navbar.php -- Remove CleanupSshKeysJob from schedule in Kernel.php -- Update getAJoke function to exclude offensive jokes -- Update getAJoke function to use HTTPS for API request -- Update CleanupHelperContainersJob to use more efficient Docker command -- Update PrivateKey model to improve code readability and maintainability -- Remove unnecessary code in PrivateKey model -- Update PrivateKey model to use ownedByCurrentTeam() scope for cleanupUnusedKeys() -- Update install.sh script to check if coolify-db volume exists before generating SSH key -- Update ServerSeeder and PopulateSshKeysDirectorySeeder -- Improve attribute sanitization in Server model -- Update confirmation button text for deletion actions -- Remove unnecessary code in shared.php file -- Update environment variables for services in compose files -- Update select.blade.php to improve trademarks policy display -- Update select.blade.php to improve trademarks policy display -- Fix typo in subscription URLs -- Add Postiz service to compose file (disabled for now) -- Update shared.php to include predefined ports for services -- Simplify SSH key synchronization logic -- Remove unused code in DatabaseBackupStatusJob and PopulateSshKeysDirectorySeeder -- Remove commented out code and improve environment variable handling in newParser function -- Improve label positioning in input and checkbox components -- Group and sort fields in StackForm by service name and password status -- Improve layout and add checkbox for task enablement in scheduled task form -- Update checkbox component to support full width option -- Update confirmation label in danger.blade.php template -- Fix typo in execute-container-command.blade.php -- Update OS_TYPE for Asahi Linux in install.sh script -- Add localhost as Server if it doesn't exist and not in cloud environment -- Add localhost as Server if it doesn't exist and not in cloud environment -- Update ProductionSeeder to fix issue with coolify_key assignment -- Improve modal confirmation titles and button labels -- Update install.sh script to remove redirection of upgrade output to /dev/null -- Fix modal input closeOutside prop in configuration.blade.php -- Add support for IPv6 addresses in sslip function -- Update environment variable name for uptime-kuma service -- Improve start proxy script to handle existing containers gracefully -- Update delete server confirmation modal buttons -- Remove unnecessary code -- Update search input placeholder in resource index view -- Remove deployment queue when deleting an application -- Improve SSH command generation in Terminal.php and terminal-server.js -- Fix indentation in modal-confirmation.blade.php -- Improve parsing of commands for sudo in parseCommandsByLineForSudo -- Improve popup component styling and button behavior -- Encode delimiter in SshMultiplexingHelper -- Remove inactivity timer in terminal-server.js -- Improve socket reconnection interval in terminal.js -- Remove unnecessary watch command from soketi service entrypoint -- Update Traefik configuration for improved security and logging -- Improve proxy configuration and code consistency in Server model -- Rename name method to sanitizedName in BaseModel for clarity -- Improve migration command and enhance application model with global scope and status checks -- Unify notification icon -- Remove unused Azure and Authentik service configurations from services.php -- Change email column types in instance_settings migration from string to text -- Change OauthSetting creation to updateOrCreate for better handling of existing records -- Rename `coolify.environment` to `coolify.environmentName` -- Rename parameter in DatabaseBackupJob for clarity -- Improve checkbox component accessibility and styling -- Remove unused tags method from ApplicationDeploymentJob -- Improve deployment status check in isAnyDeploymentInprogress function -- Extend HorizonServiceProvider from HorizonApplicationServiceProvider -- Streamline job status retrieval and clean up repository interface -- Enhance ApplicationDeploymentJob and HorizonServiceProvider for improved job handling -- Remove commented-out unsubscribe route from API -- Update redirect calls to use a consistent navigation method in deployment functions -- AppServiceProvider -- Github.php -- Improve data formatting and UI -- Comment out RootUserSeeder call in ProductionSeeder for clarity -- Streamline ProductionSeeder by removing debug logs and unnecessary checks, while ensuring essential seeding operations remain intact -- Remove debug echo statements from Init command to clean up output and improve readability -- *(workflows)* Replace jq with PHP script for version retrieval in workflows -- *(s3)* Improve S3 bucket endpoint formatting -- *(vite)* Improve environment variable handling in Vite configuration -- *(ui)* Simplify GitHub App registration UI and layout -- Simplify service start and restart workflows -- Use pull flag on docker compose up -- *(ui)* Simplify file storage modal confirmations -- *(notifications)* Improve transactional email settings handling -- *(scheduled-tasks)* Improve scheduled task creation and management -- *(billing)* Enhance Stripe subscription status handling and notifications -- *(ui)* Unhide log toggle in application settings -- *(nginx)* Streamline default Nginx configuration and improve error handling -- *(install)* Clean up install script and enhance Docker installation logic -- *(ScheduledTask)* Clean up code formatting and remove unused import -- *(app)* Remove unused MagicBar component and related code -- *(database)* Streamline SSL configuration handling across database types -- *(application)* Streamline healthcheck parsing from Dockerfile -- *(notifications)* Standardize getRecipients method signatures -- *(configuration)* Centralize configuration management in ConfigurationRepository -- *(docker)* Update image references to use centralized registry URL -- *(env)* Add centralized registry URL to environment configuration -- *(storage)* Simplify file storage iteration in Blade template -- *(models)* Add is_directory attribute to LocalFileVolume model -- *(modal)* Add ignoreWire attribute to modal-confirmation component -- *(invite-link)* Adjust layout for better responsiveness in form -- *(invite-link)* Enhance form layout for improved responsiveness -- *(network)* Enhance docker network creation with ipv6 fallback -- *(network)* Check for existing coolify network before creation -- *(database)* Enhance encryption process for local file volumes -- *(proxy)* Improve port availability checks with multiple methods -- *(database)* Update MongoDB SSL configuration for improved security -- *(database)* Enhance SSL configuration handling for various databases -- *(notifications)* Update Telegram button URL for staging environment -- *(models)* Remove unnecessary cloud check in isEnabled method -- *(database)* Streamline event listeners in Redis General component -- *(database)* Remove redundant database status display in MongoDB view -- *(database)* Update import statements for Auth in database components -- *(database)* Require PEM key file for SSL certificate regeneration -- *(database)* Change MySQL daemon command to MariaDB daemon -- *(nightly)* Update version numbers and enhance upgrade script -- *(versions)* Update version numbers for coolify and nightly -- *(email)* Validate team membership for email recipients -- *(shared)* Simplify deployment status check logic -- *(shared)* Add logging for running deployment jobs -- *(shared)* Enhance job status check to include 'reserved' -- *(email)* Improve error handling by passing context to handleError -- *(email)* Streamline email sending logic and improve configuration handling -- *(email)* Remove unnecessary whitespace in email sending logic -- *(email)* Allow custom email recipients in email sending logic -- *(email)* Enhance sender information formatting in email logic -- *(proxy)* Remove redundant stop call in restart method -- *(file-storage)* Add loadStorageOnServer method for improved error handling -- *(docker)* Parse and sanitize YAML compose file before encoding -- *(file-storage)* Improve layout and structure of input fields -- *(email)* Update label for test email recipient input -- *(database-backup)* Remove existing Docker container before backup upload -- *(database)* Improve decryption and deduplication of local file volumes -- *(database)* Remove debug output from volume update process -- *(dev)* Remove OpenAPI generation functionality -- *(migration)* Enhance local file volumes migration with logging -- *(CheckProxy)* Replace 'which' with 'command -v' for command availability checks -- *(Server)* Use data_get for safer access to settings properties in isFunctional method -- *(Application)* Rename network_aliases to custom_network_aliases across the application for clarity and consistency -- *(ApplicationDeploymentJob)* Streamline environment variable handling by introducing generate_coolify_env_variables method and consolidating logic for pull request and main branch scenarios -- *(ApplicationDeploymentJob, ApplicationDeploymentQueue)* Improve deployment status handling and log entry management with transaction support -- *(SourceManagement)* Sort sources by name and improve UI for changing Git source with better error handling -- *(Email)* Streamline SMTP and resend settings handling in copyFromInstanceSettings method -- *(Email)* Enhance error handling in SMTP and resend methods by passing context to handleError function -- *(DynamicConfigurations)* Improve handling of dynamic configuration content by ensuring fallback to empty string when content is null -- *(ServicesGenerate)* Update command signature from 'services:generate' to 'generate:services' for consistency; update Dockerfile to run service generation during build; update Odoo image version to 18 and add extra addons volume in compose configuration -- *(Dockerfile)* Streamline RUN commands for improved readability and maintainability by adding line continuations -- *(Dockerfile)* Reintroduce service generation command in the build process for consistency and ensure proper asset compilation -- *(commands)* Reorganize OpenAPI and Services generation commands into a new namespace for better structure; remove old command files -- *(Dockerfile)* Remove service generation command from the build process to streamline Dockerfile and improve build efficiency -- *(navbar-delete-team)* Simplify modal confirmation layout and enhance button styling for better user experience -- *(Server)* Remove debug logging from isReachableChanged method to clean up code and improve performance -- *(source)* Conditionally display connected source and change source options based on private key presence -- *(jobs)* Update WithoutOverlapping middleware to use expireAfter for better queue management -- *(jobs)* Comment out unused Caddy label handling in ApplicationDeploymentJob and simplify proxy path logic in Server model -- *(database)* Simplify database type checks in ServiceDatabase and enhance image validation in Docker helper -- *(shared)* Remove unused ray debugging statement from newParser function -- *(applications)* Remove redundant error response in create_env method -- *(api)* Restructure routes to include versioning and maintain existing feedback endpoint -- *(api)* Remove token variable from OpenAPI specifications for clarity -- *(environment-variables)* Remove protected variable checks from delete methods for cleaner logic -- *(http-basic-auth)* Rename 'http_basic_auth_enable' to 'http_basic_auth_enabled' across application files for consistency -- *(docker)* Remove debug statement and enhance hostname handling in Docker run conversion -- *(server)* Simplify proxy path logic and remove unnecessary conditions -- *(Database)* Streamline container shutdown process and reduce timeout duration -- *(core)* Streamline container stopping process and reduce timeout duration; update related methods for consistency -- *(database)* Update DB facade usage for consistency across service files -- *(database)* Enhance application conversion logic and add existence checks for databases and applications -- *(actions)* Standardize method naming for network and configuration deletion across application and service classes -- *(logdrain)* Consolidate log drain stopping logic to reduce redundancy -- *(StandaloneMariadb)* Add type hint for destination method to improve code clarity -- *(DeleteResourceJob)* Streamline resource deletion logic and improve conditional checks for database types -- *(jobs)* Update middleware to prevent job release after expiration for CleanupInstanceStuffsJob, RestartProxyJob, and ServerCheckJob -- *(jobs)* Unify middleware configuration to prevent job release after expiration for DockerCleanupJob and PushServerUpdateJob -- *(service)* Observium -- *(service)* Improve leantime -- *(service)* Imporve limesurvey -- *(service)* Improve CodiMD -- *(service)* Typsense -- *(services)* Improve yamtrack -- *(service)* Improve paymenter -- *(service)* Consolidate configuration change dispatch logic and remove unused navbar component -- *(sidebar)* Simplify server patching link by removing button element -- *(slide-over)* Streamline button element and improve code readability -- *(service)* Enhance modal confirmation component with event dispatching for service stop actions -- *(slide-over)* Enhance class merging for improved component styling -- *(core)* Use property promotion -- *(service)* Improve maybe -- *(applications)* Remove unused docker compose raw decoding -- *(service)* Make TYPESENSE_API_KEY required -- *(ui)* Show toast when server does not work and on stop -- *(service)* Improve superset -- *(service)* Improve Onetimesecret -- *(service)* Improve Seafile -- *(service)* Improve orangehrm -- *(service)* Improve grist -- *(application)* Enhance application stopping logic to support multiple servers -- *(pricing-plans)* Improve label class binding for payment frequency selection -- *(error-handling)* Replace generic Exception with RuntimeException for improved error specificity -- *(error-handling)* Change Exception to RuntimeException for clearer error reporting -- *(service)* Remove informational dispatch during service stop for cleaner execution -- *(server-ui)* Improve layout and messaging in advanced settings and charts views -- *(terminal-access)* Streamline resource retrieval and enhance terminal access messaging in UI -- *(terminal)* Enhance terminal connection management and error handling, including improved reconnection logic and cleanup procedures -- *(application-deployment)* Separate handling of FAILED and CANCELLED_BY_USER statuses for clearer logic and notification -- *(jobs)* Update middleware to include job-specific identifiers for WithoutOverlapping -- *(jobs)* Modify middleware to use job-specific identifier for WithoutOverlapping -- *(environment-variables)* Remove debug logging from bulk submit handling for cleaner code -- *(environment-variables)* Simplify application build pack check in environment variable handling -- *(logs)* Adjust padding in logs view for improved layout consistency -- *(application-deployment)* Streamline post-deployment process by always dispatching container status check -- *(service-management)* Enhance container stopping logic by implementing parallel processing and removing deprecated methods -- *(activity-monitor)* Change activity property visibility and update view references for consistency -- *(activity-monitor)* Enhance layout responsiveness by adjusting class bindings and structure for better display -- *(service-management)* Update stopContainersInParallel method to enforce Server type hint for improved type safety -- *(service-management)* Rearrange docker cleanup logic in StopService to improve readability -- *(database-management)* Simplify docker cleanup logic in StopDatabase to enhance readability -- *(activity-monitor)* Consolidate activity monitoring logic and remove deprecated NewActivityMonitor component -- *(activity-monitor)* Update dispatch method to use activityMonitor instead of deprecated newActivityMonitor -- *(push-server-update)* Enhance application preview handling by incorporating pull request IDs and adding status update protections -- *(docker-compose)* Replace hardcoded Docker Compose configuration with external YAML template for improved database detection testing -- *(test-database-detection)* Rename services for clarity, add new database configurations, and update application service dependencies -- *(database-detection)* Enhance isDatabaseImage function to utilize service configuration for improved detection accuracy -- *(install-scripts)* Update Docker installation process to include manual installation fallback and improve error handling -- *(logs-view)* Update logs display for service containers with improved headings and dynamic key binding -- *(logs)* Enhance container loading logic and improve UI for logs display across various resource types -- *(cloudflare-tunnel)* Enhance layout and structure of Cloudflare Tunnel documentation and confirmation modal -- *(terminal-connection)* Streamline auto-connection logic and improve component readiness checks -- *(logs)* Remove unused methods and debug functionality from Logs.php for cleaner code -- *(remoteProcess)* Update sanitize_utf8_text function to accept nullable string parameter for improved type safety -- *(events)* Remove ProxyStarted event and associated ProxyStartedNotification listener for code cleanup -- *(navbar)* Remove unnecessary parameters from server navbar component for cleaner implementation -- *(proxy)* Remove commented-out listener and method for cleaner code structure -- *(events)* Update ProxyStatusChangedUI constructor to accept nullable teamId for improved flexibility -- *(cloudflare)* Update server retrieval method for improved query efficiency -- *(navbar)* Remove unused PHP use statement for cleaner code -- *(proxy)* Streamline proxy status handling and improve dashboard availability checks -- *(navbar)* Simplify proxy status handling and enhance loading indicators for better user experience -- *(resource-operations)* Filter out build servers from the server list and clean up commented-out code in the resource operations view -- *(execute-container-command)* Simplify connection logic and improve terminal availability checks -- *(navigation)* Remove wire:navigate directive from configuration links for cleaner HTML structure -- *(proxy)* Update StartProxy calls to use named parameter for async option -- *(clone-project)* Enhance server retrieval by including destinations and filtering out build servers -- *(ui)* Terminal -- *(ui)* Remove terminal header from execute-container-command view -- *(ui)* Remove unnecessary padding from deployment, backup, and logs sections -- *(service)* Update Hoarder to their new name karakeep (#5964) -- *(service)* Karakeep naming and formatting -- *(service)* Improve miniflux -- *(core)* Rename API rate limit ENV -- *(ui)* Simplify container selection form in execute-container-command view -- *(email)* Streamline SMTP and resend settings logic for improved clarity -- *(invitation)* Rename methods for consistency and enhance invitation deletion logic -- *(user)* Streamline user deletion process and enhance team management logic -- *(ui)* Separate views for instance settings to separate paths to make it cleaner -- *(ui)* Remove unnecessary step3ButtonText attributes from modal confirmation components for cleaner code -- *(ui)* Enhance project cloning interface with improved table layout for server and resource selection -- *(terminal)* Simplify command construction for SSH execution -- *(settings)* Streamline instance admin checks and initialization of settings in Livewire components -- *(policy)* Optimize team membership checks in S3StoragePolicy -- *(popup)* Improve styling and structure of the small popup component -- *(shared)* Enhance FQDN generation logic for services in newParser function -- *(redis)* Enhance CleanupRedis command with dry-run option and improved key deletion logic -- *(init)* Standardize method naming conventions and improve command structure in Init.php -- *(shared)* Improve error handling in getTopLevelNetworks function to return network name on invalid docker-compose.yml -- *(database)* Improve error handling for unsupported database types in StartDatabaseProxy -- *(previews)* Streamline preview URL generation by utilizing application method -- *(application)* Adjust layout and spacing in general application view for improved UI -- *(postgresql)* Improve layout and spacing in SSL and Proxy configuration sections for better UI consistency - *(scheduling)* Replace deprecated job checks with ScheduledJobManager and ServerResourceManager for improved scheduling efficiency - *(previews)* Move preview domain generation logic to ApplicationPreview model for better encapsulation and consistency across webhook handlers - *(service)* Improve gowa @@ -5455,75 +1307,12 @@ All notable changes to this project will be documented in this file. - *(server)* Remove unused destinationsByServer method - *(service)* Improve evolution-api - Remove duplicated validation messages +- *(service)* Remove unused envs from hoppscotch (#6513) +- Move all env sorting to one place +- *(service)* Improve autobase ### 📚 Documentation -- Contribution guide -- How to add new services -- Update -- Update -- Update Plunk documentation link in compose/plunk.yaml -- Update link to deploy api docs -- Add TECH_STACK.md (#4883) -- *(services)* Reword nitropage url and slogan -- *(readme)* Add Convex to special sponsors section -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- *(CONTRIBUTING)* Add note about Laravel Horizon accessibility -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- *(service)* Add new docs link for zipline (#5912) -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog -- Update changelog - *(claude)* Clarify that artisan commands should only be run inside the "coolify" container during development - Add AGENTS.md for project guidance and development instructions - Update changelog @@ -5559,6 +1348,11 @@ All notable changes to this project will be documented in this file. - Update changelog - Update changelog - Update changelog +- Update changelog +- Update changelog +- Update changelog +- Update changelog +- Update changelog - *(tests)* Update testing guidelines for unit and feature tests - *(sync)* Create AI Instructions Synchronization Guide and update CLAUDE.md references - *(database-patterns)* Add critical note on mass assignment protection for new columns @@ -5603,10 +1397,6 @@ All notable changes to this project will be documented in this file. ### 🎨 Styling -- Linting -- *(css)* Update padding utility for password input and add newline in app.css -- *(css)* Refine badge utility styles in utilities.css -- *(css)* Enhance badge utility styles in utilities.css - *(environment-variable)* Adjust SVG icon margin for improved layout in locked state - *(proxy)* Adjust padding in proxy configuration form for better visual alignment - *(campfire)* Format environment variables for better readability in Docker Compose file @@ -5615,11 +1405,6 @@ All notable changes to this project will be documented in this file. ### 🧪 Testing -- Native binary target -- Dockerfile -- Remove prisma -- More tests -- Setup database for upcoming tests - Improve Git ls-remote parsing tests with uppercase SHA and negative cases - Add coverage for newline and tab rejection in volume strings - Add unit tests for ServerPatchCheck notification URL generation @@ -5631,612 +1416,6 @@ All notable changes to this project will be documented in this file. ### ⚙️ Miscellaneous Tasks -- Version bump -- Version -- Version -- Version++ -- Version++ -- Version++ -- Version++ -- Version ++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version ++ -- Version++ -- Version++ -- Version++ -- Fixed typo on New Git Source view -- Version++ -- Version++ -- Version++ -- Version++ -- Lock file + fix packages -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Update packages -- Version++ -- Update build scripts -- Update build packages -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Add .pnpm-store in .gitignore -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Minor changes -- Minor changes -- Minor changes -- Whoops -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Update staging release -- Version++ -- Version++ -- Add jda icon for lavalink service -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Version++ -- Update version to 4.0.0-beta.275 -- Update DNS server validation helper text -- Dark mode should be the default -- Improve menu item styling and spacing in service configuration and index views -- Improve menu item styling and spacing in service configuration and index views -- Improve menu item styling and spacing in project index and show views -- Remove docker compose versions -- Add Listmonk service template and logo -- Refactor GetContainersStatus.php for improved readability and maintainability -- Refactor ApplicationDeploymentJob.php for improved readability and maintainability -- Add metrics and logs directories to installation script -- Update sentinel version to 0.0.2 in versions.json -- Update permissions on metrics and logs directories -- Comment out server sentinel check in ServerStatusJob -- Update version numbers to 4.0.0-beta.278 -- Update hover behavior and cursor style in scheduled task executions view -- Refactor scheduled task view to improve code readability and maintainability -- Skip scheduled tasks if application or service is not running -- Remove debug logging statements in Kernel.php -- Handle invalid cron strings in Kernel.php -- Refactor Service.php to handle missing admin user in extraFields() method -- Update twenty CRM template with environment variables and dependencies -- Refactor applications.php to remove unused imports and improve code readability -- Refactor deployment index.blade.php for improved readability and rollback handling -- Refactor GitHub app selection UI in project creation form -- Update ServerLimitCheckJob.php to handle missing serverLimit value -- Remove unnecessary code for saving commit message -- Update DOCKER_VERSION to 26.0 in install.sh script -- Update Docker and Docker Compose versions in Dockerfiles -- Update version numbers to 4.0.0-beta.279 -- Limit commit message length to 50 characters in ApplicationDeploymentJob -- Update version to 4.0.0-beta.283 -- Change pre and post deployment command length in applications table -- Refactor container name logic in GetContainersStatus.php and ForcePasswordReset.php -- Remove unnecessary content from Docker Compose file -- Update Sentry release version to 4.0.0-beta.287 -- Add Thompson Edolo as a sponsor -- Add null checks for team in Stripe webhook -- Update Sentry release version to 4.0.0-beta.288 -- Update for version 289 -- Fix formatting issue in deployment index.blade.php file -- Remove unnecessary wire:navigate attribute in breadcrumbs.blade.php -- Rename docker dirs -- Update laravel/socialite to version v5.14.0 and livewire/livewire to version 3.4.9 -- Update modal styles for better user experience -- Update deployment index.blade.php script for better performance -- Update version numbers to 4.0.0-beta.290 -- Update version numbers to 4.0.0-beta.291 -- Update version numbers to 4.0.0-beta.292 -- Update version numbers to 4.0.0-beta.293 -- Add upgrade guide link to upgrade.blade.php -- Improve upgrade.blade.php with clearer instructions and formatting -- Update version numbers to 4.0.0-beta.294 -- Add Lightspeed.run as a sponsor -- Update Dockerfile to install vim -- Update Dockerfile with latest versions of Docker, Docker Compose, Docker Buildx, Pack, and Nixpacks -- Update version numbers to 4.0.0-beta.295 -- Update supported OS list with almalinux -- Update install.sh to support PopOS -- Update install.sh script to version 1.3.2 and handle Linux Mint as Ubuntu -- Update page title in resource index view -- Update logo file path in logto.yaml -- Update logo file path in logto.yaml -- Remove commented out code for docker container removal -- Add isAnyDeploymentInprogress function to check if any deployments are in progress -- Add ApplicationDeploymentJob and pint.json -- Update version numbers to 4.0.0-beta.298 -- Switch to database sessions from redis -- Update dependencies and remove unused code -- Update tailwindcss and vue versions in package.json -- Update service template URL in constants.php -- Update sentinel version to 0.0.8 -- Update chart styling and loading text -- Update sentinel version to 0.0.9 -- Update Spanish translation for failed authentication messages -- Add portuguese traslation -- Add Turkish translations -- Add Vietnamese translate -- Add Treive logo to donations section -- Update README.md with latest release version badge -- Update latest release version badge in README.md -- Update version to 4.0.0-beta.299 -- Move server delete component to the bottom of the page -- Update version to 4.0.0-beta.301 -- Update version to 4.0.0-beta.302 -- Update version to 4.0.0-beta.303 -- Update version to 4.0.0-beta.305 -- Update version to 4.0.0-beta.306 -- Add log1x/laravel-webfonts package -- Update version to 4.0.0-beta.307 -- Refactor ServerStatusJob constructor formatting -- Update Monaco Editor for Docker Compose and Proxy Configuration -- More details -- Refactor shared.php helper functions -- Update Plausible docker compose template to Plausible 2.1.0 -- Update Plausible docker compose template to Plausible 2.1.0 -- Update livewire/livewire dependency to version 3.4.9 -- Refactor checkIfDomainIsAlreadyUsed function -- Update storage.blade.php view for livewire project service -- Update version to 4.0.0-beta.310 -- Update composer dependencies -- Add new logo for Latitude -- Bump version to 4.0.0-beta.311 -- Update version to 4.0.0-beta.315 -- Update version to 4.0.0-beta.316 -- Update bug report template -- Update repository form with simplified URL input field -- Update width of container in general.blade.php -- Update checkbox labels in general.blade.php -- Update general page of apps -- Handle JSON parsing errors in format_docker_command_output_to_json -- Update Traefik image version to v2.11 -- Update version to 4.0.0-beta.317 -- Update version to 4.0.0-beta.318 -- Update helper message with link to documentation -- Disable health check by default -- Remove commented out code for sending internal notification -- Update APP_BASE_URL to use SERVICE_FQDN_PLANE -- Update resource-limits.blade.php with improved input field helpers -- Update version numbers to 4.0.0-beta.319 -- Remove commented out code for docker image pruning -- Collect/create/update volumes in parseDockerComposeFile function -- Update version to 4.0.0-beta.320 -- Add pull_request image builds to GH actions -- Add comment explaining the purpose of disconnecting the network in cleanup_unused_network_from_coolify_proxy() -- Update formbricks template -- Update registration view to display a notice for first user that it will be an admin -- Update server form to use password input for IP Address/Domain field -- Update navbar to include service status check -- Update navbar and configuration to improve service status check functionality -- Update workflows to include PR build and merge manifest steps -- Update UpdateCoolifyJob timeout to 10 minutes -- Update UpdateCoolifyJob to dispatch CheckForUpdatesJob synchronously -- Update version to 4.0.0-beta.321 -- Update version to 4.0.0-beta.322 -- Update version to 4.0.0-beta.323 -- Update version to 4.0.0-beta.324 -- New compose parser with tests -- Update version to 1.3.4 in install.sh and 1.0.6 in upgrade.sh -- Update memory limit to 64MB in horizon configuration -- Update php packages -- Update axios npm dependency to version 1.7.5 -- Update Coolify version to 4.0.0-beta.324 and fix file paths in upgrade script -- Update Coolify version to 4.0.0-beta.324 -- Update Coolify version to 4.0.0-beta.325 -- Update Coolify version to 4.0.0-beta.326 -- Add cd command to change directory before removing .env file -- Update Coolify version to 4.0.0-beta.327 -- Update Coolify version to 4.0.0-beta.328 -- Update sponsor links in README.md -- Update version.json to versions.json in GitHub workflow -- Cleanup stucked resources and scheduled backups -- Update GitHub workflow to use versions.json instead of version.json -- Update GitHub workflow to use versions.json instead of version.json -- Update GitHub workflow to use versions.json instead of version.json -- Update GitHub workflow to use jq container for version extraction -- Update GitHub workflow to use jq container for version extraction -- Update UI for displaying no executions found in scheduled task list -- Update UI for displaying deployment status in deployment list -- Update UI for displaying deployment status in deployment list -- Ignore unnecessary files in production build workflow -- Update server form layout and settings -- Update Dockerfile with latest versions of PACK and NIXPACKS -- Update coolify-helper.yml to get version from versions.json -- Disable Ray by default -- Enable Ray by default and update Dockerfile with latest versions of PACK and NIXPACKS -- Update Ray configuration and Dockerfile -- Add middleware for updating environment variables by UUID in `api.php` routes -- Expose port 3000 in browserless.yaml template -- Update Ray configuration and Dockerfile -- Update coolify version to 4.0.0-beta.331 -- Update versions.json and sentry.php to 4.0.0-beta.332 -- Update version to 4.0.0-beta.332 -- Update DATABASE_URL in plunk.yaml to use plunk database -- Add coolify.managed=true label to Docker image builds -- Update docker image pruning command to exclude managed images -- Update docker cleanup schedule to run daily at midnight -- Update versions.json to version 1.0.1 -- Update coolify-helper.yml to include "next" branch in push trigger -- Set timeout for ServerCheckJob to 60 seconds -- Update appwrite.yaml to include OpenSSL key variable assignment -- Update version numbers to 4.0.0-beta.333 -- Copy .env file to .env-{DATE} if it exists -- Update .env file with new values -- Update server check job middleware to use server ID instead of UUID -- Add reminder to backup .env file before running install script again -- Copy .env file to backup location during installation script -- Add reminder to backup .env file during installation script -- Update permissions in pr-build.yml and version numbers -- Add minio/mc command to Dockerfile -- Remove itsgoingd/clockwork from require-dev in composer.json -- Update 'key' value of gitlab in Service.php to use environment variable -- Update release version to 4.0.0-beta.335 -- Update constants.ssh.mux_enabled in remoteProcess.php -- Update listeners and proxy settings in server form and new server components -- Remove unnecessary null check for proxy_type in generate_default_proxy_configuration -- Remove unnecessary SSH command execution time logging -- Update release version to 4.0.0-beta.336 -- Update coolify environment variable assignment with double quotes -- Update shared.php to fix issues with source and network variables -- Update terminal styling for better readability -- Update button text for container connection form -- Update Dockerfile and workflow for Coolify Realtime (v4) -- Remove unused entrypoint script and update volume mapping -- Update .env file and docker-compose configuration -- Update APP_NAME environment variable in docker-compose.prod.yml -- Update WebSocket URL in terminal.blade.php -- Update Dockerfile and workflow for Coolify Realtime (v4) -- Update Dockerfile and workflow for Coolify Realtime (v4) -- Update Dockerfile and workflow for Coolify Realtime (v4) -- Rename Command Center to Terminal in code and views -- Update branch restriction for push event in coolify-helper.yml -- Update terminal button text and layout in application heading view -- Refactor terminal component and select form layout -- Update coolify nightly version to 4.0.0-beta.335 -- Update helper version to 1.0.1 -- Fix syntax error in versions.json -- Update version numbers to 4.0.0-beta.337 -- Update Coolify installer and scripts to include a function for fetching programming jokes -- Update docker network connection command in ApplicationDeploymentJob.php -- Add validation to prevent selecting 'default' server or container in RunCommand.php -- Update versions.json to reflect latest version of realtime container -- Update soketi image to version 1.0.1 -- Nightly - Update soketi image to version 1.0.1 and versions.json to reflect latest version of realtime container -- Update version numbers to 4.0.0-beta.339 -- Update version numbers to 4.0.0-beta.340 -- Update version numbers to 4.0.0-beta.341 -- Update version numbers to 4.0.0-beta.342 -- Update remove-labels-and-assignees-on-close.yml -- Add SSH key for localhost in ProductionSeeder -- Update SSH key generation in install.sh script -- Update ProductionSeeder to call OauthSettingSeeder and PopulateSshKeysDirectorySeeder -- Update install.sh to support Asahi Linux -- Update install.sh version to 1.6 -- Remove unused middleware and uniqueId method in DockerCleanupJob -- Refactor DockerCleanupJob to remove unused middleware and uniqueId method -- Remove unused migration file for populating SSH keys and clearing mux directory -- Add modified files to the commit -- Refactor pre-commit hook to improve performance and readability -- Update CONTRIBUTING.md with troubleshooting note about database migrations -- Refactor pre-commit hook to improve performance and readability -- Update cleanup command to use Redis instead of queue -- Update Docker commands to start proxy -- Update version numbers to 4.0.0-beta.343 -- Update version numbers to 4.0.0-beta.344 -- Update version numbers to 4.0.0-beta.345 -- Update version numbers to 4.0.0-beta.346 -- Add autocomplete attribute to input fields -- Refactor API Tokens component to use isApiEnabled flag -- Update versions.json file -- Remove unused .env.development.example file -- Update API Tokens view to include link to Settings menu -- Update web.php to cast server port as integer -- Update backup deletion labels to use language files -- Update database startup heading title -- Update database startup heading title -- Custom vite envs -- Update version numbers to 4.0.0-beta.348 -- Refactor code to improve SSH key handling and storage -- Update Mailpit logo to use SVG format -- Fix docs link in running state -- Update Coolify Realtime workflow to only trigger on the main branch -- Refactor instanceSettings() function to improve code readability -- Update Coolify Realtime image to version 1.0.2 -- Remove unnecessary code in DatabaseBackupJob.php -- Add "Not Usable" indicator for storage items -- Refactor instanceSettings() function and improve code readability -- Update version numbers to 4.0.0-beta.349 and 4.0.0-beta.350 -- Update version numbers to 4.0.0-beta.350 in configuration files -- Update command signature and description for cleanup application deployment queue -- Add missing import for Attribute class in ApplicationDeploymentQueue model -- Update modal input in server form to prevent closing on outside click -- Remove unnecessary command from SshMultiplexingHelper -- Remove commented out code for uploading to S3 in DatabaseBackupJob -- Update soketi service image to version 1.0.3 -- Update version to 4.0.0-beta.352 -- Refactor DatabaseBackupJob to handle missing team -- Update version to 4.0.0-beta.353 -- Update service application view -- Update version to 4.0.0-beta.354 -- Remove debug statement in Service model -- Remove commented code in Server model -- Fix application deployment queue filter logic -- Refactor modal-confirmation component -- Update it-tools service template and port configuration -- Update homarr service template and remove unnecessary code -- Update homarr service template and remove unnecessary code -- Update version to 4.0.0-beta.355 -- Update version to 4.0.0-beta.356 -- Remove commented code for shared variable type validation -- Update MariaDB image to version 11 and fix service environment variable orders -- Update anythingllm.yaml volumes configuration -- Update proxy configuration paths for Caddy and Nginx in dev -- Update password form submission in modal-confirmation component -- Update project query to order by name in uppercase -- Update project query to order by name in lowercase -- Update select.blade.php with improved search functionality -- Add Nitropage service template and logo -- Bump coolify-helper version to 1.0.2 -- Refactor loadServices2 method and remove unused code -- Update version to 4.0.0-beta.357 -- Update service names and volumes in windmill.yaml -- Update version to 4.0.0-beta.358 -- Ignore .ignition.json files in Docker and Git -- Add mattermost logo as svg -- Add mattermost svg to compose -- Update version to 4.0.0-beta.357 -- Fix form submission and keydown event handling in modal-confirmation.blade.php -- Update version numbers to 4.0.0-beta.359 in configuration files -- Disable adding default environment variables in shared.php -- Update laravel/horizon dependency to version 5.29.1 -- Update service extra fields to use dynamic keys -- Update livewire/livewire dependency to version 3.4.9 -- Add transmission template desc -- Update transmission docs link -- Update version numbers to 4.0.0-beta.360 in configuration files -- Update AWS environment variable names in unsend.yaml -- Update AWS environment variable names in unsend.yaml -- Update livewire/livewire dependency to version 3.4.9 -- Update version to 4.0.0-beta.361 -- Update Docker build and push actions to v6 -- Update Docker build and push actions to v6 -- Update Docker build and push actions to v6 -- Sync coolify-helper to dockerhub as well -- Push realtime to dockerhub -- Sync coolify-realtime to dockerhub -- Rename workflows -- Rename development to staging build -- Sync coolify-testing-host to dockerhbu -- Sync coolify prod image to dockerhub as well -- Update Docker version to 26.0 -- Update project resource index page -- Update project service configuration view -- Edit www helper -- Update dep -- Regenerate openapi spec -- Composer dep bump -- Dep bump -- Upgrade cloudflared and minio -- Remove comments and improve DB column naming -- Remove unused seeder -- Remove unused waitlist stuff -- Remove wired.php (not used anymore) -- Remove unused resale license job -- Remove commented out internal notification -- Remove more waitlist stuff -- Remove commented out notification -- Remove more waitlist stuff -- Remove unused code -- Fix typo -- Remove comment out code -- Some reordering -- Remove resale license reference -- Remove functions from shared.php -- Public settings for email notification -- Remove waitlist redirect -- Remove log -- Use new notification trait -- Remove unused route -- Remove unused email component -- Comment status changes as it is disabled for now -- Bump dep -- Reorder navbar -- Rename topicID to threadId like in the telegram API response -- Update PHP configuration to set memory limit using environment variable -- Regenerate API spec, removing notification fields -- Remove ray debugging -- Version ++ -- Improve Penpot healthchecks -- Switch up readonly lables to make more sense -- Remove unused computed fields -- Use the new job dispatch -- Disable volume data cloning for now -- Improve code -- Lowcoder service naming -- Use new functions -- Improve error styling -- Css -- More css as it still looks like shit -- Final css touches -- Ajust time to 50s (tests done) -- Remove debug log, finally found it -- Remove more logging -- Remove limit on commit message -- Remove dayjs -- Remove unused code and fix import -- *(dep)* Bump nixpacks version -- *(dep)* Version++ -- *(dep)* Bump helper version to 1.0.5 -- *(docker)* Add blank line for readability in Dockerfile -- *(versions)* Update coolify versions to v4.0.0-beta.388 -- *(versions)* Update coolify versions to v4.0.0-beta.389 and add helper version retrieval script -- *(versions)* Update coolify versions to v4.0.0-beta.389 -- *(core)* EnvironmentVariable Model now extends BaseModel to remove duplicated code -- *(versions)* Update coolify versions to v4.0.0-beta.3909 -- *(version)* Bump Coolify version to 4.0.0-beta.391 -- *(config)* Increase default PHP memory limit to 256M -- Add openapi response -- *(workflows)* Make naming more clear and remove unused code -- Bump Coolify version to 4.0.0-beta.392/393 -- *(ci)* Update changelog generation workflow to target 'next' branch -- *(ci)* Update changelog generation workflow to target main branch -- Rollback Coolify version to 4.0.0-beta.392 -- Bump Coolify version to 4.0.0-beta.393 -- Bump Coolify version to 4.0.0-beta.394 -- Bump Coolify version to 4.0.0-beta.395 -- Bump Coolify version to 4.0.0-beta.396 -- *(services)* Update zipline to use new Database env var. (#5210) -- *(service)* Upgrade authentik service -- *(service)* Remove unused env from zipline -- Bump helper and realtime version -- *(migration)* Remove unused columns -- *(ssl)* Improve code in ssl helper -- *(migration)* Ssl cert and key should not be nullable -- *(ssl)* Rename CA cert to `coolify-ca.crt` because of conflicts -- Rename ca crt folder to ssl -- *(ui)* Improve valid until handling -- Improve code quality suggested by code rabbit -- *(supabase)* Update Supabase service template and Postgres image version -- *(versions)* Update version numbers for coolify and nightly -- *(versions)* Update version numbers for coolify and nightly -- *(service)* Update minecraft service ENVs -- *(service)* Add more vars to infisical.yaml (#5418) -- *(service)* Add google variables to plausible.yaml (#5429) -- *(service)* Update authentik.yaml versions (#5373) -- *(core)* Remove redocs -- *(versions)* Update coolify version numbers to 4.0.0-beta.403 and 4.0.0-beta.404 -- *(service)* Remove unused code in Bugsink service -- *(versions)* Update version to 404 -- *(versions)* Bump version to 403 (#5520) -- *(versions)* Bump version to 404 -- *(versions)* Bump version to 406 -- *(versions)* Bump version to 407 -- *(versions)* Bump version to 406 -- *(versions)* Bump version to 407 and 408 for coolify and nightly -- *(versions)* Bump version to 408 for coolify and 409 for nightly -- *(versions)* Update nightly version to 4.0.0-beta.410 -- *(pre-commit)* Remove OpenAPI generation command from pre-commit hook -- *(versions)* Update realtime version to 1.0.7 and bump dependencies in package.json -- *(versions)* Bump coolify version to 4.0.0-beta.409 in configuration files -- *(versions)* Bump coolify version to 4.0.0-beta.410 and update nightly version to 4.0.0-beta.411 in configuration files -- *(templates)* Update plausible and clickhouse images to latest versions and remove mail service -- *(versions)* Update coolify version to 4.0.0-beta.411 and nightly version to 4.0.0-beta.412 in configuration files -- *(versions)* Update coolify version to 4.0.0-beta.412 and nightly version to 4.0.0-beta.413 in configuration files -- *(versions)* Update coolify version to 4.0.0-beta.413 and nightly version to 4.0.0-beta.414 in configuration files -- *(versions)* Update realtime version to 1.0.8 in versions.json -- *(versions)* Update realtime version to 1.0.8 in versions.json -- *(docker)* Update soketi image version to 1.0.8 in production configuration files -- *(versions)* Update coolify version to 4.0.0-beta.414 and nightly version to 4.0.0-beta.415 in configuration files -- *(workflows)* Adjust workflow for announcement -- *(versions)* Update coolify version to 4.0.0-beta.416 and nightly version to 4.0.0-beta.417 in configuration files; fix links in deployment view -- *(seeder)* Update git branch from 'main' to 'v4.x' for multiple examples in ApplicationSeeder -- *(versions)* Update coolify version to 4.0.0-beta.417 and nightly version to 4.0.0-beta.418 -- *(versions)* Update coolify version to 4.0.0-beta.418 -- *(versions)* Update coolify version to 4.0.0-beta.419 and nightly version to 4.0.0-beta.420 in configuration files -- *(service)* Rename hoarder server to karakeep (#5607) -- *(service)* Update Supabase services (#5708) -- *(service)* Remove unused documenso env -- *(service)* Formatting and cleanup of ryot -- *(docs)* Remove changelog and add it to gitignore -- *(versions)* Update version to 4.0.0-beta.419 -- *(service)* Diun formatting -- *(docs)* Update CHANGELOG.md -- *(service)* Switch convex vars -- *(service)* Pgbackweb formatting and naming update -- *(service)* Remove typesense default API key -- *(service)* Format yamtrack healthcheck -- *(core)* Remove unused function -- *(ui)* Remove unused stopEvent code -- *(service)* Remove unused env -- *(tests)* Update test environment database name and add new feature test for converting container environment variables to array -- *(service)* Update Immich service (#5886) -- *(service)* Remove unused logo -- *(api)* Update API docs -- *(dependencies)* Update package versions in composer.json and composer.lock for improved compatibility and performance -- *(dependencies)* Update package versions in package.json and package-lock.json for improved stability and features -- *(version)* Update coolify-realtime to version 1.0.9 in docker-compose and versions files -- *(version)* Update coolify version to 4.0.0-beta.420 and nightly version to 4.0.0-beta.421 -- *(service)* Changedetection remove unused code -- *(service)* Update Evolution API image to the official one (#6031) -- *(versions)* Bump coolify versions to v4.0.0-beta.420 and v4.0.0-beta.421 -- *(dependencies)* Update composer dependencies to latest versions including resend-laravel to ^0.19.0 and aws-sdk-php to 3.347.0 -- *(versions)* Update Coolify version to 4.0.0-beta.420.1 and add new services (karakeep, miniflux, pingvinshare) to service templates -- *(versions)* Update Coolify versions to 4.0.0-beta.420.2 and 4.0.0-beta.420.3 in multiple files -- *(versions)* Bump coolify and nightly versions to 4.0.0-beta.420.3 and 4.0.0-beta.420.4 respectively -- *(versions)* Update coolify and nightly versions to 4.0.0-beta.420.4 and 4.0.0-beta.420.5 respectively -- *(bump)* Update composer deps -- *(version)* Bump Coolify version to 4.0.0-beta.420.6 - *(service)* Update Nitropage template (#6181) - *(versions)* Update all version - *(service)* Improve matrix service @@ -6292,6 +1471,7 @@ All notable changes to this project will be documented in this file. - *(versions)* Update version numbers for Coolify releases - *(versions)* Bump Coolify stable version to 4.0.0-beta.434 - *(versions)* Update Coolify version numbers to 4.0.0-beta.435 and 4.0.0-beta.436 +- Exclude changelog from PR - Update package-lock.json - *(service)* Update convex template and image - *(signoz)* Remove unused ports @@ -6334,20 +1514,7922 @@ All notable changes to this project will be documented in this file. - *(service)* Improve n8n v2 - *(services)* Update service json - *(service)* Change sqlite pool size to v2 default +- *(service)* Improve mosquitto template (#6227) +- *(services)* Update service json +- Remove raw sql from env relationship + +### ◀️ Revert + +- *(parser)* Enhance FQDN generation logic for services and applications + +## [4.0.0-beta.420.6] - 2025-07-18 + +### 📚 Documentation + +- Update changelog +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(bump)* Update composer deps +- *(version)* Bump Coolify version to 4.0.0-beta.420.6 + +## [4.0.0-beta.420.5] - 2025-07-08 + +### 🚀 Features + +- *(scheduling)* Add command to manually run scheduled database backups and tasks with options for chunking, delays, and dry runs + +### 🐛 Bug Fixes + +- *(versions)* Update coolify version numbers in versions.json and constants.php to 4.0.0-beta.420.5 and 4.0.0-beta.420.6 +- *(database)* Ensure internal port defaults correctly for unsupported database types in StartDatabaseProxy + +### 🚜 Refactor + +- *(postgresql)* Improve layout and spacing in SSL and Proxy configuration sections for better UI consistency + +## [4.0.0-beta.420.4] - 2025-07-08 + +### 🐛 Bug Fixes + +- *(service)* Update Postiz compose configuration for improved server availability +- *(install.sh)* Use IPV4_PUBLIC_IP variable in output instead of repeated curl +- *(env)* Generate literal env variables better +- *(deployment)* Update x-data initialization in deployment view for improved functionality +- *(deployment)* Enhance COOLIFY_URL and COOLIFY_FQDN variable generation for better compatibility +- *(deployment)* Improve docker-compose domain handling and environment variable generation +- *(deployment)* Refactor domain parsing and environment variable generation using Spatie URL library +- *(deployment)* Update COOLIFY_URL and COOLIFY_FQDN generation to use Spatie URL library for improved accuracy +- *(scheduling)* Change redis cleanup command frequency from hourly to weekly for better resource management + +### 🚜 Refactor + +- *(previews)* Streamline preview URL generation by utilizing application method +- *(application)* Adjust layout and spacing in general application view for improved UI + +### 📚 Documentation + +- Update changelog +- Update changelog + +## [4.0.0-beta.420.3] - 2025-07-03 + +### 📚 Documentation + +- Update changelog + +## [4.0.0-beta.420.2] - 2025-07-03 + +### 🚀 Features + +- *(template)* Added excalidraw (#6095) +- *(template)* Add excalidraw service configuration with documentation and tags + +### 🐛 Bug Fixes + +- *(terminal)* Ensure shell execution only uses valid shell if available in terminal command +- *(ui)* Improve destination selection description for clarity in resource segregation +- *(jobs)* Update middleware to use expireAfter for WithoutOverlapping in multiple job classes +- Removing eager loading (#6071) +- *(template)* Adjust health check interval and retries for excalidraw service +- *(ui)* Env variable settings wrong order +- *(service)* Ensure configuration changes are properly tracked and dispatched + +### 🚜 Refactor + +- *(ui)* Enhance project cloning interface with improved table layout for server and resource selection +- *(terminal)* Simplify command construction for SSH execution +- *(settings)* Streamline instance admin checks and initialization of settings in Livewire components +- *(policy)* Optimize team membership checks in S3StoragePolicy +- *(popup)* Improve styling and structure of the small popup component +- *(shared)* Enhance FQDN generation logic for services in newParser function +- *(redis)* Enhance CleanupRedis command with dry-run option and improved key deletion logic +- *(init)* Standardize method naming conventions and improve command structure in Init.php +- *(shared)* Improve error handling in getTopLevelNetworks function to return network name on invalid docker-compose.yml +- *(database)* Improve error handling for unsupported database types in StartDatabaseProxy + +### 📚 Documentation + +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(versions)* Bump coolify and nightly versions to 4.0.0-beta.420.3 and 4.0.0-beta.420.4 respectively +- *(versions)* Update coolify and nightly versions to 4.0.0-beta.420.4 and 4.0.0-beta.420.5 respectively + +## [4.0.0-beta.420.1] - 2025-06-26 + +### 🐛 Bug Fixes + +- *(server)* Prepend 'mux_' to UUID in muxFilename method for consistent naming +- *(ui)* Enhance terminal access messaging to clarify server functionality and terminal status +- *(database)* Proxy ssl port if ssl is enabled + +### 🚜 Refactor + +- *(ui)* Separate views for instance settings to separate paths to make it cleaner +- *(ui)* Remove unnecessary step3ButtonText attributes from modal confirmation components for cleaner code + +### 📚 Documentation + +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(versions)* Update Coolify versions to 4.0.0-beta.420.2 and 4.0.0-beta.420.3 in multiple files + +## [4.0.0-beta.420] - 2025-06-26 + +### 🚀 Features + +- *(service)* Add Miniflux service (#5843) +- *(service)* Add Pingvin Share service (#5969) +- *(auth)* Add Discord OAuth Provider (#5552) +- *(auth)* Add Clerk OAuth Provider (#5553) +- *(auth)* Add Zitadel OAuth Provider (#5490) +- *(core)* Set custom API rate limit (#5984) +- *(service)* Enhance service status handling and UI updates +- *(cleanup)* Add functionality to delete teams with no members or servers in CleanupStuckedResources command +- *(ui)* Add heart icon and enhance popup messaging for sponsorship support +- *(settings)* Add sponsorship popup toggle and corresponding database migration +- *(migrations)* Add optimized indexes to activity_log for improved query performance + +### 🐛 Bug Fixes + +- *(service)* Audiobookshelf healthcheck command (#5993) +- *(service)* Downgrade Evolution API phone version (#5977) +- *(service)* Pingvinshare-with-clamav +- *(ssh)* Scp requires square brackets for ipv6 (#6001) +- *(github)* Changing github app breaks the webhook. it does not anymore +- *(parser)* Improve FQDN generation and update environment variable handling +- *(ui)* Enhance status refresh buttons with loading indicators +- *(ui)* Update confirmation button text for stopping database and service +- *(routes)* Update middleware for deploy route to use 'api.ability:deploy' +- *(ui)* Refine API token creation form and update helper text for clarity +- *(ui)* Adjust layout of deployments section for improved alignment +- *(ui)* Adjust project grid layout and refine server border styling for better visibility +- *(ui)* Update border styling for consistency across components and enhance loading indicators +- *(ui)* Add padding to section headers in settings views for improved spacing +- *(ui)* Reduce gap between input fields in email settings for better alignment +- *(docker)* Conditionally enable gzip compression in Traefik labels based on configuration +- *(parser)* Enable gzip compression conditionally for Pocketbase images and streamline service creation logic +- *(ui)* Update padding for trademarks policy and enhance spacing in advanced settings section +- *(ui)* Correct closing tag for sponsorship link in layout popups +- *(ui)* Refine wording in sponsorship donation prompt in layout popups +- *(ui)* Update navbar icon color and enhance popup layout for sponsorship support +- *(ui)* Add target="_blank" to sponsorship links in layout popups for improved user experience +- *(models)* Refine comment wording in User model for clarity on user deletion criteria +- *(models)* Improve user deletion logic in User model to handle team member roles and prevent deletion if user is alone in root team +- *(ui)* Update wording in sponsorship prompt for clarity and engagement +- *(shared)* Refactor gzip handling for Pocketbase in newParser function for improved clarity + +### 🚜 Refactor + +- *(service)* Update Hoarder to their new name karakeep (#5964) +- *(service)* Karakeep naming and formatting +- *(service)* Improve miniflux +- *(core)* Rename API rate limit ENV +- *(ui)* Simplify container selection form in execute-container-command view +- *(email)* Streamline SMTP and resend settings logic for improved clarity +- *(invitation)* Rename methods for consistency and enhance invitation deletion logic +- *(user)* Streamline user deletion process and enhance team management logic + +### 📚 Documentation + +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(service)* Update Evolution API image to the official one (#6031) +- *(versions)* Bump coolify versions to v4.0.0-beta.420 and v4.0.0-beta.421 +- *(dependencies)* Update composer dependencies to latest versions including resend-laravel to ^0.19.0 and aws-sdk-php to 3.347.0 +- *(versions)* Update Coolify version to 4.0.0-beta.420.1 and add new services (karakeep, miniflux, pingvinshare) to service templates + +## [4.0.0-beta.419] - 2025-06-17 + +### 🚀 Features + +- *(core)* Add 'postmarketos' to supported OS list +- *(service)* Add memos service template (#5032) +- *(ui)* Upgrade to Tailwind v4 (#5710) +- *(service)* Add Navidrome service template (#5022) +- *(service)* Add Passbolt service (#5769) +- *(service)* Add Vert service (#5663) +- *(service)* Add Ryot service (#5232) +- *(service)* Add Marimo service (#5559) +- *(service)* Add Diun service (#5113) +- *(service)* Add Observium service (#5613) +- *(service)* Add Leantime service (#5792) +- *(service)* Add Limesurvey service (#5751) +- *(service)* Add Paymenter service (#5809) +- *(service)* Add CodiMD service (#4867) +- *(modal)* Add dispatchAction property to confirmation modal +- *(security)* Implement server patching functionality +- *(service)* Add Typesense service (#5643) +- *(service)* Add Yamtrack service (#5845) +- *(service)* Add PG Back Web service (#5079) +- *(service)* Update Maybe service and adjust it for the new release (#5795) +- *(oauth)* Set redirect uri as optional and add default value (#5760) +- *(service)* Add apache superset service (#4891) +- *(service)* Add One Time Secret service (#5650) +- *(service)* Add Seafile service (#5817) +- *(service)* Add Netbird-Client service (#5873) +- *(service)* Add OrangeHRM and Grist services (#5212) +- *(rules)* Add comprehensive documentation for Coolify architecture and development practices for AI tools, especially for cursor +- *(server)* Implement server patch check notifications +- *(api)* Add latest query param to Service restart API (#5881) +- *(api)* Add connect_to_docker_network setting to App creation API (#5691) +- *(routes)* Restrict backup download access to team admins and owners +- *(destination)* Update confirmation modal text and add persistent storage warning for server deployment +- *(terminal-access)* Implement terminal access control for servers and containers, including UI updates and backend logic +- *(ca-certificate)* Add CA certificate management functionality with UI integration and routing +- *(security-patches)* Add update check initialization and enhance notification messaging in UI +- *(previews)* Add force deploy without cache functionality and update deploy method to accept force rebuild parameter +- *(security-patterns)* Expand sensitive patterns list to include additional security-related variables +- *(database-backup)* Add MongoDB credential extraction and backup handling to DatabaseBackupJob +- *(activity-monitor)* Implement auto-scrolling functionality and dynamic content observation for improved user experience +- *(utf8-handling)* Implement UTF-8 sanitization for command outputs and enhance error handling in logs processing +- *(navbar)* Add Traefik dashboard availability check and server IP handling; refactor dynamic configurations loading +- *(proxy-dashboard)* Implement ProxyDashboardCacheService to manage Traefik dashboard cache; clear cache on configuration changes and proxy actions +- *(terminal-connection)* Enhance terminal connection handling with auto-connect feature and improved status messaging +- *(terminal)* Implement resize handling with ResizeObserver for improved terminal responsiveness +- *(migration)* Add is_sentinel_enabled column to server_settings with default true +- *(seeder)* Dispatch StartProxy action for each server in ProductionSeeder +- *(seeder)* Add CheckAndStartSentinelJob dispatch for each server in ProductionSeeder +- *(seeder)* Conditionally dispatch StartProxy action based on proxy check result +- *(service)* Update Changedetection template (#5937) + +### 🐛 Bug Fixes + +- *(constants)* Adding 'fedora-asahi-remix' as a supported OS (#5646) +- *(authentik)* Update docker-compose configuration for authentik service +- *(api)* Allow nullable destination_uuid (#5683) +- *(service)* Fix documenso startup and mail (#5737) +- *(docker)* Fix production dockerfile +- *(service)* Navidrome service +- *(service)* Passbolt +- *(service)* Add missing ENVs to NTFY service (#5629) +- *(service)* NTFY is behind a proxy +- *(service)* Vert logo and ENVs +- *(service)* Add platform to Observium service +- *(ActivityMonitor)* Prevent multiple event dispatches during polling +- *(service)* Convex ENVs and update image versions (#5827) +- *(service)* Paymenter +- *(ApplicationDeploymentJob)* Ensure correct COOLIFY_FQDN/COOLIFY_URL values (#4719) +- *(service)* Snapdrop no matching manifest error (#5849) +- *(service)* Use the same volume between chatwoot and sidekiq (#5851) +- *(api)* Validate docker_compose_raw input in ApplicationsController +- *(api)* Enhance validation for docker_compose_raw in ApplicationsController +- *(select)* Update PostgreSQL versions and titles in resource selection +- *(database)* Include DatabaseStatusChanged event in activityMonitor dispatch +- *(css)* Tailwind v5 things +- *(service)* Diun ENV for consistency +- *(service)* Memos service name +- *(css)* 8+ issue with new tailwind v4 +- *(css)* `bg-coollabs-gradient` not working anymore +- *(ui)* Add back missing service navbar components +- *(deploy)* Update resource timestamp handling in deploy_resource method +- *(patches)* DNF reboot logic is flipped +- *(deployment)* Correct syntax for else statement in docker compose build command +- *(shared)* Remove unused relation from queryDatabaseByUuidWithinTeam function +- *(deployment)* Correct COOLIFY_URL and COOLIFY_FQDN assignments based on parsing version in preview deployments +- *(docker)* Ensure correct parsing of environment variables by limiting explode to 2 parts +- *(project)* Update selected environment handling to use environment name instead of UUID +- *(ui)* Update server status display and improve server addition layout +- *(service)* Neon WS Proxy service not working on ARM64 (#5887) +- *(server)* Enhance error handling in server patch check notifications +- *(PushServerUpdateJob)* Add null checks before updating application and database statuses +- *(environment-variables)* Update label text for build variable checkboxes to improve clarity +- *(service-management)* Update service stop and restart messages for improved clarity and formatting +- *(preview-form)* Update helper text formatting in preview URL template input for better readability +- *(application-management)* Improve stop messages for application, database, and service to enhance clarity and formatting +- *(application-configuration)* Prevent access to preview deployments for deploy_key applications and update menu visibility accordingly +- *(select-component)* Handle exceptions during parameter retrieval and environment selection in the mount method +- *(previews)* Escape container names in stopContainers method to prevent shell injection vulnerabilities +- *(docker)* Add protection against empty container queries in GetContainersStatus to prevent unnecessary updates +- *(modal-confirmation)* Decode HTML entities in confirmation text to ensure proper display +- *(select-component)* Enhance user interaction by adding cursor styles and disabling selection during processing +- *(deployment-show)* Remove unnecessary fixed positioning for button container to improve layout responsiveness +- *(email-notifications)* Change notify method to notifyNow for immediate test email delivery +- *(service-templates)* Update Convex service configuration to use FQDN variables +- *(database-heading)* Simplify stop database message for clarity +- *(navbar)* Remove unnecessary x-init directive for loading proxy configuration +- *(patches)* Add padding to loading message for better visibility during update checks +- *(terminal-connection)* Improve error handling and stability for auto-connection; enhance component readiness checks and retry logic +- *(terminal)* Add unique wire:key to terminal component for improved reactivity and state management +- *(css)* Adjust utility classes in utilities.css for consistent application of Tailwind directives +- *(css)* Refine utility classes in utilities.css for proper Tailwind directive application +- *(install)* Update Docker installation script to use dynamic OS_TYPE and correct installation URL +- *(cloudflare)* Add error handling to automated Cloudflare configuration script +- *(navbar)* Add error handling for proxy status check to improve user feedback +- *(web)* Update user team retrieval method for consistent authentication handling +- *(cloudflare)* Update refresh method to correctly set Cloudflare tunnel status and improve user notification on IP address update +- *(service)* Update service template for affine and add migration service for improved deployment process +- *(supabase)* Update Supabase service images and healthcheck methods for improved reliability +- *(terminal)* Now it should work +- *(degraded-status)* Remove unnecessary whitespace in badge element for cleaner HTML +- *(routes)* Add name to security route for improved route management +- *(migration)* Update default value handling for is_sentinel_enabled column in server_settings +- *(seeder)* Conditionally dispatch CheckAndStartSentinelJob based on server's sentinel status +- *(service)* Disable healthcheck logging for Gotenberg (#6005) +- *(service)* Joplin volume name (#5930) +- *(server)* Update sentinelUpdatedAt assignment to use server's sentinel_updated_at property + +### 💼 Other + +- Add support for postmarketOS (#5608) +- *(core)* Simplify events for app/db/service status changes + +### 🚜 Refactor + +- *(service)* Observium +- *(service)* Improve leantime +- *(service)* Imporve limesurvey +- *(service)* Improve CodiMD +- *(service)* Typsense +- *(services)* Improve yamtrack +- *(service)* Improve paymenter +- *(service)* Consolidate configuration change dispatch logic and remove unused navbar component +- *(sidebar)* Simplify server patching link by removing button element +- *(slide-over)* Streamline button element and improve code readability +- *(service)* Enhance modal confirmation component with event dispatching for service stop actions +- *(slide-over)* Enhance class merging for improved component styling +- *(core)* Use property promotion +- *(service)* Improve maybe +- *(applications)* Remove unused docker compose raw decoding +- *(service)* Make TYPESENSE_API_KEY required +- *(ui)* Show toast when server does not work and on stop +- *(service)* Improve superset +- *(service)* Improve Onetimesecret +- *(service)* Improve Seafile +- *(service)* Improve orangehrm +- *(service)* Improve grist +- *(application)* Enhance application stopping logic to support multiple servers +- *(pricing-plans)* Improve label class binding for payment frequency selection +- *(error-handling)* Replace generic Exception with RuntimeException for improved error specificity +- *(error-handling)* Change Exception to RuntimeException for clearer error reporting +- *(service)* Remove informational dispatch during service stop for cleaner execution +- *(server-ui)* Improve layout and messaging in advanced settings and charts views +- *(terminal-access)* Streamline resource retrieval and enhance terminal access messaging in UI +- *(terminal)* Enhance terminal connection management and error handling, including improved reconnection logic and cleanup procedures +- *(application-deployment)* Separate handling of FAILED and CANCELLED_BY_USER statuses for clearer logic and notification +- *(jobs)* Update middleware to include job-specific identifiers for WithoutOverlapping +- *(jobs)* Modify middleware to use job-specific identifier for WithoutOverlapping +- *(environment-variables)* Remove debug logging from bulk submit handling for cleaner code +- *(environment-variables)* Simplify application build pack check in environment variable handling +- *(logs)* Adjust padding in logs view for improved layout consistency +- *(application-deployment)* Streamline post-deployment process by always dispatching container status check +- *(service-management)* Enhance container stopping logic by implementing parallel processing and removing deprecated methods +- *(activity-monitor)* Change activity property visibility and update view references for consistency +- *(activity-monitor)* Enhance layout responsiveness by adjusting class bindings and structure for better display +- *(service-management)* Update stopContainersInParallel method to enforce Server type hint for improved type safety +- *(service-management)* Rearrange docker cleanup logic in StopService to improve readability +- *(database-management)* Simplify docker cleanup logic in StopDatabase to enhance readability +- *(activity-monitor)* Consolidate activity monitoring logic and remove deprecated NewActivityMonitor component +- *(activity-monitor)* Update dispatch method to use activityMonitor instead of deprecated newActivityMonitor +- *(push-server-update)* Enhance application preview handling by incorporating pull request IDs and adding status update protections +- *(docker-compose)* Replace hardcoded Docker Compose configuration with external YAML template for improved database detection testing +- *(test-database-detection)* Rename services for clarity, add new database configurations, and update application service dependencies +- *(database-detection)* Enhance isDatabaseImage function to utilize service configuration for improved detection accuracy +- *(install-scripts)* Update Docker installation process to include manual installation fallback and improve error handling +- *(logs-view)* Update logs display for service containers with improved headings and dynamic key binding +- *(logs)* Enhance container loading logic and improve UI for logs display across various resource types +- *(cloudflare-tunnel)* Enhance layout and structure of Cloudflare Tunnel documentation and confirmation modal +- *(terminal-connection)* Streamline auto-connection logic and improve component readiness checks +- *(logs)* Remove unused methods and debug functionality from Logs.php for cleaner code +- *(remoteProcess)* Update sanitize_utf8_text function to accept nullable string parameter for improved type safety +- *(events)* Remove ProxyStarted event and associated ProxyStartedNotification listener for code cleanup +- *(navbar)* Remove unnecessary parameters from server navbar component for cleaner implementation +- *(proxy)* Remove commented-out listener and method for cleaner code structure +- *(events)* Update ProxyStatusChangedUI constructor to accept nullable teamId for improved flexibility +- *(cloudflare)* Update server retrieval method for improved query efficiency +- *(navbar)* Remove unused PHP use statement for cleaner code +- *(proxy)* Streamline proxy status handling and improve dashboard availability checks +- *(navbar)* Simplify proxy status handling and enhance loading indicators for better user experience +- *(resource-operations)* Filter out build servers from the server list and clean up commented-out code in the resource operations view +- *(execute-container-command)* Simplify connection logic and improve terminal availability checks +- *(navigation)* Remove wire:navigate directive from configuration links for cleaner HTML structure +- *(proxy)* Update StartProxy calls to use named parameter for async option +- *(clone-project)* Enhance server retrieval by including destinations and filtering out build servers +- *(ui)* Terminal +- *(ui)* Remove terminal header from execute-container-command view +- *(ui)* Remove unnecessary padding from deployment, backup, and logs sections + +### 📚 Documentation + +- Update changelog +- *(service)* Add new docs link for zipline (#5912) +- Update changelog +- Update changelog +- Update changelog + +### 🎨 Styling + +- *(css)* Update padding utility for password input and add newline in app.css +- *(css)* Refine badge utility styles in utilities.css +- *(css)* Enhance badge utility styles in utilities.css + +### ⚙️ Miscellaneous Tasks + +- *(versions)* Update coolify version to 4.0.0-beta.419 and nightly version to 4.0.0-beta.420 in configuration files +- *(service)* Rename hoarder server to karakeep (#5607) +- *(service)* Update Supabase services (#5708) +- *(service)* Remove unused documenso env +- *(service)* Formatting and cleanup of ryot +- *(docs)* Remove changelog and add it to gitignore +- *(versions)* Update version to 4.0.0-beta.419 +- *(service)* Diun formatting +- *(docs)* Update CHANGELOG.md +- *(service)* Switch convex vars +- *(service)* Pgbackweb formatting and naming update +- *(service)* Remove typesense default API key +- *(service)* Format yamtrack healthcheck +- *(core)* Remove unused function +- *(ui)* Remove unused stopEvent code +- *(service)* Remove unused env +- *(tests)* Update test environment database name and add new feature test for converting container environment variables to array +- *(service)* Update Immich service (#5886) +- *(service)* Remove unused logo +- *(api)* Update API docs +- *(dependencies)* Update package versions in composer.json and composer.lock for improved compatibility and performance +- *(dependencies)* Update package versions in package.json and package-lock.json for improved stability and features +- *(version)* Update coolify-realtime to version 1.0.9 in docker-compose and versions files +- *(version)* Update coolify version to 4.0.0-beta.420 and nightly version to 4.0.0-beta.421 +- *(service)* Changedetection remove unused code + +## [4.0.0-beta.417] - 2025-05-07 + +### 🐛 Bug Fixes + +- *(select)* Update fallback logo path to use absolute URL for improved reliability + +### 📚 Documentation + +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(versions)* Update coolify version to 4.0.0-beta.418 + +## [4.0.0-beta.416] - 2025-05-05 + +### 🚀 Features + +- *(migration)* Add 'is_migrated' and 'custom_type' columns to service_applications and service_databases tables +- *(backup)* Implement custom database type selection and enhance scheduled backups management +- *(README)* Add Gozunga and Macarne to sponsors list +- *(redis)* Add scheduled cleanup command for Redis keys and enhance cleanup logic + +### 🐛 Bug Fixes + +- *(service)* Graceful shutdown of old container (#5731) +- *(ServerCheck)* Enhance proxy container check to ensure it is running before proceeding +- *(applications)* Include pull_request_id in deployment queue check to prevent duplicate deployments +- *(database)* Update label for image input field to improve clarity +- *(ServerCheck)* Set default proxy status to 'exited' to handle missing container state +- *(database)* Reduce container stop timeout from 300 to 30 seconds for improved responsiveness +- *(ui)* System theming for charts (#5740) +- *(dev)* Mount points?! +- *(dev)* Proxy mount point +- *(ui)* Allow adding scheduled backups for non-migrated databases +- *(DatabaseBackupJob)* Escape PostgreSQL password in backup command (#5759) +- *(ui)* Correct closing div tag in service index view + +### 🚜 Refactor + +- *(Database)* Streamline container shutdown process and reduce timeout duration +- *(core)* Streamline container stopping process and reduce timeout duration; update related methods for consistency +- *(database)* Update DB facade usage for consistency across service files +- *(database)* Enhance application conversion logic and add existence checks for databases and applications +- *(actions)* Standardize method naming for network and configuration deletion across application and service classes +- *(logdrain)* Consolidate log drain stopping logic to reduce redundancy +- *(StandaloneMariadb)* Add type hint for destination method to improve code clarity +- *(DeleteResourceJob)* Streamline resource deletion logic and improve conditional checks for database types +- *(jobs)* Update middleware to prevent job release after expiration for CleanupInstanceStuffsJob, RestartProxyJob, and ServerCheckJob +- *(jobs)* Unify middleware configuration to prevent job release after expiration for DockerCleanupJob and PushServerUpdateJob + +### 📚 Documentation + +- Update changelog +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(seeder)* Update git branch from 'main' to 'v4.x' for multiple examples in ApplicationSeeder +- *(versions)* Update coolify version to 4.0.0-beta.417 and nightly version to 4.0.0-beta.418 + +## [4.0.0-beta.415] - 2025-04-29 + +### 🐛 Bug Fixes + +- *(ui)* Remove required attribute from image input in service application view +- *(ui)* Change application image validation to be nullable in service application view +- *(Server)* Correct proxy path formatting for Traefik proxy type + +### 📚 Documentation + +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(versions)* Update coolify version to 4.0.0-beta.416 and nightly version to 4.0.0-beta.417 in configuration files; fix links in deployment view + +## [4.0.0-beta.414] - 2025-04-28 + +### 🐛 Bug Fixes + +- *(ui)* Disable livewire navigate feature (causing spam of setInterval()) + +## [4.0.0-beta.413] - 2025-04-28 + +### 💼 Other + +- Adjust Workflows for v5 (#5689) + +### 📚 Documentation + +- Update changelog +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(workflows)* Adjust workflow for announcement + +## [4.0.0-beta.411] - 2025-04-23 + +### 🚀 Features + +- *(deployment)* Add repository_project_id handling for private GitHub apps and clean up unused Caddy label logic +- *(api)* Enhance OpenAPI specifications with token variable and additional key attributes +- *(docker)* Add HTTP Basic Authentication support and enhance hostname parsing in Docker run conversion +- *(api)* Add HTTP Basic Authentication fields to OpenAPI specifications and enhance PrivateKey model descriptions +- *(README)* Add InterviewPal sponsorship link and corresponding SVG icon + +### 🐛 Bug Fixes + +- *(backup-edit)* Conditionally enable S3 checkbox based on available validated S3 storage +- *(source)* Update no sources found message for clarity +- *(api)* Correct middleware for service update route to ensure proper permissions +- *(api)* Handle JSON response in service creation and update methods for improved error handling +- Add 201 json code to servers validate api response +- *(docker)* Ensure password hashing only occurs when HTTP Basic Authentication is enabled +- *(docker)* Enhance hostname and GPU option validation in Docker run to compose conversion +- *(terminal)* Enhance WebSocket client verification with authorized IPs in terminal server +- *(ApplicationDeploymentJob)* Ensure source is an object before checking GitHub app properties + +### 🚜 Refactor + +- *(jobs)* Comment out unused Caddy label handling in ApplicationDeploymentJob and simplify proxy path logic in Server model +- *(database)* Simplify database type checks in ServiceDatabase and enhance image validation in Docker helper +- *(shared)* Remove unused ray debugging statement from newParser function +- *(applications)* Remove redundant error response in create_env method +- *(api)* Restructure routes to include versioning and maintain existing feedback endpoint +- *(api)* Remove token variable from OpenAPI specifications for clarity +- *(environment-variables)* Remove protected variable checks from delete methods for cleaner logic +- *(http-basic-auth)* Rename 'http_basic_auth_enable' to 'http_basic_auth_enabled' across application files for consistency +- *(docker)* Remove debug statement and enhance hostname handling in Docker run conversion +- *(server)* Simplify proxy path logic and remove unnecessary conditions + +### 📚 Documentation + +- Update changelog +- Update changelog +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(versions)* Update coolify version to 4.0.0-beta.411 and nightly version to 4.0.0-beta.412 in configuration files +- *(versions)* Update coolify version to 4.0.0-beta.412 and nightly version to 4.0.0-beta.413 in configuration files +- *(versions)* Update coolify version to 4.0.0-beta.413 and nightly version to 4.0.0-beta.414 in configuration files +- *(versions)* Update realtime version to 1.0.8 in versions.json +- *(versions)* Update realtime version to 1.0.8 in versions.json +- *(docker)* Update soketi image version to 1.0.8 in production configuration files +- *(versions)* Update coolify version to 4.0.0-beta.414 and nightly version to 4.0.0-beta.415 in configuration files + +## [4.0.0-beta.410] - 2025-04-18 + +### 🚀 Features + +- Add HTTP Basic Authentication +- *(readme)* Add new sponsors Supadata AI and WZ-IT to the README +- *(core)* Enable magic env variables for compose based applications + +### 🐛 Bug Fixes + +- *(application)* Append base directory to git branch URLs for improved path handling +- *(templates)* Correct casing of "denokv" to "denoKV" in service templates JSON +- *(navbar)* Update error message link to use route for environment variables navigation +- Unsend template +- Replace ports with expose +- *(templates)* Update Unsend compose configuration for improved service integration + +### 🚜 Refactor + +- *(jobs)* Update WithoutOverlapping middleware to use expireAfter for better queue management + +### 📚 Documentation + +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(versions)* Bump coolify version to 4.0.0-beta.410 and update nightly version to 4.0.0-beta.411 in configuration files +- *(templates)* Update plausible and clickhouse images to latest versions and remove mail service + +## [4.0.0-beta.409] - 2025-04-16 + +### 🐛 Bug Fixes + +- *(parser)* Transform associative array labels into key=value format for better compatibility +- *(redis)* Update username and password input handling to clarify database sync requirements +- *(source)* Update connected source display to handle cases with no source connected + +### 🚜 Refactor + +- *(source)* Conditionally display connected source and change source options based on private key presence + +### ⚙️ Miscellaneous Tasks + +- *(versions)* Bump coolify version to 4.0.0-beta.409 in configuration files + +## [4.0.0-beta.408] - 2025-04-14 + +### 🚀 Features + +- *(OpenApi)* Enhance OpenAPI specifications by adding UUID parameters for application, project, and service updates; improve deployment listing with pagination parameters; update command signature for OpenApi generation +- *(subscription)* Enhance subscription management with loading states and Stripe status checks + +### 🐛 Bug Fixes + +- *(pre-commit)* Correct input redirection for /dev/tty and add OpenAPI generation command +- *(pricing-plans)* Adjust grid class for improved layout consistency in subscription pricing plans +- *(migrations)* Make stripe_comment field nullable in subscriptions table +- *(mongodb)* Also apply custom config when SSL is enabled +- *(templates)* Correct casing of denoKV references in service templates and YAML files +- *(deployment)* Handle missing destination in deployment process to prevent errors + +### 💼 Other + +- Add missing openapi items to PrivateKey + +### 🚜 Refactor + +- *(commands)* Reorganize OpenAPI and Services generation commands into a new namespace for better structure; remove old command files +- *(Dockerfile)* Remove service generation command from the build process to streamline Dockerfile and improve build efficiency +- *(navbar-delete-team)* Simplify modal confirmation layout and enhance button styling for better user experience +- *(Server)* Remove debug logging from isReachableChanged method to clean up code and improve performance + +### 📚 Documentation + +- Update changelog +- Update changelog +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(versions)* Update nightly version to 4.0.0-beta.410 +- *(pre-commit)* Remove OpenAPI generation command from pre-commit hook +- *(versions)* Update realtime version to 1.0.7 and bump dependencies in package.json + +## [4.0.0-beta.407] - 2025-04-09 + +### 📚 Documentation + +- Update changelog + +## [4.0.0-beta.406] - 2025-04-05 + +### 🚀 Features + +- *(Deploy)* Add info dispatch for proxy check initiation +- *(EnvironmentVariable)* Add handling for Redis credentials in the environment variable component +- *(EnvironmentVariable)* Implement protection for critical environment variables and enhance deletion logic +- *(Application)* Add networkAliases attribute for handling network aliases as JSON or comma-separated values +- *(GithubApp)* Update default events to include 'pull_request' and streamline event handling +- *(CleanupDocker)* Add support for realtime image management in Docker cleanup process +- *(Deployment)* Enhance queue_application_deployment to handle existing deployments and return appropriate status messages +- *(SourceManagement)* Add functionality to change Git source and display current source in the application settings + +### 🐛 Bug Fixes + +- *(CheckProxy)* Update port conflict check to ensure accurate grep matching +- *(CheckProxy)* Refine port conflict detection with improved grep patterns +- *(CheckProxy)* Enhance port conflict detection by adjusting ss command for better output +- *(api)* Add back validateDataApplications (#5539) +- *(CheckProxy, Status)* Prevent proxy checks when force_stop is active; remove debug statement in General +- *(Status)* Conditionally check proxy status and refresh button based on force_stop state +- *(General)* Change redis_password property to nullable string +- *(DeployController)* Update request handling to use input method and enhance OpenAPI description for deployment endpoint + +### 💼 Other + +- Add missing UUID to openapi spec + +### 🚜 Refactor + +- *(Server)* Use data_get for safer access to settings properties in isFunctional method +- *(Application)* Rename network_aliases to custom_network_aliases across the application for clarity and consistency +- *(ApplicationDeploymentJob)* Streamline environment variable handling by introducing generate_coolify_env_variables method and consolidating logic for pull request and main branch scenarios +- *(ApplicationDeploymentJob, ApplicationDeploymentQueue)* Improve deployment status handling and log entry management with transaction support +- *(SourceManagement)* Sort sources by name and improve UI for changing Git source with better error handling +- *(Email)* Streamline SMTP and resend settings handling in copyFromInstanceSettings method +- *(Email)* Enhance error handling in SMTP and resend methods by passing context to handleError function +- *(DynamicConfigurations)* Improve handling of dynamic configuration content by ensuring fallback to empty string when content is null +- *(ServicesGenerate)* Update command signature from 'services:generate' to 'generate:services' for consistency; update Dockerfile to run service generation during build; update Odoo image version to 18 and add extra addons volume in compose configuration +- *(Dockerfile)* Streamline RUN commands for improved readability and maintainability by adding line continuations +- *(Dockerfile)* Reintroduce service generation command in the build process for consistency and ensure proper asset compilation + +### ⚙️ Miscellaneous Tasks + +- *(versions)* Bump version to 406 +- *(versions)* Bump version to 407 and 408 for coolify and nightly +- *(versions)* Bump version to 408 for coolify and 409 for nightly + +## [4.0.0-beta.405] - 2025-04-04 + +### 🚀 Features + +- *(api)* Update OpenAPI spec for services (#5448) +- *(proxy)* Enhance proxy handling and port conflict detection + +### 🐛 Bug Fixes + +- *(api)* Used ssh keys can be deleted +- *(email)* Transactional emails not sending + +### 🚜 Refactor + +- *(CheckProxy)* Replace 'which' with 'command -v' for command availability checks + +### 📚 Documentation + +- Update changelog +- Update changelog +- Update changelog +- Update changelog +- Update changelog +- Update changelog +- Update changelog +- Update changelog +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(versions)* Bump version to 406 +- *(versions)* Bump version to 407 + +## [4.0.0-beta.404] - 2025-04-03 + +### 🚀 Features + +- *(lang)* Added Azerbaijani language updated turkish language. (#5497) +- *(lang)* Added Portuguese from Brazil language (#5500) +- *(lang)* Add Indonesian language translations (#5513) + +### 🐛 Bug Fixes + +- *(docs)* Comment out execute for now +- *(installation)* Mount the docker config +- *(installation)* Path to config file for docker login +- *(service)* Add health check to Bugsink service (#5512) +- *(email)* Emails are not sent in multiple cases +- *(deployments)* Use graceful shutdown instead of `rm` +- *(docs)* Contribute service url (#5517) +- *(proxy)* Proxy restart does not work on domain +- *(ui)* Only show copy button on https +- *(database)* Custom config for MongoDB (#5471) + +### 📚 Documentation + +- Update changelog +- Update changelog +- Update changelog +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(service)* Remove unused code in Bugsink service +- *(versions)* Update version to 404 +- *(versions)* Bump version to 403 (#5520) +- *(versions)* Bump version to 404 + +## [4.0.0-beta.402] - 2025-04-01 + +### 🚀 Features + +- *(deployments)* Add list application deployments api route +- *(deploy)* Add pull request ID parameter to deploy endpoint +- *(api)* Add pull request ID parameter to applications endpoint +- *(api)* Add endpoints for retrieving application logs and deployments +- *(lang)* Added Norwegian language (#5280) +- *(dep)* Bump all dependencies + +### 🐛 Bug Fixes + +- Only get apps for the current team +- *(DeployController)* Cast 'pr' query parameter to integer +- *(deploy)* Validate team ID before deployment +- *(wakapi)* Typo in env variables and add some useful variables to wakapi.yaml (#5424) +- *(ui)* Instance Backup settings + +### 🚜 Refactor + +- *(dev)* Remove OpenAPI generation functionality +- *(migration)* Enhance local file volumes migration with logging + +### ⚙️ Miscellaneous Tasks + +- *(service)* Update minecraft service ENVs +- *(service)* Add more vars to infisical.yaml (#5418) +- *(service)* Add google variables to plausible.yaml (#5429) +- *(service)* Update authentik.yaml versions (#5373) +- *(core)* Remove redocs +- *(versions)* Update coolify version numbers to 4.0.0-beta.403 and 4.0.0-beta.404 + +## [4.0.0-beta.401] - 2025-03-28 + +### 📚 Documentation + +- Update changelog +- Update changelog + +## [4.0.0-beta.400] - 2025-03-27 + +### 🚀 Features + +- *(database)* Disable MongoDB SSL by default in migration +- *(database)* Add CA certificate generation for database servers +- *(application)* Add SPA configuration and update Nginx generation logic + +### 🐛 Bug Fixes + +- *(file-storage)* Double save on compose volumes +- *(parser)* Add logging support for applications in services + +### 🚜 Refactor + +- *(proxy)* Improve port availability checks with multiple methods +- *(database)* Update MongoDB SSL configuration for improved security +- *(database)* Enhance SSL configuration handling for various databases +- *(notifications)* Update Telegram button URL for staging environment +- *(models)* Remove unnecessary cloud check in isEnabled method +- *(database)* Streamline event listeners in Redis General component +- *(database)* Remove redundant database status display in MongoDB view +- *(database)* Update import statements for Auth in database components +- *(database)* Require PEM key file for SSL certificate regeneration +- *(database)* Change MySQL daemon command to MariaDB daemon +- *(nightly)* Update version numbers and enhance upgrade script +- *(versions)* Update version numbers for coolify and nightly +- *(email)* Validate team membership for email recipients +- *(shared)* Simplify deployment status check logic +- *(shared)* Add logging for running deployment jobs +- *(shared)* Enhance job status check to include 'reserved' +- *(email)* Improve error handling by passing context to handleError +- *(email)* Streamline email sending logic and improve configuration handling +- *(email)* Remove unnecessary whitespace in email sending logic +- *(email)* Allow custom email recipients in email sending logic +- *(email)* Enhance sender information formatting in email logic +- *(proxy)* Remove redundant stop call in restart method +- *(file-storage)* Add loadStorageOnServer method for improved error handling +- *(docker)* Parse and sanitize YAML compose file before encoding +- *(file-storage)* Improve layout and structure of input fields +- *(email)* Update label for test email recipient input +- *(database-backup)* Remove existing Docker container before backup upload +- *(database)* Improve decryption and deduplication of local file volumes +- *(database)* Remove debug output from volume update process + +### 📚 Documentation + +- Update changelog +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(versions)* Update version numbers for coolify and nightly + +### ◀️ Revert + +- Encrypting mount and fs_path + +## [4.0.0-beta.399] - 2025-03-25 + +### 🚀 Features + +- *(service)* Neon +- *(migration)* Add `ssl_certificates` table and model +- *(migration)* Add ssl setting to `standalone_postgresqls` table +- *(ui)* Add ssl settings to Postgres ui +- *(db)* Add ssl mode to Postgres URLs +- *(db)* Setup ssl during Postgres start +- *(migration)* Encrypt local file volumes content and paths +- *(ssl)* Ssl generation helper +- *(ssl)* Migrate to `ECC`certificates using `secp521r1` +- *(ssl)* Improve SSL helper +- *(ssl)* Add a Coolify CA Certificate to all servers +- *(seeder)* Call CA SSL seeder in prod and dev +- *(ssl)* Add Coolify CA Certificate when adding a new server +- *(installer)* Create CA folder during installation +- *(ssl)* Improve SSL helper +- *(ssl)* Use new improved helper for SSL generation +- *(ui)* Add CA cert UI +- *(ui)* New copy button component +- *(ui)* Use new copy button component everywhere +- *(ui)* Improve server advanced view +- *(migration)* Add CN and alternative names to DB +- *(databases)* Add CA SSL crt location to Postgres URLs +- *(ssl)* Improve ssl generation +- *(ssl)* Regenerate SSL certs job +- *(ssl)* Regenerate certificate and valid until UI +- *(ssl)* Regenerate CA cert and all other certs logic +- *(ssl)* Add full MySQL SSL Support +- *(ssl)* Add full MariaDB SSL support +- *(ssl)* Add `openssl.conf` to configure SSL extension properly +- *(ssl)* Improve SSL generation and security a lot +- *(ssl)* Check for SSL renewal twice daily +- *(ssl)* Add SSL relationships to all DBs +- Add full SSL support to MongoDB +- *(ssl)* Fix some issues and improve ssl generation helper +- *(ssl)* Ability to create `.pem` certs and add `clientAuth` to `extendedKeyUsage` +- *(ssl)* New modes for MongoDB and get `caCert` and `mountPath` correctly +- *(ssl)* Full SSL support for Redis +- New mode implementation for MongoDB +- *(ssl)* Improve Redis and remove modes +- Full SSL support for DrangonflyDB +- SSL notification +- *(github-source)* Enhance GitHub App configuration with manual and private key support +- *(ui)* Improve GitHub repository selection and styling +- *(database)* Implement two-step confirmation for database deletion +- *(assets)* Add new SVG logo for Coolify +- *(install)* Enhance Docker address pool configuration and validation +- *(install)* Improve Docker address pool management and service restart logic +- *(install)* Add missing env variable to install script +- *(LocalFileVolume)* Add binary file detection and update UI logic +- *(templates)* Change glance for v0.7 +- *(templates)* Add Freescout service template +- *(service)* Add Evolution API template +- *(service)* Add evolution-api and neon-ws-proxy templates +- *(svg)* Add coolify and evolution-api SVG logos +- *(api)* Add api to create custom services +- *(api)* Separate create and one-click routes +- *(api)* Update Services api routes and handlers +- *(api)* Unify service creation endpoint and enhance validation +- *(notifications)* Add discord ping functionality and settings +- *(user)* Implement session deletion on password reset +- *(github)* Enhance repository loading and validation in applications + +### 🐛 Bug Fixes + +- *(api)* Docker compose based apps creationg through api +- *(database)* Improve database type detection for Supabase Postgres images +- *(ssl)* Permission of ssl crt and key inside the container +- *(ui)* Make sure file mounts do not showing the encrypted values +- *(ssl)* Make default ssl mode require not verify-full as it does not need a ca cert +- *(ui)* Select component should not always uses title case +- *(db)* SSL certificates table and model +- *(migration)* Ssl certificates table +- *(databases)* Fix database name users new `uuid` instead of DB one +- *(database)* Fix volume and file mounts and naming +- *(migration)* Store subjectAlternativeNames as a json array in the db +- *(ssl)* Make sure the subjectAlternativeNames are unique and stored correctly +- *(ui)* Certificate expiration data is null before starting the DB +- *(deletion)* Fix DB deletion +- *(ssl)* Improve SSL cert file mounts +- *(ssl)* Always create ca crt on disk even if it is already there +- *(ssl)* Use mountPath parameter not a hardcoded path +- *(ssl)* Use 1 instead of on for mysql +- *(ssl)* Do not remove SSL directory +- *(ssl)* Wrong ssl cert is loaded to the server and UI error when regenerating SSL +- *(ssl)* Make sure when regenerating the CA cert it is not overwritten with a server cert +- *(ssl)* Regenerating certs for a specific DB +- *(ssl)* Fix MariaDB and MySQL need CA cert +- *(ssl)* Add mount path to DB to fix regeneration of certs +- *(ssl)* Fix SSL regeneration to sign with CA cert and use mount path +- *(ssl)* Get caCert correctly +- *(ssl)* Remove caCert even if it is a folder by accident +- *(ssl)* Ger caCert and `mountPath` correctly +- *(ui)* Only show Regenerate SSL Certificates button when there is a cert +- *(ssl)* Server id +- *(ssl)* When regenerating SSL certs the cert is not singed with the new CN +- *(ssl)* Adjust ca paths for MySQL +- *(ssl)* Remove mode selection for MariaDB as it is not supported +- *(ssl)* Permission issue with MariDB cert and key and paths +- *(ssl)* Rename Redis mode to verify-ca as it is not verify-full +- *(ui)* Remove unused mode for MongoDB +- *(ssl)* KeyDB port and caCert args are missing +- *(ui)* Enable SSL is not working correctly for KeyDB +- *(ssl)* Add `--tls` arg to DrangflyDB +- *(notification)* Always send SSL notifications +- *(database)* Change default value of enable_ssl to false for multiple tables +- *(ui)* Correct grammatical error in 404 page +- *(seeder)* Update GitHub app name in GithubAppSeeder +- *(plane)* Update APP_RELEASE to v0.25.2 in environment configuration +- *(domain)* Dispatch refreshStatus event after successful domain update +- *(database)* Correct container name generation for service databases +- *(database)* Limit container name length for database proxy +- *(database)* Handle unsupported database types in StartDatabaseProxy +- *(database)* Simplify container name generation in StartDatabaseProxy +- *(install)* Handle potential errors in Docker address pool configuration +- *(backups)* Retention settings +- *(redis)* Set default redis_username for new instances +- *(core)* Improve instantSave logic and error handling +- *(general)* Correct link to framework specific documentation +- *(core)* Redirect healthcheck route for dockercompose applications +- *(api)* Use name from request payload +- *(issue#4746)* Do not use setGitImportSettings inside of generateGitLsRemoteCommands +- Correct some spellings +- *(service)* Replace deprecated credentials env variables on keycloak service +- *(keycloak)* Update keycloak image version to 26.1 +- *(console)* Handle missing root user in password reset command +- *(ssl)* Handle missing CA certificate in SSL regeneration job +- *(copy-button)* Ensure text is safely passed to clipboard + +### 💼 Other + +- Bump Coolify to 4.0.0-beta.400 +- *(migration)* Add SSL fields to database tables +- SSL Support for KeyDB + +### 🚜 Refactor + +- *(ui)* Unhide log toggle in application settings +- *(nginx)* Streamline default Nginx configuration and improve error handling +- *(install)* Clean up install script and enhance Docker installation logic +- *(ScheduledTask)* Clean up code formatting and remove unused import +- *(app)* Remove unused MagicBar component and related code +- *(database)* Streamline SSL configuration handling across database types +- *(application)* Streamline healthcheck parsing from Dockerfile +- *(notifications)* Standardize getRecipients method signatures +- *(configuration)* Centralize configuration management in ConfigurationRepository +- *(docker)* Update image references to use centralized registry URL +- *(env)* Add centralized registry URL to environment configuration +- *(storage)* Simplify file storage iteration in Blade template +- *(models)* Add is_directory attribute to LocalFileVolume model +- *(modal)* Add ignoreWire attribute to modal-confirmation component +- *(invite-link)* Adjust layout for better responsiveness in form +- *(invite-link)* Enhance form layout for improved responsiveness +- *(network)* Enhance docker network creation with ipv6 fallback +- *(network)* Check for existing coolify network before creation +- *(database)* Enhance encryption process for local file volumes + +### 📚 Documentation + +- Update changelog +- Update changelog +- *(CONTRIBUTING)* Add note about Laravel Horizon accessibility +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(migration)* Remove unused columns +- *(ssl)* Improve code in ssl helper +- *(migration)* Ssl cert and key should not be nullable +- *(ssl)* Rename CA cert to `coolify-ca.crt` because of conflicts +- Rename ca crt folder to ssl +- *(ui)* Improve valid until handling +- Improve code quality suggested by code rabbit +- *(supabase)* Update Supabase service template and Postgres image version +- *(versions)* Update version numbers for coolify and nightly + +## [4.0.0-beta.398] - 2025-03-01 + +### 🚀 Features + +- *(billing)* Add Stripe past due subscription status tracking +- *(ui)* Add past due subscription warning banner + +### 🐛 Bug Fixes + +- *(billing)* Restrict Stripe subscription status update to 'active' only + +### 💼 Other + +- Bump Coolify to 4.0.0-beta.398 + +### 🚜 Refactor + +- *(billing)* Enhance Stripe subscription status handling and notifications + +## [4.0.0-beta.397] - 2025-02-28 + +### 🐛 Bug Fixes + +- *(billing)* Handle 'past_due' subscription status in Stripe processing +- *(revert)* Label parsing +- *(helpers)* Initialize command variable in parseCommandFromMagicEnvVariable + +### 📚 Documentation + +- Update changelog + +## [4.0.0-beta.396] - 2025-02-28 + +### 🚀 Features + +- *(ui)* Add wire:key to two-step confirmation settings +- *(database)* Add index to scheduled task executions for improved query performance +- *(database)* Add index to scheduled database backup executions + +### 🐛 Bug Fixes + +- *(core)* Production dockerfile +- *(ui)* Update storage configuration guidance link +- *(ui)* Set default SMTP encryption to starttls +- *(notifications)* Correct environment URL path in application notifications +- *(config)* Update default PostgreSQL host to coolify-db instead of postgres +- *(docker)* Improve Docker compose file validation process +- *(ui)* Restrict service retrieval to current team +- *(core)* Only validate custom compose files +- *(mail)* Set default mailer to array when not specified +- *(ui)* Correct redirect routes after task deletion +- *(core)* Adding a new server should not try to make the default docker network +- *(core)* Clean up unnecessary files during application image build +- *(core)* Improve label generation and merging for applications and services + +### 💼 Other + +- Bump all dependencies (#5216) + +### 🚜 Refactor + +- *(ui)* Simplify file storage modal confirmations +- *(notifications)* Improve transactional email settings handling +- *(scheduled-tasks)* Improve scheduled task creation and management + +### 📚 Documentation + +- Update changelog +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- Bump helper and realtime version + +## [4.0.0-beta.395] - 2025-02-22 + +### 📚 Documentation + +- Update changelog + +## [4.0.0-beta.394] - 2025-02-17 + +### 📚 Documentation + +- Update changelog + +## [4.0.0-beta.393] - 2025-02-15 + +### 📚 Documentation + +- Update changelog + +## [4.0.0-beta.392] - 2025-02-13 + +### 🚀 Features + +- *(ui)* Add top padding to pricing plans view +- *(core)* Add error logging and cron parsing to docker/server schedules +- *(core)* Prevent using servers with existing resources as build servers +- *(ui)* Add textarea switching option in service compose editor + +### 🐛 Bug Fixes + +- Pull latest image from registry when using build server +- *(deployment)* Improve server selection for deployment cancellation +- *(deployment)* Improve log line rendering and formatting +- *(s3-storage)* Optimize team admin notification query +- *(core)* Improve connection testing with dynamic disk configuration for s3 backups +- *(core)* Update service status refresh event handling +- *(ui)* Adjust polling intervals for database and service status checks +- *(service)* Update Fider service template healthcheck command +- *(core)* Improve server selection error handling in Docker component +- *(core)* Add server functionality check before dispatching container status +- *(ui)* Disable sticky scroll in Monaco editor +- *(ui)* Add literal and multiline env support to services. +- *(services)* Owncloud docs link +- *(template)* Remove db-migration step from `infisical.yaml` (#5209) +- *(service)* Penpot (#5047) + +### 🚜 Refactor + +- Use pull flag on docker compose up + +### 📚 Documentation + +- Update changelog +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- Rollback Coolify version to 4.0.0-beta.392 +- Bump Coolify version to 4.0.0-beta.393 +- Bump Coolify version to 4.0.0-beta.394 +- Bump Coolify version to 4.0.0-beta.395 +- Bump Coolify version to 4.0.0-beta.396 +- *(services)* Update zipline to use new Database env var. (#5210) +- *(service)* Upgrade authentik service +- *(service)* Remove unused env from zipline + +## [4.0.0-beta.391] - 2025-02-04 + +### 🚀 Features + +- Add application api route +- Container logs +- Remove ansi color from log +- Add lines query parameter +- *(changelog)* Add git cliff for automatic changelog generation +- *(workflows)* Improve changelog generation and workflows +- *(ui)* Add periodic status checking for services +- *(deployment)* Ensure private key is stored in filesystem before deployment +- *(slack)* Show message title in notification previews (#5063) +- *(i18n)* Add Arabic translations (#4991) +- *(i18n)* Add French translations (#4992) +- *(services)* Update `service-templates.json` + +### 🐛 Bug Fixes + +- *(core)* Improve deployment failure Slack notification formatting +- *(core)* Update Slack notification formatting to use bold correctly +- *(core)* Enhance Slack deployment success notification formatting +- *(ui)* Simplify service templates loading logic +- *(ui)* Align title and add button vertically in various views +- Handle pullrequest:updated for reliable preview deployments +- *(ui)* Fix typo on team page (#5105) +- Cal.com documentation link give 404 (#5070) +- *(slack)* Notification settings URL in `HighDiskUsage` message (#5071) +- *(ui)* Correct typo in Storage delete dialog (#5061) +- *(lang)* Add missing italian translations (#5057) +- *(service)* Improve duplicati.yaml (#4971) +- *(service)* Links in homepage service (#5002) +- *(service)* Added SMTP credentials to getoutline yaml template file (#5011) +- *(service)* Added `KEY` Variable to Beszel Template (#5021) +- *(cloudflare-tunnels)* Dead links to docs (#5104) +- System-wide GitHub apps (#5114) + +### 🚜 Refactor + +- Simplify service start and restart workflows + +### 📚 Documentation + +- *(services)* Reword nitropage url and slogan +- *(readme)* Add Convex to special sponsors section +- Update changelog + +### ⚙️ Miscellaneous Tasks + +- *(config)* Increase default PHP memory limit to 256M +- Add openapi response +- *(workflows)* Make naming more clear and remove unused code +- Bump Coolify version to 4.0.0-beta.392/393 +- *(ci)* Update changelog generation workflow to target 'next' branch +- *(ci)* Update changelog generation workflow to target main branch + +## [4.0.0-beta.390] - 2025-01-28 + +### 🚀 Features + +- *(template)* Add Open Web UI +- *(templates)* Add Open Web UI service template +- *(ui)* Update GitHub source creation advanced section label +- *(core)* Add dynamic label reset for application settings +- *(ui)* Conditionally enable advanced application settings based on label readonly status +- *(env)* Added COOLIFY_RESOURCE_UUID environment variable +- *(vite)* Add Cloudflare async script and style tag attributes +- *(meta)* Add comprehensive SEO and social media meta tags +- *(core)* Add name to default proxy configuration + +### 🐛 Bug Fixes + +- *(ui)* Update database control UI to check server functionality before displaying actions +- *(ui)* Typo in upgrade message +- *(ui)* Cloudflare tunnel configuration should be an info, not a warning +- *(s3)* DigitalOcean storage buckets do not work +- *(ui)* Correct typo in container label helper text +- Disable certain parts if readonly label is turned off +- Cleanup old scheduled_task_executions +- Validate cron expression in Scheduled Task update +- *(core)* Check cron expression on save +- *(database)* Detect more postgres database image types +- *(templates)* Update service templates +- Remove quotes in COOLIFY_CONTAINER_NAME +- *(templates)* Update Trigger.dev service templates with v3 configuration +- *(database)* Adjust MongoDB restore command and import view styling +- *(core)* Improve public repository URL parsing for branch and base directory +- *(core)* Increase HTTP/2 max concurrent streams to 250 (default) +- *(ui)* Update docker compose file helper text to clarify repository modification +- *(ui)* Skip SERVICE_FQDN and SERVICE_URL variables during update +- *(core)* Stopping database is not disabling db proxy +- *(core)* Remove --remove-orphans flag from proxy startup command to prevent other proxy deletions (db) +- *(api)* Domain check when updating domain +- *(ui)* Always redirect to dashboard after team switch +- *(backup)* Escape special characters in database backup commands + +### 💼 Other + +- Trigger.dev templates - wrong key length issue +- Trigger.dev template - missing ports and wrong env usage +- Trigger.dev template - fixed otel config +- Trigger.dev template - fixed otel config +- Trigger.dev template - fixed port config + +### 🚜 Refactor + +- *(s3)* Improve S3 bucket endpoint formatting +- *(vite)* Improve environment variable handling in Vite configuration +- *(ui)* Simplify GitHub App registration UI and layout + +### ⚙️ Miscellaneous Tasks + +- *(version)* Bump Coolify version to 4.0.0-beta.391 + +### ◀️ Revert + +- Remove Cloudflare async tag attributes + +## [4.0.0-beta.389] - 2025-01-23 + +### 🚀 Features + +- *(docs)* Update tech stack +- *(terminal)* Show terminal unavailable if the container does not have a shell on the global terminal UI +- *(ui)* Improve deployment UI + +### 🐛 Bug Fixes + +- *(service)* Infinite loading and lag with invoiceninja service (#4876) +- *(service)* Invoiceninja service +- *(workflows)* `Waiting for changes` label should also be considered and improved messages +- *(workflows)* Remove tags only if the PR has been merged into the main branch +- *(terminal)* Terminal shows that it is not available, even though it is +- *(labels)* Docker labels do not generated correctly +- *(helper)* Downgrade Nixpacks to v1.29.0 +- *(labels)* Generate labels when they are empty not when they are already generated +- *(storage)* Hetzner storage buckets not working + +### 📚 Documentation + +- Add TECH_STACK.md (#4883) + +### ⚙️ Miscellaneous Tasks + +- *(versions)* Update coolify versions to v4.0.0-beta.389 +- *(core)* EnvironmentVariable Model now extends BaseModel to remove duplicated code +- *(versions)* Update coolify versions to v4.0.0-beta.3909 + +## [4.0.0-beta.388] - 2025-01-22 + +### 🚀 Features + +- *(core)* Add SOURCE_COMMIT variable to build environment in ApplicationDeploymentJob +- *(service)* Update affine.yaml with AI environment variables (#4918) +- *(service)* Add new service Flipt (#4875) + +### 🐛 Bug Fixes + +- *(core)* Update environment variable generation logic in ApplicationDeploymentJob to handle different build packs +- *(env)* Shared variables can not be updated +- *(ui)* Metrics stuck in loading state +- *(ui)* Use `wire:navigate` to navigate to the server settings page +- *(service)* Plunk API & health check endpoint (#4925) + +## [4.0.0-beta.386] - 2025-01-22 + +### 🐛 Bug Fixes + +- *(redis)* Update environment variable keys from standalone_redis_id to resourceable_id +- *(routes)* Local API docs not available on domain or IP +- *(routes)* Local API docs not available on domain or IP +- *(core)* Update application_id references to resourable_id and resourable_type for Nixpacks configuration +- *(core)* Correct spelling of 'resourable' to 'resourceable' in Nixpacks configuration for ApplicationDeploymentJob +- *(ui)* Traefik dashboard url not working +- *(ui)* Proxy status badge flashing during navigation + +### 🚜 Refactor + +- *(workflows)* Replace jq with PHP script for version retrieval in workflows + +### ⚙️ Miscellaneous Tasks + +- *(dep)* Bump helper version to 1.0.5 +- *(docker)* Add blank line for readability in Dockerfile +- *(versions)* Update coolify versions to v4.0.0-beta.388 +- *(versions)* Update coolify versions to v4.0.0-beta.389 and add helper version retrieval script + +## [4.0.0-beta.385] - 2025-01-21 + +### 🚀 Features + +- *(core)* Wip version of coolify.json + +### 🐛 Bug Fixes + +- *(email)* Transactional email sending +- *(ui)* Add missing save button for new Docker Cleanup page +- *(ui)* Show preview deployment environment variables +- *(ui)* Show error on terminal if container has no shell (bash/sh) +- *(parser)* Resource URL should only be parsed if there is one +- *(core)* Compose parsing for apps + +### ⚙️ Miscellaneous Tasks + +- *(dep)* Bump nixpacks version +- *(dep)* Version++ + +## [4.0.0-beta.384] - 2025-01-21 + +### 🐛 Bug Fixes + +- *(ui)* Backups link should not redirected to general +- Envs with special chars during build +- *(db)* `finished_at` timestamps are not set for existing deployments +- Load service templates on cloud + +## [4.0.0-beta.383] - 2025-01-20 + +### 🐛 Bug Fixes + +- *(service)* Add healthcheck to Cloudflared service (#4859) +- Remove wire:navigate from import backups + +## [4.0.0-beta.382] - 2025-01-17 + +### 🚀 Features + +- Add log file check message in upgrade script for better troubleshooting +- Add root user details to install script + +### 🐛 Bug Fixes + +- Create the private key before the server in the prod seeder +- Update ProductionSeeder to check for private key instead of server's private key +- *(ui)* Missing underline for docs link in the Swarm section (#4860) +- *(service)* Change chatwoot service postgres image from `postgres:12` to `pgvector/pgvector:pg12` +- Docker image parser +- Add public key attribute to privatekey model +- Correct service update logic in Docker Compose parser +- Update CDN URL in install script to point to nightly version + +### 🚜 Refactor + +- Comment out RootUserSeeder call in ProductionSeeder for clarity +- Streamline ProductionSeeder by removing debug logs and unnecessary checks, while ensuring essential seeding operations remain intact +- Remove debug echo statements from Init command to clean up output and improve readability + +## [4.0.0-beta.381] - 2025-01-17 + +### 🚀 Features + +- Able to import full db backups for pg/mysql/mariadb +- Restore backup from server file +- Docker volume data cloning +- Move volume data cloning to a Job +- Volume cloning for ResourceOperations +- Remote server volume cloning +- Add horizon server details to queue +- Enhance horizon:manage command with worker restart check +- Add is_coolify_host to the server api responses +- DB migration for Backup retention +- UI for backup retention settings +- New global s3 and local backup deletion function +- Use new backup deletion functions +- Add calibre-web service +- Add actual-budget service +- Add rallly service +- Template for Gotenberg, a Docker-powered stateless API for PDF files +- Enhance import command options with additional guidance and improved checkbox label +- Purify for better sanitization +- Move docker cleanup to its own tab +- DB and Model for docker cleanup executions +- DockerCleanupExecutions relationship +- DockerCleanupDone event +- Get command and output for logs from CleanupDocker +- New sidebar menu and order +- Docker cleanup executions UI +- Add execution log to dockerCleanupJob +- Improve deployment UI +- Root user envs and seeding +- Email, username and password validation when they are set via envs +- Improved error handling and log output +- Add root user configuration variables to production environment + +### 🐛 Bug Fixes + +- Compose envs +- Scheduled tasks and backups are executed by server timezone. +- Show backup timezone on the UI +- Disappearing UI after livewire event received +- Add default vector db for anythingllm +- We need XSRF-TOKEN for terminal +- Prevent default link behavior for resource and settings actions in dashboard +- Increase default php memory limit +- Show if only build servers are added to your team +- Update Livewire button click method to use camelCase +- Local dropzonejs +- Import backups due to js stuff should not be navigated +- Install inetutils on Arch Linux +- Use ip in place of hostname from inetutils in arch +- Update import command to append file redirection for database restoration +- Ui bug on pw confirmation +- Exclude system and computed fields from model replication +- Service cloning on a separate server +- Application cloning +- `Undefined variable $fs_path` for databases +- Service and database cloning and label generation +- Labels and URL generation when cloning +- Clone naming for different database data volumes +- Implement all the cloneMe changes for ResourceOperations as well +- Volume and fileStorages cloning +- View text and helpers +- Teable +- Trigger with external db +- Set `EXPERIMENTAL_FEATURES` to false for labelstudio +- Monaco editor disabled state +- Edge case where executions could be null +- Create destination properly +- Getcontainer status should timeout after 30s +- Enable response for temporary unavailability in sentinel push endpoint +- Use timeout in cleanup resources +- Add timeout to sentinel process checks for improved reliability +- Horizon job checker +- Update response message for sentinel push route +- Add own servers on cloud +- Application deployment +- Service update statsu +- If $SERVICE found in the service specific configuration, then search for it in the db +- Instance wide GitHub apps are not available on other teams then the source team +- Function calls +- UI +- Deletion of single backup +- Backup job deletion - delete all backups from s3 and local +- Use new removeOldBackups function +- Retention functions and folder deletion for local backups +- Storage retention setting +- Db without s3 should still backup +- Wording +- `Undefined variable $service` when creating a new service +- Nodebb service +- Calibre-web service +- Rallly and actualbudget service +- Removed container_name +- Added healthcheck for gotenberg template +- Gotenberg +- *(template)* Gotenberg healthcheck, use /health instead of /version +- Use wire:navigate on sidebar +- Use wire:navigate on dashboard +- Use wire:navigate on projects page +- More wire:navigate +- Even more wire:navigate +- Service navigation +- Logs icons everywhere + terminal +- Redis DB should use the new resourceable columns +- Joomla service +- Add back letters to prod password requirement +- Check System and GitHub time and throw and error if it is over 50s out of sync +- Error message and server time getting +- Error rendering +- Render html correctly now +- Indent +- Potential fix for permissions update +- Expiration time claim ('exp') must be a numeric value +- Sanitize html error messages +- Production password rule and cleanup code +- Use json as it is just better than string for huge amount of logs +- Use `wire:navigate` on server sidebar +- Use finished_at for the end time instead of created_at +- Cancelled deployments should not show end and duration time +- Redirect to server index instead of show on error in Advanced and DockerCleanup components +- Disable registration after creating the root user +- RootUserSeeder +- Regex username validation +- Add spacing around echo outputs +- Success message +- Silent return if envs are empty or not set. + +### 💼 Other + +- Arrrrr +- Dep +- Docker dep + +### 🚜 Refactor + +- Rename parameter in DatabaseBackupJob for clarity +- Improve checkbox component accessibility and styling +- Remove unused tags method from ApplicationDeploymentJob +- Improve deployment status check in isAnyDeploymentInprogress function +- Extend HorizonServiceProvider from HorizonApplicationServiceProvider +- Streamline job status retrieval and clean up repository interface +- Enhance ApplicationDeploymentJob and HorizonServiceProvider for improved job handling +- Remove commented-out unsubscribe route from API +- Update redirect calls to use a consistent navigation method in deployment functions +- AppServiceProvider +- Github.php +- Improve data formatting and UI + +### ⚙️ Miscellaneous Tasks + +- Improve Penpot healthchecks +- Switch up readonly lables to make more sense +- Remove unused computed fields +- Use the new job dispatch +- Disable volume data cloning for now +- Improve code +- Lowcoder service naming +- Use new functions +- Improve error styling +- Css +- More css as it still looks like shit +- Final css touches +- Ajust time to 50s (tests done) +- Remove debug log, finally found it +- Remove more logging +- Remove limit on commit message +- Remove dayjs +- Remove unused code and fix import + +## [4.0.0-beta.380] - 2024-12-27 + +### 🚀 Features + +- New ServerReachabilityChanged event +- Use new ServerReachabilityChanged event instead of isDirty +- Add infomaniak oauth +- Add server disk usage check frequency +- Add environment_uuid support and update API documentation +- Add service/resource/project labels +- Add coolify.environment label +- Add database subtype +- Migrate to new encryption options +- New encryption options + +### 🐛 Bug Fixes + +- Render html on error page correctly +- Invalid API response on missing project +- Applications API response code + schema +- Applications API writing to unavailable models +- If an init script is renamed the old version is still on the server +- Oauthseeder +- Compose loading seq +- Resource clone name + volume name generation +- Update Dockerfile entrypoint path to /etc/entrypoint.d +- Debug mode +- Unreachable notifications +- Remove duplicated ServerCheckJob call +- Few fixes and use new ServerReachabilityChanged event +- Use serverStatus not just status +- Oauth seeder +- Service ui structure +- Check port 8080 and fallback to 80 +- Refactor database view +- Always use docker cleanup frequency +- Advanced server UI +- Html css +- Fix domain being override when update application +- Use nixpacks predefined build variables, but still could update the default values from Coolify +- Use local monaco-editor instead of Cloudflare +- N8n timezone +- Smtp encryption +- Bind() to 0.0.0.0:80 failed +- Oauth seeder +- Unreachable notifications +- Instance settings migration +- Only encrypt instance email settings if there are any +- Error message +- Update healthcheck and port configurations to use port 8080 + +### 🚜 Refactor + +- Rename `coolify.environment` to `coolify.environmentName` + +### ⚙️ Miscellaneous Tasks + +- Regenerate API spec, removing notification fields +- Remove ray debugging +- Version ++ + +## [4.0.0-beta.378] - 2024-12-13 + +### 🐛 Bug Fixes + +- Monaco editor light and dark mode switching +- Service status indicator + oauth saving +- Socialite for azure and authentik +- Saving oauth +- Fallback for copy button +- Copy the right text +- Maybe fallback is now working +- Only show copy button on secure context + +## [4.0.0-beta.377] - 2024-12-13 + +### 🚀 Features + +- Add deploy-only token permission +- Able to deploy without cache on every commit +- Update private key nam with new slug as well +- Allow disabling default redirect, set status to 503 +- Add TLS configuration for default redirect in Server model +- Slack notifications +- Introduce root permission +- Able to download schedule task logs +- Migrate old email notification settings from the teams table +- Migrate old discord notification settings from the teams table +- Migrate old telegram notification settings from the teams table +- Add slack notifications to a new table +- Enable success messages again +- Use new notification stuff inside team model +- Some more notification settings and better defaults +- New email notification settings +- New shared function name `is_transactional_emails_enabled()` +- New shared notifications functions +- Email Notification Settings Model +- Telegram notification settings Model +- Discord notification settings Model +- Slack notification settings Model +- New Discord notification UI +- New Slack notification UI +- New telegram UI +- Use new notification event names +- Always sent notifications +- Scheduled task success notification +- Notification trait +- Get discord Webhook form new table +- Get Slack Webhook form new table +- Use new table or instance settings for email +- Use new place for settings and topic IDs for telegram +- Encrypt instance email settings +- Use encryption in instance settings model +- Scheduled task success and failure notifications +- Add docker cleanup success and failure notification settings columns +- UI for docker cleanup success and failure notification +- Docker cleanup email views +- Docker cleanup success and failure notification files +- Scheduled task success email +- Send new docker cleanup notifications +- :passport_control: integrate Authentik authentication with Coolify +- *(notification)* Add Pushover +- Add seeder command and configuration for database seeding +- Add new password magic env with symbols +- Add documenso service + +### 🐛 Bug Fixes + +- Resolve undefined searchInput reference in Alpine.js component +- URL and sync new app name +- Typos and naming +- Client and webhook secret disappear after sync +- Missing `mysql_password` API property +- Incorrect MongoDB init API property +- Old git versions does not have --cone implemented properly +- Don't allow editing traefik config +- Restart proxy +- Dev mode +- Ui +- Display actual values for disk space checks in installer script +- Proxy change behaviour +- Add warning color +- Import NotificationSlack correctly +- Add middleware to new abilities, better ux for selecting permissions, etc. +- Root + read:sensive could read senstive data with a middlewarew +- Always have download logs button on scheduled tasks +- Missing css +- Development image +- Dockerignore +- DB migration error +- Drop all unused smtp columns +- Backward compatibility +- Email notification channel enabled function +- Instance email settins +- Make sure resend is false if SMTP is true and vice versa +- Email Notification saving +- Slack and discord url now uses text filed because encryption makes the url very long +- Notification trait +- Encryption fixes +- Docker cleanup email template +- Add missing deployment notifications to telegram +- New docker cleanup settings are now saved to the DB correctly +- Ui + migrations +- Docker cleanup email notifications +- General notifications does not go through email channel +- Test notifications to only send it to the right channel +- Remove resale_license from db as well +- Nexus service +- Fileflows volume names +- --cone +- Provider error +- Database migration +- Seeder +- Migration call +- Slack helper +- Telegram helper +- Discord helper +- Telegram topic IDs +- Make pushover settings more clear +- Typo in pushover user key +- Use Livewire refresh method and lock properties +- Create pushover settings for existing teams +- Update token permission check from 'write' to 'root' +- Pushover +- Oauth seeder +- Correct heading display for OAuth settings in settings-oauth.blade.php +- Adjust spacing in login form for improved layout +- Services env values should be sensitive +- Documenso +- Dolibarr +- Typo +- Update OauthSettingSeeder to handle new provider definitions and ensure authentik is recreated if missing +- Improve OauthSettingSeeder to correctly delete non-existent providers and ensure proper handling of provider definitions +- Encrypt resend API key in instance settings +- Resend api key is already a text column + +### 💼 Other + +- Test rename GitHub app +- Checkmate service and fix prowlar slogan (too long) + +### 🚜 Refactor + +- Update Traefik configuration for improved security and logging +- Improve proxy configuration and code consistency in Server model +- Rename name method to sanitizedName in BaseModel for clarity +- Improve migration command and enhance application model with global scope and status checks +- Unify notification icon +- Remove unused Azure and Authentik service configurations from services.php +- Change email column types in instance_settings migration from string to text +- Change OauthSetting creation to updateOrCreate for better handling of existing records + +### ⚙️ Miscellaneous Tasks + +- Regenerate openapi spec +- Composer dep bump +- Dep bump +- Upgrade cloudflared and minio +- Remove comments and improve DB column naming +- Remove unused seeder +- Remove unused waitlist stuff +- Remove wired.php (not used anymore) +- Remove unused resale license job +- Remove commented out internal notification +- Remove more waitlist stuff +- Remove commented out notification +- Remove more waitlist stuff +- Remove unused code +- Fix typo +- Remove comment out code +- Some reordering +- Remove resale license reference +- Remove functions from shared.php +- Public settings for email notification +- Remove waitlist redirect +- Remove log +- Use new notification trait +- Remove unused route +- Remove unused email component +- Comment status changes as it is disabled for now +- Bump dep +- Reorder navbar +- Rename topicID to threadId like in the telegram API response +- Update PHP configuration to set memory limit using environment variable + +## [4.0.0-beta.376] - 2024-12-07 + +### 🐛 Bug Fixes + +- Api endpoint + +## [4.0.0-beta.374] - 2024-12-03 + +### 🐛 Bug Fixes + +- Application view loading +- Postiz service +- Only able to select the right keys +- Test email should not be required +- A few inputs + +### 🧪 Testing + +- Setup database for upcoming tests + +## [4.0.0-beta.372] - 2024-11-26 + +### 🚀 Features + +- Add MacOS template +- Add Windows template +- *(service)* :sparkles: add mealie +- Add hex magic env var + +### 🐛 Bug Fixes + +- Service generate includes yml files as well (haha) +- ServercheckJob should run every 5 minutes on cloud +- New resource icons +- Search should be more visible on scroll on new resource +- Logdrain settings +- Ui +- Email should be retried with backoff +- Alpine in body layout + +### 💼 Other + +- Caddy docker labels do not honor "strip prefix" option + +## [4.0.0-beta.371] - 2024-11-22 + +### 🐛 Bug Fixes + +- Improve helper text for metrics input fields +- Refine helper text for metrics input fields +- If mux conn fails, still use it without mux + save priv key with better logic +- Migration +- Always validate ssh key +- Make sure important jobs/actions are running on high prio queue +- Do not send internal notification for backups and status jobs +- Validateconnection +- View issue +- Heading +- Remove mux cleanup +- Db backup for services +- Version should come from constants + fix stripe webhook error reporting +- Undefined variable +- Remove version.php as everything is coming from constants.php +- Sentry error +- Websocket connections autoreconnect +- Sentry error +- Sentry +- Empty server API response +- Incorrect server API patch response +- Missing `uuid` parameter on server API patch +- Missing `settings` property on servers API +- Move servers API `delete_unused_*` properties +- Servers API returning `port` as a string -> integer +- Only return server uuid on server update + +## [4.0.0-beta.370] - 2024-11-15 + +### 🐛 Bug Fixes + +- Modal (+ add) on dynamic config was not opening, removed x-cloak +- AUTOUPDATE + checkbox opacity + +## [4.0.0-beta.369] - 2024-11-15 + +### 🐛 Bug Fixes + +- Modal-input + +## [4.0.0-beta.368] - 2024-11-15 + +### 🚀 Features + +- Check local horizon scheduler deployments +- Add internal api docs to /docs/api with auth +- Add proxy type change to create/update apis + +### 🐛 Bug Fixes + +- Show proper error message on invalid Git source +- Convert HTTP to SSH source when using deploy key on GitHub +- Cloud + stripe related +- Terminal view loading in async +- Cool 500 error (thanks hugodos) +- Update schema in code decorator +- Openapi docs +- Add tests for git url converts +- Minio / logto url generation +- Admin view +- Min docker version 26 +- Pull latest service-templates.json on init +- Workflow files for coolify build +- Autocompletes +- Timezone settings validation +- Invalid tz should not prevent other jobs to be executed +- Testing-host should be built locally +- Poll with modal issue +- Terminal opening issue +- If service img not found, use github as a source +- Fallback to local coolify.png +- Gather private ips +- Cf tunnel menu should be visible when server is not validated +- Deployment optimizations +- Init script + optimize laravel +- Default docker engine version + fix install script +- Pull helper image on init +- SPA static site default nginx conf + +### 💼 Other + +- Https://github.com/coollabsio/coolify/issues/4186 +- Separate resources by type in projects view +- Improve s3 add view + +### ⚙️ Miscellaneous Tasks + +- Update dep + +## [4.0.0-beta.365] - 2024-11-11 + +### 🚀 Features + +- Custom nginx configuration for static deployments + fix 404 redirects in nginx conf + +### 🐛 Bug Fixes + +- Trigger.dev db host & sslmode=disable +- Manual update should be executed only once + better UX +- Upgrade.sh +- Missing privateKey + +## [4.0.0-beta.364] - 2024-11-08 + +### 🐛 Bug Fixes + +- Define separate volumes for mattermost service template +- Github app name is too long +- ServerTimezone update + +### ⚙️ Miscellaneous Tasks + +- Edit www helper + +## [4.0.0-beta.363] - 2024-11-08 + +### 🚀 Features + +- Add Firefox template +- Add template for Wiki.js +- Add upgrade logs to /data/coolify/source + +### 🐛 Bug Fixes + +- Saving resend api key +- Wildcard domain save +- Disable cloudflare tunnel on "localhost" + +## [4.0.0-beta.362] - 2024-11-08 + +### 🐛 Bug Fixes + +- Notifications ui +- Disable wire:navigate +- Confirmation Settings css for light mode +- Server wildcard + +## [4.0.0-beta.361] - 2024-11-08 + +### 🚀 Features + +- Add Transmission template +- Add transmission healhcheck +- Add zipline template +- Dify template +- Required envs +- Add EdgeDB +- Show warning if people would like to use sslip with https +- Add is shared to env variables +- Variabel sync and support shared vars +- Add notification settings to server_disk_usage +- Add coder service tamplate and logo +- Debug mode for sentinel +- Add jitsi template +- Add --gpu support for custom docker command + +### 🐛 Bug Fixes + +- Make sure caddy is not removed by cleanup +- Libretranslate +- Do not allow to change number of lines when streaming logs +- Plunk +- No manual timezones +- Helper push +- Format +- Add port metadata and Coolify magic to generate the domain +- Sentinel +- Metrics +- Generate sentinel url +- Only enable Sentinel for new servers +- Is_static through API +- Allow setting standalone redis variables via ENVs (team variables...) +- Check for username separately form password +- Encrypt all existing redis passwords +- Pull helper image on helper_version change +- Redis database user and password +- Able to update ipv4 / ipv6 instance settings +- Metrics for dbs +- Sentinel start fixed +- Validate sentinel custom URL when enabling sentinel +- Should be able to reset labels in read-only mode with manual click +- No sentinel for swarm yet +- Charts ui +- Volume +- Sentinel config changes restarts sentinel +- Disable sentinel for now +- Disable Sentinel temporarily +- Disable Sentinel temporarily for non-dev environments +- Access team's github apps only +- Admins should now invite owner +- Add experimental flag +- GenerateSentinelUrl method +- NumberOfLines could be null +- Login / register view +- Restart sentinel once a day +- Changing private key manually won't trigger a notification +- Grammar for helper +- Fix my own grammar +- Add telescope only in dev mode +- New way to update container statuses +- Only run server storage every 10 mins if sentinel is not active +- Cloud admin view +- Queries in kernel.php +- Lower case emails only +- Change emails to lowercase on init +- Do not error on update email +- Always authenticate with lowercase emails +- Dashboard refactor +- Add min/max length to input/texarea +- Remove livewire legacy from help view +- Remove unnecessary endpoints (magic) +- Transactional email livewire +- Destinations livewire refactor +- Refactor destination/docker view +- Logdrains validation +- Reworded +- Use Auth(), add new db proxy stop event refactor clickhouse view +- Add user/pw to db view +- Sort servers by name +- Keydb view +- Refactor tags view / remove obsolete one +- Send discord/telegram notifications on high job queue +- Server view refresh on validation +- ShowBoarding +- Show docker installation logs & ubuntu 24.10 notification +- Do not overlap servercheckjob +- Server limit check +- Server validation +- Clear route / view +- Only skip docker installation on 24.10 if its not installed +- For --gpus device support +- Db/service start should be on high queue +- Do not stop sentinel on Coolify restart +- Run resourceCheck after new serviceCheckJob +- Mongodb in dev +- Better invitation errors +- Loading indicator for db proxies +- Do not execute gh workflow on template changes +- Only use sentry in cloud +- Update packagejson of coolify-realtime + add lock file +- Update last online with old function +- Seeder should not start sentinel +- Start sentinel on seeder + +### 💼 Other + +- Add peppermint +- Loggy +- Add UI for redis password and username +- Wireguard-easy template + +### 📚 Documentation + +- Update link to deploy api docs + +### ⚙️ Miscellaneous Tasks + +- Add transmission template desc +- Update transmission docs link +- Update version numbers to 4.0.0-beta.360 in configuration files +- Update AWS environment variable names in unsend.yaml +- Update AWS environment variable names in unsend.yaml +- Update livewire/livewire dependency to version 3.4.9 +- Update version to 4.0.0-beta.361 +- Update Docker build and push actions to v6 +- Update Docker build and push actions to v6 +- Update Docker build and push actions to v6 +- Sync coolify-helper to dockerhub as well +- Push realtime to dockerhub +- Sync coolify-realtime to dockerhub +- Rename workflows +- Rename development to staging build +- Sync coolify-testing-host to dockerhbu +- Sync coolify prod image to dockerhub as well +- Update Docker version to 26.0 +- Update project resource index page +- Update project service configuration view + +## [4.0.0-beta.360] - 2024-10-11 + +### ⚙️ Miscellaneous Tasks + +- Update livewire/livewire dependency to version 3.4.9 + +## [4.0.0-beta.359] - 2024-10-11 + +### 🐛 Bug Fixes + +- Use correct env variable for invoice ninja password + +### ⚙️ Miscellaneous Tasks + +- Update laravel/horizon dependency to version 5.29.1 +- Update service extra fields to use dynamic keys + +## [4.0.0-beta.358] - 2024-10-10 + +### 🚀 Features + +- Add customHelper to stack-form +- Add cloudbeaver template +- Add ntfy template +- Add qbittorrent template +- Add Homebox template +- Add owncloud service and logo +- Add immich service +- Auto generate url +- Refactored to work with coolify auto env vars +- Affine service template and logo +- Add LibreTranslate template +- Open version in a new tab + +### 🐛 Bug Fixes + +- Signup +- Application domains should be http and https only +- Validate and sanitize application domains +- Sanitize and validate application domains + +### 💼 Other + +- Other DB options for freshrss +- Nextcloud MariaDB and MySQL versions + +### ⚙️ Miscellaneous Tasks + +- Fix form submission and keydown event handling in modal-confirmation.blade.php +- Update version numbers to 4.0.0-beta.359 in configuration files +- Disable adding default environment variables in shared.php + +## [4.0.0-beta.357] - 2024-10-08 + +### 🚀 Features + +- Add Mautic 4 and 5 to service templates +- Add keycloak template +- Add onedev template +- Improve search functionality in project selection + +### 🐛 Bug Fixes + +- Update mattermost image tag and add default port +- Remove env, change timezone +- Postgres healthcheck +- Azimutt template - still not working haha +- New parser with SERVICE_URL_ envs +- Improve service template readability +- Update password variables in Service model +- Scheduled database server +- Select server view + +### 💼 Other + +- Keycloak + +### ⚙️ Miscellaneous Tasks + +- Add mattermost logo as svg +- Add mattermost svg to compose +- Update version to 4.0.0-beta.357 + +## [4.0.0-beta.356] - 2024-10-07 + +### 🚀 Features + +- Add Argilla service configuration to Service model +- Add Invoice Ninja service configuration to Service model +- Project search on frontend +- Add ollama service with open webui and logo +- Update setType method to use slug value for type +- Refactor setType method to use slug value for type +- Refactor setType method to use slug value for type +- Add Supertokens template +- Add easyappointments service template +- Add dozzle template +- Adds forgejo service with runners + +### 🐛 Bug Fixes + +- Reset description and subject fields after submitting feedback +- Tag mass redeployments +- Service env orders, application env orders +- Proxy conf in dev +- One-click services +- Use local service-templates in dev +- New services +- Remove not used extra host +- Chatwoot service +- Directus +- Database descriptions +- Update services +- Soketi +- Select server view + +### 💼 Other + +- Update helper version +- Outline +- Directus +- Supertokens +- Supertokens json +- Rabbitmq +- Easyappointments +- Soketi +- Dozzle +- Windmill +- Coolify.json + +### ⚙️ Miscellaneous Tasks + +- Update version to 4.0.0-beta.356 +- Remove commented code for shared variable type validation +- Update MariaDB image to version 11 and fix service environment variable orders +- Update anythingllm.yaml volumes configuration +- Update proxy configuration paths for Caddy and Nginx in dev +- Update password form submission in modal-confirmation component +- Update project query to order by name in uppercase +- Update project query to order by name in lowercase +- Update select.blade.php with improved search functionality +- Add Nitropage service template and logo +- Bump coolify-helper version to 1.0.2 +- Refactor loadServices2 method and remove unused code +- Update version to 4.0.0-beta.357 +- Update service names and volumes in windmill.yaml +- Update version to 4.0.0-beta.358 +- Ignore .ignition.json files in Docker and Git + +## [4.0.0-beta.355] - 2024-10-03 + +### 🐛 Bug Fixes + +- Scheduled backup for services view +- Parser, espacing container labels + +### ⚙️ Miscellaneous Tasks + +- Update homarr service template and remove unnecessary code +- Update version to 4.0.0-beta.355 + +## [4.0.0-beta.354] - 2024-10-03 + +### 🚀 Features + +- Add it-tools service template and logo +- Add homarr service tamplate and logo + +### 🐛 Bug Fixes + +- Parse proxy config and check the set ports usage +- Update FQDN + +### ⚙️ Miscellaneous Tasks + +- Update version to 4.0.0-beta.354 +- Remove debug statement in Service model +- Remove commented code in Server model +- Fix application deployment queue filter logic +- Refactor modal-confirmation component +- Update it-tools service template and port configuration +- Update homarr service template and remove unnecessary code + +## [4.0.0-beta.353] - 2024-10-03 + +### ⚙️ Miscellaneous Tasks + +- Update version to 4.0.0-beta.353 +- Update service application view + +## [4.0.0-beta.352] - 2024-10-03 + +### 🐛 Bug Fixes + +- Service application view +- Add new supported database images + +### ⚙️ Miscellaneous Tasks + +- Update version to 4.0.0-beta.352 +- Refactor DatabaseBackupJob to handle missing team + +## [4.0.0-beta.351] - 2024-10-03 + +### 🚀 Features + +- Add strapi template + +### 🐛 Bug Fixes + +- Able to support more database dynamically from Coolify's UI +- Strapi template +- Bitcoin core template +- Api useBuildServer + +## [4.0.0-beta.349] - 2024-10-01 + +### 🚀 Features + +- Add command to check application deployment queue +- Support Hetzner S3 +- Handle HTTPS domain in ConfigureCloudflareTunnels +- Backup all databases for mysql,mariadb,postgresql +- Restart service without pulling the latest image + +### 🐛 Bug Fixes + +- Remove autofocuses +- Ipv6 scp should use -6 flag +- Cleanup stucked applicationdeploymentqueue +- Realtime watch in development mode +- Able to select root permission easier + +### 💼 Other + +- Show backup button on supported db service stacks + +### 🚜 Refactor + +- Remove deployment queue when deleting an application +- Improve SSH command generation in Terminal.php and terminal-server.js +- Fix indentation in modal-confirmation.blade.php +- Improve parsing of commands for sudo in parseCommandsByLineForSudo +- Improve popup component styling and button behavior +- Encode delimiter in SshMultiplexingHelper +- Remove inactivity timer in terminal-server.js +- Improve socket reconnection interval in terminal.js +- Remove unnecessary watch command from soketi service entrypoint + +### ⚙️ Miscellaneous Tasks + +- Update version numbers to 4.0.0-beta.350 in configuration files +- Update command signature and description for cleanup application deployment queue +- Add missing import for Attribute class in ApplicationDeploymentQueue model +- Update modal input in server form to prevent closing on outside click +- Remove unnecessary command from SshMultiplexingHelper +- Remove commented out code for uploading to S3 in DatabaseBackupJob +- Update soketi service image to version 1.0.3 + +## [4.0.0-beta.348] - 2024-10-01 + +### 🚀 Features + +- Update resource deletion job to allow configurable options through API +- Add query parameters for deleting configurations, volumes, docker cleanup, and connected networks + +### 🐛 Bug Fixes + +- In dev mode do not ask confirmation on delete +- Mixpost +- Handle deletion of 'hello' in confirmation modal for dev environment + +### 💼 Other + +- Server storage check + +### 🚜 Refactor + +- Update search input placeholder in resource index view + +### ⚙️ Miscellaneous Tasks + +- Fix docs link in running state +- Update Coolify Realtime workflow to only trigger on the main branch +- Refactor instanceSettings() function to improve code readability +- Update Coolify Realtime image to version 1.0.2 +- Remove unnecessary code in DatabaseBackupJob.php +- Add "Not Usable" indicator for storage items +- Refactor instanceSettings() function and improve code readability +- Update version numbers to 4.0.0-beta.349 and 4.0.0-beta.350 + +## [4.0.0-beta.347] - 2024-09-28 + +### 🚀 Features + +- Allow specify use_build_server when creating/updating an application +- Add support for `use_build_server` in API endpoints for creating/updating applications +- Add Mixpost template + +### 🐛 Bug Fixes + +- Filebrowser template +- Edit is_build_server_enabled upon creating application on other application type +- Save settings after assigning value + +### 💼 Other + +- Remove memlock as it caused problems for some users + +### ⚙️ Miscellaneous Tasks + +- Update Mailpit logo to use SVG format + +## [4.0.0-beta.346] - 2024-09-27 + +### 🚀 Features + +- Add ContainerStatusTypes enum for managing container status + +### 🐛 Bug Fixes + +- Proxy fixes +- Proxy +- *(templates)* Filebrowser FQDN env variable +- Handle edge case when build variables and env variables are in different format +- Compose based terminal + +### 💼 Other + +- Manual cleanup button and unused volumes and network deletion +- Force helper image removal +- Use the new confirmation flow +- Typo +- Typo in install script +- If API is disabeled do not show API token creation stuff +- Disable API by default +- Add debug bar + +### 🚜 Refactor + +- Update environment variable name for uptime-kuma service +- Improve start proxy script to handle existing containers gracefully +- Update delete server confirmation modal buttons +- Remove unnecessary code + +### ⚙️ Miscellaneous Tasks + +- Add autocomplete attribute to input fields +- Refactor API Tokens component to use isApiEnabled flag +- Update versions.json file +- Remove unused .env.development.example file +- Update API Tokens view to include link to Settings menu +- Update web.php to cast server port as integer +- Update backup deletion labels to use language files +- Update database startup heading title +- Update database startup heading title +- Custom vite envs +- Update version numbers to 4.0.0-beta.348 +- Refactor code to improve SSH key handling and storage + +## [4.0.0-beta.343] - 2024-09-25 + +### 🐛 Bug Fixes + +- Parser +- Exited services statuses +- Make sure to reload window if app status changes +- Deploy key based deployments + +### 🚜 Refactor + +- Remove commented out code and improve environment variable handling in newParser function +- Improve label positioning in input and checkbox components +- Group and sort fields in StackForm by service name and password status +- Improve layout and add checkbox for task enablement in scheduled task form +- Update checkbox component to support full width option +- Update confirmation label in danger.blade.php template +- Fix typo in execute-container-command.blade.php +- Update OS_TYPE for Asahi Linux in install.sh script +- Add localhost as Server if it doesn't exist and not in cloud environment +- Add localhost as Server if it doesn't exist and not in cloud environment +- Update ProductionSeeder to fix issue with coolify_key assignment +- Improve modal confirmation titles and button labels +- Update install.sh script to remove redirection of upgrade output to /dev/null +- Fix modal input closeOutside prop in configuration.blade.php +- Add support for IPv6 addresses in sslip function + +### ⚙️ Miscellaneous Tasks + +- Update version numbers to 4.0.0-beta.343 +- Update version numbers to 4.0.0-beta.344 +- Update version numbers to 4.0.0-beta.345 +- Update version numbers to 4.0.0-beta.346 + +## [4.0.0-beta.342] - 2024-09-24 + +### 🚀 Features + +- Add nullable constraint to 'fingerprint' column in private_keys table +- *(api)* Add an endpoint to execute a command +- *(api)* Add endpoint to execute a command + +### 🐛 Bug Fixes + +- Proxy status +- Coolify-db should not be in the managed resources +- Store original root key in the original location +- Logto service +- Cloudflared service +- Migrations +- Cloudflare tunnel configuration, ui, etc + +### 💼 Other + +- Volumes on development environment +- Clean new volume name for dev volumes +- Persist DBs, services and so on stored in data/coolify +- Add SSH Key fingerprint to DB +- Add a fingerprint to every private key on save, create... +- Make sure invalid private keys can not be added +- Encrypt private SSH keys in the DB +- Add is_sftp and is_server_ssh_key coloums +- New ssh key file name on disk +- Store all keys on disk by default +- Populate SSH key folder +- Populate SSH keys in dev +- Use new function names and logic everywhere +- Create a Multiplexing Helper +- SSH multiplexing +- Remove unused code form multiplexing +- SSH Key cleanup job +- Private key with ID 2 on dev +- Move more functions to the PrivateKey Model +- Add ssh key fingerprint and generate one for existing keys +- ID issues on dev seeders +- Server ID 0 +- Make sure in use private keys are not deleted +- Do not delete SSH Key from disk during server validation error +- UI bug, do not write ssh key to disk in server dialog +- SSH Multiplexing for Jobs +- SSH algorhytm text +- Few multiplexing things +- Clear mux directory +- Multiplexing do not write file manually +- Integrate tow step process in the modal component WIP +- Ability to hide labels +- DB start, stop confirm +- Del init script +- General confirm +- Preview deployments and typos +- Service confirmation +- Confirm file storage +- Stop service confirm +- DB image cleanup +- Confirm ressource operation +- Environment variabel deletion +- Confirm scheduled tasks +- Confirm API token +- Confirm private key +- Confirm server deletion +- Confirm server settings +- Proxy stop and restart confirmation +- GH app deletion confirmation +- Redeploy all confirmation +- User deletion confirmation +- Team deletion confirmation +- Backup job confirmation +- Delete volume confirmation +- More conformations and fixes +- Delete unused private keys button +- Ray error because port is not uncommented +- #3322 deploy DB alterations before updating +- Css issue with advanced settings and remove cf tunnel in onboarding +- New cf tunnel install flow +- Made help text more clear +- Cloudflare tunnel +- Make helper text more clean to use a FQDN and not an URL + +### 🚜 Refactor + +- Update Docker cleanup label in Heading.php and Navbar.php +- Remove commented out code in Navbar.php +- Remove CleanupSshKeysJob from schedule in Kernel.php +- Update getAJoke function to exclude offensive jokes +- Update getAJoke function to use HTTPS for API request +- Update CleanupHelperContainersJob to use more efficient Docker command +- Update PrivateKey model to improve code readability and maintainability +- Remove unnecessary code in PrivateKey model +- Update PrivateKey model to use ownedByCurrentTeam() scope for cleanupUnusedKeys() +- Update install.sh script to check if coolify-db volume exists before generating SSH key +- Update ServerSeeder and PopulateSshKeysDirectorySeeder +- Improve attribute sanitization in Server model +- Update confirmation button text for deletion actions +- Remove unnecessary code in shared.php file +- Update environment variables for services in compose files +- Update select.blade.php to improve trademarks policy display +- Update select.blade.php to improve trademarks policy display +- Fix typo in subscription URLs +- Add Postiz service to compose file (disabled for now) +- Update shared.php to include predefined ports for services +- Simplify SSH key synchronization logic +- Remove unused code in DatabaseBackupStatusJob and PopulateSshKeysDirectorySeeder + +### ⚙️ Miscellaneous Tasks + +- Update version numbers to 4.0.0-beta.342 +- Update remove-labels-and-assignees-on-close.yml +- Add SSH key for localhost in ProductionSeeder +- Update SSH key generation in install.sh script +- Update ProductionSeeder to call OauthSettingSeeder and PopulateSshKeysDirectorySeeder +- Update install.sh to support Asahi Linux +- Update install.sh version to 1.6 +- Remove unused middleware and uniqueId method in DockerCleanupJob +- Refactor DockerCleanupJob to remove unused middleware and uniqueId method +- Remove unused migration file for populating SSH keys and clearing mux directory +- Add modified files to the commit +- Refactor pre-commit hook to improve performance and readability +- Update CONTRIBUTING.md with troubleshooting note about database migrations +- Refactor pre-commit hook to improve performance and readability +- Update cleanup command to use Redis instead of queue +- Update Docker commands to start proxy + +## [4.0.0-beta.341] - 2024-09-18 + +### 🚀 Features + +- Add buddy logo + +## [4.0.0-beta.336] - 2024-09-16 + +### 🚀 Features + +- Make coolify full width by default +- Fully functional terminal for command center +- Custom terminal host + +### 🐛 Bug Fixes + +- Keep-alive ws connections +- Add build.sh to debug logs +- Update Coolify installer +- Terminal +- Generate https for minio +- Install script +- Handle WebSocket connection close in terminal.blade.php +- Able to open terminal to any containers +- Refactor run-command +- If you exit a container manually, it should close the underlying tty as well +- Move terminal to separate view on services +- Only update helper image in DB +- Generated fqdn for SERVICE_FQDN_APP_3000 magic envs + +### 💼 Other + +- Remove labels and assignees on issue close +- Make sure this action is also triggered on PR issue close + +### 🚜 Refactor + +- Remove unnecessary code in ExecuteContainerCommand.php +- Improve Docker network connection command in StartService.php +- Terminal / run command +- Add authorization check in ExecuteContainerCommand mount method +- Remove unnecessary code in Terminal.php +- Remove unnecessary code in Terminal.blade.php +- Update WebSocket connection initialization in terminal.blade.php +- Remove unnecessary console.log statements in terminal.blade.php + +### ⚙️ Miscellaneous Tasks + +- Update release version to 4.0.0-beta.336 +- Update coolify environment variable assignment with double quotes +- Update shared.php to fix issues with source and network variables +- Update terminal styling for better readability +- Update button text for container connection form +- Update Dockerfile and workflow for Coolify Realtime (v4) +- Remove unused entrypoint script and update volume mapping +- Update .env file and docker-compose configuration +- Update APP_NAME environment variable in docker-compose.prod.yml +- Update WebSocket URL in terminal.blade.php +- Update Dockerfile and workflow for Coolify Realtime (v4) +- Update Dockerfile and workflow for Coolify Realtime (v4) +- Update Dockerfile and workflow for Coolify Realtime (v4) +- Rename Command Center to Terminal in code and views +- Update branch restriction for push event in coolify-helper.yml +- Update terminal button text and layout in application heading view +- Refactor terminal component and select form layout +- Update coolify nightly version to 4.0.0-beta.335 +- Update helper version to 1.0.1 +- Fix syntax error in versions.json +- Update version numbers to 4.0.0-beta.337 +- Update Coolify installer and scripts to include a function for fetching programming jokes +- Update docker network connection command in ApplicationDeploymentJob.php +- Add validation to prevent selecting 'default' server or container in RunCommand.php +- Update versions.json to reflect latest version of realtime container +- Update soketi image to version 1.0.1 +- Nightly - Update soketi image to version 1.0.1 and versions.json to reflect latest version of realtime container +- Update version numbers to 4.0.0-beta.339 +- Update version numbers to 4.0.0-beta.340 +- Update version numbers to 4.0.0-beta.341 + +### ◀️ Revert + +- Databasebackup + +## [4.0.0-beta.335] - 2024-09-12 + +### 🐛 Bug Fixes + +- Cloudflare tunnel with new multiplexing feature + +### 💼 Other + +- SSH Multiplexing on docker desktop on Windows + +### ⚙️ Miscellaneous Tasks + +- Update release version to 4.0.0-beta.335 +- Update constants.ssh.mux_enabled in remoteProcess.php +- Update listeners and proxy settings in server form and new server components +- Remove unnecessary null check for proxy_type in generate_default_proxy_configuration +- Remove unnecessary SSH command execution time logging + +## [4.0.0-beta.334] - 2024-09-12 + +### ⚙️ Miscellaneous Tasks + +- Remove itsgoingd/clockwork from require-dev in composer.json +- Update 'key' value of gitlab in Service.php to use environment variable + +## [4.0.0-beta.333] - 2024-09-11 + +### 🐛 Bug Fixes + +- Disable mux_enabled during server validation +- Move mc command to coolify image from helper +- Keydb. add `:` delimiter for connection string + +### 💼 Other + +- Remote servers with port and user +- Do not change localhost server name on revalidation +- Release.md file + +### 🚜 Refactor + +- Improve handling of environment variable merging in upgrade script + +### ⚙️ Miscellaneous Tasks + +- Update version numbers to 4.0.0-beta.333 +- Copy .env file to .env-{DATE} if it exists +- Update .env file with new values +- Update server check job middleware to use server ID instead of UUID +- Add reminder to backup .env file before running install script again +- Copy .env file to backup location during installation script +- Add reminder to backup .env file during installation script +- Update permissions in pr-build.yml and version numbers +- Add minio/mc command to Dockerfile + +## [4.0.0-beta.332] - 2024-09-10 + +### 🚀 Features + +- Expose project description in API response +- Add elixir finetunes to the deployment job + +### 🐛 Bug Fixes + +- Reenable overlapping servercheckjob +- Appwrite template + parser +- Don't add `networks` key if `network_mode` is used +- Remove debug statement in shared.php +- Scp through cloudflare +- Delete older versions of the helper image other than the latest one +- Update remoteProcess.php to handle null values in logItem properties + +### 💼 Other + +- Set a default server timezone +- Implement SSH Multiplexing +- Enabel mux +- Cleanup stale multiplexing connections + +### 🚜 Refactor + +- Improve environment variable handling in shared.php + +### ⚙️ Miscellaneous Tasks + +- Set timeout for ServerCheckJob to 60 seconds +- Update appwrite.yaml to include OpenSSL key variable assignment + +## [4.0.0-beta.330] - 2024-09-06 + +### 🐛 Bug Fixes + +- Parser +- Plunk NEXT_PUBLIC_API_URI + +### 💼 Other + +- Pull helper image if not available otherwise s3 backup upload fails + +### 🚜 Refactor + +- Improve handling of server timezones in scheduled backups and tasks +- Improve handling of server timezones in scheduled backups and tasks +- Improve handling of server timezones in scheduled backups and tasks +- Update cleanup schedule to run daily at midnight +- Skip returning volume if driver type is cifs or nfs + +### ⚙️ Miscellaneous Tasks + +- Update coolify-helper.yml to get version from versions.json +- Disable Ray by default +- Enable Ray by default and update Dockerfile with latest versions of PACK and NIXPACKS +- Update Ray configuration and Dockerfile +- Add middleware for updating environment variables by UUID in `api.php` routes +- Expose port 3000 in browserless.yaml template +- Update Ray configuration and Dockerfile +- Update coolify version to 4.0.0-beta.331 +- Update versions.json and sentry.php to 4.0.0-beta.332 +- Update version to 4.0.0-beta.332 +- Update DATABASE_URL in plunk.yaml to use plunk database +- Add coolify.managed=true label to Docker image builds +- Update docker image pruning command to exclude managed images +- Update docker cleanup schedule to run daily at midnight +- Update versions.json to version 1.0.1 +- Update coolify-helper.yml to include "next" branch in push trigger + +## [4.0.0-beta.326] - 2024-09-03 + +### 🚀 Features + +- Update server_settings table to force docker cleanup +- Update Docker Compose file with DB_URL environment variable +- Refactor shared.php to improve environment variable handling + +### 🐛 Bug Fixes + +- Wrong executions order +- Handle project not found error in environment_details API endpoint +- Deployment running for - without "ago" +- Update helper image pulling logic to only pull if the version is newer + +### 💼 Other + +- Plunk svg + +### 📚 Documentation + +- Update Plunk documentation link in compose/plunk.yaml + +### ⚙️ Miscellaneous Tasks + +- Update UI for displaying no executions found in scheduled task list +- Update UI for displaying deployment status in deployment list +- Update UI for displaying deployment status in deployment list +- Ignore unnecessary files in production build workflow +- Update server form layout and settings +- Update Dockerfile with latest versions of PACK and NIXPACKS + +## [4.0.0-beta.324] - 2024-09-02 + +### 🚀 Features + +- Preserve git repository with advanced file storages +- Added Windmill template +- Added Budibase template +- Add shm-size for custom docker commands +- Add custom docker container options to all databases +- Able to select different postgres database +- Add new logos for jobscollider and hostinger +- Order scheduled task executions +- Add Code Server environment variables to Service model +- Add coolify build env variables to building phase +- Add new logos for GlueOps, Ubicloud, Juxtdigital, Saasykit, and Massivegrid +- Add new logos for GlueOps, Ubicloud, Juxtdigital, Saasykit, and Massivegrid + +### 🐛 Bug Fixes + +- Timezone not updated when systemd is missing +- If volumes + file mounts are defined, should merge them together in the compose file +- All mongo v4 backups should use the different backup command +- Database custom environment variables +- Connect compose apps to the right predefined network +- Docker compose destination network +- Server status when there are multiple servers +- Sync fqdn change on the UI +- Pr build names in case custom name is used +- Application patch request instant_deploy +- Canceling deployment on build server +- Backup of password protected postgresql database +- Docker cleanup job +- Storages with preserved git repository +- Parser parser parser +- New parser only in dev +- Parser parser +- Numberoflines should be number +- Docker cleanup job +- Fix directory and file mount headings in file-storage.blade.php +- Preview fqdn generation +- Revert a few lines +- Service ui sync bug +- Setup script doesn't work on rhel based images with some curl variant already installed +- Let's wait for healthy container during installation and wait an extra 20 seconds (for migrations) +- Infra files +- Log drain only for Applications +- Copy large compose files through scp (not ssh) +- Check if array is associative or not +- Openapi endpoint urls +- Convert environment variables to one format in shared.php +- Logical volumes could be overwritten with new path +- Env variable in value parsed +- Pull coolify image only when the app needs to be updated + +### 💼 Other + +- Actually update timezone on the server +- Cron jobs are executed based on the server timezone +- Server timezone seeder +- Recent backups UI +- Use apt-get instead of apt +- Typo +- Only pull helper image if the version is newer than the one + +### 🚜 Refactor + +- Update event listeners in Show components +- Refresh application to get latest database changes +- Update RabbitMQ configuration to use environment variable for port +- Remove debug statement in parseDockerComposeFile function +- ParseServiceVolumes +- Update OpenApi command to generate documentation +- Remove unnecessary server status check in destination view +- Remove unnecessary admin user email and password in budibase.yaml +- Improve saving of custom internal name in Advanced.php +- Add conditional check for volumes in generate_compose_file() +- Improve storage mount forms in add.blade.php +- Load environment variables based on resource type in sortEnvironmentVariables() +- Remove unnecessary network cleanup in Init.php +- Remove unnecessary environment variable checks in parseDockerComposeFile() +- Add null check for docker_compose_raw in parseCompose() +- Update dockerComposeParser to use YAML data from $yaml instead of $compose +- Convert service variables to key-value pairs in parseDockerComposeFile function +- Update database service name from mariadb to mysql +- Remove unnecessary code in DatabaseBackupJob and BackupExecutions +- Update Docker Compose parsing function to convert service variables to key-value pairs +- Update Docker Compose parsing function to convert service variables to key-value pairs +- Remove unused server timezone seeder and related code +- Remove unused server timezone seeder and related code +- Remove unused PullCoolifyImageJob from schedule +- Update parse method in Advanced, All, ApplicationPreview, General, and ApplicationDeploymentJob classes +- Remove commented out code for getIptables() in Dashboard.php +- Update .env file path in install.sh script +- Update SELF_HOSTED environment variable in docker-compose.prod.yml +- Remove unnecessary code for creating coolify network in upgrade.sh +- Update environment variable handling in StartClickhouse.php and ApplicationDeploymentJob.php +- Improve handling of COOLIFY_URL in shared.php +- Update build_args property type in ApplicationDeploymentJob +- Update background color of sponsor section in README.md +- Update Docker Compose location handling in PublicGitRepository +- Upgrade process of Coolify + +### 🧪 Testing + +- More tests + +### ⚙️ Miscellaneous Tasks + +- Update version to 4.0.0-beta.324 +- New compose parser with tests +- Update version to 1.3.4 in install.sh and 1.0.6 in upgrade.sh +- Update memory limit to 64MB in horizon configuration +- Update php packages +- Update axios npm dependency to version 1.7.5 +- Update Coolify version to 4.0.0-beta.324 and fix file paths in upgrade script +- Update Coolify version to 4.0.0-beta.324 +- Update Coolify version to 4.0.0-beta.325 +- Update Coolify version to 4.0.0-beta.326 +- Add cd command to change directory before removing .env file +- Update Coolify version to 4.0.0-beta.327 +- Update Coolify version to 4.0.0-beta.328 +- Update sponsor links in README.md +- Update version.json to versions.json in GitHub workflow +- Cleanup stucked resources and scheduled backups +- Update GitHub workflow to use versions.json instead of version.json +- Update GitHub workflow to use versions.json instead of version.json +- Update GitHub workflow to use versions.json instead of version.json +- Update GitHub workflow to use jq container for version extraction +- Update GitHub workflow to use jq container for version extraction + +## [4.0.0-beta.323] - 2024-08-08 + +### ⚙️ Miscellaneous Tasks + +- Update version to 4.0.0-beta.323 + +## [4.0.0-beta.322] - 2024-08-08 + +### 🐛 Bug Fixes + +- Manual update process + +### 🚜 Refactor + +- Update Server model getContainers method to use collect() for containers and containerReplicates +- Import ProxyTypes enum and use TRAEFIK instead of TRAEFIK_V2 + +### ⚙️ Miscellaneous Tasks + +- Update version to 4.0.0-beta.322 + +## [4.0.0-beta.321] - 2024-08-08 + +### 🐛 Bug Fixes + +- Scheduledbackup not found + +### 🚜 Refactor + +- Update StandalonePostgresql database initialization and backup handling +- Update cron expressions and add helper text for scheduled tasks + +### ⚙️ Miscellaneous Tasks + +- Update version to 4.0.0-beta.321 + +## [4.0.0-beta.320] - 2024-08-08 + +### 🚀 Features + +- Delete team in cloud without subscription +- Coolify init should cleanup stuck networks in proxy +- Add manual update check functionality to settings page +- Update auto update and update check frequencies in settings +- Update Upgrade component to check for latest version of Coolify +- Improve homepage service template +- Support map fields in Directus +- Labels by proxy type +- Able to generate only the required labels for resources + +### 🐛 Bug Fixes + +- Only append docker network if service/app is running +- Remove lazy load from scheduled tasks +- Plausible template +- Service_url should not have a trailing slash +- If usagebefore cannot be determined, cleanup docker with force +- Async remote command +- Only run logdrain if necessary +- Remove network if it is only connected to coolify proxy itself +- Dir mounts should have proper dirs +- File storages (dir/file mount) handled properly +- Do not use port exposes on docker compose buildpacks +- Minecraft server template fixed +- Graceful shutdown +- Stop resources gracefully +- Handle null and empty disk usage in DockerCleanupJob +- Show latest version on manual update view +- Empty string content should be saved as a file +- Update Traefik labels on init +- Add missing middleware for server check job + +### 🚜 Refactor + +- Update CleanupDatabase.php to adjust keep_days based on environment +- Adjust keep_days in CleanupDatabase.php based on environment +- Remove commented out code for cleaning up networks in CleanupDocker.php +- Update livewire polling interval in heading.blade.php +- Remove unused code for checking server status in Heading.php +- Simplify log drain installation in ServerCheckJob +- Remove unnecessary debug statement in ServerCheckJob +- Simplify log drain installation and stop log drain if necessary +- Cleanup unnecessary dynamic proxy configuration in Init command +- Remove unnecessary debug statement in ApplicationDeploymentJob +- Update timeout for graceful_shutdown_container in ApplicationDeploymentJob +- Remove unused code and optimize CheckForUpdatesJob +- Update ProxyTypes enum values to use TRAEFIK instead of TRAEFIK_V2 +- Update Traefik labels on init and cleanup unnecessary dynamic proxy configuration + +### 🎨 Styling + +- Linting + +### ⚙️ Miscellaneous Tasks + +- Update version to 4.0.0-beta.320 +- Add pull_request image builds to GH actions +- Add comment explaining the purpose of disconnecting the network in cleanup_unused_network_from_coolify_proxy() +- Update formbricks template +- Update registration view to display a notice for first user that it will be an admin +- Update server form to use password input for IP Address/Domain field +- Update navbar to include service status check +- Update navbar and configuration to improve service status check functionality +- Update workflows to include PR build and merge manifest steps +- Update UpdateCoolifyJob timeout to 10 minutes +- Update UpdateCoolifyJob to dispatch CheckForUpdatesJob synchronously + +## [4.0.0-beta.319] - 2024-07-26 + +### 🐛 Bug Fixes + +- Parse docker composer +- Service env parsing +- Service env variables +- Activity type invalid +- Update env on ui + +### 💼 Other + +- Service env parsing + +### ⚙️ Miscellaneous Tasks + +- Collect/create/update volumes in parseDockerComposeFile function + +## [4.0.0-beta.318] - 2024-07-24 + +### 🚀 Features + +- Create/delete project endpoints +- Add patch request to projects +- Add server api endpoints +- Add branddev logo to README.md +- Update API endpoint summaries +- Update Caddy button label in proxy.blade.php +- Check custom internal name through server's applications. +- New server check job + +### 🐛 Bug Fixes + +- Preview deployments should be stopped properly via gh webhook +- Deleting application should delete preview deployments +- Plane service images +- Fix issue with deployment start command in ApplicationDeploymentJob +- Directory will be created by default for compose host mounts +- Restart proxy does not work + status indicator on the UI +- Uuid in api docs type +- Raw compose deployment .env not found +- Api -> application patch endpoint +- Remove pull always when uploading backup to s3 +- Handle array env vars +- Link in task failed job notifications +- Random generated uuid will be full length (not 7 characters) +- Gitlab service +- Gitlab logo +- Bitbucket repository url +- By default volumes that we cannot determine if they are directories or files are treated as directories +- Domain update on services on the UI +- Update SERVICE_FQDN/URL env variables when you change the domain +- Several shared environment variables in one value, parsed correctly +- Members of root team should not see instance admin stuff + +### 💼 Other + +- Formbricks template add required CRON_SECRET +- Add required CRON_SECRET to Formbricks template + +### ⚙️ Miscellaneous Tasks + +- Update APP_BASE_URL to use SERVICE_FQDN_PLANE +- Update resource-limits.blade.php with improved input field helpers +- Update version numbers to 4.0.0-beta.319 +- Remove commented out code for docker image pruning + +## [4.0.0-beta.314] - 2024-07-15 + +### 🚀 Features + +- Improve error handling in loadComposeFile method +- Add readonly labels +- Preserve git repository +- Force cleanup server + +### 🐛 Bug Fixes + +- Typo in is_literal helper +- Env is_literal helper text typo +- Update docker compose pull command with --policy always +- Plane service template +- Vikunja +- Docmost template +- Drupal +- Improve github source creation +- Tag deployments +- New docker compose parsing +- Handle / in preselecting branches +- Handle custom_internal_name check in ApplicationDeploymentJob.php +- If git limit reached, ignore it and continue with a default selection +- Backup downloads +- Missing input for api endpoint +- Volume detection (dir or file) is fixed +- Supabase +- Create file storage even if content is empty + +### 💼 Other + +- Add basedir + compose file in new compose based apps + +### 🚜 Refactor + +- Remove unused code and fix storage form layout +- Update Docker Compose build command to include --pull flag +- Update DockerCleanupJob to handle nullable usageBefore property +- Server status job and docker cleanup job +- Update DockerCleanupJob to use server settings for force cleanup +- Update DockerCleanupJob to use server settings for force cleanup +- Disable health check for Rust applications during deployment + +### ⚙️ Miscellaneous Tasks + +- Update version to 4.0.0-beta.315 +- Update version to 4.0.0-beta.316 +- Update bug report template +- Update repository form with simplified URL input field +- Update width of container in general.blade.php +- Update checkbox labels in general.blade.php +- Update general page of apps +- Handle JSON parsing errors in format_docker_command_output_to_json +- Update Traefik image version to v2.11 +- Update version to 4.0.0-beta.317 +- Update version to 4.0.0-beta.318 +- Update helper message with link to documentation +- Disable health check by default +- Remove commented out code for sending internal notification + +### ◀️ Revert + +- Pull policy +- Advanced dropdown + +## [4.0.0-beta.308] - 2024-07-11 + +### 🚀 Features + +- Cleanup unused docker networks from proxy +- Compose parser v2 +- Display time interval for rollback images +- Add security and storage access key env to twenty template +- Add new logo for Latitude +- Enable legacy model binding in Livewire configuration + +### 🐛 Bug Fixes + +- Do not overwrite hardcoded variables if they rely on another variable +- Remove networks when deleting a docker compose based app +- Api +- Always set project name during app deployments +- Remove volumes as well +- Gitea pr previews +- Prevent instance fqdn persisting to other servers dynamic proxy configs +- Better volume cleanups +- Cleanup parameter +- Update redirect URL in unauthenticated exception handler +- Respect top-level configs and secrets +- Service status changed event +- Disable sentinel until a few bugs are fixed +- Service domains and envs are properly updated +- *(reactive-resume)* New healthcheck command for MinIO +- *(MinIO)* New command healthcheck +- Update minio hc in services +- Add validation for missing docker compose file + +### 🚜 Refactor + +- Add force parameter to StartProxy handle method +- Comment out unused code for network cleanup +- Reset default labels when docker_compose_domains is modified +- Webhooks view +- Tags view +- Only get instanceSettings once from db +- Update Dockerfile to set CI environment variable to true +- Remove unnecessary code in AppServiceProvider.php +- Update Livewire configuration views +- Update Webhooks.php to use nullable type for webhook URLs +- Add lazy loading to tags in Livewire configuration view +- Update metrics.blade.php to improve alert message clarity +- Update version numbers to 4.0.0-beta.312 +- Update version numbers to 4.0.0-beta.314 + +### ⚙️ Miscellaneous Tasks + +- Update Plausible docker compose template to Plausible 2.1.0 +- Update Plausible docker compose template to Plausible 2.1.0 +- Update livewire/livewire dependency to version 3.4.9 +- Refactor checkIfDomainIsAlreadyUsed function +- Update storage.blade.php view for livewire project service +- Update version to 4.0.0-beta.310 +- Update composer dependencies +- Add new logo for Latitude +- Bump version to 4.0.0-beta.311 + +### ◀️ Revert + +- Instancesettings + +## [4.0.0-beta.301] - 2024-06-24 + +### 🚀 Features + +- Local fonts +- More API endpoints +- Bulk env update api endpoint +- Update server settings metrics history days to 7 +- New app API endpoint +- Private gh deployments through api +- Lots of api endpoints +- Api api api api api api +- Rename CloudCleanupSubs to CloudCleanupSubscriptions +- Early fraud warning webhook +- Improve internal notification message for early fraud warning webhook +- Add schema for uuid property in app update response + +### 🐛 Bug Fixes + +- Run user commands on high prio queue +- Load js locally +- Remove lemon + paddle things +- Run container commands on high priority +- Image logo +- Remove both option for api endpoints. it just makes things complicated +- Cleanup subs in cloud +- Show keydbs/dragonflies/clickhouses +- Only run cloud clean on cloud + remove root team +- Force cleanup on busy servers +- Check domain on new app via api +- Custom container name will be the container name, not just internal network name +- Api updates +- Yaml everywhere +- Add newline character to private key before saving +- Add validation for webhook endpoint selection +- Database input validators +- Remove own app from domain checks +- Return data of app update + +### 💼 Other + +- Update process +- Glances service +- Glances +- Able to update application + +### 🚜 Refactor + +- Update Service model's saveComposeConfigs method +- Add default environment to Service model's saveComposeConfigs method +- Improve handling of default environment in Service model's saveComposeConfigs method +- Remove commented out code in Service model's saveComposeConfigs method +- Update stack-form.blade.php to include wire:target attribute for submit button +- Update code to use str() instead of Str::of() for string manipulation +- Improve formatting and readability of source.blade.php +- Add is_build_time property to nixpacks_php_fallback_path and nixpacks_php_root_dir +- Simplify code for retrieving subscription in Stripe webhook + +### ⚙️ Miscellaneous Tasks + +- Update version to 4.0.0-beta.302 +- Update version to 4.0.0-beta.303 +- Update version to 4.0.0-beta.305 +- Update version to 4.0.0-beta.306 +- Add log1x/laravel-webfonts package +- Update version to 4.0.0-beta.307 +- Refactor ServerStatusJob constructor formatting +- Update Monaco Editor for Docker Compose and Proxy Configuration +- More details +- Refactor shared.php helper functions + +## [4.0.0-beta.298] - 2024-06-24 + +### 🚀 Features + +- Spanish translation +- Cancelling a deployment will check if new could be started. +- Add supaguide logo to donations section +- Nixpacks now could reach local dbs internally +- Add Tigris logo to other/logos directory +- COOLIFY_CONTAINER_NAME predefined variable +- Charts +- Sentinel + charts +- Container metrics +- Add high priority queue +- Add metrics warning for servers without Sentinel enabled +- Add blacksmith logo to donations section +- Preselect server and destination if only one found +- More api endpoints +- Add API endpoint to update application by UUID +- Update statusnook logo filename in compose template + +### 🐛 Bug Fixes + +- Stripprefix middleware correctly labeled to http +- Bitbucket link +- Compose generator +- Do no truncate repositories wtih domain (git) in it +- In services should edit compose file for volumes and envs +- Handle laravel deployment better +- Db proxy status shown better in the UI +- Show commit message on webhooks + prs +- Metrics parsing +- Charts +- Application custom labels reset after saving +- Static build with new nixpacks build process +- Make server charts one livewire component with one interval selector +- You can now add env variable from ui to services +- Update compose environment with UI defined variables +- Refresh deployable compose without reload +- Remove cloud stripe notifications +- App deployment should be in high queue +- Remove zoom from modals +- Get envs before sortby +- MB is % lol +- Projects with 0 envs + +### 💼 Other + +- Unnecessary notification + +### 🚜 Refactor + +- Update text color for stderr output in deployment show view +- Update text color for stderr output in deployment show view +- Remove debug code for saving environment variables +- Update Docker build commands for better performance and flexibility +- Update image sizes and add new logos to README.md +- Update README.md with new logos and fix styling +- Update shared.php to use correct key for retrieving sentinel version +- Update container name assignment in Application model +- Remove commented code for docker container removal +- Update Application model to include getDomainsByUuid method +- Update Project/Show component to sort environments by created_at +- Update profile index view to display 2FA QR code in a centered container +- Update dashboard.blade.php to use project's default environment for redirection +- Update gitCommitLink method to handle null values in source.html_url +- Update docker-compose generation to use multi-line literal block + +### ⚙️ Miscellaneous Tasks + +- Update version numbers to 4.0.0-beta.298 +- Switch to database sessions from redis +- Update dependencies and remove unused code +- Update tailwindcss and vue versions in package.json +- Update service template URL in constants.php +- Update sentinel version to 0.0.8 +- Update chart styling and loading text +- Update sentinel version to 0.0.9 +- Update Spanish translation for failed authentication messages +- Add portuguese traslation +- Add Turkish translations +- Add Vietnamese translate +- Add Treive logo to donations section +- Update README.md with latest release version badge +- Update latest release version badge in README.md +- Update version to 4.0.0-beta.299 +- Move server delete component to the bottom of the page +- Update version to 4.0.0-beta.301 + +## [4.0.0-beta.297] - 2024-06-11 + +### 🚀 Features + +- Easily redirect between www-and-non-www domains +- Add logos for new sponsors +- Add homepage template +- Update homepage.yaml with environment variables and volumes + +### 🐛 Bug Fixes + +- Multiline build args +- Setup script doesnt link to the correct source code file +- Install.sh do not reinstall packages on arch +- Just restart + +### 🚜 Refactor + +- Replaces duplications in code with a single function + +### ⚙️ Miscellaneous Tasks + +- Update page title in resource index view +- Update logo file path in logto.yaml +- Update logo file path in logto.yaml +- Remove commented out code for docker container removal +- Add isAnyDeploymentInprogress function to check if any deployments are in progress +- Add ApplicationDeploymentJob and pint.json + +## [4.0.0-beta.295] - 2024-06-10 + +### 🚀 Features + +- Able to change database passwords on the UI. It won't sync to the database. +- Able to add several domains to compose based previews +- Add bounty program link to bug report template +- Add titles +- Db proxy logs + +### 🐛 Bug Fixes + +- Custom docker compose commands, add project dir if needed +- Autoupdate process +- Backup executions view +- Handle previously defined compose previews +- Sort backup executions +- Supabase service, newest versions +- Set default name for Docker volumes if it is null +- Multiline variable should be literal + should be multiline in bash with \ +- Gitlab merge request should close PR + +### 💼 Other + +- Rocketchat +- New services based git apps + +### 🚜 Refactor + +- Append utm_source parameter to documentation URL +- Update save_environment_variables method to use application's environment_variables instead of environment_variables_preview +- Update deployment previews heading to "Deployments" +- Remove unused variables and improve code readability +- Initialize null properties in Github Change component +- Improve pre and post deployment command inputs +- Improve handling of Docker volumes in parseDockerComposeFile function + +### ⚙️ Miscellaneous Tasks + +- Update version numbers to 4.0.0-beta.295 +- Update supported OS list with almalinux +- Update install.sh to support PopOS +- Update install.sh script to version 1.3.2 and handle Linux Mint as Ubuntu + +## [4.0.0-beta.294] - 2024-06-04 + +### ⚙️ Miscellaneous Tasks + +- Update Dockerfile with latest versions of Docker, Docker Compose, Docker Buildx, Pack, and Nixpacks + +## [4.0.0-beta.289] - 2024-05-29 + +### 🚀 Features + +- Add PHP memory limit environment variable to docker-compose.prod.yml +- Add manual update option to UpdateCoolify handle method +- Add port configuration for Vaultwarden service + +### 🐛 Bug Fixes + +- Sync upgrade process +- Publish horizon +- Add missing team model +- Test new upgrade process? +- Throw exception +- Build server dirs not created on main server +- Compose load with non-root user +- Able to redeploy dockerfile based apps without cache +- Compose previews does have env variables +- Fine-tune cdn pulls +- Spamming :D +- Parse docker version better +- Compose issues +- SERVICE_FQDN has source port in it +- Logto service +- Allow invitations via email +- Sort by defined order + fixed typo +- Only ignore volumes with driver_opts +- Check env in args for compose based apps + +### 🚜 Refactor + +- Update destination.blade.php to add group class for better styling +- Applicationdeploymentjob +- Improve code structure in ApplicationDeploymentJob.php +- Remove unnecessary debug statement in ApplicationDeploymentJob.php +- Remove unnecessary debug statements and improve code structure in RunRemoteProcess.php and ApplicationDeploymentJob.php +- Remove unnecessary logging statements from UpdateCoolify +- Update storage form inputs in show.blade.php +- Improve Docker Compose parsing for services +- Remove unnecessary port appending in updateCompose function +- Remove unnecessary form class in profile index.blade.php +- Update form layout in invite-link.blade.php +- Add log entry when starting new application deployment +- Improve Docker Compose parsing for services +- Update Docker Compose parsing for services +- Update slogan in shlink.yaml +- Improve display of deployment time in index.blade.php +- Remove commented out code for clearing Ray logs +- Update save_environment_variables method to use application's environment_variables instead of environment_variables_preview + +### ⚙️ Miscellaneous Tasks + +- Update for version 289 +- Fix formatting issue in deployment index.blade.php file +- Remove unnecessary wire:navigate attribute in breadcrumbs.blade.php +- Rename docker dirs +- Update laravel/socialite to version v5.14.0 and livewire/livewire to version 3.4.9 +- Update modal styles for better user experience +- Update deployment index.blade.php script for better performance +- Update version numbers to 4.0.0-beta.290 +- Update version numbers to 4.0.0-beta.291 +- Update version numbers to 4.0.0-beta.292 +- Update version numbers to 4.0.0-beta.293 +- Add upgrade guide link to upgrade.blade.php +- Improve upgrade.blade.php with clearer instructions and formatting +- Update version numbers to 4.0.0-beta.294 +- Add Lightspeed.run as a sponsor +- Update Dockerfile to install vim + +## [4.0.0-beta.288] - 2024-05-28 + +### 🐛 Bug Fixes + +- Do not allow service storage mount point modifications +- Volume adding + +### ⚙️ Miscellaneous Tasks + +- Update Sentry release version to 4.0.0-beta.288 + +## [4.0.0-beta.287] - 2024-05-27 + +### 🚀 Features + +- Handle incomplete expired subscriptions in Stripe webhook +- Add more persistent storage types + +### 🐛 Bug Fixes + +- Force load services from cdn on reload list + +### ⚙️ Miscellaneous Tasks + +- Update Sentry release version to 4.0.0-beta.287 +- Add Thompson Edolo as a sponsor +- Add null checks for team in Stripe webhook + +## [4.0.0-beta.286] - 2024-05-27 + +### 🚀 Features + +- If the time seems too long it remains at 0s +- Improve Docker Engine start logic in ServerStatusJob +- If proxy stopped manually, it won't start back again +- Exclude_from_hc magic +- Gitea manual webhooks +- Add container logs in case the container does not start healthy + +### 🐛 Bug Fixes + +- Wrong time during a failed deployment +- Removal of the failed deployment condition, addition of since started instead of finished time +- Use local versions + service templates and query them every 10 minutes +- Check proxy functionality before removing unnecessary coolify.yaml file and checking Docker Engine +- Show first 20 users only in admin view +- Add subpath for services +- Ghost subdir +- Do not pull templates in dev +- Templates +- Update error message for invalid token to mention invalid signature +- Disable containerStopped job for now +- Disable unreachable/revived notifications for now +- JSON_UNESCAPED_UNICODE +- Add wget to nixpacks builds +- Pre and post deployment commands +- Bitbucket commits link +- Better way to add curl/wget to nixpacks +- Root team able to download backups +- Build server should not have a proxy +- Improve build server functionalities +- Sentry issue +- Sentry +- Sentry error + livewire downgrade +- Sentry +- Sentry +- Sentry error +- Sentry + +### 🚜 Refactor + +- Update edit-domain form in project service view +- Add Huly services to compose file +- Remove redundant heading in backup settings page +- Add isBuildServer method to Server model +- Update docker network creation in ApplicationDeploymentJob + +### ⚙️ Miscellaneous Tasks + +- Change pre and post deployment command length in applications table +- Refactor container name logic in GetContainersStatus.php and ForcePasswordReset.php +- Remove unnecessary content from Docker Compose file + +## [4.0.0-beta.285] - 2024-05-21 + +### 🚀 Features + +- Add SerpAPI as a Github Sponsor +- Admin view for deleting users +- Scheduled task failed notification + +### 🐛 Bug Fixes + +- Optimize new resource creation +- Show it docker compose has syntax errors + +### 💼 Other + +- Responsive here and there + +## [4.0.0-beta.284] - 2024-05-19 + +### 🚀 Features + +- Add hc logs to healthchecks + +### ◀️ Revert + +- Hc return code check + +## [4.0.0-beta.283] - 2024-05-17 + +### 🚀 Features + +- Update healthcheck test in StartMongodb action +- Add pull_request_id filter to get_last_successful_deployment method in Application model + +### 🐛 Bug Fixes + +- PR deployments have good predefined envs + +### ⚙️ Miscellaneous Tasks + +- Update version to 4.0.0-beta.283 + +## [4.0.0-beta.281] - 2024-05-17 + +### 🚀 Features + +- Shows the latest deployment commit + message on status +- New manual update process + remove next_channel +- Add lastDeploymentInfo and lastDeploymentLink props to breadcrumbs and status components +- Sort envs alphabetically and creation date +- Improve sorting of environment variables in the All component + +### 🐛 Bug Fixes + +- Hc from localhost to 127.0.0.1 +- Use rc in hc +- Telegram group chat notifications + +## [4.0.0-beta.280] - 2024-05-16 + +### 🐛 Bug Fixes + +- Commit message length + +## [4.0.0-beta.279] - 2024-05-16 + +### ⚙️ Miscellaneous Tasks + +- Update version numbers to 4.0.0-beta.279 +- Limit commit message length to 50 characters in ApplicationDeploymentJob + +## [4.0.0-beta.278] - 2024-05-16 + +### 🚀 Features + +- Adding new COOLIFY_ variables +- Save commit message and better view on deployments +- Toggle label escaping mechanism + +### 🐛 Bug Fixes + +- Use commit hash on webhooks + +### ⚙️ Miscellaneous Tasks + +- Refactor Service.php to handle missing admin user in extraFields() method +- Update twenty CRM template with environment variables and dependencies +- Refactor applications.php to remove unused imports and improve code readability +- Refactor deployment index.blade.php for improved readability and rollback handling +- Refactor GitHub app selection UI in project creation form +- Update ServerLimitCheckJob.php to handle missing serverLimit value +- Remove unnecessary code for saving commit message +- Update DOCKER_VERSION to 26.0 in install.sh script +- Update Docker and Docker Compose versions in Dockerfiles + +## [4.0.0-beta.277] - 2024-05-10 + +### 🚀 Features + +- Add AdminRemoveUser command to remove users from the database + +### 🐛 Bug Fixes + +- Color for resource operation server and project name +- Only show realtime error on non-cloud instances +- Only allow push and mr gitlab events +- Improve scheduled task adding/removing +- Docker compose dependencies for pr previews +- Properly populating dependencies + +### 💼 Other + +- Fix a few boxes here and there + +### ⚙️ Miscellaneous Tasks + +- Update version numbers to 4.0.0-beta.278 +- Update hover behavior and cursor style in scheduled task executions view +- Refactor scheduled task view to improve code readability and maintainability +- Skip scheduled tasks if application or service is not running +- Remove debug logging statements in Kernel.php +- Handle invalid cron strings in Kernel.php + +## [4.0.0-beta.275] - 2024-05-06 + +### 🚀 Features + +- Add container name to network aliases in ApplicationDeploymentJob +- Add lazy loading for images in General.php and improve Docker Compose file handling in Application.php +- Experimental sentinel +- Start Sentinel on servers. +- Pull new sentinel image and restart container +- Init metrics + +### 🐛 Bug Fixes + +- Typo in tags.blade.php +- Install.sh error +- Env file +- Comment out internal notification in email_verify method +- Confirmation for custom labels +- Change permissions on newly created dirs + +### 💼 Other + +- Fix tag view + +### 🚜 Refactor + +- Add SCHEDULER environment variable to StartSentinel.php + +### ⚙️ Miscellaneous Tasks + +- Dark mode should be the default +- Improve menu item styling and spacing in service configuration and index views +- Improve menu item styling and spacing in service configuration and index views +- Improve menu item styling and spacing in project index and show views +- Remove docker compose versions +- Add Listmonk service template and logo +- Refactor GetContainersStatus.php for improved readability and maintainability +- Refactor ApplicationDeploymentJob.php for improved readability and maintainability +- Add metrics and logs directories to installation script +- Update sentinel version to 0.0.2 in versions.json +- Update permissions on metrics and logs directories +- Comment out server sentinel check in ServerStatusJob + +## [4.0.0-beta.273] - 2024-05-03 + +### 🐛 Bug Fixes + +- Formbricks image origin +- Add port even if traefik is used + +### ⚙️ Miscellaneous Tasks + +- Update version to 4.0.0-beta.275 +- Update DNS server validation helper text + +## [4.0.0-beta.267] - 2024-04-26 + +### 🚀 Features + +- Initial datalist +- Update service contribution docs URL +- The final pricing plan, pay-as-you-go + +### 🐛 Bug Fixes + +- Move s3 storages to separate view +- Mongo db backup +- Backups +- Autoupdate +- Respect start period and chekc interval for hc +- Parse HEALTHCHECK from dockerfile +- Make s3 name and endpoint required +- Able to update source path for predefined volumes +- Get logs with non-root user +- Mongo 4.0 db backup + +### 💼 Other + +- Update resource operations view + +### ◀️ Revert + +- Variable parsing + +## [4.0.0-beta.266] - 2024-04-24 + +### 🐛 Bug Fixes + +- Refresh public ips on start + +## [4.0.0-beta.259] - 2024-04-17 + +### 🚀 Features + +- Literal env variables +- Lazy load stuffs + tell user if compose based deployments have missing envs +- Can edit file/dir volumes from ui in compose based apps +- Upgrade Appwrite service template to 1.5 +- Upgrade Appwrite service template to 1.5 +- Add db name to backup notifications + +### 🐛 Bug Fixes + +- Helper image only pulled if required, not every 10 mins +- Make sure that confs when checking if it is changed sorted +- Respect .env file (for default values) +- Remove temporary cloudflared config +- Remove lazy loading until bug figured out +- Rollback feature +- Base64 encode .env +- $ in labels escaped +- .env saved to deployment server, not to build server +- Do no able to delete gh app without deleting resources +- 500 error on edge case +- Able to select server when creating new destination +- N8n template + +### 💼 Other + +- Non-root user for remote servers +- Non-root + +## [4.0.0-beta.258] - 2024-04-12 + +### 🚀 Features + +- Dynamic mux time + +### 🐛 Bug Fixes + +- Check each required binaries one-by-one + +## [4.0.0-beta.256] - 2024-04-12 + +### 🚀 Features + +- Upload large backups +- Edit domains easier for compose +- Able to delete configuration from server +- Configuration checker for all resources +- Allow tab in textarea + +### 🐛 Bug Fixes + +- Service config hash update +- Redeploy if image not found in restart only mode + +### 💼 Other + +- New pricing +- Fix allowTab logic +- Use 2 space instead of tab + +## [4.0.0-beta.252] - 2024-04-09 + +### 🚀 Features + +- Add amazon linux 2023 + +### 🐛 Bug Fixes + +- Git submodule update +- Unintended left padding on sidebar +- Hashed random delimeter in ssh commands + make sure to remove the delimeter from the command + +## [4.0.0-beta.250] - 2024-04-05 + +### 🚀 Features + +- *(application)* Update submodules after git checkout + +## [4.0.0-beta.249] - 2024-04-03 + +### 🚀 Features + +- Able to make rsa/ed ssh keys + +### 🐛 Bug Fixes + +- Warning if you use multiple domains for a service +- New github app creation +- Always rebuild Dockerfile / dockerimage buildpacks +- Do not rebuild dockerfile based apps twice +- Make sure if envs are changed, rebuild is needed +- Members cannot manage subscriptions +- IsMember +- Storage layout +- How to update docker-compose, environment variables and fqdns + +### 💼 Other + +- Light buttons +- Multiple server view + +## [4.0.0-beta.242] - 2024-03-25 + +### 🚀 Features + +- Change page width +- Watch paths + +### 🐛 Bug Fixes + +- Compose env has SERVICE, but not defined for Coolify +- Public service database +- Make sure service db proxy restarted +- Restart service db proxies +- Two factor +- Ui for tags +- Update resources view +- Realtime connection check +- Multline env in dev mode +- Scheduled backup for other service databases (supabase) +- PR deployments should not be distributed to 2 servers +- Name/from address required for resend +- Autoupdater +- Async service loads +- Disabled inputs are not trucated +- Duplicated generated fqdns are now working +- Uis +- Ui for cftunnels +- Search services +- Trial users subscription page +- Async public key loading +- Unfunctional server should see resources + +### 💼 Other + +- Run cleanup every day +- Fix +- Fix log outputs +- Automatic cloudflare tunnels +- Backup executions + +## [4.0.0-beta.241] - 2024-03-20 + +### 🚀 Features + +- Able to run scheduler/horizon programatically + +### 🐛 Bug Fixes + +- Volumes for prs +- Shared env variable parsing + +### 💼 Other + +- Redesign +- Redesign + +## [4.0.0-beta.240] - 2024-03-18 + +### 🐛 Bug Fixes + +- Empty get logs number of lines +- Only escape envs after v239+ +- 0 in env value +- Consistent container name +- Custom ip address should turn off rolling update +- Multiline input +- Raw compose deployment +- Dashboard view if no project found + +## [4.0.0-beta.239] - 2024-03-14 + +### 🐛 Bug Fixes + +- Duplicate dockerfile +- Multiline env variables +- Server stopped, service page not reachable + +## [4.0.0-beta.237] - 2024-03-14 + +### 🚀 Features + +- Domains api endpoint +- Resources api endpoint +- Team api endpoint +- Add deployment details to deploy endpoint +- Add deployments api +- Experimental caddy support +- Dynamic configuration for caddy +- Reset password +- Show resources on source page + +### 🐛 Bug Fixes + +- Deploy api messages +- Fqdn null in case docker compose bp +- Reload caddy issue +- /realtime endpoint +- Proxy switch +- Service ports for services + caddy +- Failed deployments should send failed email/notification +- Consider custom healthchecks in dockerfile +- Create initial files async +- Docker compose validation + +## [4.0.0-beta.235] - 2024-03-05 + +### 🐛 Bug Fixes + +- Should note delete personal teams +- Make sure to show some buttons +- Sort repositories by name + +## [4.0.0-beta.224] - 2024-02-23 + +### 🚀 Features + +- Custom server limit +- Delay container/server jobs +- Add static ipv4 ipv6 support +- Server disabled by overflow +- Preview deployment logs +- Collect webhooks during maintenance +- Logs and execute commands with several servers + +### 🐛 Bug Fixes + +- Subscription / plan switch, etc +- Firefly service +- Force enable/disable server in case ultimate package quantity decreases +- Server disabled +- Custom dockerfile location always checked +- Import to mysql and mariadb +- Resource tab not loading if server is not reachable +- Load unmanaged async +- Do not show n/a networsk +- Service container status updates +- Public prs should not be commented +- Pull request deployments + build servers +- Env value generation +- Sentry error +- Service status updated + +### 💼 Other + +- Change + icon to hamburger. + +## [4.0.0-beta.222] - 2024-02-22 + +### 🚀 Features + +- Able to add dynamic configurations from proxy dashboard + +### 🐛 Bug Fixes + +- Connections being stuck and not processed until proxy restarts +- Use latest image if nothing is specified +- No coolify.yaml found +- Server validation +- Statuses +- Unknown image of service until it is uploaded + +## [4.0.0-beta.220] - 2024-02-19 + +### 🚀 Features + +- Save github app permission locally +- Minversion for services + +### 🐛 Bug Fixes + +- Add openbsd ssh server check +- Resources +- Empty build variables +- *(server)* Revalidate server button not showing in server's page +- Fluent bit ident level +- Submodule cloning +- Database status +- Permission change updates from webhook +- Server validation + +### 💼 Other + +- Updates + +## [4.0.0-beta.213] - 2024-02-12 + +### 🚀 Features + +- Magic for traefik redirectregex in services +- Revalidate server +- Disable gzip compression on service applications + +### 🐛 Bug Fixes + +- Cleanup scheduled tasks +- Padding left on input boxes +- Use ls / command instead ls +- Do not add the same server twice +- Only show redeployment required if status is not exited + +## [4.0.0-beta.212] - 2024-02-08 + +### 🚀 Features + +- Cleanup queue + +### 🐛 Bug Fixes + +- New menu on navbar +- Make sure resources are deleted in async mode +- Go to prod env from dashboard if there is no other envs defined +- User proper image_tag, if set +- New menu ui +- Lock logdrain configuration when one of them are enabled +- Add docker compose check during server validation +- Get service stack as uuid, not name +- Menu +- Flex wrap deployment previews +- Boolean docker options +- Only add 'networks' key if 'network_mode' is absent + +## [4.0.0-beta.206] - 2024-02-05 + +### 🚀 Features + +- Clone to env +- Multi deployments + +### 🐛 Bug Fixes + +- Wrap tags and avoid horizontal overflow +- Stripe webhooks +- Feedback from self-hosted envs to discord + +### 💼 Other + +- Specific about newrelic logdrains + +## [4.0.0-beta.201] - 2024-01-29 + +### 🚀 Features + +- Added manual webhook support for bitbucket +- Add initial support for custom docker run commands +- Cleanup unreachable servers +- Tags and tag deploy webhooks + +### 🐛 Bug Fixes + +- Bitbucket manual deployments +- Webhooks for multiple apps +- Unhealthy deployments should be failed +- Add env variables for wordpress template without database +- Service deletion function +- Service deletion fix +- Dns validation + duplicated fqdns +- Validate server navbar upated +- Regenerate labels on application clone +- Service deletion +- Not able to use other shared envs +- Sentry fix +- Sentry +- Sentry error +- Sentry +- Sentry error +- Create dynamic directory +- Migrate to new modal +- Duplicate domain check +- Tags + +### 💼 Other + +- New modal component + +## [4.0.0-beta.188] - 2024-01-11 + +### 🚀 Features + +- Search between resources +- Move resources between projects / environments +- Clone any resource +- Shared environments +- Concurrent builds / server +- Able to deploy multiple resources with webhook +- Add PR comments +- Dashboard live deployment view + +### 🐛 Bug Fixes + +- Preview deployments with nixpacks +- Cleanup docker stuffs before upgrading +- Service deletion command +- Cpuset limits was determined in a way that apps only used 1 CPU max, ehh, sorry. +- Service stack view +- Change proxy view +- Checkbox click +- Git pull command for deploy key based previews +- Server status job +- Service deletion bug! +- Links +- Redis custom conf +- Sentry error +- Restrict concurrent deployments per server +- Queue +- Change env variable length + +### 💼 Other + +- Send notification email if payment + +### 🚜 Refactor + +- Compose file and install script + +## [4.0.0-beta.186] - 2024-01-11 + +### 🚀 Features + +- Import backups + +### 🐛 Bug Fixes + +- Do not include thegameplan.json into build image +- Submit error on postgresql +- Email verification / forgot password +- Escape build envs properly for nixpacks + docker build +- Undead endpoint +- Upload limit on ui +- Save cmd output propely (merge) +- Load profile on remote commands +- Load profile and set envs on remote cmd +- Restart should not update config hash + +## [4.0.0-beta.184] - 2024-01-09 + +### 🐛 Bug Fixes + +- Healthy status +- Show framework based notification in build logs +- Traefik labels +- Use ip for sslip in dev if remote server is used +- Service labels without ports (unknown ports) +- Sort and rename (unique part) of labels +- Settings menu +- Remove traefik debug in dev mode +- Php pgsql to 8.2 +- Static buildpack should set port 80 +- Update navbar on build_pack change + +## [4.0.0-beta.183] - 2024-01-06 + +### 🚀 Features + +- Add www-non-www redirects to traefik + +### 🐛 Bug Fixes + +- Database env variables + +## [4.0.0-beta.182] - 2024-01-04 + +### 🐛 Bug Fixes + +- File storage save + +## [4.0.0-beta.181] - 2024-01-03 + +### 🐛 Bug Fixes + +- Nixpacks buildpack + +## [4.0.0-beta.180] - 2024-01-03 + +### 🐛 Bug Fixes + +- Nixpacks cache +- Only add restart policy if its empty (compose) + +## [4.0.0-beta.179] - 2024-01-02 + +### 🐛 Bug Fixes + +- Set deployment failed if new container is not healthy + +## [4.0.0-beta.177] - 2024-01-02 + +### 🚀 Features + +- Raw docker compose deployments + +### 🐛 Bug Fixes + +- Duplicate compose variable + +## [4.0.0-beta.176] - 2023-12-31 + +### 🐛 Bug Fixes + +- Horizon + +## [4.0.0-beta.175] - 2023-12-30 + +### 🚀 Features + +- Add environment description + able to change name + +### 🐛 Bug Fixes + +- Sub +- Wrong env variable parsing +- Deploy key + docker compose + +## [4.0.0-beta.174] - 2023-12-27 + +### 🐛 Bug Fixes + +- Restore falsely deleted coolify-db-backup + +## [4.0.0-beta.173] - 2023-12-27 + +### 🐛 Bug Fixes + +- Cpu limit to float from int +- Add source commit to final envs +- Routing, switch back to old one +- Deploy instead of restart in case swarm is used +- Button title + +## [4.0.0-beta.163] - 2023-12-15 + +### 🚀 Features + +- Custom docker compose commands + +### 🐛 Bug Fixes + +- Domains for compose bp +- No action in webhooks +- Add debug output to gitlab webhooks +- Do not push dockerimage +- Add alpha to swarm +- Server not found +- Do not autovalidate server on mount +- Server update schedule +- Swarm support ui +- Server ready +- Get swarm service logs +- Docker compose apps env rewritten +- Storage error on dbs +- Why?! +- Stay tuned + +### 💼 Other + +- Swarm +- Swarm + +## [4.0.0-beta.155] - 2023-12-11 + +### 🚀 Features + +- Autoupdate env during seed +- Disable autoupdate +- Randomly sleep between executions +- Pull latest images for services + +### 🐛 Bug Fixes + +- Do not send telegram noti on intent payment failed +- Database ui is realtime based +- Live mode for github webhooks +- Ui +- Realtime connection popup could be disabled +- Realtime check +- Add new destination +- Proxy logs +- Db status check +- Pusher host +- Add ipv6 +- Realtime connection?! +- Websocket +- Better handling of errors with install script +- Install script parse version +- Only allow to modify in .env file if AUTOUPDATE is set +- Is autoupdate not null +- Run init command after production seeder +- Init +- Comma in traefik custom labels +- Ignore if dynamic config could not be set +- Service env variable ovewritten if it has a default value +- Labelling +- Non-ascii chars in labels +- Labels +- Init script echos +- Update Coolify script +- Null notify +- Check queued deployments as well +- Copy invitation +- Password reset / invitation link requests +- Add catch all route +- Revert random container job delay +- Backup executions view +- Only check server status in container status job +- Improve server status check times +- Handle other types of generated values +- Server checking status +- Ui for adding new destination +- Reset domains on compose file change + +### 💼 Other + +- Fix for comma in labels +- Add image name to service stack + better options visibility + +### 🚜 Refactor + +- Service logs are now on one page +- Application status changed realtime +- Custom labels +- Clone project + +## [4.0.0-beta.154] - 2023-12-07 + +### 🚀 Features + +- Execute command in container + +### 🐛 Bug Fixes + +- Container selection +- Service navbar using new realtime events +- Do not create duplicated networks +- Live event +- Service start + event +- Service deletion job +- Double ws connection +- Boarding view + +### 💼 Other + +- Env vars +- Migrate to livewire 3 + +## [4.0.0-beta.124] - 2023-11-13 + +### 🚀 Features + +- Log drain (wip) +- Enable/disable log drain by service +- Log drainer container check +- Add docker engine support install script to rhel based systems +- Save timestamp configuration for logs +- Custom log drain endpoints +- Auto-restart tcp proxies for databases + +### 🐛 Bug Fixes + +- *(fider template)* Use the correct docs url +- Fqdn for minio +- Generate service fields +- Mariadb backups +- When to pull image +- Do not allow to enter local ip addresses +- Reset password +- Only report nonruntime errors +- Handle different label formats in services +- Server adding process +- Show defined resources in server tab, so you will know what you need to delete before you can delete the server. +- Lots of regarding git + docker compose deployments +- Pull request build variables +- Double default password length +- Do not remove deployment in case compose based failed +- No container servers +- Sentry issue +- Dockercompose save ./ volumes under /data/coolify +- Server view for link() +- Default value do not overwrite existing env value +- Use official install script with rancher (one will work for sure) +- Add cf tunnel to boarding server view +- Prevent autorefresh of proxy status +- Missing docker image thing +- Add hc for soketi +- Deploy the right compose file +- Bind volumes for compose bp +- Use hc port 80 in case of static build +- Switching to static build + +### 💼 Other + +- New deployment jobs +- Compose based apps +- Swarm +- Swarm +- Swarm +- Swarm +- Disable trial +- Meilisearch +- Broadcast +- 🌮 + +### 🚜 Refactor + +- Env variable generator + +### ◀️ Revert + +- Wip + +## [4.0.0-beta.109] - 2023-11-06 + +### 🚀 Features + +- Deployment logs fullscreen +- Service database backups +- Make service databases public + +### 🐛 Bug Fixes + +- Missing environment variables prevewi on service +- Invoice.paid should sleep for 5 seconds +- Local dev repo +- Deployments ui +- Dockerfile build pack fix +- Set labels on generate domain +- Network service parse +- Notification url in containerstatusjob +- Gh webhook response 200 to installation_repositories +- Delete destination +- No id found +- Missing $mailMessage +- Set default from/sender names +- No environments +- Telegram text +- Private key not found error +- UI +- Resourcesdelete command +- Port number should be int +- Separate delete with validation of server +- Add nixpacks info +- Remove filter +- Container logs are now followable in full-screen and sorted by timestamp +- Ui for labels +- Ui +- Deletions +- Build_image not found +- Github source view +- Github source view +- Dockercleanupjob should be released back +- Ui +- Local ip address +- Revert workdir to basedir +- Container status jobs for old pr deployments +- Service updates + +## [4.0.0-beta.99] - 2023-10-24 + +### 🚀 Features + +- Improve deployment time by a lot + +### 🐛 Bug Fixes + +- Space in build args +- Lock SERVICE_FQDN envs +- If user is invited, that means its email is verified +- Force password reset on invited accounts +- Add ssh options to git ls-remote +- Git ls-remote +- Remove coolify labels from ui + +### 💼 Other + +- Fix subs + +## [4.0.0-beta.97] - 2023-10-20 + +### 🚀 Features + +- Standalone mongodb +- Cloning project +- Api tokens + deploy webhook +- Start all kinds of things +- Simple search functionality +- Mysql, mariadb +- Lock environment variables +- Download local backups + +### 🐛 Bug Fixes + +- Service docs links +- Add PGUSER to prevent HC warning +- Preselect s3 storage if available +- Port exposes change, shoud regenerate label +- Boarding +- Clone to with the same environment name +- Cleanup stucked resources on start +- Do not allow to delete env if a resource is defined +- Service template generator + appwrite +- Mongodb backup +- Make sure coolfiy network exists on install +- Syncbunny command +- Encrypt mongodb password +- Mongodb healtcheck command +- Rate limit for api + add mariadb + mysql +- Server settings guarded + +### 💼 Other + +- Generate services +- Mongodb backup +- Mongodb backup +- Updates + +## [4.0.0-beta.93] - 2023-10-18 + +### 🚀 Features + +- Able to customize docker labels on applications +- Show if config is not applied + +### 🐛 Bug Fixes + +- Setup:dev script & contribution guide +- Do not show configuration changed if config_hash is null +- Add config_hash if its null (old deployments) +- Label generation +- Labels +- Email channel no recepients +- Limit horizon processes to 2 by default +- Add custom port as ssh option to deploy_key based commands +- Remove custom port from git repo url +- ContainerStatus job + +### 💼 Other + +- PAT by team + +## [4.0.0-beta.92] - 2023-10-17 + +### 🐛 Bug Fixes + +- Proxy start process + +## [4.0.0-beta.91] - 2023-10-17 + +### 🐛 Bug Fixes + +- Always start proxy if not NONE is selected + +### 💼 Other + +- Add helper to service domains + +## [4.0.0-beta.90] - 2023-10-17 + +### 🐛 Bug Fixes + +- Only include config.json if its exists and a file + +### 💼 Other + +- Wordpress + +## [4.0.0-beta.89] - 2023-10-17 + +### 🐛 Bug Fixes + +- Noindex meta tag +- Show docker build logs + +## [4.0.0-beta.88] - 2023-10-17 + +### 🚀 Features + +- Use docker login credentials from server + +## [4.0.0-beta.87] - 2023-10-17 + +### 🐛 Bug Fixes + +- Service status check is a bit better +- Generate fqdn if you deleted a service app, but it requires fqdn +- Cancel any deployments + queue next +- Add internal domain names during build process + +## [4.0.0-beta.86] - 2023-10-15 + +### 🐛 Bug Fixes + +- Build image before starting dockerfile buildpacks + +## [4.0.0-beta.85] - 2023-10-14 + +### 🐛 Bug Fixes + +- Redis URL generated + +## [4.0.0-beta.83] - 2023-10-13 + +### 🐛 Bug Fixes + +- Docker hub URL + +## [4.0.0-beta.70] - 2023-10-09 + +### 🚀 Features + +- Add email verification for cloud +- Able to deploy docker images +- Add dockerfile location +- Proxy logs on the ui +- Add custom redis conf + +### 🐛 Bug Fixes + +- Server validation process +- Fqdn could be null +- Small +- Server unreachable count +- Do not reset unreachable count +- Contact docs +- Check connection +- Server saving +- No env goto envs from dashboard +- Goto +- Tcp proxy for dbs +- Database backups +- Only send email if transactional email set +- Backupfailed notification is forced +- Use port exposed for reverse proxy +- Contact link +- Use only ip addresses for servers +- Deleted team and it is the current one +- Add new team button +- Transactional email link +- Dashboard goto link +- Only require registry image in case of dockerimage bp +- Instant save build pack change +- Public git +- Cannot remove localhost +- Check localhost connection +- Send unreachable/revived notifications +- Boarding + verification +- Make sure proxy wont start in NONE mode +- Service check status 10 sec +- IsCloud in production seeder +- Make sure to use IP address +- Dockerfile location feature +- Server ip could be hostname in self-hosted +- Urls should be password fields +- No backup for redis +- Show database logs in case of its not healthy and running +- Proxy check for ports, do not kill anything listening on port 80/443 +- Traefik dashboard ip +- Db labels +- Docker cleanup jobs +- Timeout for instant remote processes +- Dev containerjobs +- Backup database one-by-one. +- Turn off static deployment if you switch buildpacks + +### 💼 Other + +- Dockerimage +- Updated dashboard +- Fix +- Fix +- Coolify proxy access logs exposed in dev +- Able to select environment on new resource +- Delete server +- Redis + +## [4.0.0-beta.58] - 2023-10-02 + +### 🚀 Features + +- Reset root password +- Attach Coolify defined networks to services +- Delete resource command +- Multiselect removable resources +- Disable service, required version +- Basedir / monorepo initial support +- Init version of any git deployment +- Deploy private repo with ssh key + +### 🐛 Bug Fixes + +- If waitlist is disabled, redirect to register +- Add destination to new services +- Predefined content for files +- Move /data to ./_data in dev +- UI +- Show all storages in one place for services +- Ui +- Add _data to vite ignore +- Only use _ in volume names for services +- Volume names in services +- Volume names +- Service logs visible if the whole service stack is not running +- Ui +- Compose magic +- Compose parser updated +- Dev compose files +- Traefik labels for multiport deployments +- Visible version number +- Remove SERVICE_ from deployable compose +- Delete event to deleting +- Move dev data to volumes to prevent permission issues +- Traefik labelling in case of several http and https domain added +- PR deployments use the first fqdn as base +- Email notifications subscription fixed +- Services - do not remove unnecessary things for now +- Decrease max horizon processes to get lower memory usage +- Test emails only available for user owned smtp/resend +- Ui for self-hosted email settings +- Set smtp notifications on by default +- Select branch on other git +- Private repository +- Contribution guide +- Public repository names +- *(create)* Flex wrap on server & network selection +- Better unreachable/revived server statuses +- Able to set base dir for Dockerfile build pack + +### 💼 Other + +- Uptime kume hc updated +- Switch back to /data (volume errors) +- Notifications +- Add shared email option to everyone + +## [4.0.0-beta.57] - 2023-10-02 + +### 🚀 Features + +- Container logs + +### 🐛 Bug Fixes + +- Always pull helper image in dev +- Only show last 1000 lines +- Service status + +## [4.0.0-beta.47] - 2023-09-28 + +### 🐛 Bug Fixes + +- Next helper image +- Service templates +- Sync:bunny +- Update process if server has been renamed +- Reporting handler +- Localhost privatekey update +- Remove private key in case you removed a github app +- Only show manually added private keys on server view +- Show source on all type of applications +- Docker cleanup should be a job by server +- File/dir based volumes are now read from the server +- Respect server fqdn +- If public repository does not have a main branch +- Preselect branc on private repos +- Deploykey branch +- Backups are now working again +- Not found base_branch in git webhooks +- Coolify db backup +- Preview deployments name, status etc +- Services should have destination as well +- Dockerfile expose is not overwritten +- If app settings is not saved to db +- Do not show subscription cancelled noti +- Show real volume names +- Only parse expose in dockerfiles if ports_exposes is empty +- Add uuid to volume names +- New volumes for services should have - instead of _ + +### 💼 Other + +- Fix previews to preview + +## [4.0.0-beta.46] - 2023-09-28 + +### 🐛 Bug Fixes + +- Containerstatusjob +- Aaaaaaaaaaaaaaaaa +- Services view +- Services +- Manually create network for services +- Disable early updates +- Sslip for localhost +- ContainerStatusJob +- Cannot delete env with available services +- Sync command +- Install script drops an error +- Prevent sync version (it needs an option) +- Instance fqdn setting +- Sentry 4510197209 +- Sentry 4504136641 +- Sentry 4502634789 + +## [4.0.0-beta.45] - 2023-09-24 + +### 🚀 Features + +- Services +- Image tag for services + +### 🐛 Bug Fixes + +- Applications with port mappins do a normal update (not rolling update) +- Put back build pack chooser +- Proxy configuration + starter +- Show real storage name on services +- New service template layout + +### 💼 Other + +- Fixed z-index for version link. +- Add source button +- Fixed z-index for magicbar +- A bit better error +- More visible feedback button +- Update help modal +- Help +- Marketing emails + +## [4.0.0-beta.28] - 2023-09-08 + +### 🚀 Features + +- Telegram topics separation +- Developer view for env variables +- Cache team settings +- Generate public key from private keys +- Able to invite more people at once +- Trial +- Dynamic trial period +- Ssh-agent instead of filesystem based ssh keys +- New container status checks +- Generate ssh key +- Sentry add email for better support +- Healthcheck for apps +- Add cloudflare tunnel support + +### 🐛 Bug Fixes + +- Db backup job +- Sentry 4459819517 +- Sentry 4451028626 +- Ui +- Retry notifications +- Instance email settings +- Ui +- Test email on for admins or custom smtp +- Coolify already exists should not throw error +- Delete database related things when delete database +- Remove -q from docker compose +- Errors in views +- Only send internal notifcations to enabled channels +- Recovery code +- Email sending error +- Sentry 4469575117 +- Old docker version error +- Errors +- Proxy check, reduce jobs, etc +- Queue after commit +- Remove nixpkgarchive +- Remove nixpkgarchive from ui +- Webhooks should not run if server is not functional +- Server is functional check +- Confirm email before sending +- Help should send cc on email +- Sub type +- Show help modal everywhere +- Forgot password +- Disable dockerfile based healtcheck for now +- Add timeout for ssh commands +- Prevent weird ui bug for validateServer +- Lowercase email in forgot password +- Lower case email on waitlist +- Encrypt jobs +- ProcessWithEnv()->run +- Plus boarding step about Coolify +- SaveConfigurationSync +- Help uri +- Sub for root +- Redirect on server not found +- Ip check +- Uniqueips +- Simply reply to help messages +- Help +- Rate limit +- Collect billing address +- Invitation +- Smtp view +- Ssh-agent revert +- Restarting container state on ui +- Generate new key +- Missing upgrade js +- Team error +- 4.0.0-beta.37 +- Localhost +- Proxy start (if not proxy defined, use Traefik) +- Do not remove localhost in boarding +- Allow non ip address (DNS) +- InstallDocker id not found +- Boarding +- Errors +- Proxy container status +- Proxy configuration saving +- Convert startProxy to action +- Stop/start UI on apps and dbs +- Improve localhost boarding process +- Try to use old docker-compose +- Boarding again +- Send internal notifications of email errors +- Add github app change on new app view +- Delete environment variables on app/db delete +- Save proxy configuration +- Add proxy to network with periodic check +- Proxy connections +- Delete persistent storages on resource deletion +- Prevent overwrite already existing env variables in services +- Mappings +- Sentry issue 4478125289 +- Make sure proxy path created +- StartProxy +- Server validation with cf tunnels +- Only show traefik dashboard if its available +- Services +- Database schema +- Report livewire errors +- Links with path +- Add traefik labels no matter if traefik is selected or not +- Add expose port for containers +- Also check docker socks permission on validation + +### 💼 Other + +- User should know that the public key +- Services are not availble yet +- Show registered users on waitlist page +- Nixpacksarchive +- Add Plausible analytics +- Global env variables +- Fix +- Trial emails +- Server check instead of app check +- Show trial instead of sub +- Server lost connection +- Services +- Services +- Services +- Ui for services +- Services +- Services +- Services +- Fixes +- Fix typo + +## [4.0.0-beta.27] - 2023-09-08 + +### 🐛 Bug Fixes + +- Bug + +## [4.0.0-beta.26] - 2023-09-08 + +### 🚀 Features + +- Public database + +## [4.0.0-beta.25] - 2023-09-07 + +### 🐛 Bug Fixes + +- SaveModel email settings + +## [4.0.0-beta.24] - 2023-09-06 + +### 🚀 Features + +- Send request in cloud +- Add discord notifications + +### 🐛 Bug Fixes + +- Form address +- Show hosted email service, just disable for non pro subs +- Add navbar for source + keys +- Add docker network to build process +- Overlapping apps +- Do not show system wide git on cloud +- Lowercase image names +- Typo + +### 💼 Other + +- Backup existing database + +## [4.0.0-beta.23] - 2023-09-01 + +### 🐛 Bug Fixes + +- Sentry bug +- Button loading animation + +## [4.0.0-beta.22] - 2023-09-01 + +### 🚀 Features + +- Add resend as transactional emails + +### 🐛 Bug Fixes + +- DockerCleanupjob +- Validation +- Webhook endpoint in cloud and no system wide gh app +- Subscriptions +- Password confirmation +- Proxy start job +- Dockerimage jobs are not overlapping + +## [4.0.0-beta.21] - 2023-08-27 + +### 🚀 Features + +- Invite by email from waitlist +- Rolling update + +### 🐛 Bug Fixes + +- Limits & server creation page +- Fqdn on apps + +### 💼 Other + +- Boarding + +## [4.0.0-beta.20] - 2023-08-17 + +### 🚀 Features + +- Send internal notification to discord +- Monitor server connection + +### 🐛 Bug Fixes + +- Make coolify-db backups unique dir + +## [4.0.0-beta.19] - 2023-08-15 + +### 🚀 Features + +- Pricing plans ans subs +- Add s3 storages +- Init postgresql database +- Add backup notifications +- Dockerfile build pack +- Cloud +- Force password reset + waitlist + +### 🐛 Bug Fixes + +- Remove buggregator from dev +- Able to change localhost's private key +- Readonly input box +- Notifications +- Licensing +- Subscription link +- Migrate db schema for smtp + discord +- Text field +- Null fqdn notifications +- Remove old modal +- Proxy stop/start ui +- Proxy UI +- Empty description +- Input and textarea +- Postgres_username name to not name, lol +- DatabaseBackupJob.php +- No storage +- Backup now button +- Ui + subscription +- Self-hosted + +### 💼 Other + +- Scheduled backups + +## [4.0.0-beta.18] - 2023-07-14 + +### 🚀 Features + +- Able to control multiplexing +- Add runRemoteCommandSync +- Github repo with deployment key +- Add persistent volumes +- Debuggable executeNow commands +- Add private gh repos +- Delete gh app +- Installation/update github apps +- Auto-deploy +- Deploy key based deployments +- Resource limits +- Long running queue with 1 hour of timeout +- Add arm build to dev +- Disk cleanup threshold by server +- Notify user of disk cleanup init + +### 🐛 Bug Fixes + +- Logo of CCCareers +- Typo +- Ssh +- Nullable name on deploy_keys +- Enviroments +- Remove dd - oops +- Add inprogress activity +- Application view +- Only set status in case the last command block is finished +- Poll activity +- Small typo +- Show activity on load +- Deployment should fail on error +- Tests +- Version +- Status not needed +- No project redirect +- Gh actions +- Set status +- Seeders +- Do not modify localhost +- Deployment_uuid -> type_uuid +- Read env from config, bc of cache +- Private key change view +- New destination +- Do not update next channel all the time +- Cancel deployment button +- Public repo limit shown + branch should be preselected. +- Better status on ui for apps +- Arm coolify version +- Formatting +- Gh actions +- Show github app secrets +- Do not force next version updates +- Debug log button +- Deployment key based works +- Deployment cancel/debug buttons +- Upgrade button +- Changing static build changes port +- Overwrite default nginx configuration +- Do not overlap docker image names +- Oops +- Found image name +- Name length +- Semicolons encoding by traefik +- Base_dir wip & outputs +- Cleanup docker images +- Nginx try_files +- Master is the default, not main +- No ms in rate limit resets +- Loading after button text +- Default value +- Localhost is usable +- Update docker-compose prod +- Cloud/checkoutid/lms +- Type of license code +- More verbose error +- Version lol +- Update prod compose +- Version + +### 💼 Other + +- Extract process handling from async job. +- Extract process handling from async job. +- Extract process handling from async job. +- Extract process handling from async job. +- Extract process handling from async job. +- Extract process handling from async job. +- Extract process handling from async job. +- Persisting data + +## [3.12.28] - 2023-03-16 + +### 🐛 Bug Fixes + +- Revert from dockerhub if ghcr.io does not exists + +## [3.12.27] - 2023-03-07 + +### 🐛 Bug Fixes + +- Show ip address as host in public dbs + +## [3.12.24] - 2023-03-04 + +### 🐛 Bug Fixes + +- Nestjs buildpack + +## [3.12.22] - 2023-03-03 + +### 🚀 Features + +- Add host path to any container + +### 🐛 Bug Fixes + +- Set PACK_VERSION to 0.27.0 +- PublishDirectory +- Host volumes +- Replace . & .. & $PWD with ~ +- Handle log format volumes + +## [3.12.19] - 2023-02-20 + +### 🚀 Features + +- Github raw icon url +- Remove svg support + +### 🐛 Bug Fixes + +- Typos in docs +- Url +- Network in compose files +- Escape new line chars in wp custom configs +- Applications cannot be deleted +- Arm servics +- Base directory not found +- Cannot delete resource when you are not on root team +- Empty port in docker compose + +## [3.12.18] - 2023-01-24 + +### 🐛 Bug Fixes + +- CleanupStuckedContainers +- CleanupStuckedContainers + +## [3.12.16] - 2023-01-20 + +### 🐛 Bug Fixes + +- Stucked containers + +## [3.12.15] - 2023-01-20 + +### 🐛 Bug Fixes + +- Cleanup function +- Cleanup stucked containers +- Deletion + cleanupStuckedContainers + +## [3.12.14] - 2023-01-19 + +### 🐛 Bug Fixes + +- Www redirect + +## [3.12.13] - 2023-01-18 + +### 🐛 Bug Fixes + +- Secrets + +## [3.12.12] - 2023-01-17 + +### 🚀 Features + +- Init h2c (http2/grpc) support +- Http + h2c paralel + +### 🐛 Bug Fixes + +- Build args docker compose +- Grpc + +## [3.12.11] - 2023-01-16 + +### 🐛 Bug Fixes + +- Compose file location +- Docker log sequence +- Delete apps with previews +- Do not cleanup compose applications as unconfigured +- Build env variables with docker compose +- Public gh repo reload compose + +### 💼 Other + +- Trpc +- Trpc +- Trpc +- Trpc +- Trpc +- Trpc +- Trpc + +## [3.12.10] - 2023-01-11 + +### 💼 Other + +- Add missing variables + +## [3.12.9] - 2023-01-11 + +### 🚀 Features + +- Add Openblocks icon +- Adding icon for whoogle +- *(ui)* Add libretranslate service icon +- Handle invite_only plausible analytics + +### 🐛 Bug Fixes + +- Custom gitlab git user +- Add documentation link again +- Remove prefetches +- Doc link +- Temporary disable dns check with dns servers +- Local images for reverting +- Secrets + +## [3.12.8] - 2022-12-27 + +### 🐛 Bug Fixes + +- Parsing secrets +- Read-only permission +- Read-only iam +- $ sign in secrets + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.12.5] - 2022-12-26 + +### 🐛 Bug Fixes + +- Remove unused imports + +### 💼 Other + +- Conditional on environment + +## [3.12.2] - 2022-12-19 + +### 🐛 Bug Fixes + +- Appwrite tmp volume +- Do not replace secret +- Root user for dbs on arm +- Escape secrets +- Escape env vars +- Envs +- Docker buildpack env +- Secrets with newline +- Secrets +- Add default node_env variable +- Add default node_env variable +- Secrets +- Secrets +- Gh actions +- Duplicate env variables +- Cleanupstorage + +### 💼 Other + +- Trpc +- Trpc +- Trpc +- Trpc +- Trpc +- Trpc +- Trpc +- Trpc +- Trpc +- Trpc + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.12.1] - 2022-12-13 + +### 🐛 Bug Fixes + +- Build commands +- Migration file +- Adding missing appwrite volume + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.12.0] - 2022-12-09 + +### 🚀 Features + +- Use registry for building +- Docker registries working +- Custom docker compose file location in repo +- Save doNotTrackData to db +- Add default sentry +- Do not track in settings +- System wide git out of beta +- Custom previewseparator +- Sentry frontend +- Able to host static/php sites on arm +- Save application data before deploying +- SimpleDockerfile deployment +- Able to push image to docker registry +- Revert to remote image +- *(api)* Name label + +### 🐛 Bug Fixes + +- 0 destinations redirect after creation +- Seed +- Sentry dsn update +- Dnt +- Ui +- Only visible with publicrepo +- Migrations +- Prevent webhook errors to be logged +- Login error +- Remove beta from systemwide git +- Git checkout +- Remove sentry before migration +- Webhook previewseparator +- Apache on arm +- Update PR/MRs with new previewSeparator +- Static for arm +- Failed builds should not push images +- Turn off autodeploy for simpledockerfiles +- Security hole +- Rde +- Delete resource on dashboard +- Wrong port in case of docker compose +- Public db icon on dashboard +- Cleanup + +### 💼 Other + +- Pocketbase release + +## [3.11.10] - 2022-11-16 + +### 🚀 Features + +- Only show expose if no proxy conf defined in template +- Custom/private docker registries + +### 🐛 Bug Fixes + +- Local dev api/ws urls +- Wrong template/type +- Gitea icon is svg +- Gh actions +- Gh actions +- Replace $$generate vars +- Webhook traefik +- Exposed ports +- Wrong icons on dashboard +- Escape % in secrets +- Move debug log settings to build logs +- Storage for compose bp + debug on +- Hasura admin secret +- Logs +- Mounts +- Load logs after build failed +- Accept logged and not logged user in /base +- Remote haproxy password/etc +- Remove hardcoded sentry dsn +- Nope in database strings + +### ⚙️ Miscellaneous Tasks + +- Version++ +- Version++ +- Version++ +- Version++ + +## [3.11.9] - 2022-11-15 + +### 🐛 Bug Fixes + +- IsBot issue + +## [3.11.8] - 2022-11-14 + +### 🐛 Bug Fixes + +- Default icon for new services + +## [3.11.1] - 2022-11-08 + +### 🚀 Features + +- Rollback coolify + +### 🐛 Bug Fixes + +- Remove contribution docs +- Umami template +- Compose webhooks fixed +- Variable replacements +- Doc links +- For rollback +- N8n and weblate icon +- Expose ports for services +- Wp + mysql on arm +- Show rollback button loading +- No tags error +- Update on mobile +- Dashboard error +- GetTemplates +- Docker compose persistent volumes +- Application persistent storage things +- Volume names for undefined volume names in compose +- Empty secrets on UI +- Ports for services + +### 💼 Other + +- Secrets on apps +- Fix +- Fixes +- Reload compose loading + +### 🚜 Refactor + +- Code + +### ⚙️ Miscellaneous Tasks + +- Version++ +- Add jda icon for lavalink service +- Version++ + +### ◀️ Revert + +- Revert: revert + +## [3.11.0] - 2022-11-07 + +### 🚀 Features + +- Initial support for specific git commit +- Add default to latest commit and support for gitlab +- Redirect catch-all rule + +### 🐛 Bug Fixes + +- Secret errors +- Service logs +- Heroku bp +- Expose port is readonly on the wrong condition +- Toast +- Traefik proxy q 10s +- App logs view +- Tooltip +- Toast, rde, webhooks +- Pathprefix +- Load public repos +- Webhook simplified +- Remote webhooks +- Previews wbh +- Webhooks +- Websecure redirect +- Wb for previews +- Pr stopps main deployment +- Preview wbh +- Wh catchall for all +- Remove old minio proxies +- Template files +- Compose icon +- Templates +- Confirm restart service +- Template +- Templates +- Templates +- Plausible analytics things +- Appwrite webhook +- Coolify instance proxy +- Migrate template +- Preview webhooks +- Simplify webhooks +- Remove ghost-mariadb from the list +- More simplified webhooks +- Umami + ghost issues + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.10.16] - 2022-10-12 + +### 🐛 Bug Fixes + +- Single container logs and usage with compose + +### 💼 Other + +- New resource label + +## [3.10.15] - 2022-10-12 + +### 🚀 Features + +- Monitoring by container + +### 🐛 Bug Fixes + +- Do not show nope as ip address for dbs +- Add git sha to build args +- Smart search for new services +- Logs for not running containers +- Update docker binaries +- Gh release +- Dev container +- Gitlab auth and compose reload +- Check compose domains in general +- Port required if fqdn is set +- Appwrite v1 missing containers +- Dockerfile +- Pull does not work remotely on huge compose file + +### ⚙️ Miscellaneous Tasks + +- Update staging release + +## [3.10.14] - 2022-10-05 + +### 🚀 Features + +- Docker compose support +- Docker compose +- Docker compose + +### 🐛 Bug Fixes + +- Do not use npx +- Pure docker based development + +### 💼 Other + +- Docker-compose support +- Docker compose +- Remove worker jobs +- One less worker thread + +### 🧪 Testing + +- Remove prisma + +## [3.10.5] - 2022-09-26 + +### 🚀 Features + +- Add migration button to appwrite +- Custom certificate +- Ssl cert on traefik config +- Refresh resource status on dashboard +- Ssl certificate sets custom ssl for applications +- System-wide github apps +- Cleanup unconfigured applications +- Cleanup unconfigured services and databases + +### 🐛 Bug Fixes + +- Ui +- Tooltip +- Dropdown +- Ssl certificate distribution +- Db migration +- Multiplex ssh connections +- Able to search with id +- Not found redirect +- Settings db requests +- Error during saving logs +- Consider base directory in heroku bp +- Basedirectory should be empty if null +- Allow basedirectory for heroku +- Stream logs for heroku bp +- Debug log for bp +- Scp without host verification & cert copy +- Base directory & docker bp +- Laravel php chooser +- Multiplex ssh and ssl copy +- Seed new preview secret types +- Error notification +- Empty preview value +- Error notification +- Seed +- Service logs +- Appwrite function network is not the default +- Logs in docker bp +- Able to delete apps in unconfigured state +- Disable development low disk space +- Only log things to console in dev mode +- Do not get status of more than 10 resources defined by category +- BaseDirectory +- Dashboard statuses +- Default buildImage and baseBuildImage +- Initial deploy status +- Show logs better +- Do not start tcp proxy without main container +- Cleanup stucked tcp proxies +- Default 0 pending invitations +- Handle forked repositories +- Typo +- Pr branches +- Fork pr previews +- Remove unnecessary things +- Meilisearch data dir +- Verify and configure remote docker engines +- Add buildkit features +- Nope if you are not logged in + +### 💼 Other + +- Responsive! +- Fixes +- Fix git icon +- Dropdown as infobox +- Small logs on mobile +- Improvements +- Fix destination view +- Settings view +- More UI improvements +- Fixes +- Fixes +- Fix +- Fixes +- Beta features +- Fix button +- Service fixes +- Fix basedirectory meaning +- Resource button fix +- Main resource search +- Dev logs +- Loading button +- Fix gitlab importer view +- Small fix +- Beta flag +- Hasura console notification +- Fix +- Fix +- Fixes +- Inprogress version of iam +- Fix indicato +- Iam & settings update +- Send 200 for ping and installation wh +- Settings icon + +### ⚙️ Miscellaneous Tasks + +- Version++ +- Version++ +- Version++ +- Version++ +- Version++ +- Version++ +- Version++ ### ◀️ Revert - Show usage everytime -- Revert: revert -- Wip -- Variable parsing -- Hc return code check -- Instancesettings -- Pull policy -- Advanced dropdown -- Databasebackup -- Remove Cloudflare async tag attributes -- Encrypting mount and fs_path -- *(parser)* Enhance FQDN generation logic for services and applications + +## [3.10.2] - 2022-09-11 + +### 🚀 Features + +- Add queue reset button +- Previewapplications init +- PreviewApplications finalized +- Fluentbit +- Show remote servers +- *(layout)* Added drawer when user is in mobile +- Re-apply ui improves +- *(ui)* Improve header of pages +- *(styles)* Make header css component +- *(routes)* Improve ui for apps, databases and services logs + +### 🐛 Bug Fixes + +- Changing umami image URL to get latest version +- Gitlab importer for public repos +- Show error logs +- Umami init sql +- Plausible analytics actions +- Login +- Dev url +- UpdateMany build logs +- Fallback to db logs +- Fluentbit configuration +- Coolify update +- Fluentbit and logs +- Canceling build +- Logging +- Load more +- Build logs +- Versions of appwrite +- Appwrite?! +- Get building status +- Await +- Await #2 +- Update PR building status +- Appwrite default version 1.0 +- Undead endpoint does not require JWT +- *(routes)* Improve design of application page +- *(routes)* Improve design of git sources page +- *(routes)* Ui from destinations page +- *(routes)* Ui from databases page +- *(routes)* Ui from databases page +- *(routes)* Ui from databases page +- *(routes)* Ui from services page +- *(routes)* More ui tweaks +- *(routes)* More ui tweaks +- *(routes)* More ui tweaks +- *(routes)* More ui tweaks +- *(routes)* Ui from settings page +- *(routes)* Duplicates classes in services page +- *(routes)* Searchbar ui +- Github conflicts +- *(routes)* More ui tweaks +- *(routes)* More ui tweaks +- *(routes)* More ui tweaks +- *(routes)* More ui tweaks +- Ui with headers +- *(routes)* Header of settings page in databases +- *(routes)* Ui from secrets table + +### 💼 Other + +- Fix plausible +- Fix cleanup button +- Fix buttons + +### ⚙️ Miscellaneous Tasks + +- Version++ +- Minor changes +- Minor changes +- Minor changes +- Whoops + +## [3.10.1] - 2022-09-10 + +### 🐛 Bug Fixes + +- Show restarting apps +- Show restarting application & logs +- Remove unnecessary gitlab group name +- Secrets for PR +- Volumes for services +- Build secrets for apps +- Delete resource use window location + +### 💼 Other + +- Fix button +- Fix follow button +- Arm should be on next all the time + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.10.0] - 2022-09-08 + +### 🚀 Features + +- New servers view + +### 🐛 Bug Fixes + +- Change to execa from utils +- Save search input +- Ispublic status on databases +- Port checkers +- Ui variables +- Glitchtip env to pyhton boolean +- Autoupdater + +### 💼 Other + +- Dashboard updates +- Fix tooltip + +## [3.9.4] - 2022-09-07 + +### 🐛 Bug Fixes + +- DnsServer formatting +- Settings for service + +## [3.9.3] - 2022-09-07 + +### 🐛 Bug Fixes + +- Pr previews + +## [3.9.2] - 2022-09-07 + +### 🚀 Features + +- Add traefik acme json to coolify container +- Database secrets + +### 🐛 Bug Fixes + +- Gitlab webhook +- Use ip address instead of window location +- Use ip instead of window location host +- Service state update +- Add initial DNS servers +- Revert last change with domain check +- Service volume generation +- Minio default env variables +- Add php 8.1/8.2 +- Edgedb ui +- Edgedb stuff +- Edgedb + +### 💼 Other + +- Fix login/register page +- Update devcontainer +- Add debug log +- Fix initial loading icon bg +- Fix loading start/stop db/services +- Dashboard updates and a lot more + +### ⚙️ Miscellaneous Tasks + +- Version++ +- Version++ + +## [3.9.0] - 2022-09-06 + +### 🐛 Bug Fixes + +- Debug api logging + gh actions +- Workdir +- Move restart button to settings + +## [3.9.1-rc.1] - 2022-09-06 + +### 🚀 Features + +- *(routes)* Rework ui from login and register page + +### 🐛 Bug Fixes + +- Ssh pid agent name +- Repository link trim +- Fqdn or expose port required +- Service deploymentEnabled +- Expose port is not required +- Remote verification +- Dockerfile + +### 💼 Other + +- Database_branches +- Login page + +### ⚙️ Miscellaneous Tasks + +- Version++ +- Version++ + +## [3.9.0-rc.1] - 2022-09-02 + +### 🚀 Features + +- New service - weblate +- Restart application +- Show elapsed time on running builds +- Github allow fual branches +- Gitlab dual branch +- Taiga + +### 🐛 Bug Fixes + +- Glitchtip things +- Loading state on start +- Ui +- Submodule +- Gitlab webhooks +- UI + refactor +- Exposedport on save +- Appwrite letsencrypt +- Traefik appwrite +- Traefik +- Finally works! :) +- Rename components + remove PR/MR deployment from public repos +- Settings missing id +- Explainer component +- Database name on logs view +- Taiga + +### 💼 Other + +- Fixes +- Change tooltips and info boxes +- Added rc release + +### 🧪 Testing + +- Native binary target +- Dockerfile + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.8.9] - 2022-08-30 + +### 🐛 Bug Fixes + +- Oh god Prisma + +## [3.8.8] - 2022-08-30 + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.8.6] - 2022-08-30 + +### 🐛 Bug Fixes + +- Pr deployment +- CompareVersions +- Include +- Include +- Gitlab apps + +### 💼 Other + +- Fixes +- Route to the correct path when creating destination from db config + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.8.5] - 2022-08-27 + +### 🐛 Bug Fixes + +- Copy all files during install process +- Typo +- Process +- White labeled icon on navbar +- Whitelabeled icon +- Next/nuxt deployment type +- Again + +## [3.8.4] - 2022-08-27 + +### 🐛 Bug Fixes + +- UI thinkgs +- Delete team while it is active +- Team switching +- Queue cleanup +- Decrypt secrets +- Cleanup build cache as well +- Pr deployments + remove public gits + +### 💼 Other + +- Dashbord fixes +- Fixes + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.8.3] - 2022-08-26 + +### 🐛 Bug Fixes + +- Secrets decryption + +## [3.8.2] - 2022-08-26 + +### 🚀 Features + +- *(ui)* Rework home UI and with responsive design + +### 🐛 Bug Fixes + +- Never stop deplyo queue +- Build queue system +- High cpu usage +- Worker +- Better worker system + +### 💼 Other + +- Dashboard fine-tunes +- Fine-tune +- Fixes +- Fix + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.8.1] - 2022-08-24 + +### 🐛 Bug Fixes + +- Ui buttons +- Clear queue on cancelling jobs +- Cancelling jobs +- Dashboard for admins + +## [3.8.0] - 2022-08-23 + +### 🚀 Features + +- Searxng service + +### 🐛 Bug Fixes + +- Port checker +- Cancel build after 5 seconds +- ExposedPort checker +- Batch secret = +- Dashboard for non-root users +- Stream build logs +- Show build log start/end + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.7.0] - 2022-08-19 + +### 🚀 Features + +- Add GlitchTip service + +### 🐛 Bug Fixes + +- Missing commas +- ExposedPort is just optional + +### ⚙️ Miscellaneous Tasks + +- Add .pnpm-store in .gitignore +- Version++ + +## [3.6.0] - 2022-08-18 + +### 🚀 Features + +- Import public repos (wip) +- Public repo deployment +- Force rebuild + env.PORT for port + public repo build + +### 🐛 Bug Fixes + +- Bots without exposed ports + +### 💼 Other + +- Fixes here and there + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.5.2] - 2022-08-17 + +### 🐛 Bug Fixes + +- Restart containers on-failure instead of always +- Show that Ghost values could be changed + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.5.1] - 2022-08-17 + +### 🐛 Bug Fixes + +- Revert docker compose version to 2.6.1 +- Trim secrets + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.5.0] - 2022-08-17 + +### 🚀 Features + +- Deploy bots (no domains) +- Custom dns servers + +### 🐛 Bug Fixes + +- Dns button ui +- Bot deployments +- Bots +- AutoUpdater & cleanupStorage jobs + +### 💼 Other + +- Typing + +## [3.4.0] - 2022-08-16 + +### 🚀 Features + +- Appwrite service +- Heroku deployments + +### 🐛 Bug Fixes + +- Replace docker compose with docker-compose on CSB +- Dashboard ui +- Create coolify-infra, if it does not exists +- Gitpod conf and heroku buildpacks +- Appwrite +- Autoimport + readme +- Services import +- Heroku icon +- Heroku icon + +## [3.3.4] - 2022-08-15 + +### 🐛 Bug Fixes + +- Make it public button +- Loading indicator + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.3.3] - 2022-08-14 + +### 🐛 Bug Fixes + +- Decryption errors +- Postgresql on ARM + +## [3.3.2] - 2022-08-12 + +### 🐛 Bug Fixes + +- Debounce dashboard status requests + +### 💼 Other + +- Fider + +## [3.3.1] - 2022-08-12 + +### 🐛 Bug Fixes + +- Empty buildpack icons + +## [3.2.3] - 2022-08-12 + +### 🚀 Features + +- Databases on ARM +- Mongodb arm support +- New dashboard + +### 🐛 Bug Fixes + +- Cleanup stucked prisma-engines +- Toast +- Secrets +- Cleanup prisma engine if there is more than 1 +- !isARM to isARM +- Enterprise GH link + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.2.2] - 2022-08-11 + +### 🐛 Bug Fixes + +- Coolify-network on verification + +## [3.2.1] - 2022-08-11 + +### 🚀 Features + +- Init heroku buildpacks + +### 🐛 Bug Fixes + +- Follow/cancel buttons +- Only remove coolify managed containers +- White-labeled env +- Schema + +### 💼 Other + +- Fix + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.2.0] - 2022-08-11 + +### 🚀 Features + +- Persistent storage for all services +- Cleanup clickhouse db + +### 🐛 Bug Fixes + +- Rde local ports +- Empty remote destinations could be removed +- Tips +- Lowercase issues fider +- Tooltip colors +- Update clickhouse configuration +- Cleanup command +- Enterprise Github instance endpoint + +### 💼 Other + +- Local ssh port +- Redesign a lot +- Fixes +- Loading indicator for plausible buttons + +## [3.1.4] - 2022-08-01 + +### 🚀 Features + +- Moodle init +- Remote docker engine init +- Working on remote docker engine +- Rde +- Remote docker engine +- Ipv4 and ipv6 +- Contributors +- Add arch to database +- Stop preview deployment + +### 🐛 Bug Fixes + +- Settings from api +- Selectable destinations +- Gitpod hardcodes +- Typo +- Typo +- Expose port checker +- States and exposed ports +- CleanupStorage +- Remote traefik webhook +- Remote engine ip address +- RemoteipAddress +- Explanation for remote engine url +- Tcp proxy +- Lol +- Webhook +- Dns check for rde +- Gitpod +- Revert last commit +- Dns check +- Dns checker +- Webhook +- Df and more debug +- Webhooks +- Load previews async +- Destination icon +- Pr webhook +- Cache image +- No ssh key found +- Prisma migration + update of docker and stuffs +- Ui +- Ui +- Only 1 ssh-agent is needed +- Reuse ssh connection +- Ssh tunnel +- Dns checking +- Fider BASE_URL set correctly + +### 💼 Other + +- Error message https://github.com/coollabsio/coolify/issues/502 +- Changes +- Settings +- For removing app + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.1.3] - 2022-07-18 + +### 🚀 Features + +- Init moodle and separate stuffs to shared package + +### 🐛 Bug Fixes + +- More types for API +- More types +- Do not rebuild in case image exists and sha not changed +- Gitpod urls +- Remove new service start process +- Remove shared dir, deployment does not work +- Gitlab custom url +- Location url for services and apps + +## [3.1.2] - 2022-07-14 + +### 🐛 Bug Fixes + +- Admin password reset should not timeout +- Message for double branches +- Turn off autodeploy if double branch is configured + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.1.1] - 2022-07-13 + +### 🚀 Features + +- Gitpod integration + +### 🐛 Bug Fixes + +- Cleanup less often and can do it manually + +### ⚙️ Miscellaneous Tasks + +- Version++ +- Version++ + +## [3.1.0] - 2022-07-12 + +### 🚀 Features + +- Ability to change deployment type for nextjs +- Ability to change deployment type for nuxtjs +- Gitpod ready code(almost) +- Add Docker buildpack exposed port setting +- Custom port for git instances + +### 🐛 Bug Fixes + +- GitLab pagination load data +- Service domain checker +- Wp missing ftp solution +- Ftp WP issues +- Ftp?! +- Gitpod updates +- Gitpod +- Gitpod +- Wordpress FTP permission issues +- GitLab search fields +- GitHub App button +- GitLab loop on misconfigured source +- Gitpod + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [3.0.3] - 2022-07-06 + +### 🐛 Bug Fixes + +- Domain check +- Domain check +- TrustProxy for Fastify +- Hostname issue + +## [3.0.2] - 2022-07-06 + +### 🐛 Bug Fixes + +- New destination can be created +- Include post +- New destinations + +## [3.0.1] - 2022-07-06 + +### 🐛 Bug Fixes + +- Seeding +- Forgot that the version bump changed 😅 + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.9.11] - 2022-06-20 + +### 🐛 Bug Fixes + +- Be able to change database + service versions +- Lock file + +## [2.9.10] - 2022-06-17 + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.9.9] - 2022-06-10 + +### 🐛 Bug Fixes + +- Host and reload for uvicorn +- Remove package-lock + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.9.8] - 2022-06-10 + +### 🐛 Bug Fixes + +- Persistent nocodb +- Nocodb persistency + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.9.7] - 2022-06-09 + +### 🐛 Bug Fixes + +- Plausible custom script +- Plausible script and middlewares +- Remove console log +- Remove comments +- Traefik middleware + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.9.6] - 2022-06-02 + +### 🐛 Bug Fixes + +- Fider changed an env variable name +- Pnpm command + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.9.5] - 2022-06-02 + +### 🐛 Bug Fixes + +- Proxy stop missing argument + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.9.4] - 2022-06-01 + +### 🐛 Bug Fixes + +- Demo version forms +- Typo +- Revert gh and gl cloning + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.9.3] - 2022-05-31 + +### 🐛 Bug Fixes + +- Recurisve clone instead of submodule +- Versions +- Only reconfigure coolify proxy if its missconfigured + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.9.2] - 2022-05-31 + +### 🐛 Bug Fixes + +- TrustProxy +- Force restart proxy +- Only restart coolify proxy in case of version prior to 2.9.2 +- Force restart proxy on seeding +- Add GIT ENV variable for submodules + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.9.1] - 2022-05-31 + +### 🐛 Bug Fixes + +- GitHub fixes + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.9.0] - 2022-05-31 + +### 🚀 Features + +- PageLoader +- Database + service usage + +### 🐛 Bug Fixes + +- Service checks +- Remove console.log +- Traefik +- Remove debug things +- WIP Traefik +- Proxy for http +- PR deployments view +- Minio urls + domain checks +- Remove gh token on git source changes +- Do not fetch app state in case of missconfiguration +- Demo instance save domain instantly +- Instant save on demo instance +- New source canceled view +- Lint errors in database services +- Otherfqdns +- Host key verification +- Ftp connection + +### 💼 Other + +- Appwrite +- Testing WS +- Traefik?! +- Traefik +- Traefik +- Traefik migration +- Traefik +- Traefik +- Traefik +- Notifications and application usage +- *(fix)* Traefik +- Css + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.8.2] - 2022-05-16 + +### 🐛 Bug Fixes + +- Gastby buildpack + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.8.1] - 2022-05-10 + +### 🐛 Bug Fixes + +- WP custom db +- UI + +## [2.6.1] - 2022-05-03 + +### 🚀 Features + +- Basic server usage on dashboard +- Show usage trends +- Usage on dashboard +- Custom script path for Plausible +- WP could have custom db +- Python image selection + +### 🐛 Bug Fixes + +- ExposedPorts +- Logos for dbs +- Do not run SSL renew in development +- Check domain for coolify before saving +- Remove debug info +- Cancel jobs +- Cancel old builds in database +- Better DNS check to prevent errors +- Check DNS in prod only +- DNS check +- Disable sentry for now +- Cancel +- Sentry +- No image for Docker buildpack +- Default packagemanager +- Server usage only shown for root team +- Expose ports for services +- UI +- Navbar UI +- UI +- UI +- Remove RC python +- UI +- UI +- UI +- Default Python package + +### ⚙️ Miscellaneous Tasks + +- Version++ +- Version++ +- Version++ +- Version++ + +## [2.6.0] - 2022-05-02 + +### 🚀 Features + +- Hasura as a service +- Gzip compression +- Laravel buildpack is working! +- Laravel +- Fider service +- Database and services logs +- DNS check settings for SSL generation +- Cancel builds! + +### 🐛 Bug Fixes + +- Unami svg size +- Team switching moved to IAM menu +- Always use IP address for webhooks +- Remove unnecessary test endpoint +- UI +- Migration +- Fider envs +- Checking low disk space +- Build image +- Update autoupdate env variable +- Renew certificates +- Webhook build images +- Missing node versions + +### 💼 Other + +- Laravel + +## [2.4.11] - 2022-04-20 + +### 🚀 Features + +- Deno DB migration +- Show exited containers on UI & better UX +- Query container state periodically +- Install svelte-18n and init setup +- Umami service +- Coolify auto-updater +- Autoupdater +- Select base image for buildpacks + +### 🐛 Bug Fixes + +- Deno configurations +- Text on deno buildpack +- Correct branch shown in build logs +- Vscode permission fix +- I18n +- Locales +- Application logs is not reversed and queried better +- Do not activate i18n for now +- GitHub token cleanup on team switch +- No logs found +- Code cleanups +- Reactivate posgtres password +- Contribution guide +- Simplify list services +- Contribution +- Contribution guide +- Contribution guide +- Packagemanager finder + +### 💼 Other + +- Umami service +- Base image selector + +### 📚 Documentation + +- How to add new services +- Update +- Update + +### ⚙️ Miscellaneous Tasks + +- Version++ +- Version++ +- Version++ + +## [2.4.10] - 2022-04-17 + +### 🚀 Features + +- Add persistent storage for services +- Multiply dockerfile locations for docker buildpack +- Testing fluentd logging driver +- Fluentbit investigation +- Initial deno support + +### 🐛 Bug Fixes + +- Switch from bitnami/redis to normal redis +- Use redis-alpine +- Wordpress extra config +- Stop sFTP connection on wp stop +- Change user's id in sftp wp instance +- Use arm based certbot on arm +- Buildlog line number is not string +- Application logs paginated +- Switch to stream on applications logs +- Scroll to top for logs +- Pull new images for services all the time it's started. +- White-labeled custom logo +- Application logs + +### 💼 Other + +- Show extraconfig if wp is running + +### ⚙️ Miscellaneous Tasks + +- Version++ +- Version++ + +## [2.4.9] - 2022-04-14 + +### 🐛 Bug Fixes + +- Postgres root pw is pw field +- Teams view +- Improved tcp proxy monitoring for databases/ftp +- Add HTTP proxy checks +- Loading of new destinations +- Better performance for cleanup images +- Remove proxy container in case of dependent container is down +- Restart local docker coolify proxy in case of something happens to it +- Id of service container + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.4.8] - 2022-04-13 + +### 🐛 Bug Fixes + +- Register should happen if coolify proxy cannot be started +- GitLab typo +- Remove system wide pw reset + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.4.7] - 2022-04-13 + +### 🐛 Bug Fixes + +- Destinations to HAProxy + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.4.6] - 2022-04-13 + +### 🐛 Bug Fixes + +- Cleanup images older than a day +- Meilisearch service +- Load all branches, not just the first 30 +- ProjectID for Github +- DNS check before creating SSL cert +- Try catch me +- Restart policy for resources +- No permission on first registration +- Reverting postgres password for now + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.4.5] - 2022-04-12 + +### 🐛 Bug Fixes + +- Types +- Invitations +- Timeout values + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.4.4] - 2022-04-12 + +### 🐛 Bug Fixes + +- Haproxy build stuffs +- Proxy + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.4.3] - 2022-04-12 + +### 🐛 Bug Fixes + +- Remove unnecessary save button haha +- Update dockerfile + +### ⚙️ Miscellaneous Tasks + +- Update packages +- Version++ +- Update build scripts +- Update build packages + +## [2.4.2] - 2022-04-09 + +### 🐛 Bug Fixes + +- Missing install repositories GitHub +- Return own and other sources better +- Show config missing on sources + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.4.1] - 2022-04-09 + +### 🐛 Bug Fixes + +- Enable https for Ghost +- Postgres root passwor shown and set +- Able to change postgres user password from ui +- DB Connecting string generator + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.4.0] - 2022-04-08 + +### 🚀 Features + +- Wordpress on-demand SFTP +- Finalize on-demand sftp for wp +- PHP Composer support +- Working on-demand sftp to wp data +- Admin team sees everything +- Able to change service version/tag +- Basic white labeled version +- Able to modify database passwords + +### 🐛 Bug Fixes + +- Add openssl to image +- Permission issues +- On-demand sFTP for wp +- Fix for fix haha +- Do not pull latest image +- Updated db versions +- Only show proxy for admin team +- Team view for root team +- Do not trigger >1 webhooks on GitLab +- Possible fix for spikes in CPU usage +- Last commit +- Www or not-www, that's the question +- Fix for the fix that fixes the fix +- Ton of updates for users/teams +- Small typo +- Unique storage paths +- Self-hosted GitLab URL +- No line during buildLog +- Html/apiUrls cannot end with / +- Typo +- Missing buildpack + +### 💼 Other + +- Fix +- Better layout for root team +- Fix +- Fixes +- Fix +- Fix +- Fix +- Fix +- Fix +- Fix +- Fix +- Insane amount +- Fix +- Fixes +- Fixes +- Fix +- Fixes +- Fixes + +### 📚 Documentation + +- Contribution guide + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.3.3] - 2022-04-05 + +### 🐛 Bug Fixes + +- Add git lfs while deploying +- Try to update build status several times +- Update stucked builds +- Update stucked builds on startup +- Revert seed +- Lame fixing +- Remove asyncUntil + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.3.2] - 2022-04-04 + +### 🐛 Bug Fixes + +- *(php)* If .htaccess file found use apache +- Add default webhook domain for n8n + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.3.1] - 2022-04-04 + +### 🐛 Bug Fixes + +- Secrets build/runtime coudl be changed after save +- Default configuration + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.3.0] - 2022-04-04 + +### 🚀 Features + +- Initial python support +- Add loading on register button +- *(dev)* Allow windows users to use pnpm dev +- MeiliSearch service +- Add abilitry to paste env files + +### 🐛 Bug Fixes + +- Ignore coolify proxy error for now +- Python no wsgi +- If user not found +- Rename envs to secrets +- Infinite loop on www domains +- No need to paste clear text env for previews +- Build log fix attempt #1 +- Small UI fix on logs +- Lets await! +- Async progress +- Remove console.log +- Build log +- UI +- Gitlab & Github urls + +### 💼 Other + +- Improvements + +### ⚙️ Miscellaneous Tasks + +- Version++ +- Version++ +- Lock file + fix packages + +## [2.2.7] - 2022-04-01 + +### 🐛 Bug Fixes + +- Haproxy errors +- Build variables +- Use NodeJS for sveltekit for now + +## [2.2.6] - 2022-03-31 + +### 🐛 Bug Fixes + +- Add PROTO headers + +## [2.2.5] - 2022-03-31 + +### 🐛 Bug Fixes + +- Registration enabled/disabled + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.2.4] - 2022-03-31 + +### 🐛 Bug Fixes + +- Gitlab repo url +- No need to dashify anymore + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.2.3] - 2022-03-31 + +### 🐛 Bug Fixes + +- List ghost services +- Reload window on settings saved +- Persistent storage on webhooks +- Add license +- Space in repo names + +### ⚙️ Miscellaneous Tasks + +- Version++ +- Version++ +- Version++ +- Fixed typo on New Git Source view + +## [2.2.0] - 2022-03-27 + +### 🚀 Features + +- Add n8n.io service +- Add update kuma service +- Ghost service + +### 🐛 Bug Fixes + +- Ghost logo size +- Ghost icon, remove console.log + +### 💼 Other + +- Colors on svelte-select + +### ⚙️ Miscellaneous Tasks + +- Version ++ + +## [2.1.1] - 2022-03-25 + +### 🐛 Bug Fixes + +- Cleanup only 2 hours+ old images + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.1.0] - 2022-03-23 + +### 🚀 Features + +- Use compose instead of normal docker cmd +- Be able to redeploy PRs + +### 🐛 Bug Fixes + +- Skip ssl cert in case of error +- Volumes + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.0.31] - 2022-03-20 + +### 🚀 Features + +- Add PHP modules + +### 🐛 Bug Fixes + +- Cleanup old builds +- Only cleanup same app +- Add nginx + htaccess files + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.0.30] - 2022-03-19 + +### 🐛 Bug Fixes + +- No cookie found +- Missing session data +- No error if GitSource is missing +- No webhook secret found? +- Basedir for dockerfiles +- Better queue system + more support on monorepos +- Remove build logs in case of app removed + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.0.29] - 2022-03-11 + +### 🚀 Features + +- Webhooks inititate all applications with the correct branch +- Check ssl for new apps/services first +- Autodeploy pause +- Install pnpm into docker image if pnpm lock file is used + +### 🐛 Bug Fixes + +- Personal Gitlab repos +- Autodeploy true by default for GH repos + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.0.28] - 2022-03-04 + +### 🚀 Features + +- Service secrets + +### 🐛 Bug Fixes + +- Do not error if proxy is not running + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.0.27] - 2022-03-02 + +### 🚀 Features + +- Send version with update request + +### 🐛 Bug Fixes + +- Check when a container is running +- Reload haproxy if new cert is added +- Cleanup coolify images +- Application state in UI + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.0.26] - 2022-03-02 + +### 🐛 Bug Fixes + +- Update process + +## [2.0.25] - 2022-03-02 + +### 🚀 Features + +- Languagetool service + +### 🐛 Bug Fixes + +- Reload proxy on ssl cert +- Volume name + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.0.24] - 2022-03-02 + +### 🐛 Bug Fixes + +- Better proxy check +- Ssl + sslrenew +- Null proxyhash on restart +- Reconfigure proxy on restart +- Update process + +## [2.0.23] - 2022-02-28 + +### 🐛 Bug Fixes + +- Be sure .env exists +- Missing fqdn for services +- Default npm command +- Add coolify-image label for build images +- Cleanup old images, > 3 days + +### 💼 Other + +- Colorful states +- Application start + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.0.22] - 2022-02-27 + +### 🐛 Bug Fixes + +- Coolify image pulls +- Remove wrong/stuck proxy configurations +- Always use a buildpack +- Add icons for eleventy + astro +- Fix proxy every 10 secs +- Do not remove coolify proxy +- Update version + +### 💼 Other + +- Remote docker engine + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.0.21] - 2022-02-24 + +### 🚀 Features + +- Random subdomain for demo +- Random domain for services +- Astro buildpack +- 11ty buildpack +- Registration page + +### 🐛 Bug Fixes + +- Http for demo, oops +- Docker scanner +- Improvement on image pulls + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.0.20] - 2022-02-23 + +### 🐛 Bug Fixes + +- Revert default network + +### 💼 Other + +- Dns check + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.0.19] - 2022-02-23 + +### 🐛 Bug Fixes + +- Random network name for demo +- Settings fqdn grr + +## [2.0.18] - 2022-02-22 + +### 🚀 Features + +- Ports range + +### 🐛 Bug Fixes + +- Email is lowercased in login +- Lowercase email everywhere +- Use normal docker-compose in dev + +### 💼 Other + +- Make copy/password visible + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.0.17] - 2022-02-21 + +### 🐛 Bug Fixes + +- Move tokens from session to cookie/store + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.0.14] - 2022-02-18 + +### 🚀 Features + +- Basic password reset form +- Scan for lock files and set right commands +- Public port range (WIP) + +### 🐛 Bug Fixes + +- SSL app off +- Local docker host +- Typo +- Lets encrypt +- Remove SSL with stop +- SSL off for services +- Grr +- Running state css +- Minor fixes +- Remove force SSL when doing let's encrypt request +- GhToken in session now +- Random port for certbot +- Follow icon +- Plausible volume fixed +- Database connection strings +- Gitlab webhooks fixed +- If DNS not found, do not redirect +- Github token + +### ⚙️ Miscellaneous Tasks + +- Version++ +- Version ++ + +## [2.0.13] - 2022-02-17 + +### 🐛 Bug Fixes + +- Login issues + +## [2.0.11] - 2022-02-15 + +### 🚀 Features + +- Follow logs +- Generate www & non-www SSL certs + +### 🐛 Bug Fixes + +- Window error in SSR +- GitHub sync PR's +- Load more button +- Small fixes +- Typo +- Error with follow logs +- IsDomainConfigured +- TransactionIds +- Coolify image cleanup +- Cleanup every 10 mins +- Cleanup images +- Add no user redis to uri +- Secure cookie disabled by default +- Buggy svelte-kit-cookie-session + +### 💼 Other + +- Only allow cleanup in production + +### ⚙️ Miscellaneous Tasks + +- Version++ +- Version++ + +## [2.0.10] - 2022-02-15 + +### 🐛 Bug Fixes + +- Typo +- Error handling +- Stopping service without proxy +- Coolify proxy start + +### ⚙️ Miscellaneous Tasks + +- Version++ + +## [2.0.8] - 2022-02-14 + +### 🐛 Bug Fixes + +- Validate secrets +- Truncate git clone errors +- Branch used does not throw error + +## [2.0.7] - 2022-02-13 + +### 🚀 Features + +- Www <-> non-www redirection for apps +- Www <-> non-www redirection + +### 🐛 Bug Fixes + +- Package.json +- Build secrets should be visible in runtime +- New secret should have default values + +## [2.0.5] - 2022-02-11 + +### 🚀 Features + +- VaultWarden service + +### 🐛 Bug Fixes + +- PreventDefault on a button, thats all +- Haproxy check should not throw error +- Delete all build files +- Cleanup images +- More error handling in proxy configuration + cleanups +- Local static assets +- Check sentry +- Typo + +### ⚙️ Miscellaneous Tasks + +- Version +- Version + +## [2.0.4] - 2022-02-11 + +### 🚀 Features + +- Use tags in update +- New update process (#115) + +### 🐛 Bug Fixes + +- Docker Engine bug related to live-restore and IPs +- Version + +## [2.0.3] - 2022-02-10 + +### 🐛 Bug Fixes + +- Capture non-error as error +- Only delete id.rsa in case of it exists +- Status is not available yet + +### ⚙️ Miscellaneous Tasks + +- Version bump + +## [2.0.2] - 2022-02-10 + +### 🐛 Bug Fixes + +- Secrets join +- ENV variables set differently + +## [1.0.0] - 2021-03-24 diff --git a/public/svgs/autobase.svg b/public/svgs/autobase.svg new file mode 100644 index 000000000..1ae0493c0 --- /dev/null +++ b/public/svgs/autobase.svg @@ -0,0 +1,3 @@ + + + diff --git a/templates/compose/autobase.yaml b/templates/compose/autobase.yaml new file mode 100644 index 000000000..5ee398f3e --- /dev/null +++ b/templates/compose/autobase.yaml @@ -0,0 +1,59 @@ +# documentation: https://autobase.tech/docs/ +# slogan: Autobase for PostgreSQL® is an open-source alternative to cloud-managed databases (self-hosted DBaaS). +# tags: database, postgres, automation, self-hosted, dbaas +# logo: svgs/autobase.svg +# port: 80 + +services: + autobase: + image: autobase/console_ui:2.4.1 + platform: linux/amd64 + environment: + - SERVICE_FQDN_AUTOBASE_80 + - PG_CONSOLE_AUTHORIZATION_TOKEN=${SERVICE_PASSWORD_UI} + - PG_CONSOLE_API_HOST=autobase-api + healthcheck: + test: [ "CMD", "curl", "http://localhost:80/" ] + interval: 10s + timeout: 5s + retries: 5 + depends_on: + autobase-api: + condition: service_healthy + + autobase-db: + image: autobase/console_db:2.4.1 + platform: linux/amd64 + environment: + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + volumes: + - autobase-db-data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 5s + timeout: 5s + retries: 10 + + autobase-api: + image: autobase/console_api:2.4.1 + platform: linux/amd64 + environment: + - PG_CONSOLE_DB_HOST=autobase-db + - PG_CONSOLE_DB_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - PG_CONSOLE_AUTHORIZATION_TOKEN=${SERVICE_PASSWORD_UI} + - PG_CONSOLE_ENCRYPTIONKEY=${SERVICE_BASE64_ENCRYPTIONKEY} + - PG_CONSOLE_LOGGER_LEVEL=${PG_CONSOLE_LOGGER_LEVEL:-info} + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /tmp/ansible:/tmp/ansible + healthcheck: + test: ["CMD", "curl", "-fsS", + "-H", "accept: application/json", + "-H", "Authorization: Bearer ${SERVICE_PASSWORD_UI}", + "http://localhost:8080/api/v1/version"] + interval: 10s + timeout: 5s + retries: 5 + depends_on: + autobase-db: + condition: service_healthy From fdb7bc5cd292277c3fbc0e8b402e39618c2bc9a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yannik=20S=C3=BC=C3=9F?= Date: Thu, 8 Jan 2026 18:51:23 +0100 Subject: [PATCH 025/191] fix(service): twenty template (#6996) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 🏔️ Peak <122374094+peaklabs-dev@users.noreply.github.com> --- templates/compose/twenty.yaml | 146 ++++++++++++++++++++++------------ 1 file changed, 93 insertions(+), 53 deletions(-) diff --git a/templates/compose/twenty.yaml b/templates/compose/twenty.yaml index 371d280f6..3df15c453 100644 --- a/templates/compose/twenty.yaml +++ b/templates/compose/twenty.yaml @@ -1,4 +1,3 @@ -# ignore: true # documentation: https://docs.twenty.com # slogan: Twenty is a CRM designed to fit your unique business needs. # category: cms @@ -8,86 +7,127 @@ services: twenty: - image: 'twentycrm/twenty:latest' + image: twentycrm/twenty:v1.15 environment: - SERVICE_URL_TWENTY_3000 - - SERVER_URL=$SERVICE_URL_TWENTY - - FRONT_BASE_URL=$SERVICE_URL_TWENTY + - SERVER_URL=${SERVICE_URL_TWENTY} + - FRONT_BASE_URL=${SERVICE_URL_TWENTY} + - APP_SECRET=${SERVICE_BASE64_32_SECRET} - ENABLE_DB_MIGRATIONS=true - - CACHE_STORAGE_TYPE=${CACHE_STORAGE_TYPE:-redis} - - REDIS_URL=redis://redis:6379 - - # https://twenty.com/developers/section/self-hosting/self-hosting-var#security - - API_RATE_LIMITING_TTL=${API_RATE_LIMITING_TTL:-100} - - API_RATE_LIMITING_LIMIT=${API_RATE_LIMITING_LIMIT:-100} - - # https://twenty.com/developers/section/self-hosting/self-hosting-var#tokens - - APP_SECRET=$SERVICE_BASE64_32_SECRET - - POSTGRES_ADMIN_PASSWORD=$SERVICE_PASSWORD_POSTGRES - - PG_DATABASE_URL=postgres://postgres:$SERVICE_PASSWORD_POSTGRES@postgres:5432/default - - # https://twenty.com/developers/section/self-hosting/self-hosting-var#auth - - IS_SIGN_UP_DISABLED=${IS_SIGN_UP_DISABLED:-false} - - PASSWORD_RESET_TOKEN_EXPIRES_IN=${PASSWORD_RESET_TOKEN_EXPIRES_IN:-5m} - - # https://twenty.com/developers/section/self-hosting/self-hosting-var#workspace-cleaning - - WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION=$WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION - - WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION=$WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION - - # https://twenty.com/developers/section/self-hosting/self-hosting-var#captcha - - STORAGE_TYPE=${STORAGE_TYPE:-local} + - 'CACHE_STORAGE_TYPE=${CACHE_STORAGE_TYPE:-redis}' + - 'REDIS_URL=redis://redis:6379' + - 'API_RATE_LIMITING_TTL=${API_RATE_LIMITING_TTL:-100}' + - 'API_RATE_LIMITING_LIMIT=${API_RATE_LIMITING_LIMIT:-100}' + - POSTGRES_ADMIN_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - 'PG_DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB:-twenty-db}' + - 'IS_SIGN_UP_DISABLED=${IS_SIGN_UP_DISABLED:-false}' + - 'PASSWORD_RESET_TOKEN_EXPIRES_IN=${PASSWORD_RESET_TOKEN_EXPIRES_IN:-5m}' + - WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION=${WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION:-7} + - WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION=${WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION:-21} + - 'STORAGE_TYPE=${STORAGE_TYPE:-local}' - STORAGE_S3_REGION=$STORAGE_S3_REGION - STORAGE_S3_NAME=$STORAGE_S3_NAME - STORAGE_S3_ENDPOINT=$STORAGE_S3_ENDPOINT - STORAGE_S3_ACCESS_KEY_ID=$STORAGE_S3_ACCESS_KEY_ID - STORAGE_S3_SECRET_ACCESS_KEY=$STORAGE_S3_SECRET_ACCESS_KEY - - # https://twenty.com/developers/section/self-hosting/self-hosting-var#message-queue - - MESSAGE_QUEUE_TYPE=${MESSAGE_QUEUE_TYPE:-pg-boss} - - # https://twenty.com/developers/section/self-hosting/self-hosting-var#email + - 'MESSAGE_QUEUE_TYPE=${MESSAGE_QUEUE_TYPE:-pg-boss}' - EMAIL_FROM_ADDRESS=$EMAIL_FROM_ADDRESS - EMAIL_FROM_NAME=$EMAIL_FROM_NAME - EMAIL_SYSTEM_ADDRESS=$EMAIL_SYSTEM_ADDRESS - - EMAIL_DRIVER=${EMAIL_DRIVER:-logger} + - 'EMAIL_DRIVER=${EMAIL_DRIVER:-logger}' - EMAIL_SMTP_HOST=$EMAIL_SMTP_HOST - EMAIL_SMTP_PORT=$EMAIL_SMTP_PORT - EMAIL_SMTP_USER=$EMAIL_SMTP_USER - EMAIL_SMTP_PASSWORD=$EMAIL_SMTP_PASSWORD - - # https://twenty.com/developers/section/self-hosting/self-hosting-var#debug-/-development - SIGN_IN_PREFILLED=false - - DEBUG_MODE=${DEBUG_MODE:-false} - - # https://twenty.com/developers/section/self-hosting/self-hosting-var#telemetry - - TELEMETRY_ENABLED=${TELEMETRY_ENABLED:-false} + - 'DEBUG_MODE=${DEBUG_MODE:-false}' + - 'TELEMETRY_ENABLED=${TELEMETRY_ENABLED:-false}' + volumes: + - twenty-local-storage:/app/packages/twenty-server/.local-storage + healthcheck: + test: + - CMD + - curl + - '-f' + - 'http://127.0.0.1:3000/healthz' + interval: 2s + timeout: 5s + retries: 10 + start_period: 10s depends_on: postgres: condition: service_healthy - healthcheck: - test: ["CMD", "curl", "-f", "http://127.0.0.1:3000/healthz"] - interval: 2s - timeout: 10s - retries: 15 - postgres: - image: "twentycrm/twenty-postgres:latest" + + worker: + image: twentycrm/twenty:v1.15 + command: ["yarn", "worker:prod"] + volumes: + - twenty-local-storage:/app/packages/twenty-server/.local-storage environment: - - POSTGRES_USER=postgres - - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES - - POSTGRES_DB=default + - SERVICE_URL_TWENTY_3000 + - SERVER_URL=${SERVICE_URL_TWENTY} + - FRONT_BASE_URL=${SERVICE_URL_TWENTY} + - APP_SECRET=${SERVICE_BASE64_32_SECRET} + - ENABLE_DB_MIGRATIONS=true + - 'CACHE_STORAGE_TYPE=${CACHE_STORAGE_TYPE:-redis}' + - 'REDIS_URL=redis://redis:6379' + - 'API_RATE_LIMITING_TTL=${API_RATE_LIMITING_TTL:-100}' + - 'API_RATE_LIMITING_LIMIT=${API_RATE_LIMITING_LIMIT:-100}' + - POSTGRES_ADMIN_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - 'PG_DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB:-twenty-db}' + - 'IS_SIGN_UP_DISABLED=${IS_SIGN_UP_DISABLED:-false}' + - 'PASSWORD_RESET_TOKEN_EXPIRES_IN=${PASSWORD_RESET_TOKEN_EXPIRES_IN:-5m}' + - WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION=${WORKSPACE_INACTIVE_DAYS_BEFORE_NOTIFICATION:-7} + - WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION=${WORKSPACE_INACTIVE_DAYS_BEFORE_DELETION:-21} + - 'STORAGE_TYPE=${STORAGE_TYPE:-local}' + - STORAGE_S3_REGION=$STORAGE_S3_REGION + - STORAGE_S3_NAME=$STORAGE_S3_NAME + - STORAGE_S3_ENDPOINT=$STORAGE_S3_ENDPOINT + - STORAGE_S3_ACCESS_KEY_ID=$STORAGE_S3_ACCESS_KEY_ID + - STORAGE_S3_SECRET_ACCESS_KEY=$STORAGE_S3_SECRET_ACCESS_KEY + - 'MESSAGE_QUEUE_TYPE=${MESSAGE_QUEUE_TYPE:-pg-boss}' + - EMAIL_FROM_ADDRESS=$EMAIL_FROM_ADDRESS + - EMAIL_FROM_NAME=$EMAIL_FROM_NAME + - EMAIL_SYSTEM_ADDRESS=$EMAIL_SYSTEM_ADDRESS + - 'EMAIL_DRIVER=${EMAIL_DRIVER:-logger}' + - EMAIL_SMTP_HOST=$EMAIL_SMTP_HOST + - EMAIL_SMTP_PORT=$EMAIL_SMTP_PORT + - EMAIL_SMTP_USER=$EMAIL_SMTP_USER + - EMAIL_SMTP_PASSWORD=$EMAIL_SMTP_PASSWORD + - SIGN_IN_PREFILLED=false + - 'DEBUG_MODE=${DEBUG_MODE:-false}' + - 'TELEMETRY_ENABLED=${TELEMETRY_ENABLED:-false}' + - DISABLE_DB_MIGRATIONS=true + - DISABLE_CRON_JOBS_REGISTRATION=true + depends_on: + twenty: + condition: service_healthy + + postgres: + image: postgres:16-alpine + environment: + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB:-twenty-db} volumes: - - pg-data:/bitnami/postgresql + - postgres-data:/var/lib/postgresql/data healthcheck: - test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + test: + - CMD-SHELL + - 'pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}' interval: 5s timeout: 20s retries: 10 + redis: - image: "redis:latest" + image: redis:7-alpine volumes: - - "redis-data:/data" + - redis-data:/data healthcheck: - test: ["CMD", "redis-cli", "ping"] + test: + - CMD + - redis-cli + - ping interval: 5s timeout: 20s retries: 10 From 4e4f3294909d1b050b92d4e9e12c11f0284a042a Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 8 Jan 2026 21:10:17 +0100 Subject: [PATCH 026/191] chore(service): improve uptime kuma - improve uptime kuma healthcheck - rename volume --- templates/compose/uptime-kuma.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/compose/uptime-kuma.yaml b/templates/compose/uptime-kuma.yaml index 4ca0682c7..7291e35c3 100644 --- a/templates/compose/uptime-kuma.yaml +++ b/templates/compose/uptime-kuma.yaml @@ -11,9 +11,9 @@ services: environment: - SERVICE_URL_UPTIMEKUMA_3001 volumes: - - uptime-kuma:/app/data + - uptime-kuma-data:/app/data healthcheck: test: ["CMD-SHELL", "extra/healthcheck"] - interval: 2s - timeout: 10s - retries: 15 + interval: 5s + timeout: 5s + retries: 10 From cf06f43aa02d2397ab330ecb367b23aecabd5dff Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 8 Jan 2026 21:10:43 +0100 Subject: [PATCH 027/191] feat(service): add uptime kuma v2 with mysql --- templates/compose/uptime-kuma-with-mysql.yaml | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 templates/compose/uptime-kuma-with-mysql.yaml diff --git a/templates/compose/uptime-kuma-with-mysql.yaml b/templates/compose/uptime-kuma-with-mysql.yaml new file mode 100644 index 000000000..dffa2f8d2 --- /dev/null +++ b/templates/compose/uptime-kuma-with-mysql.yaml @@ -0,0 +1,38 @@ +# documentation: https://github.com/louislam/uptime-kuma?tab=readme-ov-file +# slogan: Uptime Kuma is a monitoring tool for tracking the status and performance of your applications in real-time. +# category: monitoring +# tags: monitoring, status, performance, web, services, applications, real-time +# logo: svgs/uptime-kuma.svg +# port: 3001 + +services: + uptime-kuma: + image: louislam/uptime-kuma:2 + environment: + - SERVICE_URL_UPTIMEKUMA_3001 + - TZ=${TZ:-Etc/UTC} + volumes: + - uptime-kuma-data:/app/data + healthcheck: + test: ["CMD-SHELL", "extra/healthcheck"] + interval: 5s + timeout: 5s + retries: 10 + depends_on: + mysql: + condition: service_healthy + + mysql: + image: mysql:8 + environment: + - MYSQL_USER=${SERVICE_USER_MYSQL} + - MYSQL_PASSWORD=${SERVICE_PASSWORD_MYSQL} + - MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_ROOT} + - MYSQL_DATABASE=${MYSQL_DATABASE:-uptime-kuma-db} + healthcheck: + test: ["CMD", "mysqladmin", "ping", "-h", "127.0.0.1"] + interval: 5s + timeout: 20s + retries: 10 + volumes: + - mysql-data:/var/lib/mysql From a7894ca20700106322aea33db1155e2ca9e5075a Mon Sep 17 00:00:00 2001 From: Alex Date: Thu, 8 Jan 2026 21:13:56 +0100 Subject: [PATCH 028/191] feat(service): add uptime kuma with mariadb template (#7256) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 🏔️ Peak <122374094+peaklabs-dev@users.noreply.github.com> --- .../compose/uptime-kuma-with-mariadb.yaml | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 templates/compose/uptime-kuma-with-mariadb.yaml diff --git a/templates/compose/uptime-kuma-with-mariadb.yaml b/templates/compose/uptime-kuma-with-mariadb.yaml new file mode 100644 index 000000000..926b2beaa --- /dev/null +++ b/templates/compose/uptime-kuma-with-mariadb.yaml @@ -0,0 +1,38 @@ +# documentation: https://github.com/louislam/uptime-kuma?tab=readme-ov-file +# slogan: Uptime Kuma is a monitoring tool for tracking the status and performance of your applications in real-time. +# category: monitoring +# tags: monitoring, status, performance, web, services, applications, real-time +# logo: svgs/uptime-kuma.svg +# port: 3001 + +services: + uptime-kuma: + image: louislam/uptime-kuma:2 + environment: + - SERVICE_URL_UPTIMEKUMA_3001 + - TZ=${TZ:-Etc/UTC} + volumes: + - uptime-kuma-data:/app/data + healthcheck: + test: ["CMD-SHELL", "extra/healthcheck"] + interval: 5s + timeout: 5s + retries: 10 + depends_on: + mariadb: + condition: service_healthy + + mariadb: + image: mariadb:11 + environment: + - MYSQL_USER=${SERVICE_USER_MARIADB} + - MYSQL_PASSWORD=${SERVICE_PASSWORD_MARIADB} + - MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_ROOT} + - MYSQL_DATABASE=${MYSQL_DATABASE:-uptime-kuma-db} + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + interval: 5s + timeout: 20s + retries: 10 + volumes: + - mariadb-data:/var/lib/mysql From b78c6df7804a571588c62422ebddea95fd9d41f6 Mon Sep 17 00:00:00 2001 From: Stellar Rounin Date: Thu, 8 Jan 2026 14:32:32 -0600 Subject: [PATCH 029/191] feat(service): add calibre web automated with downloader template (#6419) --- .../calibre-web-automated-with-downloader.png | Bin 0 -> 22559 bytes ...calibre-web-automated-book-downloader.yaml | 45 ++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 public/svgs/calibre-web-automated-with-downloader.png create mode 100644 templates/compose/calibre-web-automated-book-downloader.yaml diff --git a/public/svgs/calibre-web-automated-with-downloader.png b/public/svgs/calibre-web-automated-with-downloader.png new file mode 100644 index 0000000000000000000000000000000000000000..758b268223c7d0d87fe0f53b56b833d3a9054035 GIT binary patch literal 22559 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

lkbCZa`t= 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 literal 0 HcmV?d00001 diff --git a/templates/compose/calibre-web-automated-book-downloader.yaml b/templates/compose/calibre-web-automated-book-downloader.yaml new file mode 100644 index 000000000..37f8a2752 --- /dev/null +++ b/templates/compose/calibre-web-automated-book-downloader.yaml @@ -0,0 +1,45 @@ +# documentation: https://github.com/calibrain/calibre-web-automated-book-downloader +# slogan: An intuitive web interface for searching and requesting book downloads, designed to work seamlessly with Calibre-Web-Automated. +# tags: calibre,calibre-web,ebook,library,epub,ereader,kindle,book,reader,download,downloader +# logo: svgs/calibre-web-automated-with-downloader.png +# port: 8083 + +services: + calibre-web-automated: + image: crocodilestick/calibre-web-automated:latest + environment: + - SERVICE_URL_CWA_8083 + - PUID=${PUID:-1000} + - PGID=${PGID:-1000} + - TZ=${TZ:-UTC} + - NETWORK_SHARE_MODE=${NETWORK_SHARE_MODE:-false} + volumes: + - cwa-config:/config + - cwa-book-ingest:/cwa-book-ingest + - calibre-library:/calibre-library + - calibre-plugins:/config/.config/calibre/plugins + healthcheck: + test: + - CMD-SHELL + - 'curl -fs http://localhost:8083 || exit 1' + interval: 30s + timeout: 10s + retries: 3 + start_period: 30s + + calibre-web-downloader: + image: ghcr.io/calibrain/calibre-web-automated-book-downloader:latest + environment: + - SERVICE_URL_DOWNLOADER_8084 + - FLASK_PORT=${FLASK_PORT:-8084} + - LOG_LEVEL=${LOG_LEVEL:-info} + - BOOK_LANGUAGE=${BOOK_LANGUAGE:-en} + - USE_BOOK_TITLE=${USE_BOOK_TITLE:-true} + - TZ=${TZ:-America/New_York} + - APP_ENV=${APP_ENV:-prod} + - UID=${UID:-1000} + - GID=${GID:-100} + - CWA_DB_PATH=${CWA_DB_PATH:-/cwa-config/app.db} + volumes: + - cwa-book-ingest:/cwa-book-ingest + - cwa-config:/cwa-config From d4d6da9328f23b83b0f30b0fd980d746ba162adb Mon Sep 17 00:00:00 2001 From: 4www <1502484+4www@users.noreply.github.com> Date: Thu, 8 Jan 2026 22:11:03 +0100 Subject: [PATCH 030/191] feat(service): improve matrix templates (#7560) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 🏔️ Peak <122374094+peaklabs-dev@users.noreply.github.com> --- .../matrix-synapse-with-postgresql.yaml | 128 +++++++++++++++++ .../compose/matrix-synapse-with-sqlite.yaml | 71 ++++++++++ templates/compose/matrix.yaml | 132 ------------------ 3 files changed, 199 insertions(+), 132 deletions(-) create mode 100644 templates/compose/matrix-synapse-with-postgresql.yaml create mode 100644 templates/compose/matrix-synapse-with-sqlite.yaml delete mode 100644 templates/compose/matrix.yaml diff --git a/templates/compose/matrix-synapse-with-postgresql.yaml b/templates/compose/matrix-synapse-with-postgresql.yaml new file mode 100644 index 000000000..74969c757 --- /dev/null +++ b/templates/compose/matrix-synapse-with-postgresql.yaml @@ -0,0 +1,128 @@ +# documentation: https://element-hq.github.io/synapse/latest/welcome_and_overview.html +# slogan: Chat securely with your family, friends, community, or build great apps with Matrix! +# category: messaging +# tags: chat, slack, discord, voip, video, call, matrix, synapse, postgresql +# logo: svgs/matrix.svg +# port: 8008 + +# IMPORTANT: SYNAPSE_SERVER_NAME is permanent and cannot be changed after first deployment! +# - If hosting at matrix.example.org but want user IDs like @user:example.org, set SYNAPSE_SERVER_NAME=example.org +# - You'll need to set up .well-known delegation at https://example.org/.well-known/matrix/server +# - See: https://element-hq.github.io/synapse/latest/delegate.html + +services: + synapse: + image: matrixdotorg/synapse:latest + environment: + - SERVICE_URL_SYNAPSE_8008 + - SYNAPSE_SERVER_NAME=${SYNAPSE_SERVER_NAME:?} + - SYNAPSE_REPORT_STATS=${SYNAPSE_REPORT_STATS:-no} + - ENABLE_REGISTRATION=${ENABLE_REGISTRATION:-false} + - SERVICE_USER_ADMIN=${SERVICE_USER_ADMIN} + - SERVICE_PASSWORD_ADMIN=${SERVICE_PASSWORD_ADMIN} + - SERVICE_USER_POSTGRESQL=${SERVICE_USER_POSTGRESQL} + - SERVICE_PASSWORD_POSTGRESQL=${SERVICE_PASSWORD_POSTGRESQL} + - POSTGRES_DB=${POSTGRES_DB:-synapse-db} + volumes: + - synapse-data:/data + entrypoint: + - /bin/bash + - -c + - | + ! test -f /data/homeserver.yaml && /start.py generate + + # Extract secrets from generated config + grep "registration_shared_secret" /data/homeserver.yaml \ + | awk '{print $2}' > ./registration_shared_secret + + grep "macaroon_secret_key" /data/homeserver.yaml \ + | awk '{print $2}' > ./macaroon_secret_key + + grep "form_secret" /data/homeserver.yaml \ + | awk '{print $2}' > ./form_secret + + # Create homeserver.yaml with PostgreSQL + cat < /data/homeserver.yaml + server_name: "${SYNAPSE_SERVER_NAME}" + pid_file: /data/homeserver.pid + public_baseurl: "${SERVICE_URL_SYNAPSE}/" + + listeners: + - port: 8008 + tls: false + type: http + x_forwarded: true + bind_addresses: ['0.0.0.0'] + resources: + - names: [client, federation] + compress: false + + database: + name: psycopg2 + args: + user: ${SERVICE_USER_POSTGRESQL} + password: ${SERVICE_PASSWORD_POSTGRESQL} + database: ${POSTGRES_DB:-synapse-db} + host: postgres + port: 5432 + cp_min: 5 + cp_max: 10 + + log_config: "/data/${SYNAPSE_SERVER_NAME}.log.config" + media_store_path: /data/media_store + report_stats: ${SYNAPSE_REPORT_STATS} + + registration_shared_secret: $(<./registration_shared_secret) + macaroon_secret_key: $(<./macaroon_secret_key) + form_secret: $(<./form_secret) + signing_key_path: "/data/${SYNAPSE_SERVER_NAME}.signing.key" + + trusted_key_servers: + - server_name: "matrix.org" + EOF + + [ "${ENABLE_REGISTRATION}" = "true" ] && ! grep "#registration" /data/homeserver.yaml &>/dev/null \ + && echo >> /data/homeserver.yaml \ + && cat <> /data/homeserver.yaml + enable_registration: true + EOF + + # Register admin user if provided + register_admin(){ + while ! curl -sf http://localhost:8008/health > /dev/null; do + sleep 2 + done + register_new_matrix_user \ + -a \ + -u ${SERVICE_USER_ADMIN} \ + -p ${SERVICE_PASSWORD_ADMIN} \ + -c /data/homeserver.yaml \ + http://localhost:8008 &>/dev/null + } + [ -n "${SERVICE_USER_ADMIN}" ] && register_admin & + + /start.py + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8008/health"] + interval: 10s + timeout: 5s + retries: 10 + start_period: 10s + depends_on: + postgres: + condition: service_healthy + + postgres: + image: postgres:16-alpine + environment: + - POSTGRES_USER=${SERVICE_USER_POSTGRESQL} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL} + - POSTGRES_DB=${POSTGRES_DB:-synapse-db} + - POSTGRES_INITDB_ARGS=--encoding=UTF8 --lc-collate=C --lc-ctype=C + volumes: + - postgres-data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB:-synapse-db}"] + interval: 5s + timeout: 5s + retries: 10 diff --git a/templates/compose/matrix-synapse-with-sqlite.yaml b/templates/compose/matrix-synapse-with-sqlite.yaml new file mode 100644 index 000000000..e0884f54d --- /dev/null +++ b/templates/compose/matrix-synapse-with-sqlite.yaml @@ -0,0 +1,71 @@ +# documentation: https://element-hq.github.io/synapse/latest/welcome_and_overview.html +# slogan: Chat securely with your family, friends, community, or build great apps with Matrix! +# category: messaging +# tags: chat,slack,discord,voip,video,call,matrix,synapse,sqlite +# logo: svgs/matrix.svg +# port: 8008 + +# IMPORTANT: SYNAPSE_SERVER_NAME is permanent and cannot be changed after first deployment! +# - If hosting at matrix.example.org but want user IDs like @user:example.org, set SYNAPSE_SERVER_NAME=example.org +# - You'll need to set up .well-known delegation at https://example.org/.well-known/matrix/server +# - See: https://element-hq.github.io/synapse/latest/delegate.html + +services: + synapse: + image: matrixdotorg/synapse:latest + environment: + - SERVICE_URL_SYNAPSE_8008 + - SYNAPSE_SERVER_NAME=${SYNAPSE_SERVER_NAME:?} + - SYNAPSE_REPORT_STATS=${SYNAPSE_REPORT_STATS:-no} + - ENABLE_REGISTRATION=${ENABLE_REGISTRATION:-false} + - SERVICE_USER_ADMIN=${SERVICE_USER_ADMIN} + - SERVICE_PASSWORD_ADMIN=${SERVICE_PASSWORD_ADMIN} + volumes: + - synapse-data:/data + entrypoint: /bin/bash + command: + - -c + - | + # Generate config on first run + if [ ! -f /data/homeserver.yaml ]; then + # Generate default config using SYNAPSE_SERVER_NAME (permanent, used in user IDs) + /start.py generate + + # Set public_baseurl to actual deployment URL (may differ from server_name) + # This allows hosting at matrix.example.org while server_name is example.org + if ! grep -q "public_baseurl" /data/homeserver.yaml; then + sed -i "/^server_name:/a public_baseurl: ${SERVICE_URL_SYNAPSE}/" /data/homeserver.yaml + fi + + # Configure listener for reverse proxy + sed -i 's/bind_addresses: \[.*\]/bind_addresses: ["0.0.0.0"]/' /data/homeserver.yaml + sed -i '/x_forwarded:/d' /data/homeserver.yaml + sed -i '/type: http/a \ x_forwarded: true' /data/homeserver.yaml + + # Enable registration if requested + if [ "${ENABLE_REGISTRATION}" = "true" ] && ! grep -q "enable_registration" /data/homeserver.yaml; then + echo "enable_registration: true" >> /data/homeserver.yaml + fi + fi + + # Register admin user if credentials provided + if [ -n "${SERVICE_USER_ADMIN}" ] && [ -n "${SERVICE_PASSWORD_ADMIN}" ]; then + ( + while ! curl -sf http://localhost:8008/health > /dev/null 2>&1; do + sleep 2 + done + register_new_matrix_user -a \ + -u "${SERVICE_USER_ADMIN}" \ + -p "${SERVICE_PASSWORD_ADMIN}" \ + -c /data/homeserver.yaml \ + http://localhost:8008 2>/dev/null || true + ) & + fi + + exec /start.py + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8008/health"] + interval: 30s + timeout: 10s + retries: 5 + start_period: 20s diff --git a/templates/compose/matrix.yaml b/templates/compose/matrix.yaml deleted file mode 100644 index 09bd81b54..000000000 --- a/templates/compose/matrix.yaml +++ /dev/null @@ -1,132 +0,0 @@ -# documentation: https://matrix.org/docs/chat_basics/matrix-for-im/ -# slogan: Chat securely with your family, friends, community, or build great apps with Matrix! -# category: messaging -# tags: chat,slack,discord,voip,video,call -# logo: svgs/matrix.svg -# port: 8008 - -services: - matrix: - image: matrixdotorg/synapse:latest - environment: - - SERVICE_URL_MATRIX_8008 - - SYNAPSE_SERVER_NAME=${SERVICE_FQDN_MATRIX} - - SYNAPSE_REPORT_STATS=${SYNAPSE_REPORT_STATS:-no} - - ENABLE_REGISTRATION=${ENABLE_REGISTRATION:-false} - - RECAPTCHA_PUBLIC_KEY=${RECAPTCHA_PUBLIC_KEY} - - RECAPTCHA_PRIVATE_KEY=${RECAPTCHA_PRIVATE_KEY} - - _SERVER_NAME=${SERVICE_FQDN_MATRIX} - - _ADMIN_NAME=${SERVICE_USER_ADMIN} - - _ADMIN_PASS=${SERVICE_PASSWORD_ADMIN} - volumes: - - matrix-data:/data - entrypoint: - - /bin/bash - - -c - - | - ! test -f /data/homeserver.yaml && /start.py generate - - # registration_shared_secret - grep "registration_shared_secret" /data/homeserver.yaml \ - | awk '{print $2}' > ./registration_shared_secret - - # macaroon_secret_key - grep "macaroon_secret_key" /data/homeserver.yaml \ - | awk '{print $2}' > ./macaroon_secret_key - - # form_secret - grep "form_secret" /data/homeserver.yaml \ - | awk '{print $2}' > ./form_secret - - ########################## - # # - # homeserver.yaml: start # - # # - ########################## - cat < /data/homeserver.yaml - server_name: "${SERVICE_FQDN_MATRIX}" - pid_file: /data/homeserver.pid - - # server - listeners: - - port: 8008 - tls: false - type: http - x_forwarded: true - resources: - - names: [client, federation] - compress: false - - # database - database: - name: sqlite3 - args: - database: /data/homeserver.db - - # general - log_config: "/data/${SERVICE_FQDN_MATRIX}.log.config" - media_store_path: /data/media_store - report_stats: false - - # secrets - registration_shared_secret: $(<./registration_shared_secret) - macaroon_secret_key: $(<./macaroon_secret_key) - form_secret: $(<./form_secret) - signing_key_path: "/data/${SERVICE_FQDN_MATRIX}.signing.key" - - #rooms - auto_join_rooms: - - "#general:${SERVICE_FQDN_MATRIX}" - - # federation - trusted_key_servers: - - server_name: "matrix.org" - autocreate_auto_join_rooms_federated: false - allow_public_rooms_over_federation: false - EOF - ######################## - # # - # homeserver.yaml: end # - # # - ######################## - - [ "${ENABLE_REGISTRATION}" = "true" ] && ! grep "#registration" /data/homeserver.yaml &>/dev/null \ - && echo >> /data/homeserver.yaml \ - && cat <> /data/homeserver.yaml - #registration - enable_registration: true # Allows users to register on your server. - EOF - - [ -n "${RECAPTCHA_PUBLIC_KEY}" ] && ! grep "${RECAPTCHA_PUBLIC_KEY}" /data/homeserver.yaml &>/dev/null \ - && echo >> /data/homeserver.yaml \ - && cat <> /data/homeserver.yaml - # reCAPTCHA settings - enable_registration_captcha: true # Enables CAPTCHA for registrations. - recaptcha_public_key: "${RECAPTCHA_PUBLIC_KEY}" - recaptcha_private_key: "${RECAPTCHA_PRIVATE_KEY}" - recaptcha_siteverify_api: "https://www.google.com/recaptcha/api/siteverify" - EOF - - register_admin(){ - while ! curl -I localhost:8008 &>/dev/null; do - sleep 1 - done - register_new_matrix_user \ - -a \ - -u ${SERVICE_USER_ADMIN} \ - -p ${SERVICE_PASSWORD_ADMIN} \ - -c /data/homeserver.yaml \ - http://localhost:8008 &>/dev/null - } - register_admin & - - /start.py - healthcheck: - test: - - CMD - - curl - - -I - - localhost:8008 - interval: 5s - timeout: 3s - retries: 5 From 5d4f7a3a0b891535516e057370a7e0bc0a8532a1 Mon Sep 17 00:00:00 2001 From: dgloukhman <57081330+dgloukhman@users.noreply.github.com> Date: Thu, 8 Jan 2026 23:17:05 +0100 Subject: [PATCH 031/191] feat(service): add booklore template (#7838) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 🏔️ Peak <122374094+peaklabs-dev@users.noreply.github.com> --- public/svgs/booklore.svg | 4 +++ templates/compose/booklore.yaml | 48 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 public/svgs/booklore.svg create mode 100644 templates/compose/booklore.yaml diff --git a/public/svgs/booklore.svg b/public/svgs/booklore.svg new file mode 100644 index 000000000..cd8230fa2 --- /dev/null +++ b/public/svgs/booklore.svg @@ -0,0 +1,4 @@ + + + + diff --git a/templates/compose/booklore.yaml b/templates/compose/booklore.yaml new file mode 100644 index 000000000..fddde8de0 --- /dev/null +++ b/templates/compose/booklore.yaml @@ -0,0 +1,48 @@ +# documentation: https://booklore.org/docs/getting-started +# slogan: Booklore is an open-source library management system for your digital book collection. +# tags: media, books, kobo, epub, ebook, KOreader +# logo: svgs/booklore.svg +# port: 80 + +services: + booklore: + image: booklore/booklore:v1.16.5 + environment: + - SERVICE_URL_BOOKLORE_80 + - USER_ID=${BOOKLORE_USER_ID:-0} + - GROUP_ID=${BOOKLORE_GROUP_ID:-0} + - TZ=${TZ:-UTC} + - DATABASE_URL=jdbc:mariadb://mariadb:3306/${MARIADB_DATABASE:-booklore-db} + - DATABASE_USERNAME=${SERVICE_USER_MARIADB} + - DATABASE_PASSWORD=${SERVICE_PASSWORD_MARIADB} + - BOOKLORE_PORT=80 + volumes: + - booklore-data:/app/data + - booklore-books:/books + - type: bind + source: ~/booklore + target: /bookdrop + is_directory: true + healthcheck: + test: "wget --no-verbose --tries=1 --spider http://localhost/login || exit 1" + interval: 10s + timeout: 5s + retries: 10 + depends_on: + mariadb: + condition: service_healthy + + mariadb: + image: mariadb:12 + environment: + - MARIADB_USER=${SERVICE_USER_MARIADB} + - MARIADB_PASSWORD=${SERVICE_PASSWORD_MARIADB} + - MARIADB_ROOT_PASSWORD=${SERVICE_PASSWORD_MARIADBROOT} + - MARIADB_DATABASE=${MARIADB_DATABASE:-booklore-db} + volumes: + - mariadb-data:/var/lib/mysql + healthcheck: + test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] + interval: 10s + timeout: 5s + retries: 10 From 9faa3966a665b05eca3f471a4c600fe1993afe6b Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 8 Jan 2026 23:18:43 +0100 Subject: [PATCH 032/191] chore(services): upgrade service template json files --- templates/service-templates-latest.json | 153 +++++++++++++++++++++++- templates/service-templates.json | 153 +++++++++++++++++++++++- 2 files changed, 294 insertions(+), 12 deletions(-) diff --git a/templates/service-templates-latest.json b/templates/service-templates-latest.json index d5ed6fd29..d86255c1e 100644 --- a/templates/service-templates-latest.json +++ b/templates/service-templates-latest.json @@ -189,6 +189,22 @@ "minversion": "0.0.0", "port": "9000" }, + "autobase": { + "documentation": "https://autobase.tech/docs/?utm_source=coolify.io", + "slogan": "Autobase for PostgreSQL\u00ae is an open-source alternative to cloud-managed databases (self-hosted DBaaS).", + "compose": "c2VydmljZXM6CiAgYXV0b2Jhc2U6CiAgICBpbWFnZTogJ2F1dG9iYXNlL2NvbnNvbGVfdWk6Mi40LjEnCiAgICBwbGF0Zm9ybTogbGludXgvYW1kNjQKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9BVVRPQkFTRV84MAogICAgICAtICdQR19DT05TT0xFX0FVVEhPUklaQVRJT05fVE9LRU49JHtTRVJWSUNFX1BBU1NXT1JEX1VJfScKICAgICAgLSBQR19DT05TT0xFX0FQSV9IT1NUPWF1dG9iYXNlLWFwaQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwLycKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgICBkZXBlbmRzX29uOgogICAgICBhdXRvYmFzZS1hcGk6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICBhdXRvYmFzZS1kYjoKICAgIGltYWdlOiAnYXV0b2Jhc2UvY29uc29sZV9kYjoyLjQuMScKICAgIHBsYXRmb3JtOiBsaW51eC9hbWQ2NAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICB2b2x1bWVzOgogICAgICAtICdhdXRvYmFzZS1kYi1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSBwb3N0Z3JlcycKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgYXV0b2Jhc2UtYXBpOgogICAgaW1hZ2U6ICdhdXRvYmFzZS9jb25zb2xlX2FwaToyLjQuMScKICAgIHBsYXRmb3JtOiBsaW51eC9hbWQ2NAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUEdfQ09OU09MRV9EQl9IT1NUPWF1dG9iYXNlLWRiCiAgICAgIC0gJ1BHX0NPTlNPTEVfREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnUEdfQ09OU09MRV9BVVRIT1JJWkFUSU9OX1RPS0VOPSR7U0VSVklDRV9QQVNTV09SRF9VSX0nCiAgICAgIC0gJ1BHX0NPTlNPTEVfRU5DUllQVElPTktFWT0ke1NFUlZJQ0VfQkFTRTY0X0VOQ1JZUFRJT05LRVl9JwogICAgICAtICdQR19DT05TT0xFX0xPR0dFUl9MRVZFTD0ke1BHX0NPTlNPTEVfTE9HR0VSX0xFVkVMOi1pbmZvfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJy92YXIvcnVuL2RvY2tlci5zb2NrOi92YXIvcnVuL2RvY2tlci5zb2NrJwogICAgICAtICcvdG1wL2Fuc2libGU6L3RtcC9hbnNpYmxlJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZnNTJwogICAgICAgIC0gJy1IJwogICAgICAgIC0gJ2FjY2VwdDogYXBwbGljYXRpb24vanNvbicKICAgICAgICAtICctSCcKICAgICAgICAtICdBdXRob3JpemF0aW9uOiBCZWFyZXIgJHtTRVJWSUNFX1BBU1NXT1JEX1VJfScKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwODAvYXBpL3YxL3ZlcnNpb24nCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogNQogICAgZGVwZW5kc19vbjoKICAgICAgYXV0b2Jhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkK", + "tags": [ + "database", + "postgres", + "automation", + "self-hosted", + "dbaas" + ], + "category": null, + "logo": "svgs/autobase.svg", + "minversion": "0.0.0", + "port": "80" + }, "babybuddy": { "documentation": "https://docs.baby-buddy.net?utm_source=coolify.io", "slogan": "It helps parents track their baby's daily activities, growth, and health with ease.", @@ -263,6 +279,23 @@ "minversion": "0.0.0", "port": "3000" }, + "booklore": { + "documentation": "https://booklore.org/docs/getting-started?utm_source=coolify.io", + "slogan": "Booklore is an open-source library management system for your digital book collection.", + "compose": "c2VydmljZXM6CiAgYm9va2xvcmU6CiAgICBpbWFnZTogJ2Jvb2tsb3JlL2Jvb2tsb3JlOnYxLjE2LjUnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX1VSTF9CT09LTE9SRV84MAogICAgICAtICdVU0VSX0lEPSR7Qk9PS0xPUkVfVVNFUl9JRDotMH0nCiAgICAgIC0gJ0dST1VQX0lEPSR7Qk9PS0xPUkVfR1JPVVBfSUQ6LTB9JwogICAgICAtICdUWj0ke1RaOi1VVEN9JwogICAgICAtICdEQVRBQkFTRV9VUkw9amRiYzptYXJpYWRiOi8vbWFyaWFkYjozMzA2LyR7TUFSSUFEQl9EQVRBQkFTRTotYm9va2xvcmUtZGJ9JwogICAgICAtICdEQVRBQkFTRV9VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9NQVJJQURCfScKICAgICAgLSAnREFUQUJBU0VfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01BUklBREJ9JwogICAgICAtIEJPT0tMT1JFX1BPUlQ9ODAKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2Jvb2tsb3JlLWRhdGE6L2FwcC9kYXRhJwogICAgICAtICdib29rbG9yZS1ib29rczovYm9va3MnCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiB+L2Jvb2tsb3JlCiAgICAgICAgdGFyZ2V0OiAvYm9va2Ryb3AKICAgICAgICBpc19kaXJlY3Rvcnk6IHRydWUKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OiAnd2dldCAtLW5vLXZlcmJvc2UgLS10cmllcz0xIC0tc3BpZGVyIGh0dHA6Ly9sb2NhbGhvc3QvbG9naW4gfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogMTBzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICBkZXBlbmRzX29uOgogICAgICBtYXJpYWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgbWFyaWFkYjoKICAgIGltYWdlOiAnbWFyaWFkYjoxMicKICAgIGVudmlyb25tZW50OgogICAgICAtICdNQVJJQURCX1VTRVI9JHtTRVJWSUNFX1VTRVJfTUFSSUFEQn0nCiAgICAgIC0gJ01BUklBREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01BUklBREJ9JwogICAgICAtICdNQVJJQURCX1JPT1RfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01BUklBREJST09UfScKICAgICAgLSAnTUFSSUFEQl9EQVRBQkFTRT0ke01BUklBREJfREFUQUJBU0U6LWJvb2tsb3JlLWRifScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ21hcmlhZGItZGF0YTovdmFyL2xpYi9teXNxbCcKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBoZWFsdGhjaGVjay5zaAogICAgICAgIC0gJy0tY29ubmVjdCcKICAgICAgICAtICctLWlubm9kYl9pbml0aWFsaXplZCcKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiAxMAo=", + "tags": [ + "media", + "books", + "kobo", + "epub", + "ebook", + "koreader" + ], + "category": null, + "logo": "svgs/booklore.svg", + "minversion": "0.0.0", + "port": "80" + }, "bookstack": { "documentation": "https://www.bookstackapp.com/docs/?utm_source=coolify.io", "slogan": "BookStack is a simple, self-hosted, easy-to-use platform for organising and storing information", @@ -363,6 +396,28 @@ "minversion": "0.0.0", "port": "3000" }, + "calibre-web-automated-book-downloader": { + "documentation": "https://github.com/calibrain/calibre-web-automated-book-downloader?utm_source=coolify.io", + "slogan": "An intuitive web interface for searching and requesting book downloads, designed to work seamlessly with Calibre-Web-Automated.", + "compose": "c2VydmljZXM6CiAgY2FsaWJyZS13ZWItYXV0b21hdGVkOgogICAgaW1hZ2U6ICdjcm9jb2RpbGVzdGljay9jYWxpYnJlLXdlYi1hdXRvbWF0ZWQ6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9VUkxfQ1dBXzgwODMKICAgICAgLSAnUFVJRD0ke1BVSUQ6LTEwMDB9JwogICAgICAtICdQR0lEPSR7UEdJRDotMTAwMH0nCiAgICAgIC0gJ1RaPSR7VFo6LVVUQ30nCiAgICAgIC0gJ05FVFdPUktfU0hBUkVfTU9ERT0ke05FVFdPUktfU0hBUkVfTU9ERTotZmFsc2V9JwogICAgdm9sdW1lczoKICAgICAgLSAnY3dhLWNvbmZpZzovY29uZmlnJwogICAgICAtICdjd2EtYm9vay1pbmdlc3Q6L2N3YS1ib29rLWluZ2VzdCcKICAgICAgLSAnY2FsaWJyZS1saWJyYXJ5Oi9jYWxpYnJlLWxpYnJhcnknCiAgICAgIC0gJ2NhbGlicmUtcGx1Z2luczovY29uZmlnLy5jb25maWcvY2FsaWJyZS9wbHVnaW5zJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdjdXJsIC1mcyBodHRwOi8vbG9jYWxob3N0OjgwODMgfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgICAgIHN0YXJ0X3BlcmlvZDogMzBzCiAgY2FsaWJyZS13ZWItZG93bmxvYWRlcjoKICAgIGltYWdlOiAnZ2hjci5pby9jYWxpYnJhaW4vY2FsaWJyZS13ZWItYXV0b21hdGVkLWJvb2stZG93bmxvYWRlcjpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX1VSTF9ET1dOTE9BREVSXzgwODQKICAgICAgLSAnRkxBU0tfUE9SVD0ke0ZMQVNLX1BPUlQ6LTgwODR9JwogICAgICAtICdMT0dfTEVWRUw9JHtMT0dfTEVWRUw6LWluZm99JwogICAgICAtICdCT09LX0xBTkdVQUdFPSR7Qk9PS19MQU5HVUFHRTotZW59JwogICAgICAtICdVU0VfQk9PS19USVRMRT0ke1VTRV9CT09LX1RJVExFOi10cnVlfScKICAgICAgLSAnVFo9JHtUWjotQW1lcmljYS9OZXdfWW9ya30nCiAgICAgIC0gJ0FQUF9FTlY9JHtBUFBfRU5WOi1wcm9kfScKICAgICAgLSAnVUlEPSR7VUlEOi0xMDAwfScKICAgICAgLSAnR0lEPSR7R0lEOi0xMDB9JwogICAgICAtICdDV0FfREJfUEFUSD0ke0NXQV9EQl9QQVRIOi0vY3dhLWNvbmZpZy9hcHAuZGJ9JwogICAgdm9sdW1lczoKICAgICAgLSAnY3dhLWJvb2staW5nZXN0Oi9jd2EtYm9vay1pbmdlc3QnCiAgICAgIC0gJ2N3YS1jb25maWc6L2N3YS1jb25maWcnCg==", + "tags": [ + "calibre", + "calibre-web", + "ebook", + "library", + "epub", + "ereader", + "kindle", + "book", + "reader", + "download", + "downloader" + ], + "category": null, + "logo": "svgs/calibre-web-automated-with-downloader.png", + "minversion": "0.0.0", + "port": "8083" + }, "calibre-web": { "documentation": "https://github.com/linuxserver/docker-calibre-web?utm_source=coolify.io", "slogan": "Calibre-web is a web app providing a clean interface for browsing, reading and downloading eBooks.", @@ -2456,17 +2511,40 @@ "minversion": "0.0.0", "port": "3000" }, - "matrix": { - "documentation": "https://matrix.org/docs/chat_basics/matrix-for-im/?utm_source=coolify.io", + "matrix-synapse-with-postgresql": { + "documentation": "https://element-hq.github.io/synapse/latest/welcome_and_overview.html?utm_source=coolify.io", "slogan": "Chat securely with your family, friends, community, or build great apps with Matrix!", - "compose": "c2VydmljZXM6CiAgbWF0cml4OgogICAgaW1hZ2U6ICdtYXRyaXhkb3Rvcmcvc3luYXBzZTpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX1VSTF9NQVRSSVhfODAwOAogICAgICAtICdTWU5BUFNFX1NFUlZFUl9OQU1FPSR7U0VSVklDRV9GUUROX01BVFJJWH0nCiAgICAgIC0gJ1NZTkFQU0VfUkVQT1JUX1NUQVRTPSR7U1lOQVBTRV9SRVBPUlRfU1RBVFM6LW5vfScKICAgICAgLSAnRU5BQkxFX1JFR0lTVFJBVElPTj0ke0VOQUJMRV9SRUdJU1RSQVRJT046LWZhbHNlfScKICAgICAgLSAnUkVDQVBUQ0hBX1BVQkxJQ19LRVk9JHtSRUNBUFRDSEFfUFVCTElDX0tFWX0nCiAgICAgIC0gJ1JFQ0FQVENIQV9QUklWQVRFX0tFWT0ke1JFQ0FQVENIQV9QUklWQVRFX0tFWX0nCiAgICAgIC0gJ19TRVJWRVJfTkFNRT0ke1NFUlZJQ0VfRlFETl9NQVRSSVh9JwogICAgICAtICdfQURNSU5fTkFNRT0ke1NFUlZJQ0VfVVNFUl9BRE1JTn0nCiAgICAgIC0gJ19BRE1JTl9QQVNTPSR7U0VSVklDRV9QQVNTV09SRF9BRE1JTn0nCiAgICB2b2x1bWVzOgogICAgICAtICdtYXRyaXgtZGF0YTovZGF0YScKICAgIGVudHJ5cG9pbnQ6CiAgICAgIC0gL2Jpbi9iYXNoCiAgICAgIC0gJy1jJwogICAgICAtICIhIHRlc3QgLWYgL2RhdGEvaG9tZXNlcnZlci55YW1sICYmIC9zdGFydC5weSBnZW5lcmF0ZVxuXG4jIHJlZ2lzdHJhdGlvbl9zaGFyZWRfc2VjcmV0XG5ncmVwIFwicmVnaXN0cmF0aW9uX3NoYXJlZF9zZWNyZXRcIiAvZGF0YS9ob21lc2VydmVyLnlhbWwgXFxcbnwgYXdrICd7cHJpbnQgJDJ9JyA+IC4vcmVnaXN0cmF0aW9uX3NoYXJlZF9zZWNyZXRcblxuIyBtYWNhcm9vbl9zZWNyZXRfa2V5XG5ncmVwIFwibWFjYXJvb25fc2VjcmV0X2tleVwiIC9kYXRhL2hvbWVzZXJ2ZXIueWFtbCBcXFxufCBhd2sgJ3twcmludCAkMn0nID4gLi9tYWNhcm9vbl9zZWNyZXRfa2V5XG5cbiMgZm9ybV9zZWNyZXRcbmdyZXAgXCJmb3JtX3NlY3JldFwiIC9kYXRhL2hvbWVzZXJ2ZXIueWFtbCBcXFxufCBhd2sgJ3twcmludCAkMn0nID4gLi9mb3JtX3NlY3JldFxuXG4jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjI1xuIyAgICAgICAgICAgICAgICAgICAgICAgICNcbiMgaG9tZXNlcnZlci55YW1sOiBzdGFydCAjXG4jICAgICAgICAgICAgICAgICAgICAgICAgI1xuIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyNcbmNhdCA8PEVPRiA+IC9kYXRhL2hvbWVzZXJ2ZXIueWFtbFxuc2VydmVyX25hbWU6IFwiJHtTRVJWSUNFX0ZRRE5fTUFUUklYfVwiXG5waWRfZmlsZTogL2RhdGEvaG9tZXNlcnZlci5waWRcblxuIyBzZXJ2ZXJcbmxpc3RlbmVyczpcbiAgLSBwb3J0OiA4MDA4XG4gICAgdGxzOiBmYWxzZVxuICAgIHR5cGU6IGh0dHBcbiAgICB4X2ZvcndhcmRlZDogdHJ1ZVxuICAgIHJlc291cmNlczpcbiAgICAgIC0gbmFtZXM6IFtjbGllbnQsIGZlZGVyYXRpb25dXG4gICAgICAgIGNvbXByZXNzOiBmYWxzZVxuXG4jIGRhdGFiYXNlXG5kYXRhYmFzZTpcbiAgbmFtZTogc3FsaXRlM1xuICBhcmdzOlxuICAgIGRhdGFiYXNlOiAvZGF0YS9ob21lc2VydmVyLmRiXG5cbiMgZ2VuZXJhbFxubG9nX2NvbmZpZzogXCIvZGF0YS8ke1NFUlZJQ0VfRlFETl9NQVRSSVh9LmxvZy5jb25maWdcIlxubWVkaWFfc3RvcmVfcGF0aDogL2RhdGEvbWVkaWFfc3RvcmVcbnJlcG9ydF9zdGF0czogZmFsc2VcblxuIyBzZWNyZXRzXG5yZWdpc3RyYXRpb25fc2hhcmVkX3NlY3JldDogJCg8Li9yZWdpc3RyYXRpb25fc2hhcmVkX3NlY3JldClcbm1hY2Fyb29uX3NlY3JldF9rZXk6ICQoPC4vbWFjYXJvb25fc2VjcmV0X2tleSlcbmZvcm1fc2VjcmV0OiAkKDwuL2Zvcm1fc2VjcmV0KVxuc2lnbmluZ19rZXlfcGF0aDogXCIvZGF0YS8ke1NFUlZJQ0VfRlFETl9NQVRSSVh9LnNpZ25pbmcua2V5XCJcblxuI3Jvb21zXG5hdXRvX2pvaW5fcm9vbXM6XG4gIC0gXCIjZ2VuZXJhbDoke1NFUlZJQ0VfRlFETl9NQVRSSVh9XCJcblxuIyBmZWRlcmF0aW9uXG50cnVzdGVkX2tleV9zZXJ2ZXJzOlxuICAtIHNlcnZlcl9uYW1lOiBcIm1hdHJpeC5vcmdcIlxuYXV0b2NyZWF0ZV9hdXRvX2pvaW5fcm9vbXNfZmVkZXJhdGVkOiBmYWxzZVxuYWxsb3dfcHVibGljX3Jvb21zX292ZXJfZmVkZXJhdGlvbjogZmFsc2VcbkVPRlxuIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjXG4jICAgICAgICAgICAgICAgICAgICAgICNcbiMgaG9tZXNlcnZlci55YW1sOiBlbmQgI1xuIyAgICAgICAgICAgICAgICAgICAgICAjXG4jIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyNcblxuWyBcIiR7RU5BQkxFX1JFR0lTVFJBVElPTn1cIiA9IFwidHJ1ZVwiIF0gJiYgISBncmVwIFwiI3JlZ2lzdHJhdGlvblwiIC9kYXRhL2hvbWVzZXJ2ZXIueWFtbCAmPi9kZXYvbnVsbCBcXFxuJiYgZWNobyA+PiAvZGF0YS9ob21lc2VydmVyLnlhbWwgXFxcbiYmIGNhdCA8PEVPRiA+PiAvZGF0YS9ob21lc2VydmVyLnlhbWxcbiNyZWdpc3RyYXRpb25cbmVuYWJsZV9yZWdpc3RyYXRpb246IHRydWUgICMgQWxsb3dzIHVzZXJzIHRvIHJlZ2lzdGVyIG9uIHlvdXIgc2VydmVyLlxuRU9GXG5cblsgLW4gXCIke1JFQ0FQVENIQV9QVUJMSUNfS0VZfVwiIF0gJiYgISBncmVwIFwiJHtSRUNBUFRDSEFfUFVCTElDX0tFWX1cIiAvZGF0YS9ob21lc2VydmVyLnlhbWwgJj4vZGV2L251bGwgXFxcbiYmIGVjaG8gPj4gL2RhdGEvaG9tZXNlcnZlci55YW1sIFxcXG4mJiBjYXQgPDxFT0YgPj4gL2RhdGEvaG9tZXNlcnZlci55YW1sXG4jIHJlQ0FQVENIQSBzZXR0aW5nc1xuZW5hYmxlX3JlZ2lzdHJhdGlvbl9jYXB0Y2hhOiB0cnVlICAjIEVuYWJsZXMgQ0FQVENIQSBmb3IgcmVnaXN0cmF0aW9ucy5cbnJlY2FwdGNoYV9wdWJsaWNfa2V5OiBcIiR7UkVDQVBUQ0hBX1BVQkxJQ19LRVl9XCJcbnJlY2FwdGNoYV9wcml2YXRlX2tleTogXCIke1JFQ0FQVENIQV9QUklWQVRFX0tFWX1cIlxucmVjYXB0Y2hhX3NpdGV2ZXJpZnlfYXBpOiBcImh0dHBzOi8vd3d3Lmdvb2dsZS5jb20vcmVjYXB0Y2hhL2FwaS9zaXRldmVyaWZ5XCJcbkVPRlxuXG5yZWdpc3Rlcl9hZG1pbigpe1xuICB3aGlsZSAhIGN1cmwgLUkgbG9jYWxob3N0OjgwMDggJj4vZGV2L251bGw7IGRvXG4gICAgc2xlZXAgMVxuICBkb25lXG4gIHJlZ2lzdGVyX25ld19tYXRyaXhfdXNlciBcXFxuICAgIC1hIFxcXG4gICAgLXUgJHtTRVJWSUNFX1VTRVJfQURNSU59IFxcXG4gICAgLXAgJHtTRVJWSUNFX1BBU1NXT1JEX0FETUlOfSBcXFxuICAgIC1jIC9kYXRhL2hvbWVzZXJ2ZXIueWFtbCBcXFxuICAgIGh0dHA6Ly9sb2NhbGhvc3Q6ODAwOCAmPi9kZXYvbnVsbFxufVxucmVnaXN0ZXJfYWRtaW4gJlxuXG4vc3RhcnQucHlcbiIKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLUknCiAgICAgICAgLSAnbG9jYWxob3N0OjgwMDgnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAzcwogICAgICByZXRyaWVzOiA1Cg==", + "compose": "c2VydmljZXM6CiAgc3luYXBzZToKICAgIGltYWdlOiAnbWF0cml4ZG90b3JnL3N5bmFwc2U6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9VUkxfU1lOQVBTRV84MDA4CiAgICAgIC0gJ1NZTkFQU0VfU0VSVkVSX05BTUU9JHtTWU5BUFNFX1NFUlZFUl9OQU1FOj99JwogICAgICAtICdTWU5BUFNFX1JFUE9SVF9TVEFUUz0ke1NZTkFQU0VfUkVQT1JUX1NUQVRTOi1ub30nCiAgICAgIC0gJ0VOQUJMRV9SRUdJU1RSQVRJT049JHtFTkFCTEVfUkVHSVNUUkFUSU9OOi1mYWxzZX0nCiAgICAgIC0gJ1NFUlZJQ0VfVVNFUl9BRE1JTj0ke1NFUlZJQ0VfVVNFUl9BRE1JTn0nCiAgICAgIC0gJ1NFUlZJQ0VfUEFTU1dPUkRfQURNSU49JHtTRVJWSUNFX1BBU1NXT1JEX0FETUlOfScKICAgICAgLSAnU0VSVklDRV9VU0VSX1BPU1RHUkVTUUw9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVNRTH0nCiAgICAgIC0gJ1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNRTD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNRTH0nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LXN5bmFwc2UtZGJ9JwogICAgdm9sdW1lczoKICAgICAgLSAnc3luYXBzZS1kYXRhOi9kYXRhJwogICAgZW50cnlwb2ludDoKICAgICAgLSAvYmluL2Jhc2gKICAgICAgLSAnLWMnCiAgICAgIC0gIiEgdGVzdCAtZiAvZGF0YS9ob21lc2VydmVyLnlhbWwgJiYgL3N0YXJ0LnB5IGdlbmVyYXRlXG5cbiMgRXh0cmFjdCBzZWNyZXRzIGZyb20gZ2VuZXJhdGVkIGNvbmZpZ1xuZ3JlcCBcInJlZ2lzdHJhdGlvbl9zaGFyZWRfc2VjcmV0XCIgL2RhdGEvaG9tZXNlcnZlci55YW1sIFxcXG58IGF3ayAne3ByaW50ICQyfScgPiAuL3JlZ2lzdHJhdGlvbl9zaGFyZWRfc2VjcmV0XG5cbmdyZXAgXCJtYWNhcm9vbl9zZWNyZXRfa2V5XCIgL2RhdGEvaG9tZXNlcnZlci55YW1sIFxcXG58IGF3ayAne3ByaW50ICQyfScgPiAuL21hY2Fyb29uX3NlY3JldF9rZXlcblxuZ3JlcCBcImZvcm1fc2VjcmV0XCIgL2RhdGEvaG9tZXNlcnZlci55YW1sIFxcXG58IGF3ayAne3ByaW50ICQyfScgPiAuL2Zvcm1fc2VjcmV0XG5cbiMgQ3JlYXRlIGhvbWVzZXJ2ZXIueWFtbCB3aXRoIFBvc3RncmVTUUxcbmNhdCA8PEVPRiA+IC9kYXRhL2hvbWVzZXJ2ZXIueWFtbFxuc2VydmVyX25hbWU6IFwiJHtTWU5BUFNFX1NFUlZFUl9OQU1FfVwiXG5waWRfZmlsZTogL2RhdGEvaG9tZXNlcnZlci5waWRcbnB1YmxpY19iYXNldXJsOiBcIiR7U0VSVklDRV9VUkxfU1lOQVBTRX0vXCJcblxubGlzdGVuZXJzOlxuICAtIHBvcnQ6IDgwMDhcbiAgICB0bHM6IGZhbHNlXG4gICAgdHlwZTogaHR0cFxuICAgIHhfZm9yd2FyZGVkOiB0cnVlXG4gICAgYmluZF9hZGRyZXNzZXM6IFsnMC4wLjAuMCddXG4gICAgcmVzb3VyY2VzOlxuICAgICAgLSBuYW1lczogW2NsaWVudCwgZmVkZXJhdGlvbl1cbiAgICAgICAgY29tcHJlc3M6IGZhbHNlXG5cbmRhdGFiYXNlOlxuICBuYW1lOiBwc3ljb3BnMlxuICBhcmdzOlxuICAgIHVzZXI6ICR7U0VSVklDRV9VU0VSX1BPU1RHUkVTUUx9XG4gICAgcGFzc3dvcmQ6ICR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMfVxuICAgIGRhdGFiYXNlOiAke1BPU1RHUkVTX0RCOi1zeW5hcHNlLWRifVxuICAgIGhvc3Q6IHBvc3RncmVzXG4gICAgcG9ydDogNTQzMlxuICAgIGNwX21pbjogNVxuICAgIGNwX21heDogMTBcblxubG9nX2NvbmZpZzogXCIvZGF0YS8ke1NZTkFQU0VfU0VSVkVSX05BTUV9LmxvZy5jb25maWdcIlxubWVkaWFfc3RvcmVfcGF0aDogL2RhdGEvbWVkaWFfc3RvcmVcbnJlcG9ydF9zdGF0czogJHtTWU5BUFNFX1JFUE9SVF9TVEFUU31cblxucmVnaXN0cmF0aW9uX3NoYXJlZF9zZWNyZXQ6ICQoPC4vcmVnaXN0cmF0aW9uX3NoYXJlZF9zZWNyZXQpXG5tYWNhcm9vbl9zZWNyZXRfa2V5OiAkKDwuL21hY2Fyb29uX3NlY3JldF9rZXkpXG5mb3JtX3NlY3JldDogJCg8Li9mb3JtX3NlY3JldClcbnNpZ25pbmdfa2V5X3BhdGg6IFwiL2RhdGEvJHtTWU5BUFNFX1NFUlZFUl9OQU1FfS5zaWduaW5nLmtleVwiXG5cbnRydXN0ZWRfa2V5X3NlcnZlcnM6XG4gIC0gc2VydmVyX25hbWU6IFwibWF0cml4Lm9yZ1wiXG5FT0ZcblxuWyBcIiR7RU5BQkxFX1JFR0lTVFJBVElPTn1cIiA9IFwidHJ1ZVwiIF0gJiYgISBncmVwIFwiI3JlZ2lzdHJhdGlvblwiIC9kYXRhL2hvbWVzZXJ2ZXIueWFtbCAmPi9kZXYvbnVsbCBcXFxuJiYgZWNobyA+PiAvZGF0YS9ob21lc2VydmVyLnlhbWwgXFxcbiYmIGNhdCA8PEVPRiA+PiAvZGF0YS9ob21lc2VydmVyLnlhbWxcbmVuYWJsZV9yZWdpc3RyYXRpb246IHRydWVcbkVPRlxuXG4jIFJlZ2lzdGVyIGFkbWluIHVzZXIgaWYgcHJvdmlkZWRcbnJlZ2lzdGVyX2FkbWluKCl7XG4gIHdoaWxlICEgY3VybCAtc2YgaHR0cDovL2xvY2FsaG9zdDo4MDA4L2hlYWx0aCA+IC9kZXYvbnVsbDsgZG9cbiAgICBzbGVlcCAyXG4gIGRvbmVcbiAgcmVnaXN0ZXJfbmV3X21hdHJpeF91c2VyIFxcXG4gICAgLWEgXFxcbiAgICAtdSAke1NFUlZJQ0VfVVNFUl9BRE1JTn0gXFxcbiAgICAtcCAke1NFUlZJQ0VfUEFTU1dPUkRfQURNSU59IFxcXG4gICAgLWMgL2RhdGEvaG9tZXNlcnZlci55YW1sIFxcXG4gICAgaHR0cDovL2xvY2FsaG9zdDo4MDA4ICY+L2Rldi9udWxsXG59XG5bIC1uIFwiJHtTRVJWSUNFX1VTRVJfQURNSU59XCIgXSAmJiByZWdpc3Rlcl9hZG1pbiAmXG5cbi9zdGFydC5weVxuIgogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwMDgvaGVhbHRoJwogICAgICBpbnRlcnZhbDogMTBzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICAgIHN0YXJ0X3BlcmlvZDogMTBzCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3JlczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogIHBvc3RncmVzOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNi1hbHBpbmUnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU1FMfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTUUx9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1zeW5hcHNlLWRifScKICAgICAgLSAnUE9TVEdSRVNfSU5JVERCX0FSR1M9LS1lbmNvZGluZz1VVEY4IC0tbGMtY29sbGF0ZT1DIC0tbGMtY3R5cGU9QycKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Bvc3RncmVzLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCOi1zeW5hcHNlLWRifScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCg==", "tags": [ "chat", "slack", "discord", "voip", "video", - "call" + "call", + "matrix", + "synapse", + "postgresql" + ], + "category": "messaging", + "logo": "svgs/matrix.svg", + "minversion": "0.0.0", + "port": "8008" + }, + "matrix-synapse-with-sqlite": { + "documentation": "https://element-hq.github.io/synapse/latest/welcome_and_overview.html?utm_source=coolify.io", + "slogan": "Chat securely with your family, friends, community, or build great apps with Matrix!", + "compose": "c2VydmljZXM6CiAgc3luYXBzZToKICAgIGltYWdlOiAnbWF0cml4ZG90b3JnL3N5bmFwc2U6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9VUkxfU1lOQVBTRV84MDA4CiAgICAgIC0gJ1NZTkFQU0VfU0VSVkVSX05BTUU9JHtTWU5BUFNFX1NFUlZFUl9OQU1FOj99JwogICAgICAtICdTWU5BUFNFX1JFUE9SVF9TVEFUUz0ke1NZTkFQU0VfUkVQT1JUX1NUQVRTOi1ub30nCiAgICAgIC0gJ0VOQUJMRV9SRUdJU1RSQVRJT049JHtFTkFCTEVfUkVHSVNUUkFUSU9OOi1mYWxzZX0nCiAgICAgIC0gJ1NFUlZJQ0VfVVNFUl9BRE1JTj0ke1NFUlZJQ0VfVVNFUl9BRE1JTn0nCiAgICAgIC0gJ1NFUlZJQ0VfUEFTU1dPUkRfQURNSU49JHtTRVJWSUNFX1BBU1NXT1JEX0FETUlOfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3N5bmFwc2UtZGF0YTovZGF0YScKICAgIGVudHJ5cG9pbnQ6IC9iaW4vYmFzaAogICAgY29tbWFuZDoKICAgICAgLSAnLWMnCiAgICAgIC0gIiMgR2VuZXJhdGUgY29uZmlnIG9uIGZpcnN0IHJ1blxuaWYgWyAhIC1mIC9kYXRhL2hvbWVzZXJ2ZXIueWFtbCBdOyB0aGVuXG4gICMgR2VuZXJhdGUgZGVmYXVsdCBjb25maWcgdXNpbmcgU1lOQVBTRV9TRVJWRVJfTkFNRSAocGVybWFuZW50LCB1c2VkIGluIHVzZXIgSURzKVxuICAvc3RhcnQucHkgZ2VuZXJhdGVcblxuICAjIFNldCBwdWJsaWNfYmFzZXVybCB0byBhY3R1YWwgZGVwbG95bWVudCBVUkwgKG1heSBkaWZmZXIgZnJvbSBzZXJ2ZXJfbmFtZSlcbiAgIyBUaGlzIGFsbG93cyBob3N0aW5nIGF0IG1hdHJpeC5leGFtcGxlLm9yZyB3aGlsZSBzZXJ2ZXJfbmFtZSBpcyBleGFtcGxlLm9yZ1xuICBpZiAhIGdyZXAgLXEgXCJwdWJsaWNfYmFzZXVybFwiIC9kYXRhL2hvbWVzZXJ2ZXIueWFtbDsgdGhlblxuICAgIHNlZCAtaSBcIi9ec2VydmVyX25hbWU6L2EgcHVibGljX2Jhc2V1cmw6ICR7U0VSVklDRV9VUkxfU1lOQVBTRX0vXCIgL2RhdGEvaG9tZXNlcnZlci55YW1sXG4gIGZpXG5cbiAgIyBDb25maWd1cmUgbGlzdGVuZXIgZm9yIHJldmVyc2UgcHJveHlcbiAgc2VkIC1pICdzL2JpbmRfYWRkcmVzc2VzOiBcXFsuKlxcXS9iaW5kX2FkZHJlc3NlczogW1wiMC4wLjAuMFwiXS8nIC9kYXRhL2hvbWVzZXJ2ZXIueWFtbFxuICBzZWQgLWkgJy94X2ZvcndhcmRlZDovZCcgL2RhdGEvaG9tZXNlcnZlci55YW1sXG4gIHNlZCAtaSAnL3R5cGU6IGh0dHAvYSBcXCAgICB4X2ZvcndhcmRlZDogdHJ1ZScgL2RhdGEvaG9tZXNlcnZlci55YW1sXG5cbiAgIyBFbmFibGUgcmVnaXN0cmF0aW9uIGlmIHJlcXVlc3RlZFxuICBpZiBbIFwiJHtFTkFCTEVfUkVHSVNUUkFUSU9OfVwiID0gXCJ0cnVlXCIgXSAmJiAhIGdyZXAgLXEgXCJlbmFibGVfcmVnaXN0cmF0aW9uXCIgL2RhdGEvaG9tZXNlcnZlci55YW1sOyB0aGVuXG4gICAgZWNobyBcImVuYWJsZV9yZWdpc3RyYXRpb246IHRydWVcIiA+PiAvZGF0YS9ob21lc2VydmVyLnlhbWxcbiAgZmlcbmZpXG5cbiMgUmVnaXN0ZXIgYWRtaW4gdXNlciBpZiBjcmVkZW50aWFscyBwcm92aWRlZFxuaWYgWyAtbiBcIiR7U0VSVklDRV9VU0VSX0FETUlOfVwiIF0gJiYgWyAtbiBcIiR7U0VSVklDRV9QQVNTV09SRF9BRE1JTn1cIiBdOyB0aGVuXG4gIChcbiAgICB3aGlsZSAhIGN1cmwgLXNmIGh0dHA6Ly9sb2NhbGhvc3Q6ODAwOC9oZWFsdGggPiAvZGV2L251bGwgMj4mMTsgZG9cbiAgICAgIHNsZWVwIDJcbiAgICBkb25lXG4gICAgcmVnaXN0ZXJfbmV3X21hdHJpeF91c2VyIC1hIFxcXG4gICAgICAtdSBcIiR7U0VSVklDRV9VU0VSX0FETUlOfVwiIFxcXG4gICAgICAtcCBcIiR7U0VSVklDRV9QQVNTV09SRF9BRE1JTn1cIiBcXFxuICAgICAgLWMgL2RhdGEvaG9tZXNlcnZlci55YW1sIFxcXG4gICAgICBodHRwOi8vbG9jYWxob3N0OjgwMDggMj4vZGV2L251bGwgfHwgdHJ1ZVxuICApICZcbmZpXG5cbmV4ZWMgL3N0YXJ0LnB5XG4iCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly9sb2NhbGhvc3Q6ODAwOC9oZWFsdGgnCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDUKICAgICAgc3RhcnRfcGVyaW9kOiAyMHMK", + "tags": [ + "chat", + "slack", + "discord", + "voip", + "video", + "call", + "matrix", + "synapse", + "sqlite" ], "category": "messaging", "logo": "svgs/matrix.svg", @@ -3844,6 +3922,19 @@ "minversion": "0.0.0", "port": "8080" }, + "redmine": { + "documentation": "https://www.redmine.org/?utm_source=coolify.io", + "slogan": "Redmine is a flexible project management web application. Written using the Ruby on Rails framework, it is cross-platform and cross-database.", + "compose": "c2VydmljZXM6CiAgcmVkbWluZToKICAgIGltYWdlOiAncmVkbWluZTo2LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9SRURNSU5FXzMwMDAKICAgICAgLSAnU0VDUkVUX0tFWV9CQVNFPSR7U0VSVklDRV9QQVNTV09SRF82NF9SRURNSU5FfScKICAgICAgLSBSRURNSU5FX0RCX1BPU1RHUkVTPXBvc3RncmVzcWwKICAgICAgLSBSRURNSU5FX0RCX1BPUlQ9NTQzMgogICAgICAtICdSRURNSU5FX0RCX1VTRVJOQU1FPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUkVETUlORV9EQl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfNjRfUE9TVEdSRVN9JwogICAgICAtICdSRURNSU5FX0RCX0RBVEFCQVNFPSR7UE9TVEdSRVNfREFUQUJBU0U6LXJlZG1pbmUtZGJ9JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICd3Z2V0IC1xTy0gaHR0cDovLzEyNy4wLjAuMTozMDAwLycKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDUKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3JlZG1pbmUtY29uZmlnOi91c3Ivc3JjL3JlZG1pbmUvY29uZmlnJwogICAgICAtICdyZWRtaW5lLWZpbGVzOi91c3Ivc3JjL3JlZG1pbmUvZmlsZXMnCiAgICAgIC0gJ3JlZG1pbmUtdGhlbWVzOi91c3Ivc3JjL3JlZG1pbmUvdGhlbWVzJwogICAgICAtICdyZWRtaW5lLXBsdWdpbnM6L3Vzci9zcmMvcmVkbWluZS9wbHVnaW5zJwogICAgZGVwZW5kc19vbjoKICAgICAgcG9zdGdyZXNxbDoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogIHBvc3RncmVzcWw6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE3LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQVRBQkFTRTotcmVkbWluZS1kYn0nCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0Z3Jlc3FsLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDUK", + "tags": [ + "redmine", + "project management" + ], + "category": null, + "logo": "svgs/redmine.svg", + "minversion": "0.0.0", + "port": "3000" + }, "rivet-engine": { "documentation": "https://www.rivet.dev/docs?utm_source=coolify.io", "slogan": "Build and scale stateful workloads with long-lived processes", @@ -4195,7 +4286,7 @@ "supabase": { "documentation": "https://supabase.io?utm_source=coolify.io", "slogan": "The open source Firebase alternative.", - "compose": "c2VydmljZXM6CiAgc3VwYWJhc2Uta29uZzoKICAgIGltYWdlOiAna29uZzoyLjguMScKICAgIGVudHJ5cG9pbnQ6ICdiYXNoIC1jICcnZXZhbCAiZWNobyBcIiQkKGNhdCB+L3RlbXAueW1sKVwiIiA+IH4va29uZy55bWwgJiYgL2RvY2tlci1lbnRyeXBvaW50LnNoIGtvbmcgZG9ja2VyLXN0YXJ0JycnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfVVJMX1NVUEFCQVNFS09OR184MDAwCiAgICAgIC0gJ0tPTkdfUE9SVF9NQVBTPTQ0Mzo4MDAwJwogICAgICAtICdKV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtIEtPTkdfREFUQUJBU0U9b2ZmCiAgICAgIC0gS09OR19ERUNMQVJBVElWRV9DT05GSUc9L2hvbWUva29uZy9rb25nLnltbAogICAgICAtICdLT05HX0ROU19PUkRFUj1MQVNULEEsQ05BTUUnCiAgICAgIC0gJ0tPTkdfUExVR0lOUz1yZXF1ZXN0LXRyYW5zZm9ybWVyLGNvcnMsa2V5LWF1dGgsYWNsLGJhc2ljLWF1dGgnCiAgICAgIC0gS09OR19OR0lOWF9QUk9YWV9QUk9YWV9CVUZGRVJfU0laRT0xNjBrCiAgICAgIC0gJ0tPTkdfTkdJTlhfUFJPWFlfUFJPWFlfQlVGRkVSUz02NCAxNjBrJwogICAgICAtICdTVVBBQkFTRV9BTk9OX0tFWT0ke1NFUlZJQ0VfU1VQQUJBU0VBTk9OX0tFWX0nCiAgICAgIC0gJ1NVUEFCQVNFX1NFUlZJQ0VfS0VZPSR7U0VSVklDRV9TVVBBQkFTRVNFUlZJQ0VfS0VZfScKICAgICAgLSAnREFTSEJPQVJEX1VTRVJOQU1FPSR7U0VSVklDRV9VU0VSX0FETUlOfScKICAgICAgLSAnREFTSEJPQVJEX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9BRE1JTn0nCiAgICB2b2x1bWVzOgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2FwaS9rb25nLnltbAogICAgICAgIHRhcmdldDogL2hvbWUva29uZy90ZW1wLnltbAogICAgICAgIGNvbnRlbnQ6ICJfZm9ybWF0X3ZlcnNpb246ICcyLjEnXG5fdHJhbnNmb3JtOiB0cnVlXG5cbiMjI1xuIyMjIENvbnN1bWVycyAvIFVzZXJzXG4jIyNcbmNvbnN1bWVyczpcbiAgLSB1c2VybmFtZTogREFTSEJPQVJEXG4gIC0gdXNlcm5hbWU6IGFub25cbiAgICBrZXlhdXRoX2NyZWRlbnRpYWxzOlxuICAgICAgLSBrZXk6ICRTVVBBQkFTRV9BTk9OX0tFWVxuICAtIHVzZXJuYW1lOiBzZXJ2aWNlX3JvbGVcbiAgICBrZXlhdXRoX2NyZWRlbnRpYWxzOlxuICAgICAgLSBrZXk6ICRTVVBBQkFTRV9TRVJWSUNFX0tFWVxuXG4jIyNcbiMjIyBBY2Nlc3MgQ29udHJvbCBMaXN0XG4jIyNcbmFjbHM6XG4gIC0gY29uc3VtZXI6IGFub25cbiAgICBncm91cDogYW5vblxuICAtIGNvbnN1bWVyOiBzZXJ2aWNlX3JvbGVcbiAgICBncm91cDogYWRtaW5cblxuIyMjXG4jIyMgRGFzaGJvYXJkIGNyZWRlbnRpYWxzXG4jIyNcbmJhc2ljYXV0aF9jcmVkZW50aWFsczpcbi0gY29uc3VtZXI6IERBU0hCT0FSRFxuICB1c2VybmFtZTogJERBU0hCT0FSRF9VU0VSTkFNRVxuICBwYXNzd29yZDogJERBU0hCT0FSRF9QQVNTV09SRFxuXG5cbiMjI1xuIyMjIEFQSSBSb3V0ZXNcbiMjI1xuc2VydmljZXM6XG5cbiAgIyMgT3BlbiBBdXRoIHJvdXRlc1xuICAtIG5hbWU6IGF1dGgtdjEtb3BlblxuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS92ZXJpZnlcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGF1dGgtdjEtb3BlblxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2F1dGgvdjEvdmVyaWZ5XG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAtIG5hbWU6IGF1dGgtdjEtb3Blbi1jYWxsYmFja1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS9jYWxsYmFja1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogYXV0aC12MS1vcGVuLWNhbGxiYWNrXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvYXV0aC92MS9jYWxsYmFja1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgLSBuYW1lOiBhdXRoLXYxLW9wZW4tYXV0aG9yaXplXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtYXV0aDo5OTk5L2F1dGhvcml6ZVxuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogYXV0aC12MS1vcGVuLWF1dGhvcml6ZVxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2F1dGgvdjEvYXV0aG9yaXplXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuXG4gICMjIFNlY3VyZSBBdXRoIHJvdXRlc1xuICAtIG5hbWU6IGF1dGgtdjFcbiAgICBfY29tbWVudDogJ0dvVHJ1ZTogL2F1dGgvdjEvKiAtPiBodHRwOi8vc3VwYWJhc2UtYXV0aDo5OTk5LyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtYXV0aDo5OTk5L1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogYXV0aC12MS1hbGxcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9hdXRoL3YxL1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgICAgIC0gbmFtZToga2V5LWF1dGhcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfY3JlZGVudGlhbHM6IGZhbHNlXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG4gICAgICAgICAgICAtIGFub25cblxuICAjIyBTZWN1cmUgUkVTVCByb3V0ZXNcbiAgLSBuYW1lOiByZXN0LXYxXG4gICAgX2NvbW1lbnQ6ICdQb3N0Z1JFU1Q6IC9yZXN0L3YxLyogLT4gaHR0cDovL3N1cGFiYXNlLXJlc3Q6MzAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLXJlc3Q6MzAwMC9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IHJlc3QtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvcmVzdC92MS9cbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gICAgICAtIG5hbWU6IGtleS1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiB0cnVlXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG4gICAgICAgICAgICAtIGFub25cblxuICAjIyBTZWN1cmUgR3JhcGhRTCByb3V0ZXNcbiAgLSBuYW1lOiBncmFwaHFsLXYxXG4gICAgX2NvbW1lbnQ6ICdQb3N0Z1JFU1Q6IC9ncmFwaHFsL3YxLyogLT4gaHR0cDovL3N1cGFiYXNlLXJlc3Q6MzAwMC9ycGMvZ3JhcGhxbCdcbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1yZXN0OjMwMDAvcnBjL2dyYXBocWxcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGdyYXBocWwtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvZ3JhcGhxbC92MVxuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgICAgIC0gbmFtZToga2V5LWF1dGhcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfY3JlZGVudGlhbHM6IHRydWVcbiAgICAgIC0gbmFtZTogcmVxdWVzdC10cmFuc2Zvcm1lclxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgYWRkOlxuICAgICAgICAgICAgaGVhZGVyczpcbiAgICAgICAgICAgICAgLSBDb250ZW50LVByb2ZpbGU6Z3JhcGhxbF9wdWJsaWNcbiAgICAgIC0gbmFtZTogYWNsXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2dyb3Vwc19oZWFkZXI6IHRydWVcbiAgICAgICAgICBhbGxvdzpcbiAgICAgICAgICAgIC0gYWRtaW5cbiAgICAgICAgICAgIC0gYW5vblxuXG4gICMjIFNlY3VyZSBSZWFsdGltZSByb3V0ZXNcbiAgLSBuYW1lOiByZWFsdGltZS12MS13c1xuICAgIF9jb21tZW50OiAnUmVhbHRpbWU6IC9yZWFsdGltZS92MS8qIC0+IHdzOi8vcmVhbHRpbWU6NDAwMC9zb2NrZXQvKidcbiAgICB1cmw6IGh0dHA6Ly9yZWFsdGltZS1kZXY6NDAwMC9zb2NrZXRcbiAgICBwcm90b2NvbDogd3NcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IHJlYWx0aW1lLXYxLXdzXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvcmVhbHRpbWUvdjEvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAgICAgLSBuYW1lOiBrZXktYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogZmFsc2VcbiAgICAgIC0gbmFtZTogYWNsXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2dyb3Vwc19oZWFkZXI6IHRydWVcbiAgICAgICAgICBhbGxvdzpcbiAgICAgICAgICAgIC0gYWRtaW5cbiAgICAgICAgICAgIC0gYW5vblxuICAtIG5hbWU6IHJlYWx0aW1lLXYxLXJlc3RcbiAgICBfY29tbWVudDogJ1JlYWx0aW1lOiAvcmVhbHRpbWUvdjEvKiAtPiB3czovL3JlYWx0aW1lOjQwMDAvc29ja2V0LyonXG4gICAgdXJsOiBodHRwOi8vcmVhbHRpbWUtZGV2OjQwMDAvYXBpXG4gICAgcHJvdG9jb2w6IGh0dHBcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IHJlYWx0aW1lLXYxLXJlc3RcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9yZWFsdGltZS92MS9hcGlcbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gICAgICAtIG5hbWU6IGtleS1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiBmYWxzZVxuICAgICAgLSBuYW1lOiBhY2xcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfZ3JvdXBzX2hlYWRlcjogdHJ1ZVxuICAgICAgICAgIGFsbG93OlxuICAgICAgICAgICAgLSBhZG1pblxuICAgICAgICAgICAgLSBhbm9uXG5cbiAgIyMgU3RvcmFnZSByb3V0ZXM6IHRoZSBzdG9yYWdlIHNlcnZlciBtYW5hZ2VzIGl0cyBvd24gYXV0aFxuICAtIG5hbWU6IHN0b3JhZ2UtdjFcbiAgICBfY29tbWVudDogJ1N0b3JhZ2U6IC9zdG9yYWdlL3YxLyogLT4gaHR0cDovL3N1cGFiYXNlLXN0b3JhZ2U6NTAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLXN0b3JhZ2U6NTAwMC9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IHN0b3JhZ2UtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvc3RvcmFnZS92MS9cbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG5cbiAgIyMgRWRnZSBGdW5jdGlvbnMgcm91dGVzXG4gIC0gbmFtZTogZnVuY3Rpb25zLXYxXG4gICAgX2NvbW1lbnQ6ICdFZGdlIEZ1bmN0aW9uczogL2Z1bmN0aW9ucy92MS8qIC0+IGh0dHA6Ly9zdXBhYmFzZS1lZGdlLWZ1bmN0aW9uczo5MDAwLyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtZWRnZS1mdW5jdGlvbnM6OTAwMC9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGZ1bmN0aW9ucy12MS1hbGxcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9mdW5jdGlvbnMvdjEvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuXG4gICMjIEFuYWx5dGljcyByb3V0ZXNcbiAgLSBuYW1lOiBhbmFseXRpY3MtdjFcbiAgICBfY29tbWVudDogJ0FuYWx5dGljczogL2FuYWx5dGljcy92MS8qIC0+IGh0dHA6Ly9sb2dmbGFyZTo0MDAwLyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBhbmFseXRpY3MtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvYW5hbHl0aWNzL3YxL1xuXG4gICMjIFNlY3VyZSBEYXRhYmFzZSByb3V0ZXNcbiAgLSBuYW1lOiBtZXRhXG4gICAgX2NvbW1lbnQ6ICdwZy1tZXRhOiAvcGcvKiAtPiBodHRwOi8vc3VwYWJhc2UtbWV0YTo4MDgwLyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtbWV0YTo4MDgwL1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogbWV0YS1hbGxcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9wZy9cbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBrZXktYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogZmFsc2VcbiAgICAgIC0gbmFtZTogYWNsXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2dyb3Vwc19oZWFkZXI6IHRydWVcbiAgICAgICAgICBhbGxvdzpcbiAgICAgICAgICAgIC0gYWRtaW5cblxuICAjIyBQcm90ZWN0ZWQgRGFzaGJvYXJkIC0gY2F0Y2ggYWxsIHJlbWFpbmluZyByb3V0ZXNcbiAgLSBuYW1lOiBkYXNoYm9hcmRcbiAgICBfY29tbWVudDogJ1N0dWRpbzogLyogLT4gaHR0cDovL3N0dWRpbzozMDAwLyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2Utc3R1ZGlvOjMwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBkYXNoYm9hcmQtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAgICAgLSBuYW1lOiBiYXNpYy1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiB0cnVlXG4iCiAgc3VwYWJhc2Utc3R1ZGlvOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9zdHVkaW86MjAyNS4xMi4xNy1zaGEtNDNmNGY3ZicKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBub2RlCiAgICAgICAgLSAnLWUnCiAgICAgICAgLSAiZmV0Y2goJ2h0dHA6Ly8xMjcuMC4wLjE6MzAwMC9hcGkvcGxhdGZvcm0vcHJvZmlsZScpLnRoZW4oKHIpID0+IHtpZiAoci5zdGF0dXMgIT09IDIwMCkgdGhyb3cgbmV3IEVycm9yKHIuc3RhdHVzKX0pIgogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBIT1NUTkFNRT0wLjAuMC4wCiAgICAgIC0gJ1NUVURJT19QR19NRVRBX1VSTD1odHRwOi8vc3VwYWJhc2UtbWV0YTo4MDgwJwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdERUZBVUxUX09SR0FOSVpBVElPTl9OQU1FPSR7U1RVRElPX0RFRkFVTFRfT1JHQU5JWkFUSU9OOi1EZWZhdWx0IE9yZ2FuaXphdGlvbn0nCiAgICAgIC0gJ0RFRkFVTFRfUFJPSkVDVF9OQU1FPSR7U1RVRElPX0RFRkFVTFRfUFJPSkVDVDotRGVmYXVsdCBQcm9qZWN0fScKICAgICAgLSAnU1VQQUJBU0VfVVJMPWh0dHA6Ly9zdXBhYmFzZS1rb25nOjgwMDAnCiAgICAgIC0gJ1NVUEFCQVNFX1BVQkxJQ19VUkw9JHtTRVJWSUNFX1VSTF9TVVBBQkFTRUtPTkd9JwogICAgICAtICdTVVBBQkFTRV9BTk9OX0tFWT0ke1NFUlZJQ0VfU1VQQUJBU0VBTk9OX0tFWX0nCiAgICAgIC0gJ1NVUEFCQVNFX1NFUlZJQ0VfS0VZPSR7U0VSVklDRV9TVVBBQkFTRVNFUlZJQ0VfS0VZfScKICAgICAgLSAnQVVUSF9KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdMT0dGTEFSRV9BUElfS0VZPSR7U0VSVklDRV9QQVNTV09SRF9MT0dGTEFSRX0nCiAgICAgIC0gJ0xPR0ZMQVJFX1VSTD1odHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAnCiAgICAgIC0gJ1NVUEFCQVNFX1BVQkxJQ19BUEk9JHtTRVJWSUNFX1VSTF9TVVBBQkFTRUtPTkd9JwogICAgICAtIE5FWFRfUFVCTElDX0VOQUJMRV9MT0dTPXRydWUKICAgICAgLSBORVhUX0FOQUxZVElDU19CQUNLRU5EX1BST1ZJREVSPXBvc3RncmVzCiAgICAgIC0gJ09QRU5BSV9BUElfS0VZPSR7T1BFTkFJX0FQSV9LRVl9JwogIHN1cGFiYXNlLWRiOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9wb3N0Z3JlczoxNS44LjEuMDQ4JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6ICdwZ19pc3JlYWR5IC1VIHBvc3RncmVzIC1oIDEyNy4wLjAuMScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS12ZWN0b3I6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGNvbW1hbmQ6CiAgICAgIC0gcG9zdGdyZXMKICAgICAgLSAnLWMnCiAgICAgIC0gY29uZmlnX2ZpbGU9L2V0Yy9wb3N0Z3Jlc3FsL3Bvc3RncmVzcWwuY29uZgogICAgICAtICctYycKICAgICAgLSBsb2dfbWluX21lc3NhZ2VzPWZhdGFsCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBQT1NUR1JFU19IT1NUPS92YXIvcnVuL3Bvc3RncmVzcWwKICAgICAgLSAnUEdQT1JUPSR7UE9TVEdSRVNfUE9SVDotNTQzMn0nCiAgICAgIC0gJ1BPU1RHUkVTX1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSAnUEdQQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQR0RBVEFCQVNFPSR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtICdKV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdKV1RfRVhQPSR7SldUX0VYUElSWTotMzYwMH0nCiAgICB2b2x1bWVzOgogICAgICAtICdzdXBhYmFzZS1kYi1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi9yZWFsdGltZS5zcWwKICAgICAgICB0YXJnZXQ6IC9kb2NrZXItZW50cnlwb2ludC1pbml0ZGIuZC9taWdyYXRpb25zLzk5LXJlYWx0aW1lLnNxbAogICAgICAgIGNvbnRlbnQ6ICJcXHNldCBwZ3VzZXIgYGVjaG8gXCJzdXBhYmFzZV9hZG1pblwiYFxuXG5jcmVhdGUgc2NoZW1hIGlmIG5vdCBleGlzdHMgX3JlYWx0aW1lO1xuYWx0ZXIgc2NoZW1hIF9yZWFsdGltZSBvd25lciB0byA6cGd1c2VyO1xuIgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2RiL19zdXBhYmFzZS5zcWwKICAgICAgICB0YXJnZXQ6IC9kb2NrZXItZW50cnlwb2ludC1pbml0ZGIuZC9taWdyYXRpb25zLzk3LV9zdXBhYmFzZS5zcWwKICAgICAgICBjb250ZW50OiAiXFxzZXQgcGd1c2VyIGBlY2hvIFwiJFBPU1RHUkVTX1VTRVJcImBcblxuQ1JFQVRFIERBVEFCQVNFIF9zdXBhYmFzZSBXSVRIIE9XTkVSIDpwZ3VzZXI7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvcG9vbGVyLnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL21pZ3JhdGlvbnMvOTktcG9vbGVyLnNxbAogICAgICAgIGNvbnRlbnQ6ICJcXHNldCBwZ3VzZXIgYGVjaG8gXCJzdXBhYmFzZV9hZG1pblwiYFxuXFxjIF9zdXBhYmFzZVxuY3JlYXRlIHNjaGVtYSBpZiBub3QgZXhpc3RzIF9zdXBhdmlzb3I7XG5hbHRlciBzY2hlbWEgX3N1cGF2aXNvciBvd25lciB0byA6cGd1c2VyO1xuXFxjIHBvc3RncmVzXG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvd2ViaG9va3Muc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvaW5pdC1zY3JpcHRzLzk4LXdlYmhvb2tzLnNxbAogICAgICAgIGNvbnRlbnQ6ICJCRUdJTjtcbi0tIENyZWF0ZSBwZ19uZXQgZXh0ZW5zaW9uXG5DUkVBVEUgRVhURU5TSU9OIElGIE5PVCBFWElTVFMgcGdfbmV0IFNDSEVNQSBleHRlbnNpb25zO1xuLS0gQ3JlYXRlIHN1cGFiYXNlX2Z1bmN0aW9ucyBzY2hlbWFcbkNSRUFURSBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIEFVVEhPUklaQVRJT04gc3VwYWJhc2VfYWRtaW47XG5HUkFOVCBVU0FHRSBPTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5BTFRFUiBERUZBVUxUIFBSSVZJTEVHRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBHUkFOVCBBTEwgT04gVEFCTEVTIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5BTFRFUiBERUZBVUxUIFBSSVZJTEVHRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBHUkFOVCBBTEwgT04gRlVOQ1RJT05TIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5BTFRFUiBERUZBVUxUIFBSSVZJTEVHRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBHUkFOVCBBTEwgT04gU0VRVUVOQ0VTIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4tLSBzdXBhYmFzZV9mdW5jdGlvbnMubWlncmF0aW9ucyBkZWZpbml0aW9uXG5DUkVBVEUgVEFCTEUgc3VwYWJhc2VfZnVuY3Rpb25zLm1pZ3JhdGlvbnMgKFxuICB2ZXJzaW9uIHRleHQgUFJJTUFSWSBLRVksXG4gIGluc2VydGVkX2F0IHRpbWVzdGFtcHR6IE5PVCBOVUxMIERFRkFVTFQgTk9XKClcbik7XG4tLSBJbml0aWFsIHN1cGFiYXNlX2Z1bmN0aW9ucyBtaWdyYXRpb25cbklOU0VSVCBJTlRPIHN1cGFiYXNlX2Z1bmN0aW9ucy5taWdyYXRpb25zICh2ZXJzaW9uKSBWQUxVRVMgKCdpbml0aWFsJyk7XG4tLSBzdXBhYmFzZV9mdW5jdGlvbnMuaG9va3MgZGVmaW5pdGlvblxuQ1JFQVRFIFRBQkxFIHN1cGFiYXNlX2Z1bmN0aW9ucy5ob29rcyAoXG4gIGlkIGJpZ3NlcmlhbCBQUklNQVJZIEtFWSxcbiAgaG9va190YWJsZV9pZCBpbnRlZ2VyIE5PVCBOVUxMLFxuICBob29rX25hbWUgdGV4dCBOT1QgTlVMTCxcbiAgY3JlYXRlZF9hdCB0aW1lc3RhbXB0eiBOT1QgTlVMTCBERUZBVUxUIE5PVygpLFxuICByZXF1ZXN0X2lkIGJpZ2ludFxuKTtcbkNSRUFURSBJTkRFWCBzdXBhYmFzZV9mdW5jdGlvbnNfaG9va3NfcmVxdWVzdF9pZF9pZHggT04gc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzIFVTSU5HIGJ0cmVlIChyZXF1ZXN0X2lkKTtcbkNSRUFURSBJTkRFWCBzdXBhYmFzZV9mdW5jdGlvbnNfaG9va3NfaF90YWJsZV9pZF9oX25hbWVfaWR4IE9OIHN1cGFiYXNlX2Z1bmN0aW9ucy5ob29rcyBVU0lORyBidHJlZSAoaG9va190YWJsZV9pZCwgaG9va19uYW1lKTtcbkNPTU1FTlQgT04gVEFCTEUgc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzIElTICdTdXBhYmFzZSBGdW5jdGlvbnMgSG9va3M6IEF1ZGl0IHRyYWlsIGZvciB0cmlnZ2VyZWQgaG9va3MuJztcbkNSRUFURSBGVU5DVElPTiBzdXBhYmFzZV9mdW5jdGlvbnMuaHR0cF9yZXF1ZXN0KClcbiAgUkVUVVJOUyB0cmlnZ2VyXG4gIExBTkdVQUdFIHBscGdzcWxcbiAgQVMgJGZ1bmN0aW9uJFxuICBERUNMQVJFXG4gICAgcmVxdWVzdF9pZCBiaWdpbnQ7XG4gICAgcGF5bG9hZCBqc29uYjtcbiAgICB1cmwgdGV4dCA6PSBUR19BUkdWWzBdOjp0ZXh0O1xuICAgIG1ldGhvZCB0ZXh0IDo9IFRHX0FSR1ZbMV06OnRleHQ7XG4gICAgaGVhZGVycyBqc29uYiBERUZBVUxUICd7fSc6Ompzb25iO1xuICAgIHBhcmFtcyBqc29uYiBERUZBVUxUICd7fSc6Ompzb25iO1xuICAgIHRpbWVvdXRfbXMgaW50ZWdlciBERUZBVUxUIDEwMDA7XG4gIEJFR0lOXG4gICAgSUYgdXJsIElTIE5VTEwgT1IgdXJsID0gJ251bGwnIFRIRU5cbiAgICAgIFJBSVNFIEVYQ0VQVElPTiAndXJsIGFyZ3VtZW50IGlzIG1pc3NpbmcnO1xuICAgIEVORCBJRjtcblxuICAgIElGIG1ldGhvZCBJUyBOVUxMIE9SIG1ldGhvZCA9ICdudWxsJyBUSEVOXG4gICAgICBSQUlTRSBFWENFUFRJT04gJ21ldGhvZCBhcmd1bWVudCBpcyBtaXNzaW5nJztcbiAgICBFTkQgSUY7XG5cbiAgICBJRiBUR19BUkdWWzJdIElTIE5VTEwgT1IgVEdfQVJHVlsyXSA9ICdudWxsJyBUSEVOXG4gICAgICBoZWFkZXJzID0gJ3tcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIn0nOjpqc29uYjtcbiAgICBFTFNFXG4gICAgICBoZWFkZXJzID0gVEdfQVJHVlsyXTo6anNvbmI7XG4gICAgRU5EIElGO1xuXG4gICAgSUYgVEdfQVJHVlszXSBJUyBOVUxMIE9SIFRHX0FSR1ZbM10gPSAnbnVsbCcgVEhFTlxuICAgICAgcGFyYW1zID0gJ3t9Jzo6anNvbmI7XG4gICAgRUxTRVxuICAgICAgcGFyYW1zID0gVEdfQVJHVlszXTo6anNvbmI7XG4gICAgRU5EIElGO1xuXG4gICAgSUYgVEdfQVJHVls0XSBJUyBOVUxMIE9SIFRHX0FSR1ZbNF0gPSAnbnVsbCcgVEhFTlxuICAgICAgdGltZW91dF9tcyA9IDEwMDA7XG4gICAgRUxTRVxuICAgICAgdGltZW91dF9tcyA9IFRHX0FSR1ZbNF06OmludGVnZXI7XG4gICAgRU5EIElGO1xuXG4gICAgQ0FTRVxuICAgICAgV0hFTiBtZXRob2QgPSAnR0VUJyBUSEVOXG4gICAgICAgIFNFTEVDVCBodHRwX2dldCBJTlRPIHJlcXVlc3RfaWQgRlJPTSBuZXQuaHR0cF9nZXQoXG4gICAgICAgICAgdXJsLFxuICAgICAgICAgIHBhcmFtcyxcbiAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgIHRpbWVvdXRfbXNcbiAgICAgICAgKTtcbiAgICAgIFdIRU4gbWV0aG9kID0gJ1BPU1QnIFRIRU5cbiAgICAgICAgcGF5bG9hZCA9IGpzb25iX2J1aWxkX29iamVjdChcbiAgICAgICAgICAnb2xkX3JlY29yZCcsIE9MRCxcbiAgICAgICAgICAncmVjb3JkJywgTkVXLFxuICAgICAgICAgICd0eXBlJywgVEdfT1AsXG4gICAgICAgICAgJ3RhYmxlJywgVEdfVEFCTEVfTkFNRSxcbiAgICAgICAgICAnc2NoZW1hJywgVEdfVEFCTEVfU0NIRU1BXG4gICAgICAgICk7XG5cbiAgICAgICAgU0VMRUNUIGh0dHBfcG9zdCBJTlRPIHJlcXVlc3RfaWQgRlJPTSBuZXQuaHR0cF9wb3N0KFxuICAgICAgICAgIHVybCxcbiAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICAgIHBhcmFtcyxcbiAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgIHRpbWVvdXRfbXNcbiAgICAgICAgKTtcbiAgICAgIEVMU0VcbiAgICAgICAgUkFJU0UgRVhDRVBUSU9OICdtZXRob2QgYXJndW1lbnQgJSBpcyBpbnZhbGlkJywgbWV0aG9kO1xuICAgIEVORCBDQVNFO1xuXG4gICAgSU5TRVJUIElOVE8gc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzXG4gICAgICAoaG9va190YWJsZV9pZCwgaG9va19uYW1lLCByZXF1ZXN0X2lkKVxuICAgIFZBTFVFU1xuICAgICAgKFRHX1JFTElELCBUR19OQU1FLCByZXF1ZXN0X2lkKTtcblxuICAgIFJFVFVSTiBORVc7XG4gIEVORFxuJGZ1bmN0aW9uJDtcbi0tIFN1cGFiYXNlIHN1cGVyIGFkbWluXG5ET1xuJCRcbkJFR0lOXG4gIElGIE5PVCBFWElTVFMgKFxuICAgIFNFTEVDVCAxXG4gICAgRlJPTSBwZ19yb2xlc1xuICAgIFdIRVJFIHJvbG5hbWUgPSAnc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluJ1xuICApXG4gIFRIRU5cbiAgICBDUkVBVEUgVVNFUiBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4gTk9JTkhFUklUIENSRUFURVJPTEUgTE9HSU4gTk9SRVBMSUNBVElPTjtcbiAgRU5EIElGO1xuRU5EXG4kJDtcbkdSQU5UIEFMTCBQUklWSUxFR0VTIE9OIFNDSEVNQSBzdXBhYmFzZV9mdW5jdGlvbnMgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluO1xuR1JBTlQgQUxMIFBSSVZJTEVHRVMgT04gQUxMIFRBQkxFUyBJTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbjtcbkdSQU5UIEFMTCBQUklWSUxFR0VTIE9OIEFMTCBTRVFVRU5DRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW47XG5BTFRFUiBVU0VSIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiBTRVQgc2VhcmNoX3BhdGggPSBcInN1cGFiYXNlX2Z1bmN0aW9uc1wiO1xuQUxURVIgdGFibGUgXCJzdXBhYmFzZV9mdW5jdGlvbnNcIi5taWdyYXRpb25zIE9XTkVSIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbjtcbkFMVEVSIHRhYmxlIFwic3VwYWJhc2VfZnVuY3Rpb25zXCIuaG9va3MgT1dORVIgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluO1xuQUxURVIgZnVuY3Rpb24gXCJzdXBhYmFzZV9mdW5jdGlvbnNcIi5odHRwX3JlcXVlc3QoKSBPV05FUiBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW47XG5HUkFOVCBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4gVE8gcG9zdGdyZXM7XG4tLSBSZW1vdmUgdW51c2VkIHN1cGFiYXNlX3BnX25ldF9hZG1pbiByb2xlXG5ET1xuJCRcbkJFR0lOXG4gIElGIEVYSVNUUyAoXG4gICAgU0VMRUNUIDFcbiAgICBGUk9NIHBnX3JvbGVzXG4gICAgV0hFUkUgcm9sbmFtZSA9ICdzdXBhYmFzZV9wZ19uZXRfYWRtaW4nXG4gIClcbiAgVEhFTlxuICAgIFJFQVNTSUdOIE9XTkVEIEJZIHN1cGFiYXNlX3BnX25ldF9hZG1pbiBUTyBzdXBhYmFzZV9hZG1pbjtcbiAgICBEUk9QIE9XTkVEIEJZIHN1cGFiYXNlX3BnX25ldF9hZG1pbjtcbiAgICBEUk9QIFJPTEUgc3VwYWJhc2VfcGdfbmV0X2FkbWluO1xuICBFTkQgSUY7XG5FTkRcbiQkO1xuLS0gcGdfbmV0IGdyYW50cyB3aGVuIGV4dGVuc2lvbiBpcyBhbHJlYWR5IGVuYWJsZWRcbkRPXG4kJFxuQkVHSU5cbiAgSUYgRVhJU1RTIChcbiAgICBTRUxFQ1QgMVxuICAgIEZST00gcGdfZXh0ZW5zaW9uXG4gICAgV0hFUkUgZXh0bmFtZSA9ICdwZ19uZXQnXG4gIClcbiAgVEhFTlxuICAgIEdSQU5UIFVTQUdFIE9OIFNDSEVNQSBuZXQgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluLCBwb3N0Z3JlcywgYW5vbiwgYXV0aGVudGljYXRlZCwgc2VydmljZV9yb2xlO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRUNVUklUWSBERUZJTkVSO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VDVVJJVFkgREVGSU5FUjtcbiAgICBBTFRFUiBmdW5jdGlvbiBuZXQuaHR0cF9nZXQodXJsIHRleHQsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIEZST00gUFVCTElDO1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBGUk9NIFBVQkxJQztcbiAgICBHUkFOVCBFWEVDVVRFIE9OIEZVTkNUSU9OIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4sIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4gICAgR1JBTlQgRVhFQ1VURSBPTiBGVU5DVElPTiBuZXQuaHR0cF9wb3N0KHVybCB0ZXh0LCBib2R5IGpzb25iLCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiwgcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbiAgRU5EIElGO1xuRU5EXG4kJDtcbi0tIEV2ZW50IHRyaWdnZXIgZm9yIHBnX25ldFxuQ1JFQVRFIE9SIFJFUExBQ0UgRlVOQ1RJT04gZXh0ZW5zaW9ucy5ncmFudF9wZ19uZXRfYWNjZXNzKClcblJFVFVSTlMgZXZlbnRfdHJpZ2dlclxuTEFOR1VBR0UgcGxwZ3NxbFxuQVMgJCRcbkJFR0lOXG4gIElGIEVYSVNUUyAoXG4gICAgU0VMRUNUIDFcbiAgICBGUk9NIHBnX2V2ZW50X3RyaWdnZXJfZGRsX2NvbW1hbmRzKCkgQVMgZXZcbiAgICBKT0lOIHBnX2V4dGVuc2lvbiBBUyBleHRcbiAgICBPTiBldi5vYmppZCA9IGV4dC5vaWRcbiAgICBXSEVSRSBleHQuZXh0bmFtZSA9ICdwZ19uZXQnXG4gIClcbiAgVEhFTlxuICAgIEdSQU5UIFVTQUdFIE9OIFNDSEVNQSBuZXQgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluLCBwb3N0Z3JlcywgYW5vbiwgYXV0aGVudGljYXRlZCwgc2VydmljZV9yb2xlO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRUNVUklUWSBERUZJTkVSO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VDVVJJVFkgREVGSU5FUjtcbiAgICBBTFRFUiBmdW5jdGlvbiBuZXQuaHR0cF9nZXQodXJsIHRleHQsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIEZST00gUFVCTElDO1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBGUk9NIFBVQkxJQztcbiAgICBHUkFOVCBFWEVDVVRFIE9OIEZVTkNUSU9OIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4sIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4gICAgR1JBTlQgRVhFQ1VURSBPTiBGVU5DVElPTiBuZXQuaHR0cF9wb3N0KHVybCB0ZXh0LCBib2R5IGpzb25iLCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiwgcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbiAgRU5EIElGO1xuRU5EO1xuJCQ7XG5DT01NRU5UIE9OIEZVTkNUSU9OIGV4dGVuc2lvbnMuZ3JhbnRfcGdfbmV0X2FjY2VzcyBJUyAnR3JhbnRzIGFjY2VzcyB0byBwZ19uZXQnO1xuRE9cbiQkXG5CRUdJTlxuICBJRiBOT1QgRVhJU1RTIChcbiAgICBTRUxFQ1QgMVxuICAgIEZST00gcGdfZXZlbnRfdHJpZ2dlclxuICAgIFdIRVJFIGV2dG5hbWUgPSAnaXNzdWVfcGdfbmV0X2FjY2VzcydcbiAgKSBUSEVOXG4gICAgQ1JFQVRFIEVWRU5UIFRSSUdHRVIgaXNzdWVfcGdfbmV0X2FjY2VzcyBPTiBkZGxfY29tbWFuZF9lbmQgV0hFTiBUQUcgSU4gKCdDUkVBVEUgRVhURU5TSU9OJylcbiAgICBFWEVDVVRFIFBST0NFRFVSRSBleHRlbnNpb25zLmdyYW50X3BnX25ldF9hY2Nlc3MoKTtcbiAgRU5EIElGO1xuRU5EXG4kJDtcbklOU0VSVCBJTlRPIHN1cGFiYXNlX2Z1bmN0aW9ucy5taWdyYXRpb25zICh2ZXJzaW9uKSBWQUxVRVMgKCcyMDIxMDgwOTE4MzQyM191cGRhdGVfZ3JhbnRzJyk7XG5BTFRFUiBmdW5jdGlvbiBzdXBhYmFzZV9mdW5jdGlvbnMuaHR0cF9yZXF1ZXN0KCkgU0VDVVJJVFkgREVGSU5FUjtcbkFMVEVSIGZ1bmN0aW9uIHN1cGFiYXNlX2Z1bmN0aW9ucy5odHRwX3JlcXVlc3QoKSBTRVQgc2VhcmNoX3BhdGggPSBzdXBhYmFzZV9mdW5jdGlvbnM7XG5SRVZPS0UgQUxMIE9OIEZVTkNUSU9OIHN1cGFiYXNlX2Z1bmN0aW9ucy5odHRwX3JlcXVlc3QoKSBGUk9NIFBVQkxJQztcbkdSQU5UIEVYRUNVVEUgT04gRlVOQ1RJT04gc3VwYWJhc2VfZnVuY3Rpb25zLmh0dHBfcmVxdWVzdCgpIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5DT01NSVQ7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvcm9sZXMuc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvaW5pdC1zY3JpcHRzLzk5LXJvbGVzLnNxbAogICAgICAgIGNvbnRlbnQ6ICItLSBOT1RFOiBjaGFuZ2UgdG8geW91ciBvd24gcGFzc3dvcmRzIGZvciBwcm9kdWN0aW9uIGVudmlyb25tZW50c1xuIFxcc2V0IHBncGFzcyBgZWNobyBcIiRQT1NUR1JFU19QQVNTV09SRFwiYFxuXG4gQUxURVIgVVNFUiBhdXRoZW50aWNhdG9yIFdJVEggUEFTU1dPUkQgOidwZ3Bhc3MnO1xuIEFMVEVSIFVTRVIgcGdib3VuY2VyIFdJVEggUEFTU1dPUkQgOidwZ3Bhc3MnO1xuIEFMVEVSIFVTRVIgc3VwYWJhc2VfYXV0aF9hZG1pbiBXSVRIIFBBU1NXT1JEIDoncGdwYXNzJztcbiBBTFRFUiBVU0VSIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiBXSVRIIFBBU1NXT1JEIDoncGdwYXNzJztcbiBBTFRFUiBVU0VSIHN1cGFiYXNlX3N0b3JhZ2VfYWRtaW4gV0lUSCBQQVNTV09SRCA6J3BncGFzcyc7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvand0LnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL2luaXQtc2NyaXB0cy85OS1qd3Quc3FsCiAgICAgICAgY29udGVudDogIlxcc2V0IGp3dF9zZWNyZXQgYGVjaG8gXCIkSldUX1NFQ1JFVFwiYFxuXFxzZXQgand0X2V4cCBgZWNobyBcIiRKV1RfRVhQXCJgXG5cXHNldCBkYl9uYW1lIGBlY2hvIFwiJHtQT1NUR1JFU19EQjotcG9zdGdyZXN9XCJgXG5cbkFMVEVSIERBVEFCQVNFIDpkYl9uYW1lIFNFVCBcImFwcC5zZXR0aW5ncy5qd3Rfc2VjcmV0XCIgVE8gOidqd3Rfc2VjcmV0JztcbkFMVEVSIERBVEFCQVNFIDpkYl9uYW1lIFNFVCBcImFwcC5zZXR0aW5ncy5qd3RfZXhwXCIgVE8gOidqd3RfZXhwJztcbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi9sb2dzLnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL21pZ3JhdGlvbnMvOTktbG9ncy5zcWwKICAgICAgICBjb250ZW50OiAiXFxzZXQgcGd1c2VyIGBlY2hvIFwic3VwYWJhc2VfYWRtaW5cImBcblxcYyBfc3VwYWJhc2VcbmNyZWF0ZSBzY2hlbWEgaWYgbm90IGV4aXN0cyBfYW5hbHl0aWNzO1xuYWx0ZXIgc2NoZW1hIF9hbmFseXRpY3Mgb3duZXIgdG8gOnBndXNlcjtcblxcYyBwb3N0Z3Jlc1xuIgogICAgICAtICdzdXBhYmFzZS1kYi1jb25maWc6L2V0Yy9wb3N0Z3Jlc3FsLWN1c3RvbScKICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICBpbWFnZTogJ3N1cGFiYXNlL2xvZ2ZsYXJlOjEuNC4wJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjQwMDAvaGVhbHRoJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMTAKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBMT0dGTEFSRV9OT0RFX0hPU1Q9MTI3LjAuMC4xCiAgICAgIC0gREJfVVNFUk5BTUU9c3VwYWJhc2VfYWRtaW4KICAgICAgLSBEQl9EQVRBQkFTRT1fc3VwYWJhc2UKICAgICAgLSAnREJfSE9TVE5BTUU9JHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9JwogICAgICAtICdEQl9QT1JUPSR7UE9TVEdSRVNfUE9SVDotNTQzMn0nCiAgICAgIC0gJ0RCX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gREJfU0NIRU1BPV9hbmFseXRpY3MKICAgICAgLSAnTE9HRkxBUkVfQVBJX0tFWT0ke1NFUlZJQ0VfUEFTU1dPUkRfTE9HRkxBUkV9JwogICAgICAtIExPR0ZMQVJFX1NJTkdMRV9URU5BTlQ9dHJ1ZQogICAgICAtIExPR0ZMQVJFX1NJTkdMRV9URU5BTlRfTU9ERT10cnVlCiAgICAgIC0gTE9HRkxBUkVfU1VQQUJBU0VfTU9ERT10cnVlCiAgICAgIC0gTE9HRkxBUkVfTUlOX0NMVVNURVJfU0laRT0xCiAgICAgIC0gJ1BPU1RHUkVTX0JBQ0tFTkRfVVJMPXBvc3RncmVzcWw6Ly9zdXBhYmFzZV9hZG1pbjoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9L19zdXBhYmFzZScKICAgICAgLSBQT1NUR1JFU19CQUNLRU5EX1NDSEVNQT1fYW5hbHl0aWNzCiAgICAgIC0gTE9HRkxBUkVfRkVBVFVSRV9GTEFHX09WRVJSSURFPW11bHRpYmFja2VuZD10cnVlCiAgc3VwYWJhc2UtdmVjdG9yOgogICAgaW1hZ2U6ICd0aW1iZXJpby92ZWN0b3I6MC4yOC4xLWFscGluZScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLS1uby12ZXJib3NlJwogICAgICAgIC0gJy0tdHJpZXM9MScKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICdodHRwOi8vc3VwYWJhc2UtdmVjdG9yOjkwMDEvaGVhbHRoJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgdm9sdW1lczoKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9sb2dzL3ZlY3Rvci55bWwKICAgICAgICB0YXJnZXQ6IC9ldGMvdmVjdG9yL3ZlY3Rvci55bWwKICAgICAgICByZWFkX29ubHk6IHRydWUKICAgICAgICBjb250ZW50OiAiYXBpOlxuICBlbmFibGVkOiB0cnVlXG4gIGFkZHJlc3M6IDAuMC4wLjA6OTAwMVxuXG5zb3VyY2VzOlxuICBkb2NrZXJfaG9zdDpcbiAgICB0eXBlOiBkb2NrZXJfbG9nc1xuICAgIGV4Y2x1ZGVfY29udGFpbmVyczpcbiAgICAgIC0gc3VwYWJhc2UtdmVjdG9yXG5cbnRyYW5zZm9ybXM6XG4gIHByb2plY3RfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gZG9ja2VyX2hvc3RcbiAgICBzb3VyY2U6IHwtXG4gICAgICAucHJvamVjdCA9IFwiZGVmYXVsdFwiXG4gICAgICAuZXZlbnRfbWVzc2FnZSA9IGRlbCgubWVzc2FnZSlcbiAgICAgIC5hcHBuYW1lID0gZGVsKC5jb250YWluZXJfbmFtZSlcbiAgICAgIGRlbCguY29udGFpbmVyX2NyZWF0ZWRfYXQpXG4gICAgICBkZWwoLmNvbnRhaW5lcl9pZClcbiAgICAgIGRlbCguc291cmNlX3R5cGUpXG4gICAgICBkZWwoLnN0cmVhbSlcbiAgICAgIGRlbCgubGFiZWwpXG4gICAgICBkZWwoLmltYWdlKVxuICAgICAgZGVsKC5ob3N0KVxuICAgICAgZGVsKC5zdHJlYW0pXG4gIHJvdXRlcjpcbiAgICB0eXBlOiByb3V0ZVxuICAgIGlucHV0czpcbiAgICAgIC0gcHJvamVjdF9sb2dzXG4gICAgcm91dGU6XG4gICAgICBrb25nOiAnc3RhcnRzX3dpdGgoc3RyaW5nISguYXBwbmFtZSksIFwic3VwYWJhc2Uta29uZ1wiKSdcbiAgICAgIGF1dGg6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJzdXBhYmFzZS1hdXRoXCIpJ1xuICAgICAgcmVzdDogJ3N0YXJ0c193aXRoKHN0cmluZyEoLmFwcG5hbWUpLCBcInN1cGFiYXNlLXJlc3RcIiknXG4gICAgICByZWFsdGltZTogJ3N0YXJ0c193aXRoKHN0cmluZyEoLmFwcG5hbWUpLCBcInJlYWx0aW1lLWRldlwiKSdcbiAgICAgIHN0b3JhZ2U6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJzdXBhYmFzZS1zdG9yYWdlXCIpJ1xuICAgICAgZnVuY3Rpb25zOiAnc3RhcnRzX3dpdGgoc3RyaW5nISguYXBwbmFtZSksIFwic3VwYWJhc2UtZnVuY3Rpb25zXCIpJ1xuICAgICAgZGI6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJzdXBhYmFzZS1kYlwiKSdcbiAgIyBJZ25vcmVzIG5vbiBuZ2lueCBlcnJvcnMgc2luY2UgdGhleSBhcmUgcmVsYXRlZCB3aXRoIGtvbmcgYm9vdGluZyB1cFxuICBrb25nX2xvZ3M6XG4gICAgdHlwZTogcmVtYXBcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5rb25nXG4gICAgc291cmNlOiB8LVxuICAgICAgcmVxLCBlcnIgPSBwYXJzZV9uZ2lueF9sb2coLmV2ZW50X21lc3NhZ2UsIFwiY29tYmluZWRcIilcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAudGltZXN0YW1wID0gcmVxLnRpbWVzdGFtcFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0LmhlYWRlcnMucmVmZXJlciA9IHJlcS5yZWZlcmVyXG4gICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QuaGVhZGVycy51c2VyX2FnZW50ID0gcmVxLmFnZW50XG4gICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QuaGVhZGVycy5jZl9jb25uZWN0aW5nX2lwID0gcmVxLmNsaWVudFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0Lm1ldGhvZCA9IHJlcS5tZXRob2RcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5wYXRoID0gcmVxLnBhdGhcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5wcm90b2NvbCA9IHJlcS5wcm90b2NvbFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXNwb25zZS5zdGF0dXNfY29kZSA9IHJlcS5zdGF0dXNcbiAgICAgIH1cbiAgICAgIGlmIGVyciAhPSBudWxsIHtcbiAgICAgICAgYWJvcnRcbiAgICAgIH1cbiAgIyBJZ25vcmVzIG5vbiBuZ2lueCBlcnJvcnMgc2luY2UgdGhleSBhcmUgcmVsYXRlZCB3aXRoIGtvbmcgYm9vdGluZyB1cFxuICBrb25nX2VycjpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLmtvbmdcbiAgICBzb3VyY2U6IHwtXG4gICAgICAubWV0YWRhdGEucmVxdWVzdC5tZXRob2QgPSBcIkdFVFwiXG4gICAgICAubWV0YWRhdGEucmVzcG9uc2Uuc3RhdHVzX2NvZGUgPSAyMDBcbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfbmdpbnhfbG9nKC5ldmVudF9tZXNzYWdlLCBcImVycm9yXCIpXG4gICAgICBpZiBlcnIgPT0gbnVsbCB7XG4gICAgICAgICAgLnRpbWVzdGFtcCA9IHBhcnNlZC50aW1lc3RhbXBcbiAgICAgICAgICAuc2V2ZXJpdHkgPSBwYXJzZWQuc2V2ZXJpdHlcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5ob3N0ID0gcGFyc2VkLmhvc3RcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5oZWFkZXJzLmNmX2Nvbm5lY3RpbmdfaXAgPSBwYXJzZWQuY2xpZW50XG4gICAgICAgICAgdXJsLCBlcnIgPSBzcGxpdChwYXJzZWQucmVxdWVzdCwgXCIgXCIpXG4gICAgICAgICAgaWYgZXJyID09IG51bGwge1xuICAgICAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5tZXRob2QgPSB1cmxbMF1cbiAgICAgICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QucGF0aCA9IHVybFsxXVxuICAgICAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5wcm90b2NvbCA9IHVybFsyXVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIGVyciAhPSBudWxsIHtcbiAgICAgICAgYWJvcnRcbiAgICAgIH1cbiAgIyBHb3RydWUgbG9ncyBhcmUgc3RydWN0dXJlZCBqc29uIHN0cmluZ3Mgd2hpY2ggZnJvbnRlbmQgcGFyc2VzIGRpcmVjdGx5LiBCdXQgd2Uga2VlcCBtZXRhZGF0YSBmb3IgY29uc2lzdGVuY3kuXG4gIGF1dGhfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLmF1dGhcbiAgICBzb3VyY2U6IHwtXG4gICAgICBwYXJzZWQsIGVyciA9IHBhcnNlX2pzb24oLmV2ZW50X21lc3NhZ2UpXG4gICAgICBpZiBlcnIgPT0gbnVsbCB7XG4gICAgICAgICAgLm1ldGFkYXRhLnRpbWVzdGFtcCA9IHBhcnNlZC50aW1lXG4gICAgICAgICAgLm1ldGFkYXRhID0gbWVyZ2UhKC5tZXRhZGF0YSwgcGFyc2VkKVxuICAgICAgfVxuICAjIFBvc3RnUkVTVCBsb2dzIGFyZSBzdHJ1Y3R1cmVkIHNvIHdlIHNlcGFyYXRlIHRpbWVzdGFtcCBmcm9tIG1lc3NhZ2UgdXNpbmcgcmVnZXhcbiAgcmVzdF9sb2dzOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIucmVzdFxuICAgIHNvdXJjZTogfC1cbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfcmVnZXgoLmV2ZW50X21lc3NhZ2UsIHInXig/UDx0aW1lPi4qKTogKD9QPG1zZz4uKikkJylcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAuZXZlbnRfbWVzc2FnZSA9IHBhcnNlZC5tc2dcbiAgICAgICAgICAudGltZXN0YW1wID0gdG9fdGltZXN0YW1wIShwYXJzZWQudGltZSlcbiAgICAgICAgICAubWV0YWRhdGEuaG9zdCA9IC5wcm9qZWN0XG4gICAgICB9XG4gICMgUmVhbHRpbWUgbG9ncyBhcmUgc3RydWN0dXJlZCBzbyB3ZSBwYXJzZSB0aGUgc2V2ZXJpdHkgbGV2ZWwgdXNpbmcgcmVnZXggKGlnbm9yZSB0aW1lIGJlY2F1c2UgaXQgaGFzIG5vIGRhdGUpXG4gIHJlYWx0aW1lX2xvZ3M6XG4gICAgdHlwZTogcmVtYXBcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5yZWFsdGltZVxuICAgIHNvdXJjZTogfC1cbiAgICAgIC5tZXRhZGF0YS5wcm9qZWN0ID0gZGVsKC5wcm9qZWN0KVxuICAgICAgLm1ldGFkYXRhLmV4dGVybmFsX2lkID0gLm1ldGFkYXRhLnByb2plY3RcbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfcmVnZXgoLmV2ZW50X21lc3NhZ2UsIHInXig/UDx0aW1lPlxcZCs6XFxkKzpcXGQrXFwuXFxkKykgXFxbKD9QPGxldmVsPlxcdyspXFxdICg/UDxtc2c+LiopJCcpXG4gICAgICBpZiBlcnIgPT0gbnVsbCB7XG4gICAgICAgICAgLmV2ZW50X21lc3NhZ2UgPSBwYXJzZWQubXNnXG4gICAgICAgICAgLm1ldGFkYXRhLmxldmVsID0gcGFyc2VkLmxldmVsXG4gICAgICB9XG4gICMgU3RvcmFnZSBsb2dzIG1heSBjb250YWluIGpzb24gb2JqZWN0cyBzbyB3ZSBwYXJzZSB0aGVtIGZvciBjb21wbGV0ZW5lc3NcbiAgc3RvcmFnZV9sb2dzOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIuc3RvcmFnZVxuICAgIHNvdXJjZTogfC1cbiAgICAgIC5tZXRhZGF0YS5wcm9qZWN0ID0gZGVsKC5wcm9qZWN0KVxuICAgICAgLm1ldGFkYXRhLnRlbmFudElkID0gLm1ldGFkYXRhLnByb2plY3RcbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfanNvbiguZXZlbnRfbWVzc2FnZSlcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAuZXZlbnRfbWVzc2FnZSA9IHBhcnNlZC5tc2dcbiAgICAgICAgICAubWV0YWRhdGEubGV2ZWwgPSBwYXJzZWQubGV2ZWxcbiAgICAgICAgICAubWV0YWRhdGEudGltZXN0YW1wID0gcGFyc2VkLnRpbWVcbiAgICAgICAgICAubWV0YWRhdGEuY29udGV4dFswXS5ob3N0ID0gcGFyc2VkLmhvc3RuYW1lXG4gICAgICAgICAgLm1ldGFkYXRhLmNvbnRleHRbMF0ucGlkID0gcGFyc2VkLnBpZFxuICAgICAgfVxuICAjIFBvc3RncmVzIGxvZ3Mgc29tZSBtZXNzYWdlcyB0byBzdGRlcnIgd2hpY2ggd2UgbWFwIHRvIHdhcm5pbmcgc2V2ZXJpdHkgbGV2ZWxcbiAgZGJfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLmRiXG4gICAgc291cmNlOiB8LVxuICAgICAgLm1ldGFkYXRhLmhvc3QgPSBcImRiLWRlZmF1bHRcIlxuICAgICAgLm1ldGFkYXRhLnBhcnNlZC50aW1lc3RhbXAgPSAudGltZXN0YW1wXG5cbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfcmVnZXgoLmV2ZW50X21lc3NhZ2UsIHInLiooP1A8bGV2ZWw+SU5GT3xOT1RJQ0V8V0FSTklOR3xFUlJPUnxMT0d8RkFUQUx8UEFOSUM/KTouKicsIG51bWVyaWNfZ3JvdXBzOiB0cnVlKVxuXG4gICAgICBpZiBlcnIgIT0gbnVsbCB8fCBwYXJzZWQgPT0gbnVsbCB7XG4gICAgICAgIC5tZXRhZGF0YS5wYXJzZWQuZXJyb3Jfc2V2ZXJpdHkgPSBcImluZm9cIlxuICAgICAgfVxuICAgICAgaWYgcGFyc2VkICE9IG51bGwge1xuICAgICAgLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSA9IHBhcnNlZC5sZXZlbFxuICAgICAgfVxuICAgICAgaWYgLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSA9PSBcImluZm9cIiB7XG4gICAgICAgICAgLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSA9IFwibG9nXCJcbiAgICAgIH1cbiAgICAgIC5tZXRhZGF0YS5wYXJzZWQuZXJyb3Jfc2V2ZXJpdHkgPSB1cGNhc2UhKC5tZXRhZGF0YS5wYXJzZWQuZXJyb3Jfc2V2ZXJpdHkpXG5cbnNpbmtzOlxuICBsb2dmbGFyZV9hdXRoOlxuICAgIHR5cGU6ICdodHRwJ1xuICAgIGlucHV0czpcbiAgICAgIC0gYXV0aF9sb2dzXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL2FwaS9sb2dzP3NvdXJjZV9uYW1lPWdvdHJ1ZS5sb2dzLnByb2QmYXBpX2tleT0ke0xPR0ZMQVJFX0FQSV9LRVk/TE9HRkxBUkVfQVBJX0tFWSBpcyByZXF1aXJlZH0nXG4gIGxvZ2ZsYXJlX3JlYWx0aW1lOlxuICAgIHR5cGU6ICdodHRwJ1xuICAgIGlucHV0czpcbiAgICAgIC0gcmVhbHRpbWVfbG9nc1xuICAgIGVuY29kaW5nOlxuICAgICAgY29kZWM6ICdqc29uJ1xuICAgIG1ldGhvZDogJ3Bvc3QnXG4gICAgcmVxdWVzdDpcbiAgICAgIHJldHJ5X21heF9kdXJhdGlvbl9zZWNzOiAxMFxuICAgIHVyaTogJ2h0dHA6Ly9zdXBhYmFzZS1hbmFseXRpY3M6NDAwMC9hcGkvbG9ncz9zb3VyY2VfbmFtZT1yZWFsdGltZS5sb2dzLnByb2QmYXBpX2tleT0ke0xPR0ZMQVJFX0FQSV9LRVk/TE9HRkxBUkVfQVBJX0tFWSBpcyByZXF1aXJlZH0nXG4gIGxvZ2ZsYXJlX3Jlc3Q6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSByZXN0X2xvZ3NcbiAgICBlbmNvZGluZzpcbiAgICAgIGNvZGVjOiAnanNvbidcbiAgICBtZXRob2Q6ICdwb3N0J1xuICAgIHJlcXVlc3Q6XG4gICAgICByZXRyeV9tYXhfZHVyYXRpb25fc2VjczogMTBcbiAgICB1cmk6ICdodHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAvYXBpL2xvZ3M/c291cmNlX25hbWU9cG9zdGdSRVNULmxvZ3MucHJvZCZhcGlfa2V5PSR7TE9HRkxBUkVfQVBJX0tFWT9MT0dGTEFSRV9BUElfS0VZIGlzIHJlcXVpcmVkfSdcbiAgbG9nZmxhcmVfZGI6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSBkYl9sb2dzXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgIyBXZSBtdXN0IHJvdXRlIHRoZSBzaW5rIHRocm91Z2gga29uZyBiZWNhdXNlIGluZ2VzdGluZyBsb2dzIGJlZm9yZSBsb2dmbGFyZSBpcyBmdWxseSBpbml0aWFsaXNlZCB3aWxsXG4gICAgIyBsZWFkIHRvIGJyb2tlbiBxdWVyaWVzIGZyb20gc3R1ZGlvLiBUaGlzIHdvcmtzIGJ5IHRoZSBhc3N1bXB0aW9uIHRoYXQgY29udGFpbmVycyBhcmUgc3RhcnRlZCBpbiB0aGVcbiAgICAjIGZvbGxvd2luZyBvcmRlcjogdmVjdG9yID4gZGIgPiBsb2dmbGFyZSA+IGtvbmdcbiAgICB1cmk6ICdodHRwOi8vc3VwYWJhc2Uta29uZzo4MDAwL2FuYWx5dGljcy92MS9hcGkvbG9ncz9zb3VyY2VfbmFtZT1wb3N0Z3Jlcy5sb2dzJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuICBsb2dmbGFyZV9mdW5jdGlvbnM6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIuZnVuY3Rpb25zXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL2FwaS9sb2dzP3NvdXJjZV9uYW1lPWRlbm8tcmVsYXktbG9ncyZhcGlfa2V5PSR7TE9HRkxBUkVfQVBJX0tFWT9MT0dGTEFSRV9BUElfS0VZIGlzIHJlcXVpcmVkfSdcbiAgbG9nZmxhcmVfc3RvcmFnZTpcbiAgICB0eXBlOiAnaHR0cCdcbiAgICBpbnB1dHM6XG4gICAgICAtIHN0b3JhZ2VfbG9nc1xuICAgIGVuY29kaW5nOlxuICAgICAgY29kZWM6ICdqc29uJ1xuICAgIG1ldGhvZDogJ3Bvc3QnXG4gICAgcmVxdWVzdDpcbiAgICAgIHJldHJ5X21heF9kdXJhdGlvbl9zZWNzOiAxMFxuICAgIHVyaTogJ2h0dHA6Ly9zdXBhYmFzZS1hbmFseXRpY3M6NDAwMC9hcGkvbG9ncz9zb3VyY2VfbmFtZT1zdG9yYWdlLmxvZ3MucHJvZC4yJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuICBsb2dmbGFyZV9rb25nOlxuICAgIHR5cGU6ICdodHRwJ1xuICAgIGlucHV0czpcbiAgICAgIC0ga29uZ19sb2dzXG4gICAgICAtIGtvbmdfZXJyXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL2FwaS9sb2dzP3NvdXJjZV9uYW1lPWNsb3VkZmxhcmUubG9ncy5wcm9kJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuIgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jazpybycKICAgIGVudmlyb25tZW50OgogICAgICAtICdMT0dGTEFSRV9BUElfS0VZPSR7U0VSVklDRV9QQVNTV09SRF9MT0dGTEFSRX0nCiAgICBjb21tYW5kOgogICAgICAtICctLWNvbmZpZycKICAgICAgLSBldGMvdmVjdG9yL3ZlY3Rvci55bWwKICBzdXBhYmFzZS1yZXN0OgogICAgaW1hZ2U6ICdwb3N0Z3Jlc3QvcG9zdGdyZXN0OnYxMi4yLjEyJwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUEdSU1RfREJfVVJJPXBvc3RncmVzOi8vYXV0aGVudGljYXRvcjoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9LyR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnUEdSU1RfREJfU0NIRU1BUz0ke1BHUlNUX0RCX1NDSEVNQVM6LXB1YmxpYyxzdG9yYWdlLGdyYXBocWxfcHVibGljfScKICAgICAgLSBQR1JTVF9EQl9BTk9OX1JPTEU9YW5vbgogICAgICAtICdQR1JTVF9KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtIFBHUlNUX0RCX1VTRV9MRUdBQ1lfR1VDUz1mYWxzZQogICAgICAtICdQR1JTVF9BUFBfU0VUVElOR1NfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSAnUEdSU1RfQVBQX1NFVFRJTkdTX0pXVF9FWFA9JHtKV1RfRVhQSVJZOi0zNjAwfScKICAgIGNvbW1hbmQ6IHBvc3RncmVzdAogICAgZXhjbHVkZV9mcm9tX2hjOiB0cnVlCiAgc3VwYWJhc2UtYXV0aDoKICAgIGltYWdlOiAnc3VwYWJhc2UvZ290cnVlOnYyLjE3NC4wJwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gd2dldAogICAgICAgIC0gJy0tbm8tdmVyYm9zZScKICAgICAgICAtICctLXRyaWVzPTEnCiAgICAgICAgLSAnLS1zcGlkZXInCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo5OTk5L2hlYWx0aCcKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIGVudmlyb25tZW50OgogICAgICAtIEdPVFJVRV9BUElfSE9TVD0wLjAuMC4wCiAgICAgIC0gR09UUlVFX0FQSV9QT1JUPTk5OTkKICAgICAgLSAnQVBJX0VYVEVSTkFMX1VSTD0ke0FQSV9FWFRFUk5BTF9VUkw6LWh0dHA6Ly9zdXBhYmFzZS1rb25nOjgwMDB9JwogICAgICAtIEdPVFJVRV9EQl9EUklWRVI9cG9zdGdyZXMKICAgICAgLSAnR09UUlVFX0RCX0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovL3N1cGFiYXNlX2F1dGhfYWRtaW46JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUAke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn06JHtQT1NUR1JFU19QT1JUOi01NDMyfS8ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gJ0dPVFJVRV9TSVRFX1VSTD0ke1NFUlZJQ0VfVVJMX1NVUEFCQVNFS09OR30nCiAgICAgIC0gJ0dPVFJVRV9VUklfQUxMT1dfTElTVD0ke0FERElUSU9OQUxfUkVESVJFQ1RfVVJMU30nCiAgICAgIC0gJ0dPVFJVRV9ESVNBQkxFX1NJR05VUD0ke0RJU0FCTEVfU0lHTlVQOi1mYWxzZX0nCiAgICAgIC0gR09UUlVFX0pXVF9BRE1JTl9ST0xFUz1zZXJ2aWNlX3JvbGUKICAgICAgLSBHT1RSVUVfSldUX0FVRD1hdXRoZW50aWNhdGVkCiAgICAgIC0gR09UUlVFX0pXVF9ERUZBVUxUX0dST1VQX05BTUU9YXV0aGVudGljYXRlZAogICAgICAtICdHT1RSVUVfSldUX0VYUD0ke0pXVF9FWFBJUlk6LTM2MDB9JwogICAgICAtICdHT1RSVUVfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSAnR09UUlVFX0VYVEVSTkFMX0VNQUlMX0VOQUJMRUQ9JHtFTkFCTEVfRU1BSUxfU0lHTlVQOi10cnVlfScKICAgICAgLSAnR09UUlVFX0VYVEVSTkFMX0FOT05ZTU9VU19VU0VSU19FTkFCTEVEPSR7RU5BQkxFX0FOT05ZTU9VU19VU0VSUzotZmFsc2V9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX0FVVE9DT05GSVJNPSR7RU5BQkxFX0VNQUlMX0FVVE9DT05GSVJNOi1mYWxzZX0nCiAgICAgIC0gJ0dPVFJVRV9TTVRQX0FETUlOX0VNQUlMPSR7U01UUF9BRE1JTl9FTUFJTH0nCiAgICAgIC0gJ0dPVFJVRV9TTVRQX0hPU1Q9JHtTTVRQX0hPU1R9JwogICAgICAtICdHT1RSVUVfU01UUF9QT1JUPSR7U01UUF9QT1JUOi01ODd9JwogICAgICAtICdHT1RSVUVfU01UUF9VU0VSPSR7U01UUF9VU0VSfScKICAgICAgLSAnR09UUlVFX1NNVFBfUEFTUz0ke1NNVFBfUEFTU30nCiAgICAgIC0gJ0dPVFJVRV9TTVRQX1NFTkRFUl9OQU1FPSR7U01UUF9TRU5ERVJfTkFNRX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVVJMUEFUSFNfSU5WSVRFPSR7TUFJTEVSX1VSTFBBVEhTX0lOVklURTotL2F1dGgvdjEvdmVyaWZ5fScKICAgICAgLSAnR09UUlVFX01BSUxFUl9VUkxQQVRIU19DT05GSVJNQVRJT049JHtNQUlMRVJfVVJMUEFUSFNfQ09ORklSTUFUSU9OOi0vYXV0aC92MS92ZXJpZnl9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1VSTFBBVEhTX1JFQ09WRVJZPSR7TUFJTEVSX1VSTFBBVEhTX1JFQ09WRVJZOi0vYXV0aC92MS92ZXJpZnl9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1VSTFBBVEhTX0VNQUlMX0NIQU5HRT0ke01BSUxFUl9VUkxQQVRIU19FTUFJTF9DSEFOR0U6LS9hdXRoL3YxL3ZlcmlmeX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVEVNUExBVEVTX0lOVklURT0ke01BSUxFUl9URU1QTEFURVNfSU5WSVRFfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9URU1QTEFURVNfQ09ORklSTUFUSU9OPSR7TUFJTEVSX1RFTVBMQVRFU19DT05GSVJNQVRJT059JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1RFTVBMQVRFU19SRUNPVkVSWT0ke01BSUxFUl9URU1QTEFURVNfUkVDT1ZFUll9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1RFTVBMQVRFU19NQUdJQ19MSU5LPSR7TUFJTEVSX1RFTVBMQVRFU19NQUdJQ19MSU5LfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9URU1QTEFURVNfRU1BSUxfQ0hBTkdFPSR7TUFJTEVSX1RFTVBMQVRFU19FTUFJTF9DSEFOR0V9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1NVQkpFQ1RTX0NPTkZJUk1BVElPTj0ke01BSUxFUl9TVUJKRUNUU19DT05GSVJNQVRJT059JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1NVQkpFQ1RTX1JFQ09WRVJZPSR7TUFJTEVSX1NVQkpFQ1RTX1JFQ09WRVJZfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9TVUJKRUNUU19NQUdJQ19MSU5LPSR7TUFJTEVSX1NVQkpFQ1RTX01BR0lDX0xJTkt9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1NVQkpFQ1RTX0VNQUlMX0NIQU5HRT0ke01BSUxFUl9TVUJKRUNUU19FTUFJTF9DSEFOR0V9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1NVQkpFQ1RTX0lOVklURT0ke01BSUxFUl9TVUJKRUNUU19JTlZJVEV9JwogICAgICAtICdHT1RSVUVfRVhURVJOQUxfUEhPTkVfRU5BQkxFRD0ke0VOQUJMRV9QSE9ORV9TSUdOVVA6LXRydWV9JwogICAgICAtICdHT1RSVUVfU01TX0FVVE9DT05GSVJNPSR7RU5BQkxFX1BIT05FX0FVVE9DT05GSVJNOi10cnVlfScKICByZWFsdGltZS1kZXY6CiAgICBpbWFnZTogJ3N1cGFiYXNlL3JlYWx0aW1lOnYyLjM0LjQ3JwogICAgY29udGFpbmVyX25hbWU6IHJlYWx0aW1lLWRldi5zdXBhYmFzZS1yZWFsdGltZQogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1zU2ZMJwogICAgICAgIC0gJy0taGVhZCcKICAgICAgICAtICctbycKICAgICAgICAtIC9kZXYvbnVsbAogICAgICAgIC0gJy1IJwogICAgICAgIC0gJ0F1dGhvcml6YXRpb246IEJlYXJlciAke1NFUlZJQ0VfU1VQQUJBU0VBTk9OX0tFWX0nCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo0MDAwL2FwaS90ZW5hbnRzL3JlYWx0aW1lLWRldi9oZWFsdGgnCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIGludGVydmFsOiA1cwogICAgICByZXRyaWVzOiAzCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBQT1JUPTQwMDAKICAgICAgLSAnREJfSE9TVD0ke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn0nCiAgICAgIC0gJ0RCX1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSBEQl9VU0VSPXN1cGFiYXNlX2FkbWluCiAgICAgIC0gJ0RCX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ0RCX05BTUU9JHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtICdEQl9BRlRFUl9DT05ORUNUX1FVRVJZPVNFVCBzZWFyY2hfcGF0aCBUTyBfcmVhbHRpbWUnCiAgICAgIC0gREJfRU5DX0tFWT1zdXBhYmFzZXJlYWx0aW1lCiAgICAgIC0gJ0FQSV9KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtIEZMWV9BTExPQ19JRD1mbHkxMjMKICAgICAgLSBGTFlfQVBQX05BTUU9cmVhbHRpbWUKICAgICAgLSAnU0VDUkVUX0tFWV9CQVNFPSR7U0VDUkVUX1BBU1NXT1JEX1JFQUxUSU1FfScKICAgICAgLSAnRVJMX0FGTEFHUz0tcHJvdG9fZGlzdCBpbmV0X3RjcCcKICAgICAgLSBFTkFCTEVfVEFJTFNDQUxFPWZhbHNlCiAgICAgIC0gIkROU19OT0RFUz0nJyIKICAgICAgLSBSTElNSVRfTk9GSUxFPTEwMDAwCiAgICAgIC0gQVBQX05BTUU9cmVhbHRpbWUKICAgICAgLSBTRUVEX1NFTEZfSE9TVD10cnVlCiAgICAgIC0gTE9HX0xFVkVMPWVycm9yCiAgICAgIC0gUlVOX0pBTklUT1I9dHJ1ZQogICAgICAtIEpBTklUT1JfSU5URVJWQUw9NjAwMDAKICAgIGNvbW1hbmQ6ICJzaCAtYyBcIi9hcHAvYmluL21pZ3JhdGUgJiYgL2FwcC9iaW4vcmVhbHRpbWUgZXZhbCAnUmVhbHRpbWUuUmVsZWFzZS5zZWVkcyhSZWFsdGltZS5SZXBvKScgJiYgL2FwcC9iaW4vc2VydmVyXCJcbiIKICBzdXBhYmFzZS1taW5pbzoKICAgIGltYWdlOiAnZ2hjci5pby9jb29sbGFic2lvL21pbmlvOlJFTEVBU0UuMjAyNS0xMC0xNVQxNy0yOS01NVonCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnTUlOSU9fUk9PVF9VU0VSPSR7U0VSVklDRV9VU0VSX01JTklPfScKICAgICAgLSAnTUlOSU9fUk9PVF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfTUlOSU99JwogICAgY29tbWFuZDogJ3NlcnZlciAtLWNvbnNvbGUtYWRkcmVzcyAiOjkwMDEiIC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIG1jCiAgICAgICAgLSByZWFkeQogICAgICAgIC0gbG9jYWwKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogICAgdm9sdW1lczoKICAgICAgLSAnLi92b2x1bWVzL3N0b3JhZ2U6L2RhdGEnCiAgbWluaW8tY3JlYXRlYnVja2V0OgogICAgaW1hZ2U6IG1pbmlvL21jCiAgICByZXN0YXJ0OiAnbm8nCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnTUlOSU9fUk9PVF9VU0VSPSR7U0VSVklDRV9VU0VSX01JTklPfScKICAgICAgLSAnTUlOSU9fUk9PVF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfTUlOSU99JwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtbWluaW86CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudHJ5cG9pbnQ6CiAgICAgIC0gL2VudHJ5cG9pbnQuc2gKICAgIHZvbHVtZXM6CiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL2VudHJ5cG9pbnQuc2gKICAgICAgICB0YXJnZXQ6IC9lbnRyeXBvaW50LnNoCiAgICAgICAgY29udGVudDogIiMhL2Jpbi9zaFxuL3Vzci9iaW4vbWMgYWxpYXMgc2V0IHN1cGFiYXNlLW1pbmlvIGh0dHA6Ly9zdXBhYmFzZS1taW5pbzo5MDAwICR7TUlOSU9fUk9PVF9VU0VSfSAke01JTklPX1JPT1RfUEFTU1dPUkR9O1xuL3Vzci9iaW4vbWMgbWIgLS1pZ25vcmUtZXhpc3Rpbmcgc3VwYWJhc2UtbWluaW8vc3R1YjtcbmV4aXQgMFxuIgogIHN1cGFiYXNlLXN0b3JhZ2U6CiAgICBpbWFnZTogJ3N1cGFiYXNlL3N0b3JhZ2UtYXBpOnYxLjE0LjYnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBzdXBhYmFzZS1yZXN0OgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9zdGFydGVkCiAgICAgIGltZ3Byb3h5OgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9zdGFydGVkCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gd2dldAogICAgICAgIC0gJy0tbm8tdmVyYm9zZScKICAgICAgICAtICctLXRyaWVzPTEnCiAgICAgICAgLSAnLS1zcGlkZXInCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo1MDAwL3N0YXR1cycKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZFUl9QT1JUPTUwMDAKICAgICAgLSBTRVJWRVJfUkVHSU9OPWxvY2FsCiAgICAgIC0gTVVMVElfVEVOQU5UPWZhbHNlCiAgICAgIC0gJ0FVVEhfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vc3VwYWJhc2Vfc3RvcmFnZV9hZG1pbjoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9LyR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSBEQl9JTlNUQUxMX1JPTEVTPWZhbHNlCiAgICAgIC0gU1RPUkFHRV9CQUNLRU5EPXMzCiAgICAgIC0gU1RPUkFHRV9TM19CVUNLRVQ9c3R1YgogICAgICAtICdTVE9SQUdFX1MzX0VORFBPSU5UPWh0dHA6Ly9zdXBhYmFzZS1taW5pbzo5MDAwJwogICAgICAtIFNUT1JBR0VfUzNfRk9SQ0VfUEFUSF9TVFlMRT10cnVlCiAgICAgIC0gU1RPUkFHRV9TM19SRUdJT049dXMtZWFzdC0xCiAgICAgIC0gJ0FXU19BQ0NFU1NfS0VZX0lEPSR7U0VSVklDRV9VU0VSX01JTklPfScKICAgICAgLSAnQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZPSR7U0VSVklDRV9QQVNTV09SRF9NSU5JT30nCiAgICAgIC0gVVBMT0FEX0ZJTEVfU0laRV9MSU1JVD01MjQyODgwMDAKICAgICAgLSBVUExPQURfRklMRV9TSVpFX0xJTUlUX1NUQU5EQVJEPTUyNDI4ODAwMAogICAgICAtIFVQTE9BRF9TSUdORURfVVJMX0VYUElSQVRJT05fVElNRT0xMjAKICAgICAgLSBUVVNfVVJMX1BBVEg9dXBsb2FkL3Jlc3VtYWJsZQogICAgICAtIFRVU19NQVhfU0laRT0zNjAwMDAwCiAgICAgIC0gRU5BQkxFX0lNQUdFX1RSQU5TRk9STUFUSU9OPXRydWUKICAgICAgLSAnSU1HUFJPWFlfVVJMPWh0dHA6Ly9pbWdwcm94eTo4MDgwJwogICAgICAtIElNR1BST1hZX1JFUVVFU1RfVElNRU9VVD0xNQogICAgICAtIERBVEFCQVNFX1NFQVJDSF9QQVRIPXN0b3JhZ2UKICAgICAgLSBOT0RFX0VOVj1wcm9kdWN0aW9uCiAgICAgIC0gUkVRVUVTVF9BTExPV19YX0ZPUldBUkRFRF9QQVRIPXRydWUKICAgIHZvbHVtZXM6CiAgICAgIC0gJy4vdm9sdW1lcy9zdG9yYWdlOi92YXIvbGliL3N0b3JhZ2UnCiAgaW1ncHJveHk6CiAgICBpbWFnZTogJ2RhcnRoc2ltL2ltZ3Byb3h5OnYzLjguMCcKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBpbWdwcm94eQogICAgICAgIC0gaGVhbHRoCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIGludGVydmFsOiA1cwogICAgICByZXRyaWVzOiAzCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBJTUdQUk9YWV9MT0NBTF9GSUxFU1lTVEVNX1JPT1Q9LwogICAgICAtIElNR1BST1hZX1VTRV9FVEFHPXRydWUKICAgICAgLSAnSU1HUFJPWFlfRU5BQkxFX1dFQlBfREVURUNUSU9OPSR7SU1HUFJPWFlfRU5BQkxFX1dFQlBfREVURUNUSU9OOi10cnVlfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJy4vdm9sdW1lcy9zdG9yYWdlOi92YXIvbGliL3N0b3JhZ2UnCiAgc3VwYWJhc2UtbWV0YToKICAgIGltYWdlOiAnc3VwYWJhc2UvcG9zdGdyZXMtbWV0YTp2MC44OS4zJwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBQR19NRVRBX1BPUlQ9ODA4MAogICAgICAtICdQR19NRVRBX0RCX0hPU1Q9JHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9JwogICAgICAtICdQR19NRVRBX0RCX1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSAnUEdfTUVUQV9EQl9OQU1FPSR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSBQR19NRVRBX0RCX1VTRVI9c3VwYWJhc2VfYWRtaW4KICAgICAgLSAnUEdfTUVUQV9EQl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogIHN1cGFiYXNlLWVkZ2UtZnVuY3Rpb25zOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9lZGdlLXJ1bnRpbWU6djEuNjcuNCcKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWFuYWx5dGljczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGVjaG8KICAgICAgICAtICdFZGdlIEZ1bmN0aW9ucyBpcyBoZWFsdGh5JwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gJ1NVUEFCQVNFX1VSTD0ke1NFUlZJQ0VfVVJMX1NVUEFCQVNFS09OR30nCiAgICAgIC0gJ1NVUEFCQVNFX0FOT05fS0VZPSR7U0VSVklDRV9TVVBBQkFTRUFOT05fS0VZfScKICAgICAgLSAnU1VQQUJBU0VfU0VSVklDRV9ST0xFX0tFWT0ke1NFUlZJQ0VfU1VQQUJBU0VTRVJWSUNFX0tFWX0nCiAgICAgIC0gJ1NVUEFCQVNFX0RCX1VSTD1wb3N0Z3Jlc3FsOi8vcG9zdGdyZXM6JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUAke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn06JHtQT1NUR1JFU19QT1JUOi01NDMyfS8ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gJ1ZFUklGWV9KV1Q9JHtGVU5DVElPTlNfVkVSSUZZX0pXVDotZmFsc2V9JwogICAgdm9sdW1lczoKICAgICAgLSAnLi92b2x1bWVzL2Z1bmN0aW9uczovaG9tZS9kZW5vL2Z1bmN0aW9ucycKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9mdW5jdGlvbnMvbWFpbi9pbmRleC50cwogICAgICAgIHRhcmdldDogL2hvbWUvZGVuby9mdW5jdGlvbnMvbWFpbi9pbmRleC50cwogICAgICAgIGNvbnRlbnQ6ICJpbXBvcnQgeyBzZXJ2ZSB9IGZyb20gJ2h0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjEzMS4wL2h0dHAvc2VydmVyLnRzJ1xuaW1wb3J0ICogYXMgam9zZSBmcm9tICdodHRwczovL2Rlbm8ubGFuZC94L2pvc2VAdjQuMTQuNC9pbmRleC50cydcblxuY29uc29sZS5sb2coJ21haW4gZnVuY3Rpb24gc3RhcnRlZCcpXG5cbmNvbnN0IEpXVF9TRUNSRVQgPSBEZW5vLmVudi5nZXQoJ0pXVF9TRUNSRVQnKVxuY29uc3QgVkVSSUZZX0pXVCA9IERlbm8uZW52LmdldCgnVkVSSUZZX0pXVCcpID09PSAndHJ1ZSdcblxuZnVuY3Rpb24gZ2V0QXV0aFRva2VuKHJlcTogUmVxdWVzdCkge1xuICBjb25zdCBhdXRoSGVhZGVyID0gcmVxLmhlYWRlcnMuZ2V0KCdhdXRob3JpemF0aW9uJylcbiAgaWYgKCFhdXRoSGVhZGVyKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdNaXNzaW5nIGF1dGhvcml6YXRpb24gaGVhZGVyJylcbiAgfVxuICBjb25zdCBbYmVhcmVyLCB0b2tlbl0gPSBhdXRoSGVhZGVyLnNwbGl0KCcgJylcbiAgaWYgKGJlYXJlciAhPT0gJ0JlYXJlcicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYEF1dGggaGVhZGVyIGlzIG5vdCAnQmVhcmVyIHt0b2tlbn0nYClcbiAgfVxuICByZXR1cm4gdG9rZW5cbn1cblxuYXN5bmMgZnVuY3Rpb24gdmVyaWZ5SldUKGp3dDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IGVuY29kZXIgPSBuZXcgVGV4dEVuY29kZXIoKVxuICBjb25zdCBzZWNyZXRLZXkgPSBlbmNvZGVyLmVuY29kZShKV1RfU0VDUkVUKVxuICB0cnkge1xuICAgIGF3YWl0IGpvc2Uuand0VmVyaWZ5KGp3dCwgc2VjcmV0S2V5KVxuICB9IGNhdGNoIChlcnIpIHtcbiAgICBjb25zb2xlLmVycm9yKGVycilcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxuICByZXR1cm4gdHJ1ZVxufVxuXG5zZXJ2ZShhc3luYyAocmVxOiBSZXF1ZXN0KSA9PiB7XG4gIGlmIChyZXEubWV0aG9kICE9PSAnT1BUSU9OUycgJiYgVkVSSUZZX0pXVCkge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCB0b2tlbiA9IGdldEF1dGhUb2tlbihyZXEpXG4gICAgICBjb25zdCBpc1ZhbGlkSldUID0gYXdhaXQgdmVyaWZ5SldUKHRva2VuKVxuXG4gICAgICBpZiAoIWlzVmFsaWRKV1QpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShKU09OLnN0cmluZ2lmeSh7IG1zZzogJ0ludmFsaWQgSldUJyB9KSwge1xuICAgICAgICAgIHN0YXR1czogNDAxLFxuICAgICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoZSlcbiAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoSlNPTi5zdHJpbmdpZnkoeyBtc2c6IGUudG9TdHJpbmcoKSB9KSwge1xuICAgICAgICBzdGF0dXM6IDQwMSxcbiAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IHVybCA9IG5ldyBVUkwocmVxLnVybClcbiAgY29uc3QgeyBwYXRobmFtZSB9ID0gdXJsXG4gIGNvbnN0IHBhdGhfcGFydHMgPSBwYXRobmFtZS5zcGxpdCgnLycpXG4gIGNvbnN0IHNlcnZpY2VfbmFtZSA9IHBhdGhfcGFydHNbMV1cblxuICBpZiAoIXNlcnZpY2VfbmFtZSB8fCBzZXJ2aWNlX25hbWUgPT09ICcnKSB7XG4gICAgY29uc3QgZXJyb3IgPSB7IG1zZzogJ21pc3NpbmcgZnVuY3Rpb24gbmFtZSBpbiByZXF1ZXN0JyB9XG4gICAgcmV0dXJuIG5ldyBSZXNwb25zZShKU09OLnN0cmluZ2lmeShlcnJvciksIHtcbiAgICAgIHN0YXR1czogNDAwLFxuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgfSlcbiAgfVxuXG4gIGNvbnN0IHNlcnZpY2VQYXRoID0gYC9ob21lL2Rlbm8vZnVuY3Rpb25zLyR7c2VydmljZV9uYW1lfWBcbiAgY29uc29sZS5lcnJvcihgc2VydmluZyB0aGUgcmVxdWVzdCB3aXRoICR7c2VydmljZVBhdGh9YClcblxuICBjb25zdCBtZW1vcnlMaW1pdE1iID0gMTUwXG4gIGNvbnN0IHdvcmtlclRpbWVvdXRNcyA9IDEgKiA2MCAqIDEwMDBcbiAgY29uc3Qgbm9Nb2R1bGVDYWNoZSA9IGZhbHNlXG4gIGNvbnN0IGltcG9ydE1hcFBhdGggPSBudWxsXG4gIGNvbnN0IGVudlZhcnNPYmogPSBEZW5vLmVudi50b09iamVjdCgpXG4gIGNvbnN0IGVudlZhcnMgPSBPYmplY3Qua2V5cyhlbnZWYXJzT2JqKS5tYXAoKGspID0+IFtrLCBlbnZWYXJzT2JqW2tdXSlcblxuICB0cnkge1xuICAgIGNvbnN0IHdvcmtlciA9IGF3YWl0IEVkZ2VSdW50aW1lLnVzZXJXb3JrZXJzLmNyZWF0ZSh7XG4gICAgICBzZXJ2aWNlUGF0aCxcbiAgICAgIG1lbW9yeUxpbWl0TWIsXG4gICAgICB3b3JrZXJUaW1lb3V0TXMsXG4gICAgICBub01vZHVsZUNhY2hlLFxuICAgICAgaW1wb3J0TWFwUGF0aCxcbiAgICAgIGVudlZhcnMsXG4gICAgfSlcbiAgICByZXR1cm4gYXdhaXQgd29ya2VyLmZldGNoKHJlcSlcbiAgfSBjYXRjaCAoZSkge1xuICAgIGNvbnN0IGVycm9yID0geyBtc2c6IGUudG9TdHJpbmcoKSB9XG4gICAgcmV0dXJuIG5ldyBSZXNwb25zZShKU09OLnN0cmluZ2lmeShlcnJvciksIHtcbiAgICAgIHN0YXR1czogNTAwLFxuICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgfSlcbiAgfVxufSkiCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZnVuY3Rpb25zL2hlbGxvL2luZGV4LnRzCiAgICAgICAgdGFyZ2V0OiAvaG9tZS9kZW5vL2Z1bmN0aW9ucy9oZWxsby9pbmRleC50cwogICAgICAgIGNvbnRlbnQ6ICIvLyBGb2xsb3cgdGhpcyBzZXR1cCBndWlkZSB0byBpbnRlZ3JhdGUgdGhlIERlbm8gbGFuZ3VhZ2Ugc2VydmVyIHdpdGggeW91ciBlZGl0b3I6XG4vLyBodHRwczovL2Rlbm8ubGFuZC9tYW51YWwvZ2V0dGluZ19zdGFydGVkL3NldHVwX3lvdXJfZW52aXJvbm1lbnRcbi8vIFRoaXMgZW5hYmxlcyBhdXRvY29tcGxldGUsIGdvIHRvIGRlZmluaXRpb24sIGV0Yy5cblxuaW1wb3J0IHsgc2VydmUgfSBmcm9tIFwiaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuMTc3LjEvaHR0cC9zZXJ2ZXIudHNcIlxuXG5zZXJ2ZShhc3luYyAoKSA9PiB7XG4gIHJldHVybiBuZXcgUmVzcG9uc2UoXG4gICAgYFwiSGVsbG8gZnJvbSBFZGdlIEZ1bmN0aW9ucyFcImAsXG4gICAgeyBoZWFkZXJzOiB7IFwiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwiIH0gfSxcbiAgKVxufSlcblxuLy8gVG8gaW52b2tlOlxuLy8gY3VybCAnaHR0cDovL2xvY2FsaG9zdDo8S09OR19IVFRQX1BPUlQ+L2Z1bmN0aW9ucy92MS9oZWxsbycgXFxcbi8vICAgLS1oZWFkZXIgJ0F1dGhvcml6YXRpb246IEJlYXJlciA8YW5vbi9zZXJ2aWNlX3JvbGUgQVBJIGtleT4nXG4iCiAgICBjb21tYW5kOgogICAgICAtIHN0YXJ0CiAgICAgIC0gJy0tbWFpbi1zZXJ2aWNlJwogICAgICAtIC9ob21lL2Rlbm8vZnVuY3Rpb25zL21haW4KICBzdXBhYmFzZS1zdXBhdmlzb3I6CiAgICBpbWFnZTogJ3N1cGFiYXNlL3N1cGF2aXNvcjoyLjUuMScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLXNTZkwnCiAgICAgICAgLSAnLW8nCiAgICAgICAgLSAvZGV2L251bGwKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjQwMDAvYXBpL2hlYWx0aCcKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudmlyb25tZW50OgogICAgICAtIFBPT0xFUl9URU5BTlRfSUQ9ZGV2X3RlbmFudAogICAgICAtIFBPT0xFUl9QT09MX01PREU9dHJhbnNhY3Rpb24KICAgICAgLSAnUE9PTEVSX0RFRkFVTFRfUE9PTF9TSVpFPSR7UE9PTEVSX0RFRkFVTFRfUE9PTF9TSVpFOi0yMH0nCiAgICAgIC0gJ1BPT0xFUl9NQVhfQ0xJRU5UX0NPTk49JHtQT09MRVJfTUFYX0NMSUVOVF9DT05OOi0xMDB9JwogICAgICAtIFBPUlQ9NDAwMAogICAgICAtICdQT1NUR1JFU19QT1JUPSR7UE9TVEdSRVNfUE9SVDotNTQzMn0nCiAgICAgIC0gJ1BPU1RHUkVTX0hPU1ROQU1FPSR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdEQVRBQkFTRV9VUkw9ZWN0bzovL3N1cGFiYXNlX2FkbWluOiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AJHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9OiR7UE9TVEdSRVNfUE9SVDotNTQzMn0vX3N1cGFiYXNlJwogICAgICAtIENMVVNURVJfUE9TVEdSRVM9dHJ1ZQogICAgICAtICdTRUNSRVRfS0VZX0JBU0U9JHtTRVJWSUNFX1BBU1NXT1JEX1NVUEFWSVNPUlNFQ1JFVH0nCiAgICAgIC0gJ1ZBVUxUX0VOQ19LRVk9JHtTRVJWSUNFX1BBU1NXT1JEX1ZBVUxURU5DfScKICAgICAgLSAnQVBJX0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gJ01FVFJJQ1NfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSBSRUdJT049bG9jYWwKICAgICAgLSAnRVJMX0FGTEFHUz0tcHJvdG9fZGlzdCBpbmV0X3RjcCcKICAgIGNvbW1hbmQ6CiAgICAgIC0gL2Jpbi9zaAogICAgICAtICctYycKICAgICAgLSAnL2FwcC9iaW4vbWlncmF0ZSAmJiAvYXBwL2Jpbi9zdXBhdmlzb3IgZXZhbCAiJCQoY2F0IC9ldGMvcG9vbGVyL3Bvb2xlci5leHMpIiAmJiAvYXBwL2Jpbi9zZXJ2ZXInCiAgICB2b2x1bWVzOgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL3Bvb2xlci9wb29sZXIuZXhzCiAgICAgICAgdGFyZ2V0OiAvZXRjL3Bvb2xlci9wb29sZXIuZXhzCiAgICAgICAgY29udGVudDogIns6b2ssIF99ID0gQXBwbGljYXRpb24uZW5zdXJlX2FsbF9zdGFydGVkKDpzdXBhdmlzb3IpXG57Om9rLCB2ZXJzaW9ufSA9XG4gICAgY2FzZSBTdXBhdmlzb3IuUmVwby5xdWVyeSEoXCJzZWxlY3QgdmVyc2lvbigpXCIpIGRvXG4gICAgJXtyb3dzOiBbW3Zlcl1dfSAtPiBTdXBhdmlzb3IuSGVscGVycy5wYXJzZV9wZ192ZXJzaW9uKHZlcilcbiAgICBfIC0+IG5pbFxuICAgIGVuZFxucGFyYW1zID0gJXtcbiAgICBcImV4dGVybmFsX2lkXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT09MRVJfVEVOQU5UX0lEXCIpLFxuICAgIFwiZGJfaG9zdFwiID0+IFN5c3RlbS5nZXRfZW52KFwiUE9TVEdSRVNfSE9TVE5BTUVcIiksXG4gICAgXCJkYl9wb3J0XCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT1NUR1JFU19QT1JUXCIpIHw+IFN0cmluZy50b19pbnRlZ2VyKCksXG4gICAgXCJkYl9kYXRhYmFzZVwiID0+IFN5c3RlbS5nZXRfZW52KFwiUE9TVEdSRVNfREJcIiksXG4gICAgXCJyZXF1aXJlX3VzZXJcIiA9PiBmYWxzZSxcbiAgICBcImF1dGhfcXVlcnlcIiA9PiBcIlNFTEVDVCAqIEZST00gcGdib3VuY2VyLmdldF9hdXRoKCQxKVwiLFxuICAgIFwiZGVmYXVsdF9tYXhfY2xpZW50c1wiID0+IFN5c3RlbS5nZXRfZW52KFwiUE9PTEVSX01BWF9DTElFTlRfQ09OTlwiKSxcbiAgICBcImRlZmF1bHRfcG9vbF9zaXplXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT09MRVJfREVGQVVMVF9QT09MX1NJWkVcIiksXG4gICAgXCJkZWZhdWx0X3BhcmFtZXRlcl9zdGF0dXNcIiA9PiAle1wic2VydmVyX3ZlcnNpb25cIiA9PiB2ZXJzaW9ufSxcbiAgICBcInVzZXJzXCIgPT4gWyV7XG4gICAgXCJkYl91c2VyXCIgPT4gXCJwZ2JvdW5jZXJcIixcbiAgICBcImRiX3Bhc3N3b3JkXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT1NUR1JFU19QQVNTV09SRFwiKSxcbiAgICBcIm1vZGVfdHlwZVwiID0+IFN5c3RlbS5nZXRfZW52KFwiUE9PTEVSX1BPT0xfTU9ERVwiKSxcbiAgICBcInBvb2xfc2l6ZVwiID0+IFN5c3RlbS5nZXRfZW52KFwiUE9PTEVSX0RFRkFVTFRfUE9PTF9TSVpFXCIpLFxuICAgIFwiaXNfbWFuYWdlclwiID0+IHRydWVcbiAgICB9XVxufVxuXG50ZW5hbnQgPSBTdXBhdmlzb3IuVGVuYW50cy5nZXRfdGVuYW50X2J5X2V4dGVybmFsX2lkKHBhcmFtc1tcImV4dGVybmFsX2lkXCJdKVxuXG5pZiB0ZW5hbnQgZG9cbiAgezpvaywgX30gPSBTdXBhdmlzb3IuVGVuYW50cy51cGRhdGVfdGVuYW50KHRlbmFudCwgcGFyYW1zKVxuZWxzZVxuICB7Om9rLCBffSA9IFN1cGF2aXNvci5UZW5hbnRzLmNyZWF0ZV90ZW5hbnQocGFyYW1zKVxuZW5kXG4iCg==", + "compose": "c2VydmljZXM6CiAgc3VwYWJhc2Uta29uZzoKICAgIGltYWdlOiAna29uZzoyLjguMScKICAgIGVudHJ5cG9pbnQ6ICdiYXNoIC1jICcnZXZhbCAiZWNobyBcIiQkKGNhdCB+L3RlbXAueW1sKVwiIiA+IH4va29uZy55bWwgJiYgL2RvY2tlci1lbnRyeXBvaW50LnNoIGtvbmcgZG9ja2VyLXN0YXJ0JycnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfVVJMX1NVUEFCQVNFS09OR184MDAwCiAgICAgIC0gJ0tPTkdfUE9SVF9NQVBTPTQ0Mzo4MDAwJwogICAgICAtICdKV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtIEtPTkdfREFUQUJBU0U9b2ZmCiAgICAgIC0gS09OR19ERUNMQVJBVElWRV9DT05GSUc9L2hvbWUva29uZy9rb25nLnltbAogICAgICAtICdLT05HX0ROU19PUkRFUj1MQVNULEEsQ05BTUUnCiAgICAgIC0gJ0tPTkdfUExVR0lOUz1yZXF1ZXN0LXRyYW5zZm9ybWVyLGNvcnMsa2V5LWF1dGgsYWNsLGJhc2ljLWF1dGgnCiAgICAgIC0gS09OR19OR0lOWF9QUk9YWV9QUk9YWV9CVUZGRVJfU0laRT0xNjBrCiAgICAgIC0gJ0tPTkdfTkdJTlhfUFJPWFlfUFJPWFlfQlVGRkVSUz02NCAxNjBrJwogICAgICAtICdTVVBBQkFTRV9BTk9OX0tFWT0ke1NFUlZJQ0VfU1VQQUJBU0VBTk9OX0tFWX0nCiAgICAgIC0gJ1NVUEFCQVNFX1NFUlZJQ0VfS0VZPSR7U0VSVklDRV9TVVBBQkFTRVNFUlZJQ0VfS0VZfScKICAgICAgLSAnREFTSEJPQVJEX1VTRVJOQU1FPSR7U0VSVklDRV9VU0VSX0FETUlOfScKICAgICAgLSAnREFTSEJPQVJEX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9BRE1JTn0nCiAgICB2b2x1bWVzOgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2FwaS9rb25nLnltbAogICAgICAgIHRhcmdldDogL2hvbWUva29uZy90ZW1wLnltbAogICAgICAgIGNvbnRlbnQ6ICJfZm9ybWF0X3ZlcnNpb246ICcyLjEnXG5fdHJhbnNmb3JtOiB0cnVlXG5cbiMjI1xuIyMjIENvbnN1bWVycyAvIFVzZXJzXG4jIyNcbmNvbnN1bWVyczpcbiAgLSB1c2VybmFtZTogREFTSEJPQVJEXG4gIC0gdXNlcm5hbWU6IGFub25cbiAgICBrZXlhdXRoX2NyZWRlbnRpYWxzOlxuICAgICAgLSBrZXk6ICRTVVBBQkFTRV9BTk9OX0tFWVxuICAtIHVzZXJuYW1lOiBzZXJ2aWNlX3JvbGVcbiAgICBrZXlhdXRoX2NyZWRlbnRpYWxzOlxuICAgICAgLSBrZXk6ICRTVVBBQkFTRV9TRVJWSUNFX0tFWVxuXG4jIyNcbiMjIyBBY2Nlc3MgQ29udHJvbCBMaXN0XG4jIyNcbmFjbHM6XG4gIC0gY29uc3VtZXI6IGFub25cbiAgICBncm91cDogYW5vblxuICAtIGNvbnN1bWVyOiBzZXJ2aWNlX3JvbGVcbiAgICBncm91cDogYWRtaW5cblxuIyMjXG4jIyMgRGFzaGJvYXJkIGNyZWRlbnRpYWxzXG4jIyNcbmJhc2ljYXV0aF9jcmVkZW50aWFsczpcbi0gY29uc3VtZXI6IERBU0hCT0FSRFxuICB1c2VybmFtZTogJERBU0hCT0FSRF9VU0VSTkFNRVxuICBwYXNzd29yZDogJERBU0hCT0FSRF9QQVNTV09SRFxuXG5cbiMjI1xuIyMjIEFQSSBSb3V0ZXNcbiMjI1xuc2VydmljZXM6XG5cbiAgIyMgT3BlbiBBdXRoIHJvdXRlc1xuICAtIG5hbWU6IGF1dGgtdjEtb3BlblxuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS92ZXJpZnlcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGF1dGgtdjEtb3BlblxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2F1dGgvdjEvdmVyaWZ5XG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAtIG5hbWU6IGF1dGgtdjEtb3Blbi1jYWxsYmFja1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS9jYWxsYmFja1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogYXV0aC12MS1vcGVuLWNhbGxiYWNrXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvYXV0aC92MS9jYWxsYmFja1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgLSBuYW1lOiBhdXRoLXYxLW9wZW4tYXV0aG9yaXplXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtYXV0aDo5OTk5L2F1dGhvcml6ZVxuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogYXV0aC12MS1vcGVuLWF1dGhvcml6ZVxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2F1dGgvdjEvYXV0aG9yaXplXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuXG4gICMjIFNlY3VyZSBBdXRoIHJvdXRlc1xuICAtIG5hbWU6IGF1dGgtdjFcbiAgICBfY29tbWVudDogJ0dvVHJ1ZTogL2F1dGgvdjEvKiAtPiBodHRwOi8vc3VwYWJhc2UtYXV0aDo5OTk5LyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtYXV0aDo5OTk5L1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogYXV0aC12MS1hbGxcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9hdXRoL3YxL1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgICAgIC0gbmFtZToga2V5LWF1dGhcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfY3JlZGVudGlhbHM6IGZhbHNlXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG4gICAgICAgICAgICAtIGFub25cblxuICAjIyBTZWN1cmUgUkVTVCByb3V0ZXNcbiAgLSBuYW1lOiByZXN0LXYxXG4gICAgX2NvbW1lbnQ6ICdQb3N0Z1JFU1Q6IC9yZXN0L3YxLyogLT4gaHR0cDovL3N1cGFiYXNlLXJlc3Q6MzAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLXJlc3Q6MzAwMC9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IHJlc3QtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvcmVzdC92MS9cbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gICAgICAtIG5hbWU6IGtleS1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiB0cnVlXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG4gICAgICAgICAgICAtIGFub25cblxuICAjIyBTZWN1cmUgR3JhcGhRTCByb3V0ZXNcbiAgLSBuYW1lOiBncmFwaHFsLXYxXG4gICAgX2NvbW1lbnQ6ICdQb3N0Z1JFU1Q6IC9ncmFwaHFsL3YxLyogLT4gaHR0cDovL3N1cGFiYXNlLXJlc3Q6MzAwMC9ycGMvZ3JhcGhxbCdcbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1yZXN0OjMwMDAvcnBjL2dyYXBocWxcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGdyYXBocWwtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvZ3JhcGhxbC92MVxuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgICAgIC0gbmFtZToga2V5LWF1dGhcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfY3JlZGVudGlhbHM6IHRydWVcbiAgICAgIC0gbmFtZTogcmVxdWVzdC10cmFuc2Zvcm1lclxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgYWRkOlxuICAgICAgICAgICAgaGVhZGVyczpcbiAgICAgICAgICAgICAgLSBDb250ZW50LVByb2ZpbGU6Z3JhcGhxbF9wdWJsaWNcbiAgICAgIC0gbmFtZTogYWNsXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2dyb3Vwc19oZWFkZXI6IHRydWVcbiAgICAgICAgICBhbGxvdzpcbiAgICAgICAgICAgIC0gYWRtaW5cbiAgICAgICAgICAgIC0gYW5vblxuXG4gICMjIFNlY3VyZSBSZWFsdGltZSByb3V0ZXNcbiAgLSBuYW1lOiByZWFsdGltZS12MS13c1xuICAgIF9jb21tZW50OiAnUmVhbHRpbWU6IC9yZWFsdGltZS92MS8qIC0+IHdzOi8vcmVhbHRpbWU6NDAwMC9zb2NrZXQvKidcbiAgICB1cmw6IGh0dHA6Ly9yZWFsdGltZS1kZXY6NDAwMC9zb2NrZXRcbiAgICBwcm90b2NvbDogd3NcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IHJlYWx0aW1lLXYxLXdzXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvcmVhbHRpbWUvdjEvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAgICAgLSBuYW1lOiBrZXktYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogZmFsc2VcbiAgICAgIC0gbmFtZTogYWNsXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2dyb3Vwc19oZWFkZXI6IHRydWVcbiAgICAgICAgICBhbGxvdzpcbiAgICAgICAgICAgIC0gYWRtaW5cbiAgICAgICAgICAgIC0gYW5vblxuICAtIG5hbWU6IHJlYWx0aW1lLXYxLXJlc3RcbiAgICBfY29tbWVudDogJ1JlYWx0aW1lOiAvcmVhbHRpbWUvdjEvKiAtPiB3czovL3JlYWx0aW1lOjQwMDAvc29ja2V0LyonXG4gICAgdXJsOiBodHRwOi8vcmVhbHRpbWUtZGV2OjQwMDAvYXBpXG4gICAgcHJvdG9jb2w6IGh0dHBcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IHJlYWx0aW1lLXYxLXJlc3RcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9yZWFsdGltZS92MS9hcGlcbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gICAgICAtIG5hbWU6IGtleS1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiBmYWxzZVxuICAgICAgLSBuYW1lOiBhY2xcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfZ3JvdXBzX2hlYWRlcjogdHJ1ZVxuICAgICAgICAgIGFsbG93OlxuICAgICAgICAgICAgLSBhZG1pblxuICAgICAgICAgICAgLSBhbm9uXG5cbiAgIyMgU3RvcmFnZSByb3V0ZXM6IHRoZSBzdG9yYWdlIHNlcnZlciBtYW5hZ2VzIGl0cyBvd24gYXV0aFxuICAtIG5hbWU6IHN0b3JhZ2UtdjFcbiAgICBfY29tbWVudDogJ1N0b3JhZ2U6IC9zdG9yYWdlL3YxLyogLT4gaHR0cDovL3N1cGFiYXNlLXN0b3JhZ2U6NTAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLXN0b3JhZ2U6NTAwMC9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IHN0b3JhZ2UtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvc3RvcmFnZS92MS9cbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG5cbiAgIyMgRWRnZSBGdW5jdGlvbnMgcm91dGVzXG4gIC0gbmFtZTogZnVuY3Rpb25zLXYxXG4gICAgX2NvbW1lbnQ6ICdFZGdlIEZ1bmN0aW9uczogL2Z1bmN0aW9ucy92MS8qIC0+IGh0dHA6Ly9zdXBhYmFzZS1lZGdlLWZ1bmN0aW9uczo5MDAwLyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtZWRnZS1mdW5jdGlvbnM6OTAwMC9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGZ1bmN0aW9ucy12MS1hbGxcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9mdW5jdGlvbnMvdjEvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuXG4gICMjIEFuYWx5dGljcyByb3V0ZXNcbiAgLSBuYW1lOiBhbmFseXRpY3MtdjFcbiAgICBfY29tbWVudDogJ0FuYWx5dGljczogL2FuYWx5dGljcy92MS8qIC0+IGh0dHA6Ly9sb2dmbGFyZTo0MDAwLyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBhbmFseXRpY3MtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvYW5hbHl0aWNzL3YxL1xuXG4gICMjIFNlY3VyZSBEYXRhYmFzZSByb3V0ZXNcbiAgLSBuYW1lOiBtZXRhXG4gICAgX2NvbW1lbnQ6ICdwZy1tZXRhOiAvcGcvKiAtPiBodHRwOi8vc3VwYWJhc2UtbWV0YTo4MDgwLyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtbWV0YTo4MDgwL1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogbWV0YS1hbGxcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9wZy9cbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBrZXktYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogZmFsc2VcbiAgICAgIC0gbmFtZTogYWNsXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2dyb3Vwc19oZWFkZXI6IHRydWVcbiAgICAgICAgICBhbGxvdzpcbiAgICAgICAgICAgIC0gYWRtaW5cblxuICAjIyBQcm90ZWN0ZWQgRGFzaGJvYXJkIC0gY2F0Y2ggYWxsIHJlbWFpbmluZyByb3V0ZXNcbiAgLSBuYW1lOiBkYXNoYm9hcmRcbiAgICBfY29tbWVudDogJ1N0dWRpbzogLyogLT4gaHR0cDovL3N0dWRpbzozMDAwLyonXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2Utc3R1ZGlvOjMwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBkYXNoYm9hcmQtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAgICAgLSBuYW1lOiBiYXNpYy1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiB0cnVlXG4iCiAgc3VwYWJhc2Utc3R1ZGlvOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9zdHVkaW86MjAyNi4wMS4wNy1zaGEtMDM3ZTVmOScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBub2RlCiAgICAgICAgLSAnLWUnCiAgICAgICAgLSAiZmV0Y2goJ2h0dHA6Ly8xMjcuMC4wLjE6MzAwMC9hcGkvcGxhdGZvcm0vcHJvZmlsZScpLnRoZW4oKHIpID0+IHtpZiAoci5zdGF0dXMgIT09IDIwMCkgdGhyb3cgbmV3IEVycm9yKHIuc3RhdHVzKX0pIgogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBIT1NUTkFNRT0wLjAuMC4wCiAgICAgIC0gJ1NUVURJT19QR19NRVRBX1VSTD1odHRwOi8vc3VwYWJhc2UtbWV0YTo4MDgwJwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19IT1NUPSR7UE9TVEdSRVNfSE9TVDotc3VwYWJhc2UtZGJ9JwogICAgICAtIENVUlJFTlRfQ0xJX1ZFUlNJT049Mi42Ny4xCiAgICAgIC0gJ0RFRkFVTFRfT1JHQU5JWkFUSU9OX05BTUU9JHtTVFVESU9fREVGQVVMVF9PUkdBTklaQVRJT046LURlZmF1bHQgT3JnYW5pemF0aW9ufScKICAgICAgLSAnREVGQVVMVF9QUk9KRUNUX05BTUU9JHtTVFVESU9fREVGQVVMVF9QUk9KRUNUOi1EZWZhdWx0IFByb2plY3R9JwogICAgICAtICdTVVBBQkFTRV9VUkw9aHR0cDovL3N1cGFiYXNlLWtvbmc6ODAwMCcKICAgICAgLSAnU1VQQUJBU0VfUFVCTElDX1VSTD0ke1NFUlZJQ0VfVVJMX1NVUEFCQVNFS09OR30nCiAgICAgIC0gJ1NVUEFCQVNFX0FOT05fS0VZPSR7U0VSVklDRV9TVVBBQkFTRUFOT05fS0VZfScKICAgICAgLSAnU1VQQUJBU0VfU0VSVklDRV9LRVk9JHtTRVJWSUNFX1NVUEFCQVNFU0VSVklDRV9LRVl9JwogICAgICAtICdBVVRIX0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gJ0xPR0ZMQVJFX0FQSV9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEX0xPR0ZMQVJFfScKICAgICAgLSAnTE9HRkxBUkVfVVJMPWh0dHA6Ly9zdXBhYmFzZS1hbmFseXRpY3M6NDAwMCcKICAgICAgLSAnU1VQQUJBU0VfUFVCTElDX0FQST0ke1NFUlZJQ0VfVVJMX1NVUEFCQVNFS09OR30nCiAgICAgIC0gTkVYVF9QVUJMSUNfRU5BQkxFX0xPR1M9dHJ1ZQogICAgICAtIE5FWFRfQU5BTFlUSUNTX0JBQ0tFTkRfUFJPVklERVI9cG9zdGdyZXMKICAgICAgLSAnT1BFTkFJX0FQSV9LRVk9JHtPUEVOQUlfQVBJX0tFWX0nCiAgc3VwYWJhc2UtZGI6CiAgICBpbWFnZTogJ3N1cGFiYXNlL3Bvc3RncmVzOjE1LjguMS4wNDgnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDogJ3BnX2lzcmVhZHkgLVUgcG9zdGdyZXMgLWggMTI3LjAuMC4xJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTAKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLXZlY3RvcjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgY29tbWFuZDoKICAgICAgLSBwb3N0Z3JlcwogICAgICAtICctYycKICAgICAgLSBjb25maWdfZmlsZT0vZXRjL3Bvc3RncmVzcWwvcG9zdGdyZXNxbC5jb25mCiAgICAgIC0gJy1jJwogICAgICAtIGxvZ19taW5fbWVzc2FnZXM9ZmF0YWwKICAgIGVudmlyb25tZW50OgogICAgICAtIFBPU1RHUkVTX0hPU1Q9L3Zhci9ydW4vcG9zdGdyZXNxbAogICAgICAtICdQR1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSAnUE9TVEdSRVNfUE9SVD0ke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9JwogICAgICAtICdQR1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BHREFUQUJBU0U9JHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gJ0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gJ0pXVF9FWFA9JHtKV1RfRVhQSVJZOi0zNjAwfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3N1cGFiYXNlLWRiLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2RiL3JlYWx0aW1lLnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL21pZ3JhdGlvbnMvOTktcmVhbHRpbWUuc3FsCiAgICAgICAgY29udGVudDogIlxcc2V0IHBndXNlciBgZWNobyBcInN1cGFiYXNlX2FkbWluXCJgXG5cbmNyZWF0ZSBzY2hlbWEgaWYgbm90IGV4aXN0cyBfcmVhbHRpbWU7XG5hbHRlciBzY2hlbWEgX3JlYWx0aW1lIG93bmVyIHRvIDpwZ3VzZXI7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvX3N1cGFiYXNlLnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL21pZ3JhdGlvbnMvOTctX3N1cGFiYXNlLnNxbAogICAgICAgIGNvbnRlbnQ6ICJcXHNldCBwZ3VzZXIgYGVjaG8gXCIkUE9TVEdSRVNfVVNFUlwiYFxuXG5DUkVBVEUgREFUQUJBU0UgX3N1cGFiYXNlIFdJVEggT1dORVIgOnBndXNlcjtcbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi9wb29sZXIuc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvbWlncmF0aW9ucy85OS1wb29sZXIuc3FsCiAgICAgICAgY29udGVudDogIlxcc2V0IHBndXNlciBgZWNobyBcInN1cGFiYXNlX2FkbWluXCJgXG5cXGMgX3N1cGFiYXNlXG5jcmVhdGUgc2NoZW1hIGlmIG5vdCBleGlzdHMgX3N1cGF2aXNvcjtcbmFsdGVyIHNjaGVtYSBfc3VwYXZpc29yIG93bmVyIHRvIDpwZ3VzZXI7XG5cXGMgcG9zdGdyZXNcbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi93ZWJob29rcy5zcWwKICAgICAgICB0YXJnZXQ6IC9kb2NrZXItZW50cnlwb2ludC1pbml0ZGIuZC9pbml0LXNjcmlwdHMvOTgtd2ViaG9va3Muc3FsCiAgICAgICAgY29udGVudDogIkJFR0lOO1xuLS0gQ3JlYXRlIHBnX25ldCBleHRlbnNpb25cbkNSRUFURSBFWFRFTlNJT04gSUYgTk9UIEVYSVNUUyBwZ19uZXQgU0NIRU1BIGV4dGVuc2lvbnM7XG4tLSBDcmVhdGUgc3VwYWJhc2VfZnVuY3Rpb25zIHNjaGVtYVxuQ1JFQVRFIFNDSEVNQSBzdXBhYmFzZV9mdW5jdGlvbnMgQVVUSE9SSVpBVElPTiBzdXBhYmFzZV9hZG1pbjtcbkdSQU5UIFVTQUdFIE9OIFNDSEVNQSBzdXBhYmFzZV9mdW5jdGlvbnMgVE8gcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbkFMVEVSIERFRkFVTFQgUFJJVklMRUdFUyBJTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIEdSQU5UIEFMTCBPTiBUQUJMRVMgVE8gcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbkFMVEVSIERFRkFVTFQgUFJJVklMRUdFUyBJTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIEdSQU5UIEFMTCBPTiBGVU5DVElPTlMgVE8gcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbkFMVEVSIERFRkFVTFQgUFJJVklMRUdFUyBJTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIEdSQU5UIEFMTCBPTiBTRVFVRU5DRVMgVE8gcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbi0tIHN1cGFiYXNlX2Z1bmN0aW9ucy5taWdyYXRpb25zIGRlZmluaXRpb25cbkNSRUFURSBUQUJMRSBzdXBhYmFzZV9mdW5jdGlvbnMubWlncmF0aW9ucyAoXG4gIHZlcnNpb24gdGV4dCBQUklNQVJZIEtFWSxcbiAgaW5zZXJ0ZWRfYXQgdGltZXN0YW1wdHogTk9UIE5VTEwgREVGQVVMVCBOT1coKVxuKTtcbi0tIEluaXRpYWwgc3VwYWJhc2VfZnVuY3Rpb25zIG1pZ3JhdGlvblxuSU5TRVJUIElOVE8gc3VwYWJhc2VfZnVuY3Rpb25zLm1pZ3JhdGlvbnMgKHZlcnNpb24pIFZBTFVFUyAoJ2luaXRpYWwnKTtcbi0tIHN1cGFiYXNlX2Z1bmN0aW9ucy5ob29rcyBkZWZpbml0aW9uXG5DUkVBVEUgVEFCTEUgc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzIChcbiAgaWQgYmlnc2VyaWFsIFBSSU1BUlkgS0VZLFxuICBob29rX3RhYmxlX2lkIGludGVnZXIgTk9UIE5VTEwsXG4gIGhvb2tfbmFtZSB0ZXh0IE5PVCBOVUxMLFxuICBjcmVhdGVkX2F0IHRpbWVzdGFtcHR6IE5PVCBOVUxMIERFRkFVTFQgTk9XKCksXG4gIHJlcXVlc3RfaWQgYmlnaW50XG4pO1xuQ1JFQVRFIElOREVYIHN1cGFiYXNlX2Z1bmN0aW9uc19ob29rc19yZXF1ZXN0X2lkX2lkeCBPTiBzdXBhYmFzZV9mdW5jdGlvbnMuaG9va3MgVVNJTkcgYnRyZWUgKHJlcXVlc3RfaWQpO1xuQ1JFQVRFIElOREVYIHN1cGFiYXNlX2Z1bmN0aW9uc19ob29rc19oX3RhYmxlX2lkX2hfbmFtZV9pZHggT04gc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzIFVTSU5HIGJ0cmVlIChob29rX3RhYmxlX2lkLCBob29rX25hbWUpO1xuQ09NTUVOVCBPTiBUQUJMRSBzdXBhYmFzZV9mdW5jdGlvbnMuaG9va3MgSVMgJ1N1cGFiYXNlIEZ1bmN0aW9ucyBIb29rczogQXVkaXQgdHJhaWwgZm9yIHRyaWdnZXJlZCBob29rcy4nO1xuQ1JFQVRFIEZVTkNUSU9OIHN1cGFiYXNlX2Z1bmN0aW9ucy5odHRwX3JlcXVlc3QoKVxuICBSRVRVUk5TIHRyaWdnZXJcbiAgTEFOR1VBR0UgcGxwZ3NxbFxuICBBUyAkZnVuY3Rpb24kXG4gIERFQ0xBUkVcbiAgICByZXF1ZXN0X2lkIGJpZ2ludDtcbiAgICBwYXlsb2FkIGpzb25iO1xuICAgIHVybCB0ZXh0IDo9IFRHX0FSR1ZbMF06OnRleHQ7XG4gICAgbWV0aG9kIHRleHQgOj0gVEdfQVJHVlsxXTo6dGV4dDtcbiAgICBoZWFkZXJzIGpzb25iIERFRkFVTFQgJ3t9Jzo6anNvbmI7XG4gICAgcGFyYW1zIGpzb25iIERFRkFVTFQgJ3t9Jzo6anNvbmI7XG4gICAgdGltZW91dF9tcyBpbnRlZ2VyIERFRkFVTFQgMTAwMDtcbiAgQkVHSU5cbiAgICBJRiB1cmwgSVMgTlVMTCBPUiB1cmwgPSAnbnVsbCcgVEhFTlxuICAgICAgUkFJU0UgRVhDRVBUSU9OICd1cmwgYXJndW1lbnQgaXMgbWlzc2luZyc7XG4gICAgRU5EIElGO1xuXG4gICAgSUYgbWV0aG9kIElTIE5VTEwgT1IgbWV0aG9kID0gJ251bGwnIFRIRU5cbiAgICAgIFJBSVNFIEVYQ0VQVElPTiAnbWV0aG9kIGFyZ3VtZW50IGlzIG1pc3NpbmcnO1xuICAgIEVORCBJRjtcblxuICAgIElGIFRHX0FSR1ZbMl0gSVMgTlVMTCBPUiBUR19BUkdWWzJdID0gJ251bGwnIFRIRU5cbiAgICAgIGhlYWRlcnMgPSAne1wiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwifSc6Ompzb25iO1xuICAgIEVMU0VcbiAgICAgIGhlYWRlcnMgPSBUR19BUkdWWzJdOjpqc29uYjtcbiAgICBFTkQgSUY7XG5cbiAgICBJRiBUR19BUkdWWzNdIElTIE5VTEwgT1IgVEdfQVJHVlszXSA9ICdudWxsJyBUSEVOXG4gICAgICBwYXJhbXMgPSAne30nOjpqc29uYjtcbiAgICBFTFNFXG4gICAgICBwYXJhbXMgPSBUR19BUkdWWzNdOjpqc29uYjtcbiAgICBFTkQgSUY7XG5cbiAgICBJRiBUR19BUkdWWzRdIElTIE5VTEwgT1IgVEdfQVJHVls0XSA9ICdudWxsJyBUSEVOXG4gICAgICB0aW1lb3V0X21zID0gMTAwMDtcbiAgICBFTFNFXG4gICAgICB0aW1lb3V0X21zID0gVEdfQVJHVls0XTo6aW50ZWdlcjtcbiAgICBFTkQgSUY7XG5cbiAgICBDQVNFXG4gICAgICBXSEVOIG1ldGhvZCA9ICdHRVQnIFRIRU5cbiAgICAgICAgU0VMRUNUIGh0dHBfZ2V0IElOVE8gcmVxdWVzdF9pZCBGUk9NIG5ldC5odHRwX2dldChcbiAgICAgICAgICB1cmwsXG4gICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgdGltZW91dF9tc1xuICAgICAgICApO1xuICAgICAgV0hFTiBtZXRob2QgPSAnUE9TVCcgVEhFTlxuICAgICAgICBwYXlsb2FkID0ganNvbmJfYnVpbGRfb2JqZWN0KFxuICAgICAgICAgICdvbGRfcmVjb3JkJywgT0xELFxuICAgICAgICAgICdyZWNvcmQnLCBORVcsXG4gICAgICAgICAgJ3R5cGUnLCBUR19PUCxcbiAgICAgICAgICAndGFibGUnLCBUR19UQUJMRV9OQU1FLFxuICAgICAgICAgICdzY2hlbWEnLCBUR19UQUJMRV9TQ0hFTUFcbiAgICAgICAgKTtcblxuICAgICAgICBTRUxFQ1QgaHR0cF9wb3N0IElOVE8gcmVxdWVzdF9pZCBGUk9NIG5ldC5odHRwX3Bvc3QoXG4gICAgICAgICAgdXJsLFxuICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgdGltZW91dF9tc1xuICAgICAgICApO1xuICAgICAgRUxTRVxuICAgICAgICBSQUlTRSBFWENFUFRJT04gJ21ldGhvZCBhcmd1bWVudCAlIGlzIGludmFsaWQnLCBtZXRob2Q7XG4gICAgRU5EIENBU0U7XG5cbiAgICBJTlNFUlQgSU5UTyBzdXBhYmFzZV9mdW5jdGlvbnMuaG9va3NcbiAgICAgIChob29rX3RhYmxlX2lkLCBob29rX25hbWUsIHJlcXVlc3RfaWQpXG4gICAgVkFMVUVTXG4gICAgICAoVEdfUkVMSUQsIFRHX05BTUUsIHJlcXVlc3RfaWQpO1xuXG4gICAgUkVUVVJOIE5FVztcbiAgRU5EXG4kZnVuY3Rpb24kO1xuLS0gU3VwYWJhc2Ugc3VwZXIgYWRtaW5cbkRPXG4kJFxuQkVHSU5cbiAgSUYgTk9UIEVYSVNUUyAoXG4gICAgU0VMRUNUIDFcbiAgICBGUk9NIHBnX3JvbGVzXG4gICAgV0hFUkUgcm9sbmFtZSA9ICdzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4nXG4gIClcbiAgVEhFTlxuICAgIENSRUFURSBVU0VSIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiBOT0lOSEVSSVQgQ1JFQVRFUk9MRSBMT0dJTiBOT1JFUExJQ0FUSU9OO1xuICBFTkQgSUY7XG5FTkRcbiQkO1xuR1JBTlQgQUxMIFBSSVZJTEVHRVMgT04gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW47XG5HUkFOVCBBTEwgUFJJVklMRUdFUyBPTiBBTEwgVEFCTEVTIElOIFNDSEVNQSBzdXBhYmFzZV9mdW5jdGlvbnMgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluO1xuR1JBTlQgQUxMIFBSSVZJTEVHRVMgT04gQUxMIFNFUVVFTkNFUyBJTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbjtcbkFMVEVSIFVTRVIgc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluIFNFVCBzZWFyY2hfcGF0aCA9IFwic3VwYWJhc2VfZnVuY3Rpb25zXCI7XG5BTFRFUiB0YWJsZSBcInN1cGFiYXNlX2Z1bmN0aW9uc1wiLm1pZ3JhdGlvbnMgT1dORVIgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluO1xuQUxURVIgdGFibGUgXCJzdXBhYmFzZV9mdW5jdGlvbnNcIi5ob29rcyBPV05FUiBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW47XG5BTFRFUiBmdW5jdGlvbiBcInN1cGFiYXNlX2Z1bmN0aW9uc1wiLmh0dHBfcmVxdWVzdCgpIE9XTkVSIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbjtcbkdSQU5UIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiBUTyBwb3N0Z3Jlcztcbi0tIFJlbW92ZSB1bnVzZWQgc3VwYWJhc2VfcGdfbmV0X2FkbWluIHJvbGVcbkRPXG4kJFxuQkVHSU5cbiAgSUYgRVhJU1RTIChcbiAgICBTRUxFQ1QgMVxuICAgIEZST00gcGdfcm9sZXNcbiAgICBXSEVSRSByb2xuYW1lID0gJ3N1cGFiYXNlX3BnX25ldF9hZG1pbidcbiAgKVxuICBUSEVOXG4gICAgUkVBU1NJR04gT1dORUQgQlkgc3VwYWJhc2VfcGdfbmV0X2FkbWluIFRPIHN1cGFiYXNlX2FkbWluO1xuICAgIERST1AgT1dORUQgQlkgc3VwYWJhc2VfcGdfbmV0X2FkbWluO1xuICAgIERST1AgUk9MRSBzdXBhYmFzZV9wZ19uZXRfYWRtaW47XG4gIEVORCBJRjtcbkVORFxuJCQ7XG4tLSBwZ19uZXQgZ3JhbnRzIHdoZW4gZXh0ZW5zaW9uIGlzIGFscmVhZHkgZW5hYmxlZFxuRE9cbiQkXG5CRUdJTlxuICBJRiBFWElTVFMgKFxuICAgIFNFTEVDVCAxXG4gICAgRlJPTSBwZ19leHRlbnNpb25cbiAgICBXSEVSRSBleHRuYW1lID0gJ3BnX25ldCdcbiAgKVxuICBUSEVOXG4gICAgR1JBTlQgVVNBR0UgT04gU0NIRU1BIG5ldCBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4sIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4gICAgQUxURVIgZnVuY3Rpb24gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFNFQ1VSSVRZIERFRklORVI7XG4gICAgQUxURVIgZnVuY3Rpb24gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRUNVUklUWSBERUZJTkVSO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRVQgc2VhcmNoX3BhdGggPSBuZXQ7XG4gICAgQUxURVIgZnVuY3Rpb24gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRVQgc2VhcmNoX3BhdGggPSBuZXQ7XG4gICAgUkVWT0tFIEFMTCBPTiBGVU5DVElPTiBuZXQuaHR0cF9nZXQodXJsIHRleHQsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgRlJPTSBQVUJMSUM7XG4gICAgUkVWT0tFIEFMTCBPTiBGVU5DVElPTiBuZXQuaHR0cF9wb3N0KHVybCB0ZXh0LCBib2R5IGpzb25iLCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIEZST00gUFVCTElDO1xuICAgIEdSQU5UIEVYRUNVVEUgT04gRlVOQ1RJT04gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiwgcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbiAgICBHUkFOVCBFWEVDVVRFIE9OIEZVTkNUSU9OIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluLCBwb3N0Z3JlcywgYW5vbiwgYXV0aGVudGljYXRlZCwgc2VydmljZV9yb2xlO1xuICBFTkQgSUY7XG5FTkRcbiQkO1xuLS0gRXZlbnQgdHJpZ2dlciBmb3IgcGdfbmV0XG5DUkVBVEUgT1IgUkVQTEFDRSBGVU5DVElPTiBleHRlbnNpb25zLmdyYW50X3BnX25ldF9hY2Nlc3MoKVxuUkVUVVJOUyBldmVudF90cmlnZ2VyXG5MQU5HVUFHRSBwbHBnc3FsXG5BUyAkJFxuQkVHSU5cbiAgSUYgRVhJU1RTIChcbiAgICBTRUxFQ1QgMVxuICAgIEZST00gcGdfZXZlbnRfdHJpZ2dlcl9kZGxfY29tbWFuZHMoKSBBUyBldlxuICAgIEpPSU4gcGdfZXh0ZW5zaW9uIEFTIGV4dFxuICAgIE9OIGV2Lm9iamlkID0gZXh0Lm9pZFxuICAgIFdIRVJFIGV4dC5leHRuYW1lID0gJ3BnX25ldCdcbiAgKVxuICBUSEVOXG4gICAgR1JBTlQgVVNBR0UgT04gU0NIRU1BIG5ldCBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4sIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4gICAgQUxURVIgZnVuY3Rpb24gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFNFQ1VSSVRZIERFRklORVI7XG4gICAgQUxURVIgZnVuY3Rpb24gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRUNVUklUWSBERUZJTkVSO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRVQgc2VhcmNoX3BhdGggPSBuZXQ7XG4gICAgQUxURVIgZnVuY3Rpb24gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRVQgc2VhcmNoX3BhdGggPSBuZXQ7XG4gICAgUkVWT0tFIEFMTCBPTiBGVU5DVElPTiBuZXQuaHR0cF9nZXQodXJsIHRleHQsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgRlJPTSBQVUJMSUM7XG4gICAgUkVWT0tFIEFMTCBPTiBGVU5DVElPTiBuZXQuaHR0cF9wb3N0KHVybCB0ZXh0LCBib2R5IGpzb25iLCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIEZST00gUFVCTElDO1xuICAgIEdSQU5UIEVYRUNVVEUgT04gRlVOQ1RJT04gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiwgcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbiAgICBHUkFOVCBFWEVDVVRFIE9OIEZVTkNUSU9OIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluLCBwb3N0Z3JlcywgYW5vbiwgYXV0aGVudGljYXRlZCwgc2VydmljZV9yb2xlO1xuICBFTkQgSUY7XG5FTkQ7XG4kJDtcbkNPTU1FTlQgT04gRlVOQ1RJT04gZXh0ZW5zaW9ucy5ncmFudF9wZ19uZXRfYWNjZXNzIElTICdHcmFudHMgYWNjZXNzIHRvIHBnX25ldCc7XG5ET1xuJCRcbkJFR0lOXG4gIElGIE5PVCBFWElTVFMgKFxuICAgIFNFTEVDVCAxXG4gICAgRlJPTSBwZ19ldmVudF90cmlnZ2VyXG4gICAgV0hFUkUgZXZ0bmFtZSA9ICdpc3N1ZV9wZ19uZXRfYWNjZXNzJ1xuICApIFRIRU5cbiAgICBDUkVBVEUgRVZFTlQgVFJJR0dFUiBpc3N1ZV9wZ19uZXRfYWNjZXNzIE9OIGRkbF9jb21tYW5kX2VuZCBXSEVOIFRBRyBJTiAoJ0NSRUFURSBFWFRFTlNJT04nKVxuICAgIEVYRUNVVEUgUFJPQ0VEVVJFIGV4dGVuc2lvbnMuZ3JhbnRfcGdfbmV0X2FjY2VzcygpO1xuICBFTkQgSUY7XG5FTkRcbiQkO1xuSU5TRVJUIElOVE8gc3VwYWJhc2VfZnVuY3Rpb25zLm1pZ3JhdGlvbnMgKHZlcnNpb24pIFZBTFVFUyAoJzIwMjEwODA5MTgzNDIzX3VwZGF0ZV9ncmFudHMnKTtcbkFMVEVSIGZ1bmN0aW9uIHN1cGFiYXNlX2Z1bmN0aW9ucy5odHRwX3JlcXVlc3QoKSBTRUNVUklUWSBERUZJTkVSO1xuQUxURVIgZnVuY3Rpb24gc3VwYWJhc2VfZnVuY3Rpb25zLmh0dHBfcmVxdWVzdCgpIFNFVCBzZWFyY2hfcGF0aCA9IHN1cGFiYXNlX2Z1bmN0aW9ucztcblJFVk9LRSBBTEwgT04gRlVOQ1RJT04gc3VwYWJhc2VfZnVuY3Rpb25zLmh0dHBfcmVxdWVzdCgpIEZST00gUFVCTElDO1xuR1JBTlQgRVhFQ1VURSBPTiBGVU5DVElPTiBzdXBhYmFzZV9mdW5jdGlvbnMuaHR0cF9yZXF1ZXN0KCkgVE8gcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbkNPTU1JVDtcbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi9yb2xlcy5zcWwKICAgICAgICB0YXJnZXQ6IC9kb2NrZXItZW50cnlwb2ludC1pbml0ZGIuZC9pbml0LXNjcmlwdHMvOTktcm9sZXMuc3FsCiAgICAgICAgY29udGVudDogIi0tIE5PVEU6IGNoYW5nZSB0byB5b3VyIG93biBwYXNzd29yZHMgZm9yIHByb2R1Y3Rpb24gZW52aXJvbm1lbnRzXG4gXFxzZXQgcGdwYXNzIGBlY2hvIFwiJFBPU1RHUkVTX1BBU1NXT1JEXCJgXG5cbiBBTFRFUiBVU0VSIGF1dGhlbnRpY2F0b3IgV0lUSCBQQVNTV09SRCA6J3BncGFzcyc7XG4gQUxURVIgVVNFUiBwZ2JvdW5jZXIgV0lUSCBQQVNTV09SRCA6J3BncGFzcyc7XG4gQUxURVIgVVNFUiBzdXBhYmFzZV9hdXRoX2FkbWluIFdJVEggUEFTU1dPUkQgOidwZ3Bhc3MnO1xuIEFMVEVSIFVTRVIgc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluIFdJVEggUEFTU1dPUkQgOidwZ3Bhc3MnO1xuIEFMVEVSIFVTRVIgc3VwYWJhc2Vfc3RvcmFnZV9hZG1pbiBXSVRIIFBBU1NXT1JEIDoncGdwYXNzJztcbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi9qd3Quc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvaW5pdC1zY3JpcHRzLzk5LWp3dC5zcWwKICAgICAgICBjb250ZW50OiAiXFxzZXQgand0X3NlY3JldCBgZWNobyBcIiRKV1RfU0VDUkVUXCJgXG5cXHNldCBqd3RfZXhwIGBlY2hvIFwiJEpXVF9FWFBcImBcblxcc2V0IGRiX25hbWUgYGVjaG8gXCIke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc31cImBcblxuQUxURVIgREFUQUJBU0UgOmRiX25hbWUgU0VUIFwiYXBwLnNldHRpbmdzLmp3dF9zZWNyZXRcIiBUTyA6J2p3dF9zZWNyZXQnO1xuQUxURVIgREFUQUJBU0UgOmRiX25hbWUgU0VUIFwiYXBwLnNldHRpbmdzLmp3dF9leHBcIiBUTyA6J2p3dF9leHAnO1xuIgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2RiL2xvZ3Muc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvbWlncmF0aW9ucy85OS1sb2dzLnNxbAogICAgICAgIGNvbnRlbnQ6ICJcXHNldCBwZ3VzZXIgYGVjaG8gXCJzdXBhYmFzZV9hZG1pblwiYFxuXFxjIF9zdXBhYmFzZVxuY3JlYXRlIHNjaGVtYSBpZiBub3QgZXhpc3RzIF9hbmFseXRpY3M7XG5hbHRlciBzY2hlbWEgX2FuYWx5dGljcyBvd25lciB0byA6cGd1c2VyO1xuXFxjIHBvc3RncmVzXG4iCiAgICAgIC0gJ3N1cGFiYXNlLWRiLWNvbmZpZzovZXRjL3Bvc3RncmVzcWwtY3VzdG9tJwogIHN1cGFiYXNlLWFuYWx5dGljczoKICAgIGltYWdlOiAnc3VwYWJhc2UvbG9nZmxhcmU6MS40LjAnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6NDAwMC9oZWFsdGgnCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIGludGVydmFsOiA1cwogICAgICByZXRyaWVzOiAxMAogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudmlyb25tZW50OgogICAgICAtIExPR0ZMQVJFX05PREVfSE9TVD0xMjcuMC4wLjEKICAgICAgLSBEQl9VU0VSTkFNRT1zdXBhYmFzZV9hZG1pbgogICAgICAtIERCX0RBVEFCQVNFPV9zdXBhYmFzZQogICAgICAtICdEQl9IT1NUTkFNRT0ke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn0nCiAgICAgIC0gJ0RCX1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSAnREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSBEQl9TQ0hFTUE9X2FuYWx5dGljcwogICAgICAtICdMT0dGTEFSRV9BUElfS0VZPSR7U0VSVklDRV9QQVNTV09SRF9MT0dGTEFSRX0nCiAgICAgIC0gTE9HRkxBUkVfU0lOR0xFX1RFTkFOVD10cnVlCiAgICAgIC0gTE9HRkxBUkVfU0lOR0xFX1RFTkFOVF9NT0RFPXRydWUKICAgICAgLSBMT0dGTEFSRV9TVVBBQkFTRV9NT0RFPXRydWUKICAgICAgLSBMT0dGTEFSRV9NSU5fQ0xVU1RFUl9TSVpFPTEKICAgICAgLSAnUE9TVEdSRVNfQkFDS0VORF9VUkw9cG9zdGdyZXNxbDovL3N1cGFiYXNlX2FkbWluOiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AJHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9OiR7UE9TVEdSRVNfUE9SVDotNTQzMn0vX3N1cGFiYXNlJwogICAgICAtIFBPU1RHUkVTX0JBQ0tFTkRfU0NIRU1BPV9hbmFseXRpY3MKICAgICAgLSBMT0dGTEFSRV9GRUFUVVJFX0ZMQUdfT1ZFUlJJREU9bXVsdGliYWNrZW5kPXRydWUKICBzdXBhYmFzZS12ZWN0b3I6CiAgICBpbWFnZTogJ3RpbWJlcmlvL3ZlY3RvcjowLjI4LjEtYWxwaW5lJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctLW5vLXZlcmJvc2UnCiAgICAgICAgLSAnLS10cmllcz0xJwogICAgICAgIC0gJy0tc3BpZGVyJwogICAgICAgIC0gJ2h0dHA6Ly9zdXBhYmFzZS12ZWN0b3I6OTAwMS9oZWFsdGgnCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIGludGVydmFsOiA1cwogICAgICByZXRyaWVzOiAzCiAgICB2b2x1bWVzOgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2xvZ3MvdmVjdG9yLnltbAogICAgICAgIHRhcmdldDogL2V0Yy92ZWN0b3IvdmVjdG9yLnltbAogICAgICAgIHJlYWRfb25seTogdHJ1ZQogICAgICAgIGNvbnRlbnQ6ICJhcGk6XG4gIGVuYWJsZWQ6IHRydWVcbiAgYWRkcmVzczogMC4wLjAuMDo5MDAxXG5cbnNvdXJjZXM6XG4gIGRvY2tlcl9ob3N0OlxuICAgIHR5cGU6IGRvY2tlcl9sb2dzXG4gICAgZXhjbHVkZV9jb250YWluZXJzOlxuICAgICAgLSBzdXBhYmFzZS12ZWN0b3JcblxudHJhbnNmb3JtczpcbiAgcHJvamVjdF9sb2dzOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSBkb2NrZXJfaG9zdFxuICAgIHNvdXJjZTogfC1cbiAgICAgIC5wcm9qZWN0ID0gXCJkZWZhdWx0XCJcbiAgICAgIC5ldmVudF9tZXNzYWdlID0gZGVsKC5tZXNzYWdlKVxuICAgICAgLmFwcG5hbWUgPSBkZWwoLmNvbnRhaW5lcl9uYW1lKVxuICAgICAgZGVsKC5jb250YWluZXJfY3JlYXRlZF9hdClcbiAgICAgIGRlbCguY29udGFpbmVyX2lkKVxuICAgICAgZGVsKC5zb3VyY2VfdHlwZSlcbiAgICAgIGRlbCguc3RyZWFtKVxuICAgICAgZGVsKC5sYWJlbClcbiAgICAgIGRlbCguaW1hZ2UpXG4gICAgICBkZWwoLmhvc3QpXG4gICAgICBkZWwoLnN0cmVhbSlcbiAgcm91dGVyOlxuICAgIHR5cGU6IHJvdXRlXG4gICAgaW5wdXRzOlxuICAgICAgLSBwcm9qZWN0X2xvZ3NcbiAgICByb3V0ZTpcbiAgICAgIGtvbmc6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJzdXBhYmFzZS1rb25nXCIpJ1xuICAgICAgYXV0aDogJ3N0YXJ0c193aXRoKHN0cmluZyEoLmFwcG5hbWUpLCBcInN1cGFiYXNlLWF1dGhcIiknXG4gICAgICByZXN0OiAnc3RhcnRzX3dpdGgoc3RyaW5nISguYXBwbmFtZSksIFwic3VwYWJhc2UtcmVzdFwiKSdcbiAgICAgIHJlYWx0aW1lOiAnc3RhcnRzX3dpdGgoc3RyaW5nISguYXBwbmFtZSksIFwicmVhbHRpbWUtZGV2XCIpJ1xuICAgICAgc3RvcmFnZTogJ3N0YXJ0c193aXRoKHN0cmluZyEoLmFwcG5hbWUpLCBcInN1cGFiYXNlLXN0b3JhZ2VcIiknXG4gICAgICBmdW5jdGlvbnM6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJzdXBhYmFzZS1mdW5jdGlvbnNcIiknXG4gICAgICBkYjogJ3N0YXJ0c193aXRoKHN0cmluZyEoLmFwcG5hbWUpLCBcInN1cGFiYXNlLWRiXCIpJ1xuICAjIElnbm9yZXMgbm9uIG5naW54IGVycm9ycyBzaW5jZSB0aGV5IGFyZSByZWxhdGVkIHdpdGgga29uZyBib290aW5nIHVwXG4gIGtvbmdfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLmtvbmdcbiAgICBzb3VyY2U6IHwtXG4gICAgICByZXEsIGVyciA9IHBhcnNlX25naW54X2xvZyguZXZlbnRfbWVzc2FnZSwgXCJjb21iaW5lZFwiKVxuICAgICAgaWYgZXJyID09IG51bGwge1xuICAgICAgICAgIC50aW1lc3RhbXAgPSByZXEudGltZXN0YW1wXG4gICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QuaGVhZGVycy5yZWZlcmVyID0gcmVxLnJlZmVyZXJcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5oZWFkZXJzLnVzZXJfYWdlbnQgPSByZXEuYWdlbnRcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5oZWFkZXJzLmNmX2Nvbm5lY3RpbmdfaXAgPSByZXEuY2xpZW50XG4gICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QubWV0aG9kID0gcmVxLm1ldGhvZFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0LnBhdGggPSByZXEucGF0aFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0LnByb3RvY29sID0gcmVxLnByb3RvY29sXG4gICAgICAgICAgLm1ldGFkYXRhLnJlc3BvbnNlLnN0YXR1c19jb2RlID0gcmVxLnN0YXR1c1xuICAgICAgfVxuICAgICAgaWYgZXJyICE9IG51bGwge1xuICAgICAgICBhYm9ydFxuICAgICAgfVxuICAjIElnbm9yZXMgbm9uIG5naW54IGVycm9ycyBzaW5jZSB0aGV5IGFyZSByZWxhdGVkIHdpdGgga29uZyBib290aW5nIHVwXG4gIGtvbmdfZXJyOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIua29uZ1xuICAgIHNvdXJjZTogfC1cbiAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0Lm1ldGhvZCA9IFwiR0VUXCJcbiAgICAgIC5tZXRhZGF0YS5yZXNwb25zZS5zdGF0dXNfY29kZSA9IDIwMFxuICAgICAgcGFyc2VkLCBlcnIgPSBwYXJzZV9uZ2lueF9sb2coLmV2ZW50X21lc3NhZ2UsIFwiZXJyb3JcIilcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAudGltZXN0YW1wID0gcGFyc2VkLnRpbWVzdGFtcFxuICAgICAgICAgIC5zZXZlcml0eSA9IHBhcnNlZC5zZXZlcml0eVxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0Lmhvc3QgPSBwYXJzZWQuaG9zdFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0LmhlYWRlcnMuY2ZfY29ubmVjdGluZ19pcCA9IHBhcnNlZC5jbGllbnRcbiAgICAgICAgICB1cmwsIGVyciA9IHNwbGl0KHBhcnNlZC5yZXF1ZXN0LCBcIiBcIilcbiAgICAgICAgICBpZiBlcnIgPT0gbnVsbCB7XG4gICAgICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0Lm1ldGhvZCA9IHVybFswXVxuICAgICAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5wYXRoID0gdXJsWzFdXG4gICAgICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0LnByb3RvY29sID0gdXJsWzJdXG4gICAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgZXJyICE9IG51bGwge1xuICAgICAgICBhYm9ydFxuICAgICAgfVxuICAjIEdvdHJ1ZSBsb2dzIGFyZSBzdHJ1Y3R1cmVkIGpzb24gc3RyaW5ncyB3aGljaCBmcm9udGVuZCBwYXJzZXMgZGlyZWN0bHkuIEJ1dCB3ZSBrZWVwIG1ldGFkYXRhIGZvciBjb25zaXN0ZW5jeS5cbiAgYXV0aF9sb2dzOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIuYXV0aFxuICAgIHNvdXJjZTogfC1cbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfanNvbiguZXZlbnRfbWVzc2FnZSlcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAubWV0YWRhdGEudGltZXN0YW1wID0gcGFyc2VkLnRpbWVcbiAgICAgICAgICAubWV0YWRhdGEgPSBtZXJnZSEoLm1ldGFkYXRhLCBwYXJzZWQpXG4gICAgICB9XG4gICMgUG9zdGdSRVNUIGxvZ3MgYXJlIHN0cnVjdHVyZWQgc28gd2Ugc2VwYXJhdGUgdGltZXN0YW1wIGZyb20gbWVzc2FnZSB1c2luZyByZWdleFxuICByZXN0X2xvZ3M6XG4gICAgdHlwZTogcmVtYXBcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5yZXN0XG4gICAgc291cmNlOiB8LVxuICAgICAgcGFyc2VkLCBlcnIgPSBwYXJzZV9yZWdleCguZXZlbnRfbWVzc2FnZSwgcideKD9QPHRpbWU+LiopOiAoP1A8bXNnPi4qKSQnKVxuICAgICAgaWYgZXJyID09IG51bGwge1xuICAgICAgICAgIC5ldmVudF9tZXNzYWdlID0gcGFyc2VkLm1zZ1xuICAgICAgICAgIC50aW1lc3RhbXAgPSB0b190aW1lc3RhbXAhKHBhcnNlZC50aW1lKVxuICAgICAgICAgIC5tZXRhZGF0YS5ob3N0ID0gLnByb2plY3RcbiAgICAgIH1cbiAgIyBSZWFsdGltZSBsb2dzIGFyZSBzdHJ1Y3R1cmVkIHNvIHdlIHBhcnNlIHRoZSBzZXZlcml0eSBsZXZlbCB1c2luZyByZWdleCAoaWdub3JlIHRpbWUgYmVjYXVzZSBpdCBoYXMgbm8gZGF0ZSlcbiAgcmVhbHRpbWVfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLnJlYWx0aW1lXG4gICAgc291cmNlOiB8LVxuICAgICAgLm1ldGFkYXRhLnByb2plY3QgPSBkZWwoLnByb2plY3QpXG4gICAgICAubWV0YWRhdGEuZXh0ZXJuYWxfaWQgPSAubWV0YWRhdGEucHJvamVjdFxuICAgICAgcGFyc2VkLCBlcnIgPSBwYXJzZV9yZWdleCguZXZlbnRfbWVzc2FnZSwgcideKD9QPHRpbWU+XFxkKzpcXGQrOlxcZCtcXC5cXGQrKSBcXFsoP1A8bGV2ZWw+XFx3KylcXF0gKD9QPG1zZz4uKikkJylcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAuZXZlbnRfbWVzc2FnZSA9IHBhcnNlZC5tc2dcbiAgICAgICAgICAubWV0YWRhdGEubGV2ZWwgPSBwYXJzZWQubGV2ZWxcbiAgICAgIH1cbiAgIyBTdG9yYWdlIGxvZ3MgbWF5IGNvbnRhaW4ganNvbiBvYmplY3RzIHNvIHdlIHBhcnNlIHRoZW0gZm9yIGNvbXBsZXRlbmVzc1xuICBzdG9yYWdlX2xvZ3M6XG4gICAgdHlwZTogcmVtYXBcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5zdG9yYWdlXG4gICAgc291cmNlOiB8LVxuICAgICAgLm1ldGFkYXRhLnByb2plY3QgPSBkZWwoLnByb2plY3QpXG4gICAgICAubWV0YWRhdGEudGVuYW50SWQgPSAubWV0YWRhdGEucHJvamVjdFxuICAgICAgcGFyc2VkLCBlcnIgPSBwYXJzZV9qc29uKC5ldmVudF9tZXNzYWdlKVxuICAgICAgaWYgZXJyID09IG51bGwge1xuICAgICAgICAgIC5ldmVudF9tZXNzYWdlID0gcGFyc2VkLm1zZ1xuICAgICAgICAgIC5tZXRhZGF0YS5sZXZlbCA9IHBhcnNlZC5sZXZlbFxuICAgICAgICAgIC5tZXRhZGF0YS50aW1lc3RhbXAgPSBwYXJzZWQudGltZVxuICAgICAgICAgIC5tZXRhZGF0YS5jb250ZXh0WzBdLmhvc3QgPSBwYXJzZWQuaG9zdG5hbWVcbiAgICAgICAgICAubWV0YWRhdGEuY29udGV4dFswXS5waWQgPSBwYXJzZWQucGlkXG4gICAgICB9XG4gICMgUG9zdGdyZXMgbG9ncyBzb21lIG1lc3NhZ2VzIHRvIHN0ZGVyciB3aGljaCB3ZSBtYXAgdG8gd2FybmluZyBzZXZlcml0eSBsZXZlbFxuICBkYl9sb2dzOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIuZGJcbiAgICBzb3VyY2U6IHwtXG4gICAgICAubWV0YWRhdGEuaG9zdCA9IFwiZGItZGVmYXVsdFwiXG4gICAgICAubWV0YWRhdGEucGFyc2VkLnRpbWVzdGFtcCA9IC50aW1lc3RhbXBcblxuICAgICAgcGFyc2VkLCBlcnIgPSBwYXJzZV9yZWdleCguZXZlbnRfbWVzc2FnZSwgcicuKig/UDxsZXZlbD5JTkZPfE5PVElDRXxXQVJOSU5HfEVSUk9SfExPR3xGQVRBTHxQQU5JQz8pOi4qJywgbnVtZXJpY19ncm91cHM6IHRydWUpXG5cbiAgICAgIGlmIGVyciAhPSBudWxsIHx8IHBhcnNlZCA9PSBudWxsIHtcbiAgICAgICAgLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSA9IFwiaW5mb1wiXG4gICAgICB9XG4gICAgICBpZiBwYXJzZWQgIT0gbnVsbCB7XG4gICAgICAubWV0YWRhdGEucGFyc2VkLmVycm9yX3NldmVyaXR5ID0gcGFyc2VkLmxldmVsXG4gICAgICB9XG4gICAgICBpZiAubWV0YWRhdGEucGFyc2VkLmVycm9yX3NldmVyaXR5ID09IFwiaW5mb1wiIHtcbiAgICAgICAgICAubWV0YWRhdGEucGFyc2VkLmVycm9yX3NldmVyaXR5ID0gXCJsb2dcIlxuICAgICAgfVxuICAgICAgLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSA9IHVwY2FzZSEoLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSlcblxuc2lua3M6XG4gIGxvZ2ZsYXJlX2F1dGg6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSBhdXRoX2xvZ3NcbiAgICBlbmNvZGluZzpcbiAgICAgIGNvZGVjOiAnanNvbidcbiAgICBtZXRob2Q6ICdwb3N0J1xuICAgIHJlcXVlc3Q6XG4gICAgICByZXRyeV9tYXhfZHVyYXRpb25fc2VjczogMTBcbiAgICB1cmk6ICdodHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAvYXBpL2xvZ3M/c291cmNlX25hbWU9Z290cnVlLmxvZ3MucHJvZCZhcGlfa2V5PSR7TE9HRkxBUkVfQVBJX0tFWT9MT0dGTEFSRV9BUElfS0VZIGlzIHJlcXVpcmVkfSdcbiAgbG9nZmxhcmVfcmVhbHRpbWU6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSByZWFsdGltZV9sb2dzXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL2FwaS9sb2dzP3NvdXJjZV9uYW1lPXJlYWx0aW1lLmxvZ3MucHJvZCZhcGlfa2V5PSR7TE9HRkxBUkVfQVBJX0tFWT9MT0dGTEFSRV9BUElfS0VZIGlzIHJlcXVpcmVkfSdcbiAgbG9nZmxhcmVfcmVzdDpcbiAgICB0eXBlOiAnaHR0cCdcbiAgICBpbnB1dHM6XG4gICAgICAtIHJlc3RfbG9nc1xuICAgIGVuY29kaW5nOlxuICAgICAgY29kZWM6ICdqc29uJ1xuICAgIG1ldGhvZDogJ3Bvc3QnXG4gICAgcmVxdWVzdDpcbiAgICAgIHJldHJ5X21heF9kdXJhdGlvbl9zZWNzOiAxMFxuICAgIHVyaTogJ2h0dHA6Ly9zdXBhYmFzZS1hbmFseXRpY3M6NDAwMC9hcGkvbG9ncz9zb3VyY2VfbmFtZT1wb3N0Z1JFU1QubG9ncy5wcm9kJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuICBsb2dmbGFyZV9kYjpcbiAgICB0eXBlOiAnaHR0cCdcbiAgICBpbnB1dHM6XG4gICAgICAtIGRiX2xvZ3NcbiAgICBlbmNvZGluZzpcbiAgICAgIGNvZGVjOiAnanNvbidcbiAgICBtZXRob2Q6ICdwb3N0J1xuICAgIHJlcXVlc3Q6XG4gICAgICByZXRyeV9tYXhfZHVyYXRpb25fc2VjczogMTBcbiAgICAjIFdlIG11c3Qgcm91dGUgdGhlIHNpbmsgdGhyb3VnaCBrb25nIGJlY2F1c2UgaW5nZXN0aW5nIGxvZ3MgYmVmb3JlIGxvZ2ZsYXJlIGlzIGZ1bGx5IGluaXRpYWxpc2VkIHdpbGxcbiAgICAjIGxlYWQgdG8gYnJva2VuIHF1ZXJpZXMgZnJvbSBzdHVkaW8uIFRoaXMgd29ya3MgYnkgdGhlIGFzc3VtcHRpb24gdGhhdCBjb250YWluZXJzIGFyZSBzdGFydGVkIGluIHRoZVxuICAgICMgZm9sbG93aW5nIG9yZGVyOiB2ZWN0b3IgPiBkYiA+IGxvZ2ZsYXJlID4ga29uZ1xuICAgIHVyaTogJ2h0dHA6Ly9zdXBhYmFzZS1rb25nOjgwMDAvYW5hbHl0aWNzL3YxL2FwaS9sb2dzP3NvdXJjZV9uYW1lPXBvc3RncmVzLmxvZ3MmYXBpX2tleT0ke0xPR0ZMQVJFX0FQSV9LRVk/TE9HRkxBUkVfQVBJX0tFWSBpcyByZXF1aXJlZH0nXG4gIGxvZ2ZsYXJlX2Z1bmN0aW9uczpcbiAgICB0eXBlOiAnaHR0cCdcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5mdW5jdGlvbnNcbiAgICBlbmNvZGluZzpcbiAgICAgIGNvZGVjOiAnanNvbidcbiAgICBtZXRob2Q6ICdwb3N0J1xuICAgIHJlcXVlc3Q6XG4gICAgICByZXRyeV9tYXhfZHVyYXRpb25fc2VjczogMTBcbiAgICB1cmk6ICdodHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAvYXBpL2xvZ3M/c291cmNlX25hbWU9ZGVuby1yZWxheS1sb2dzJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuICBsb2dmbGFyZV9zdG9yYWdlOlxuICAgIHR5cGU6ICdodHRwJ1xuICAgIGlucHV0czpcbiAgICAgIC0gc3RvcmFnZV9sb2dzXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL2FwaS9sb2dzP3NvdXJjZV9uYW1lPXN0b3JhZ2UubG9ncy5wcm9kLjImYXBpX2tleT0ke0xPR0ZMQVJFX0FQSV9LRVk/TE9HRkxBUkVfQVBJX0tFWSBpcyByZXF1aXJlZH0nXG4gIGxvZ2ZsYXJlX2tvbmc6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSBrb25nX2xvZ3NcbiAgICAgIC0ga29uZ19lcnJcbiAgICBlbmNvZGluZzpcbiAgICAgIGNvZGVjOiAnanNvbidcbiAgICBtZXRob2Q6ICdwb3N0J1xuICAgIHJlcXVlc3Q6XG4gICAgICByZXRyeV9tYXhfZHVyYXRpb25fc2VjczogMTBcbiAgICB1cmk6ICdodHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAvYXBpL2xvZ3M/c291cmNlX25hbWU9Y2xvdWRmbGFyZS5sb2dzLnByb2QmYXBpX2tleT0ke0xPR0ZMQVJFX0FQSV9LRVk/TE9HRkxBUkVfQVBJX0tFWSBpcyByZXF1aXJlZH0nXG4iCiAgICAgIC0gJy92YXIvcnVuL2RvY2tlci5zb2NrOi92YXIvcnVuL2RvY2tlci5zb2NrOnJvJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0xPR0ZMQVJFX0FQSV9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEX0xPR0ZMQVJFfScKICAgIGNvbW1hbmQ6CiAgICAgIC0gJy0tY29uZmlnJwogICAgICAtIGV0Yy92ZWN0b3IvdmVjdG9yLnltbAogIHN1cGFiYXNlLXJlc3Q6CiAgICBpbWFnZTogJ3Bvc3RncmVzdC9wb3N0Z3Jlc3Q6djEyLjIuMTInCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudmlyb25tZW50OgogICAgICAtICdQR1JTVF9EQl9VUkk9cG9zdGdyZXM6Ly9hdXRoZW50aWNhdG9yOiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AJHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9OiR7UE9TVEdSRVNfUE9SVDotNTQzMn0vJHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtICdQR1JTVF9EQl9TQ0hFTUFTPSR7UEdSU1RfREJfU0NIRU1BUzotcHVibGljLHN0b3JhZ2UsZ3JhcGhxbF9wdWJsaWN9JwogICAgICAtIFBHUlNUX0RCX0FOT05fUk9MRT1hbm9uCiAgICAgIC0gJ1BHUlNUX0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gUEdSU1RfREJfVVNFX0xFR0FDWV9HVUNTPWZhbHNlCiAgICAgIC0gJ1BHUlNUX0FQUF9TRVRUSU5HU19KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdQR1JTVF9BUFBfU0VUVElOR1NfSldUX0VYUD0ke0pXVF9FWFBJUlk6LTM2MDB9JwogICAgY29tbWFuZDogcG9zdGdyZXN0CiAgICBleGNsdWRlX2Zyb21faGM6IHRydWUKICBzdXBhYmFzZS1hdXRoOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9nb3RydWU6djIuMTc0LjAnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLS1uby12ZXJib3NlJwogICAgICAgIC0gJy0tdHJpZXM9MScKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjk5OTkvaGVhbHRoJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gR09UUlVFX0FQSV9IT1NUPTAuMC4wLjAKICAgICAgLSBHT1RSVUVfQVBJX1BPUlQ9OTk5OQogICAgICAtICdBUElfRVhURVJOQUxfVVJMPSR7QVBJX0VYVEVSTkFMX1VSTDotaHR0cDovL3N1cGFiYXNlLWtvbmc6ODAwMH0nCiAgICAgIC0gR09UUlVFX0RCX0RSSVZFUj1wb3N0Z3JlcwogICAgICAtICdHT1RSVUVfREJfREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vc3VwYWJhc2VfYXV0aF9hZG1pbjoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9LyR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnR09UUlVFX1NJVEVfVVJMPSR7U0VSVklDRV9VUkxfU1VQQUJBU0VLT05HfScKICAgICAgLSAnR09UUlVFX1VSSV9BTExPV19MSVNUPSR7QURESVRJT05BTF9SRURJUkVDVF9VUkxTfScKICAgICAgLSAnR09UUlVFX0RJU0FCTEVfU0lHTlVQPSR7RElTQUJMRV9TSUdOVVA6LWZhbHNlfScKICAgICAgLSBHT1RSVUVfSldUX0FETUlOX1JPTEVTPXNlcnZpY2Vfcm9sZQogICAgICAtIEdPVFJVRV9KV1RfQVVEPWF1dGhlbnRpY2F0ZWQKICAgICAgLSBHT1RSVUVfSldUX0RFRkFVTFRfR1JPVVBfTkFNRT1hdXRoZW50aWNhdGVkCiAgICAgIC0gJ0dPVFJVRV9KV1RfRVhQPSR7SldUX0VYUElSWTotMzYwMH0nCiAgICAgIC0gJ0dPVFJVRV9KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdHT1RSVUVfRVhURVJOQUxfRU1BSUxfRU5BQkxFRD0ke0VOQUJMRV9FTUFJTF9TSUdOVVA6LXRydWV9JwogICAgICAtICdHT1RSVUVfRVhURVJOQUxfQU5PTllNT1VTX1VTRVJTX0VOQUJMRUQ9JHtFTkFCTEVfQU5PTllNT1VTX1VTRVJTOi1mYWxzZX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfQVVUT0NPTkZJUk09JHtFTkFCTEVfRU1BSUxfQVVUT0NPTkZJUk06LWZhbHNlfScKICAgICAgLSAnR09UUlVFX1NNVFBfQURNSU5fRU1BSUw9JHtTTVRQX0FETUlOX0VNQUlMfScKICAgICAgLSAnR09UUlVFX1NNVFBfSE9TVD0ke1NNVFBfSE9TVH0nCiAgICAgIC0gJ0dPVFJVRV9TTVRQX1BPUlQ9JHtTTVRQX1BPUlQ6LTU4N30nCiAgICAgIC0gJ0dPVFJVRV9TTVRQX1VTRVI9JHtTTVRQX1VTRVJ9JwogICAgICAtICdHT1RSVUVfU01UUF9QQVNTPSR7U01UUF9QQVNTfScKICAgICAgLSAnR09UUlVFX1NNVFBfU0VOREVSX05BTUU9JHtTTVRQX1NFTkRFUl9OQU1FfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9VUkxQQVRIU19JTlZJVEU9JHtNQUlMRVJfVVJMUEFUSFNfSU5WSVRFOi0vYXV0aC92MS92ZXJpZnl9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1VSTFBBVEhTX0NPTkZJUk1BVElPTj0ke01BSUxFUl9VUkxQQVRIU19DT05GSVJNQVRJT046LS9hdXRoL3YxL3ZlcmlmeX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVVJMUEFUSFNfUkVDT1ZFUlk9JHtNQUlMRVJfVVJMUEFUSFNfUkVDT1ZFUlk6LS9hdXRoL3YxL3ZlcmlmeX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVVJMUEFUSFNfRU1BSUxfQ0hBTkdFPSR7TUFJTEVSX1VSTFBBVEhTX0VNQUlMX0NIQU5HRTotL2F1dGgvdjEvdmVyaWZ5fScKICAgICAgLSAnR09UUlVFX01BSUxFUl9URU1QTEFURVNfSU5WSVRFPSR7TUFJTEVSX1RFTVBMQVRFU19JTlZJVEV9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1RFTVBMQVRFU19DT05GSVJNQVRJT049JHtNQUlMRVJfVEVNUExBVEVTX0NPTkZJUk1BVElPTn0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVEVNUExBVEVTX1JFQ09WRVJZPSR7TUFJTEVSX1RFTVBMQVRFU19SRUNPVkVSWX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVEVNUExBVEVTX01BR0lDX0xJTks9JHtNQUlMRVJfVEVNUExBVEVTX01BR0lDX0xJTkt9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1RFTVBMQVRFU19FTUFJTF9DSEFOR0U9JHtNQUlMRVJfVEVNUExBVEVTX0VNQUlMX0NIQU5HRX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfU1VCSkVDVFNfQ09ORklSTUFUSU9OPSR7TUFJTEVSX1NVQkpFQ1RTX0NPTkZJUk1BVElPTn0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfU1VCSkVDVFNfUkVDT1ZFUlk9JHtNQUlMRVJfU1VCSkVDVFNfUkVDT1ZFUll9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1NVQkpFQ1RTX01BR0lDX0xJTks9JHtNQUlMRVJfU1VCSkVDVFNfTUFHSUNfTElOS30nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfU1VCSkVDVFNfRU1BSUxfQ0hBTkdFPSR7TUFJTEVSX1NVQkpFQ1RTX0VNQUlMX0NIQU5HRX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfU1VCSkVDVFNfSU5WSVRFPSR7TUFJTEVSX1NVQkpFQ1RTX0lOVklURX0nCiAgICAgIC0gJ0dPVFJVRV9FWFRFUk5BTF9QSE9ORV9FTkFCTEVEPSR7RU5BQkxFX1BIT05FX1NJR05VUDotdHJ1ZX0nCiAgICAgIC0gJ0dPVFJVRV9TTVNfQVVUT0NPTkZJUk09JHtFTkFCTEVfUEhPTkVfQVVUT0NPTkZJUk06LXRydWV9JwogIHJlYWx0aW1lLWRldjoKICAgIGltYWdlOiAnc3VwYWJhc2UvcmVhbHRpbWU6djIuMzQuNDcnCiAgICBjb250YWluZXJfbmFtZTogcmVhbHRpbWUtZGV2LnN1cGFiYXNlLXJlYWx0aW1lCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLXNTZkwnCiAgICAgICAgLSAnLS1oZWFkJwogICAgICAgIC0gJy1vJwogICAgICAgIC0gL2Rldi9udWxsCiAgICAgICAgLSAnLUgnCiAgICAgICAgLSAnQXV0aG9yaXphdGlvbjogQmVhcmVyICR7U0VSVklDRV9TVVBBQkFTRUFOT05fS0VZfScKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjQwMDAvYXBpL3RlbmFudHMvcmVhbHRpbWUtZGV2L2hlYWx0aCcKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIGVudmlyb25tZW50OgogICAgICAtIFBPUlQ9NDAwMAogICAgICAtICdEQl9IT1NUPSR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifScKICAgICAgLSAnREJfUE9SVD0ke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9JwogICAgICAtIERCX1VTRVI9c3VwYWJhc2VfYWRtaW4KICAgICAgLSAnREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnREJfTkFNRT0ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gJ0RCX0FGVEVSX0NPTk5FQ1RfUVVFUlk9U0VUIHNlYXJjaF9wYXRoIFRPIF9yZWFsdGltZScKICAgICAgLSBEQl9FTkNfS0VZPXN1cGFiYXNlcmVhbHRpbWUKICAgICAgLSAnQVBJX0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gRkxZX0FMTE9DX0lEPWZseTEyMwogICAgICAtIEZMWV9BUFBfTkFNRT1yZWFsdGltZQogICAgICAtICdTRUNSRVRfS0VZX0JBU0U9JHtTRUNSRVRfUEFTU1dPUkRfUkVBTFRJTUV9JwogICAgICAtICdFUkxfQUZMQUdTPS1wcm90b19kaXN0IGluZXRfdGNwJwogICAgICAtIEVOQUJMRV9UQUlMU0NBTEU9ZmFsc2UKICAgICAgLSAiRE5TX05PREVTPScnIgogICAgICAtIFJMSU1JVF9OT0ZJTEU9MTAwMDAKICAgICAgLSBBUFBfTkFNRT1yZWFsdGltZQogICAgICAtIFNFRURfU0VMRl9IT1NUPXRydWUKICAgICAgLSBMT0dfTEVWRUw9ZXJyb3IKICAgICAgLSBSVU5fSkFOSVRPUj10cnVlCiAgICAgIC0gSkFOSVRPUl9JTlRFUlZBTD02MDAwMAogICAgY29tbWFuZDogInNoIC1jIFwiL2FwcC9iaW4vbWlncmF0ZSAmJiAvYXBwL2Jpbi9yZWFsdGltZSBldmFsICdSZWFsdGltZS5SZWxlYXNlLnNlZWRzKFJlYWx0aW1lLlJlcG8pJyAmJiAvYXBwL2Jpbi9zZXJ2ZXJcIlxuIgogIHN1cGFiYXNlLW1pbmlvOgogICAgaW1hZ2U6ICdnaGNyLmlvL2Nvb2xsYWJzaW8vbWluaW86UkVMRUFTRS4yMDI1LTEwLTE1VDE3LTI5LTU1WicKICAgIGVudmlyb25tZW50OgogICAgICAtICdNSU5JT19ST09UX1VTRVI9JHtTRVJWSUNFX1VTRVJfTUlOSU99JwogICAgICAtICdNSU5JT19ST09UX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NSU5JT30nCiAgICBjb21tYW5kOiAnc2VydmVyIC0tY29uc29sZS1hZGRyZXNzICI6OTAwMSIgL2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gbWMKICAgICAgICAtIHJlYWR5CiAgICAgICAgLSBsb2NhbAogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgICB2b2x1bWVzOgogICAgICAtICcuL3ZvbHVtZXMvc3RvcmFnZTovZGF0YScKICBtaW5pby1jcmVhdGVidWNrZXQ6CiAgICBpbWFnZTogbWluaW8vbWMKICAgIHJlc3RhcnQ6ICdubycKICAgIGVudmlyb25tZW50OgogICAgICAtICdNSU5JT19ST09UX1VTRVI9JHtTRVJWSUNFX1VTRVJfTUlOSU99JwogICAgICAtICdNSU5JT19ST09UX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NSU5JT30nCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1taW5pbzoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW50cnlwb2ludDoKICAgICAgLSAvZW50cnlwb2ludC5zaAogICAgdm9sdW1lczoKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vZW50cnlwb2ludC5zaAogICAgICAgIHRhcmdldDogL2VudHJ5cG9pbnQuc2gKICAgICAgICBjb250ZW50OiAiIyEvYmluL3NoXG4vdXNyL2Jpbi9tYyBhbGlhcyBzZXQgc3VwYWJhc2UtbWluaW8gaHR0cDovL3N1cGFiYXNlLW1pbmlvOjkwMDAgJHtNSU5JT19ST09UX1VTRVJ9ICR7TUlOSU9fUk9PVF9QQVNTV09SRH07XG4vdXNyL2Jpbi9tYyBtYiAtLWlnbm9yZS1leGlzdGluZyBzdXBhYmFzZS1taW5pby9zdHViO1xuZXhpdCAwXG4iCiAgc3VwYWJhc2Utc3RvcmFnZToKICAgIGltYWdlOiAnc3VwYWJhc2Uvc3RvcmFnZS1hcGk6djEuMTQuNicKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHN1cGFiYXNlLXJlc3Q6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX3N0YXJ0ZWQKICAgICAgaW1ncHJveHk6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX3N0YXJ0ZWQKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLS1uby12ZXJib3NlJwogICAgICAgIC0gJy0tdHJpZXM9MScKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjUwMDAvc3RhdHVzJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVkVSX1BPUlQ9NTAwMAogICAgICAtIFNFUlZFUl9SRUdJT049bG9jYWwKICAgICAgLSBNVUxUSV9URU5BTlQ9ZmFsc2UKICAgICAgLSAnQVVUSF9KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXM6Ly9zdXBhYmFzZV9zdG9yYWdlX2FkbWluOiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AJHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9OiR7UE9TVEdSRVNfUE9SVDotNTQzMn0vJHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtIERCX0lOU1RBTExfUk9MRVM9ZmFsc2UKICAgICAgLSBTVE9SQUdFX0JBQ0tFTkQ9czMKICAgICAgLSBTVE9SQUdFX1MzX0JVQ0tFVD1zdHViCiAgICAgIC0gJ1NUT1JBR0VfUzNfRU5EUE9JTlQ9aHR0cDovL3N1cGFiYXNlLW1pbmlvOjkwMDAnCiAgICAgIC0gU1RPUkFHRV9TM19GT1JDRV9QQVRIX1NUWUxFPXRydWUKICAgICAgLSBTVE9SQUdFX1MzX1JFR0lPTj11cy1lYXN0LTEKICAgICAgLSAnQVdTX0FDQ0VTU19LRVlfSUQ9JHtTRVJWSUNFX1VTRVJfTUlOSU99JwogICAgICAtICdBV1NfU0VDUkVUX0FDQ0VTU19LRVk9JHtTRVJWSUNFX1BBU1NXT1JEX01JTklPfScKICAgICAgLSBVUExPQURfRklMRV9TSVpFX0xJTUlUPTUyNDI4ODAwMAogICAgICAtIFVQTE9BRF9GSUxFX1NJWkVfTElNSVRfU1RBTkRBUkQ9NTI0Mjg4MDAwCiAgICAgIC0gVVBMT0FEX1NJR05FRF9VUkxfRVhQSVJBVElPTl9USU1FPTEyMAogICAgICAtIFRVU19VUkxfUEFUSD11cGxvYWQvcmVzdW1hYmxlCiAgICAgIC0gVFVTX01BWF9TSVpFPTM2MDAwMDAKICAgICAgLSBFTkFCTEVfSU1BR0VfVFJBTlNGT1JNQVRJT049dHJ1ZQogICAgICAtICdJTUdQUk9YWV9VUkw9aHR0cDovL2ltZ3Byb3h5OjgwODAnCiAgICAgIC0gSU1HUFJPWFlfUkVRVUVTVF9USU1FT1VUPTE1CiAgICAgIC0gREFUQUJBU0VfU0VBUkNIX1BBVEg9c3RvcmFnZQogICAgICAtIE5PREVfRU5WPXByb2R1Y3Rpb24KICAgICAgLSBSRVFVRVNUX0FMTE9XX1hfRk9SV0FSREVEX1BBVEg9dHJ1ZQogICAgdm9sdW1lczoKICAgICAgLSAnLi92b2x1bWVzL3N0b3JhZ2U6L3Zhci9saWIvc3RvcmFnZScKICBpbWdwcm94eToKICAgIGltYWdlOiAnZGFydGhzaW0vaW1ncHJveHk6djMuOC4wJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGltZ3Byb3h5CiAgICAgICAgLSBoZWFsdGgKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIGVudmlyb25tZW50OgogICAgICAtIElNR1BST1hZX0xPQ0FMX0ZJTEVTWVNURU1fUk9PVD0vCiAgICAgIC0gSU1HUFJPWFlfVVNFX0VUQUc9dHJ1ZQogICAgICAtICdJTUdQUk9YWV9FTkFCTEVfV0VCUF9ERVRFQ1RJT049JHtJTUdQUk9YWV9FTkFCTEVfV0VCUF9ERVRFQ1RJT046LXRydWV9JwogICAgdm9sdW1lczoKICAgICAgLSAnLi92b2x1bWVzL3N0b3JhZ2U6L3Zhci9saWIvc3RvcmFnZScKICBzdXBhYmFzZS1tZXRhOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9wb3N0Z3Jlcy1tZXRhOnYwLjg5LjMnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudmlyb25tZW50OgogICAgICAtIFBHX01FVEFfUE9SVD04MDgwCiAgICAgIC0gJ1BHX01FVEFfREJfSE9TVD0ke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn0nCiAgICAgIC0gJ1BHX01FVEFfREJfUE9SVD0ke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9JwogICAgICAtICdQR19NRVRBX0RCX05BTUU9JHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtIFBHX01FVEFfREJfVVNFUj1zdXBhYmFzZV9hZG1pbgogICAgICAtICdQR19NRVRBX0RCX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgc3VwYWJhc2UtZWRnZS1mdW5jdGlvbnM6CiAgICBpbWFnZTogJ3N1cGFiYXNlL2VkZ2UtcnVudGltZTp2MS42Ny40JwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gZWNobwogICAgICAgIC0gJ0VkZ2UgRnVuY3Rpb25zIGlzIGhlYWx0aHknCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIGludGVydmFsOiA1cwogICAgICByZXRyaWVzOiAzCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSAnU1VQQUJBU0VfVVJMPSR7U0VSVklDRV9VUkxfU1VQQUJBU0VLT05HfScKICAgICAgLSAnU1VQQUJBU0VfQU5PTl9LRVk9JHtTRVJWSUNFX1NVUEFCQVNFQU5PTl9LRVl9JwogICAgICAtICdTVVBBQkFTRV9TRVJWSUNFX1JPTEVfS0VZPSR7U0VSVklDRV9TVVBBQkFTRVNFUlZJQ0VfS0VZfScKICAgICAgLSAnU1VQQUJBU0VfREJfVVJMPXBvc3RncmVzcWw6Ly9wb3N0Z3Jlczoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9LyR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnVkVSSUZZX0pXVD0ke0ZVTkNUSU9OU19WRVJJRllfSldUOi1mYWxzZX0nCiAgICB2b2x1bWVzOgogICAgICAtICcuL3ZvbHVtZXMvZnVuY3Rpb25zOi9ob21lL2Rlbm8vZnVuY3Rpb25zJwogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2Z1bmN0aW9ucy9tYWluL2luZGV4LnRzCiAgICAgICAgdGFyZ2V0OiAvaG9tZS9kZW5vL2Z1bmN0aW9ucy9tYWluL2luZGV4LnRzCiAgICAgICAgY29udGVudDogImltcG9ydCB7IHNlcnZlIH0gZnJvbSAnaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuMTMxLjAvaHR0cC9zZXJ2ZXIudHMnXG5pbXBvcnQgKiBhcyBqb3NlIGZyb20gJ2h0dHBzOi8vZGVuby5sYW5kL3gvam9zZUB2NC4xNC40L2luZGV4LnRzJ1xuXG5jb25zb2xlLmxvZygnbWFpbiBmdW5jdGlvbiBzdGFydGVkJylcblxuY29uc3QgSldUX1NFQ1JFVCA9IERlbm8uZW52LmdldCgnSldUX1NFQ1JFVCcpXG5jb25zdCBWRVJJRllfSldUID0gRGVuby5lbnYuZ2V0KCdWRVJJRllfSldUJykgPT09ICd0cnVlJ1xuXG5mdW5jdGlvbiBnZXRBdXRoVG9rZW4ocmVxOiBSZXF1ZXN0KSB7XG4gIGNvbnN0IGF1dGhIZWFkZXIgPSByZXEuaGVhZGVycy5nZXQoJ2F1dGhvcml6YXRpb24nKVxuICBpZiAoIWF1dGhIZWFkZXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgYXV0aG9yaXphdGlvbiBoZWFkZXInKVxuICB9XG4gIGNvbnN0IFtiZWFyZXIsIHRva2VuXSA9IGF1dGhIZWFkZXIuc3BsaXQoJyAnKVxuICBpZiAoYmVhcmVyICE9PSAnQmVhcmVyJykge1xuICAgIHRocm93IG5ldyBFcnJvcihgQXV0aCBoZWFkZXIgaXMgbm90ICdCZWFyZXIge3Rva2VufSdgKVxuICB9XG4gIHJldHVybiB0b2tlblxufVxuXG5hc3luYyBmdW5jdGlvbiB2ZXJpZnlKV1Qoand0OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3QgZW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpXG4gIGNvbnN0IHNlY3JldEtleSA9IGVuY29kZXIuZW5jb2RlKEpXVF9TRUNSRVQpXG4gIHRyeSB7XG4gICAgYXdhaXQgam9zZS5qd3RWZXJpZnkoand0LCBzZWNyZXRLZXkpXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGNvbnNvbGUuZXJyb3IoZXJyKVxuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbnNlcnZlKGFzeW5jIChyZXE6IFJlcXVlc3QpID0+IHtcbiAgaWYgKHJlcS5tZXRob2QgIT09ICdPUFRJT05TJyAmJiBWRVJJRllfSldUKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRva2VuID0gZ2V0QXV0aFRva2VuKHJlcSlcbiAgICAgIGNvbnN0IGlzVmFsaWRKV1QgPSBhd2FpdCB2ZXJpZnlKV1QodG9rZW4pXG5cbiAgICAgIGlmICghaXNWYWxpZEpXVCkge1xuICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KHsgbXNnOiAnSW52YWxpZCBKV1QnIH0pLCB7XG4gICAgICAgICAgc3RhdHVzOiA0MDEsXG4gICAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5lcnJvcihlKVxuICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShKU09OLnN0cmluZ2lmeSh7IG1zZzogZS50b1N0cmluZygpIH0pLCB7XG4gICAgICAgIHN0YXR1czogNDAxLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgY29uc3QgdXJsID0gbmV3IFVSTChyZXEudXJsKVxuICBjb25zdCB7IHBhdGhuYW1lIH0gPSB1cmxcbiAgY29uc3QgcGF0aF9wYXJ0cyA9IHBhdGhuYW1lLnNwbGl0KCcvJylcbiAgY29uc3Qgc2VydmljZV9uYW1lID0gcGF0aF9wYXJ0c1sxXVxuXG4gIGlmICghc2VydmljZV9uYW1lIHx8IHNlcnZpY2VfbmFtZSA9PT0gJycpIHtcbiAgICBjb25zdCBlcnJvciA9IHsgbXNnOiAnbWlzc2luZyBmdW5jdGlvbiBuYW1lIGluIHJlcXVlc3QnIH1cbiAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KGVycm9yKSwge1xuICAgICAgc3RhdHVzOiA0MDAsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICB9KVxuICB9XG5cbiAgY29uc3Qgc2VydmljZVBhdGggPSBgL2hvbWUvZGVuby9mdW5jdGlvbnMvJHtzZXJ2aWNlX25hbWV9YFxuICBjb25zb2xlLmVycm9yKGBzZXJ2aW5nIHRoZSByZXF1ZXN0IHdpdGggJHtzZXJ2aWNlUGF0aH1gKVxuXG4gIGNvbnN0IG1lbW9yeUxpbWl0TWIgPSAxNTBcbiAgY29uc3Qgd29ya2VyVGltZW91dE1zID0gMSAqIDYwICogMTAwMFxuICBjb25zdCBub01vZHVsZUNhY2hlID0gZmFsc2VcbiAgY29uc3QgaW1wb3J0TWFwUGF0aCA9IG51bGxcbiAgY29uc3QgZW52VmFyc09iaiA9IERlbm8uZW52LnRvT2JqZWN0KClcbiAgY29uc3QgZW52VmFycyA9IE9iamVjdC5rZXlzKGVudlZhcnNPYmopLm1hcCgoaykgPT4gW2ssIGVudlZhcnNPYmpba11dKVxuXG4gIHRyeSB7XG4gICAgY29uc3Qgd29ya2VyID0gYXdhaXQgRWRnZVJ1bnRpbWUudXNlcldvcmtlcnMuY3JlYXRlKHtcbiAgICAgIHNlcnZpY2VQYXRoLFxuICAgICAgbWVtb3J5TGltaXRNYixcbiAgICAgIHdvcmtlclRpbWVvdXRNcyxcbiAgICAgIG5vTW9kdWxlQ2FjaGUsXG4gICAgICBpbXBvcnRNYXBQYXRoLFxuICAgICAgZW52VmFycyxcbiAgICB9KVxuICAgIHJldHVybiBhd2FpdCB3b3JrZXIuZmV0Y2gocmVxKVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc3QgZXJyb3IgPSB7IG1zZzogZS50b1N0cmluZygpIH1cbiAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KGVycm9yKSwge1xuICAgICAgc3RhdHVzOiA1MDAsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICB9KVxuICB9XG59KSIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9mdW5jdGlvbnMvaGVsbG8vaW5kZXgudHMKICAgICAgICB0YXJnZXQ6IC9ob21lL2Rlbm8vZnVuY3Rpb25zL2hlbGxvL2luZGV4LnRzCiAgICAgICAgY29udGVudDogIi8vIEZvbGxvdyB0aGlzIHNldHVwIGd1aWRlIHRvIGludGVncmF0ZSB0aGUgRGVubyBsYW5ndWFnZSBzZXJ2ZXIgd2l0aCB5b3VyIGVkaXRvcjpcbi8vIGh0dHBzOi8vZGVuby5sYW5kL21hbnVhbC9nZXR0aW5nX3N0YXJ0ZWQvc2V0dXBfeW91cl9lbnZpcm9ubWVudFxuLy8gVGhpcyBlbmFibGVzIGF1dG9jb21wbGV0ZSwgZ28gdG8gZGVmaW5pdGlvbiwgZXRjLlxuXG5pbXBvcnQgeyBzZXJ2ZSB9IGZyb20gXCJodHRwczovL2Rlbm8ubGFuZC9zdGRAMC4xNzcuMS9odHRwL3NlcnZlci50c1wiXG5cbnNlcnZlKGFzeW5jICgpID0+IHtcbiAgcmV0dXJuIG5ldyBSZXNwb25zZShcbiAgICBgXCJIZWxsbyBmcm9tIEVkZ2UgRnVuY3Rpb25zIVwiYCxcbiAgICB7IGhlYWRlcnM6IHsgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIgfSB9LFxuICApXG59KVxuXG4vLyBUbyBpbnZva2U6XG4vLyBjdXJsICdodHRwOi8vbG9jYWxob3N0OjxLT05HX0hUVFBfUE9SVD4vZnVuY3Rpb25zL3YxL2hlbGxvJyBcXFxuLy8gICAtLWhlYWRlciAnQXV0aG9yaXphdGlvbjogQmVhcmVyIDxhbm9uL3NlcnZpY2Vfcm9sZSBBUEkga2V5PidcbiIKICAgIGNvbW1hbmQ6CiAgICAgIC0gc3RhcnQKICAgICAgLSAnLS1tYWluLXNlcnZpY2UnCiAgICAgIC0gL2hvbWUvZGVuby9mdW5jdGlvbnMvbWFpbgogIHN1cGFiYXNlLXN1cGF2aXNvcjoKICAgIGltYWdlOiAnc3VwYWJhc2Uvc3VwYXZpc29yOjIuNS4xJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctc1NmTCcKICAgICAgICAtICctbycKICAgICAgICAtIC9kZXYvbnVsbAogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6NDAwMC9hcGkvaGVhbHRoJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMTAKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHN1cGFiYXNlLWFuYWx5dGljczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUE9PTEVSX1RFTkFOVF9JRD1kZXZfdGVuYW50CiAgICAgIC0gUE9PTEVSX1BPT0xfTU9ERT10cmFuc2FjdGlvbgogICAgICAtICdQT09MRVJfREVGQVVMVF9QT09MX1NJWkU9JHtQT09MRVJfREVGQVVMVF9QT09MX1NJWkU6LTIwfScKICAgICAgLSAnUE9PTEVSX01BWF9DTElFTlRfQ09OTj0ke1BPT0xFUl9NQVhfQ0xJRU5UX0NPTk46LTEwMH0nCiAgICAgIC0gUE9SVD00MDAwCiAgICAgIC0gJ1BPU1RHUkVTX1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSAnUE9TVEdSRVNfSE9TVE5BTUU9JHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1lY3RvOi8vc3VwYWJhc2VfYWRtaW46JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUAke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn06JHtQT1NUR1JFU19QT1JUOi01NDMyfS9fc3VwYWJhc2UnCiAgICAgIC0gQ0xVU1RFUl9QT1NUR1JFUz10cnVlCiAgICAgIC0gJ1NFQ1JFVF9LRVlfQkFTRT0ke1NFUlZJQ0VfUEFTU1dPUkRfU1VQQVZJU09SU0VDUkVUfScKICAgICAgLSAnVkFVTFRfRU5DX0tFWT0ke1NFUlZJQ0VfUEFTU1dPUkRfVkFVTFRFTkN9JwogICAgICAtICdBUElfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSAnTUVUUklDU19KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtIFJFR0lPTj1sb2NhbAogICAgICAtICdFUkxfQUZMQUdTPS1wcm90b19kaXN0IGluZXRfdGNwJwogICAgY29tbWFuZDoKICAgICAgLSAvYmluL3NoCiAgICAgIC0gJy1jJwogICAgICAtICcvYXBwL2Jpbi9taWdyYXRlICYmIC9hcHAvYmluL3N1cGF2aXNvciBldmFsICIkJChjYXQgL2V0Yy9wb29sZXIvcG9vbGVyLmV4cykiICYmIC9hcHAvYmluL3NlcnZlcicKICAgIHZvbHVtZXM6CiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvcG9vbGVyL3Bvb2xlci5leHMKICAgICAgICB0YXJnZXQ6IC9ldGMvcG9vbGVyL3Bvb2xlci5leHMKICAgICAgICBjb250ZW50OiAiezpvaywgX30gPSBBcHBsaWNhdGlvbi5lbnN1cmVfYWxsX3N0YXJ0ZWQoOnN1cGF2aXNvcilcbns6b2ssIHZlcnNpb259ID1cbiAgICBjYXNlIFN1cGF2aXNvci5SZXBvLnF1ZXJ5IShcInNlbGVjdCB2ZXJzaW9uKClcIikgZG9cbiAgICAle3Jvd3M6IFtbdmVyXV19IC0+IFN1cGF2aXNvci5IZWxwZXJzLnBhcnNlX3BnX3ZlcnNpb24odmVyKVxuICAgIF8gLT4gbmlsXG4gICAgZW5kXG5wYXJhbXMgPSAle1xuICAgIFwiZXh0ZXJuYWxfaWRcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPT0xFUl9URU5BTlRfSURcIiksXG4gICAgXCJkYl9ob3N0XCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT1NUR1JFU19IT1NUTkFNRVwiKSxcbiAgICBcImRiX3BvcnRcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPU1RHUkVTX1BPUlRcIikgfD4gU3RyaW5nLnRvX2ludGVnZXIoKSxcbiAgICBcImRiX2RhdGFiYXNlXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT1NUR1JFU19EQlwiKSxcbiAgICBcInJlcXVpcmVfdXNlclwiID0+IGZhbHNlLFxuICAgIFwiYXV0aF9xdWVyeVwiID0+IFwiU0VMRUNUICogRlJPTSBwZ2JvdW5jZXIuZ2V0X2F1dGgoJDEpXCIsXG4gICAgXCJkZWZhdWx0X21heF9jbGllbnRzXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT09MRVJfTUFYX0NMSUVOVF9DT05OXCIpLFxuICAgIFwiZGVmYXVsdF9wb29sX3NpemVcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPT0xFUl9ERUZBVUxUX1BPT0xfU0laRVwiKSxcbiAgICBcImRlZmF1bHRfcGFyYW1ldGVyX3N0YXR1c1wiID0+ICV7XCJzZXJ2ZXJfdmVyc2lvblwiID0+IHZlcnNpb259LFxuICAgIFwidXNlcnNcIiA9PiBbJXtcbiAgICBcImRiX3VzZXJcIiA9PiBcInBnYm91bmNlclwiLFxuICAgIFwiZGJfcGFzc3dvcmRcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPU1RHUkVTX1BBU1NXT1JEXCIpLFxuICAgIFwibW9kZV90eXBlXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT09MRVJfUE9PTF9NT0RFXCIpLFxuICAgIFwicG9vbF9zaXplXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT09MRVJfREVGQVVMVF9QT09MX1NJWkVcIiksXG4gICAgXCJpc19tYW5hZ2VyXCIgPT4gdHJ1ZVxuICAgIH1dXG59XG5cbnRlbmFudCA9IFN1cGF2aXNvci5UZW5hbnRzLmdldF90ZW5hbnRfYnlfZXh0ZXJuYWxfaWQocGFyYW1zW1wiZXh0ZXJuYWxfaWRcIl0pXG5cbmlmIHRlbmFudCBkb1xuICB7Om9rLCBffSA9IFN1cGF2aXNvci5UZW5hbnRzLnVwZGF0ZV90ZW5hbnQodGVuYW50LCBwYXJhbXMpXG5lbHNlXG4gIHs6b2ssIF99ID0gU3VwYXZpc29yLlRlbmFudHMuY3JlYXRlX3RlbmFudChwYXJhbXMpXG5lbmRcbiIK", "tags": [ "firebase", "alternative", @@ -4438,6 +4529,20 @@ "minversion": "0.0.0", "port": "8080" }, + "twenty": { + "documentation": "https://docs.twenty.com?utm_source=coolify.io", + "slogan": "Twenty is a CRM designed to fit your unique business needs.", + "compose": "c2VydmljZXM6CiAgdHdlbnR5OgogICAgaW1hZ2U6ICd0d2VudHljcm0vdHdlbnR5OnYxLjE1JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9VUkxfVFdFTlRZXzMwMDAKICAgICAgLSAnU0VSVkVSX1VSTD0ke1NFUlZJQ0VfVVJMX1RXRU5UWX0nCiAgICAgIC0gJ0ZST05UX0JBU0VfVVJMPSR7U0VSVklDRV9VUkxfVFdFTlRZfScKICAgICAgLSAnQVBQX1NFQ1JFVD0ke1NFUlZJQ0VfQkFTRTY0XzMyX1NFQ1JFVH0nCiAgICAgIC0gRU5BQkxFX0RCX01JR1JBVElPTlM9dHJ1ZQogICAgICAtICdDQUNIRV9TVE9SQUdFX1RZUEU9JHtDQUNIRV9TVE9SQUdFX1RZUEU6LXJlZGlzfScKICAgICAgLSAnUkVESVNfVVJMPXJlZGlzOi8vcmVkaXM6NjM3OScKICAgICAgLSAnQVBJX1JBVEVfTElNSVRJTkdfVFRMPSR7QVBJX1JBVEVfTElNSVRJTkdfVFRMOi0xMDB9JwogICAgICAtICdBUElfUkFURV9MSU1JVElOR19MSU1JVD0ke0FQSV9SQVRFX0xJTUlUSU5HX0xJTUlUOi0xMDB9JwogICAgICAtICdQT1NUR1JFU19BRE1JTl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQR19EQVRBQkFTRV9VUkw9cG9zdGdyZXM6Ly8ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU306JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUBwb3N0Z3Jlczo1NDMyLyR7UE9TVEdSRVNfREI6LXR3ZW50eS1kYn0nCiAgICAgIC0gJ0lTX1NJR05fVVBfRElTQUJMRUQ9JHtJU19TSUdOX1VQX0RJU0FCTEVEOi1mYWxzZX0nCiAgICAgIC0gJ1BBU1NXT1JEX1JFU0VUX1RPS0VOX0VYUElSRVNfSU49JHtQQVNTV09SRF9SRVNFVF9UT0tFTl9FWFBJUkVTX0lOOi01bX0nCiAgICAgIC0gJ1dPUktTUEFDRV9JTkFDVElWRV9EQVlTX0JFRk9SRV9OT1RJRklDQVRJT049JHtXT1JLU1BBQ0VfSU5BQ1RJVkVfREFZU19CRUZPUkVfTk9USUZJQ0FUSU9OOi03fScKICAgICAgLSAnV09SS1NQQUNFX0lOQUNUSVZFX0RBWVNfQkVGT1JFX0RFTEVUSU9OPSR7V09SS1NQQUNFX0lOQUNUSVZFX0RBWVNfQkVGT1JFX0RFTEVUSU9OOi0yMX0nCiAgICAgIC0gJ1NUT1JBR0VfVFlQRT0ke1NUT1JBR0VfVFlQRTotbG9jYWx9JwogICAgICAtIFNUT1JBR0VfUzNfUkVHSU9OPSRTVE9SQUdFX1MzX1JFR0lPTgogICAgICAtIFNUT1JBR0VfUzNfTkFNRT0kU1RPUkFHRV9TM19OQU1FCiAgICAgIC0gU1RPUkFHRV9TM19FTkRQT0lOVD0kU1RPUkFHRV9TM19FTkRQT0lOVAogICAgICAtIFNUT1JBR0VfUzNfQUNDRVNTX0tFWV9JRD0kU1RPUkFHRV9TM19BQ0NFU1NfS0VZX0lECiAgICAgIC0gU1RPUkFHRV9TM19TRUNSRVRfQUNDRVNTX0tFWT0kU1RPUkFHRV9TM19TRUNSRVRfQUNDRVNTX0tFWQogICAgICAtICdNRVNTQUdFX1FVRVVFX1RZUEU9JHtNRVNTQUdFX1FVRVVFX1RZUEU6LXBnLWJvc3N9JwogICAgICAtIEVNQUlMX0ZST01fQUREUkVTUz0kRU1BSUxfRlJPTV9BRERSRVNTCiAgICAgIC0gRU1BSUxfRlJPTV9OQU1FPSRFTUFJTF9GUk9NX05BTUUKICAgICAgLSBFTUFJTF9TWVNURU1fQUREUkVTUz0kRU1BSUxfU1lTVEVNX0FERFJFU1MKICAgICAgLSAnRU1BSUxfRFJJVkVSPSR7RU1BSUxfRFJJVkVSOi1sb2dnZXJ9JwogICAgICAtIEVNQUlMX1NNVFBfSE9TVD0kRU1BSUxfU01UUF9IT1NUCiAgICAgIC0gRU1BSUxfU01UUF9QT1JUPSRFTUFJTF9TTVRQX1BPUlQKICAgICAgLSBFTUFJTF9TTVRQX1VTRVI9JEVNQUlMX1NNVFBfVVNFUgogICAgICAtIEVNQUlMX1NNVFBfUEFTU1dPUkQ9JEVNQUlMX1NNVFBfUEFTU1dPUkQKICAgICAgLSBTSUdOX0lOX1BSRUZJTExFRD1mYWxzZQogICAgICAtICdERUJVR19NT0RFPSR7REVCVUdfTU9ERTotZmFsc2V9JwogICAgICAtICdURUxFTUVUUllfRU5BQkxFRD0ke1RFTEVNRVRSWV9FTkFCTEVEOi1mYWxzZX0nCiAgICB2b2x1bWVzOgogICAgICAtICd0d2VudHktbG9jYWwtc3RvcmFnZTovYXBwL3BhY2thZ2VzL3R3ZW50eS1zZXJ2ZXIvLmxvY2FsLXN0b3JhZ2UnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6MzAwMC9oZWFsdGh6JwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTAKICAgICAgc3RhcnRfcGVyaW9kOiAxMHMKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgd29ya2VyOgogICAgaW1hZ2U6ICd0d2VudHljcm0vdHdlbnR5OnYxLjE1JwogICAgY29tbWFuZDoKICAgICAgLSB5YXJuCiAgICAgIC0gJ3dvcmtlcjpwcm9kJwogICAgdm9sdW1lczoKICAgICAgLSAndHdlbnR5LWxvY2FsLXN0b3JhZ2U6L2FwcC9wYWNrYWdlcy90d2VudHktc2VydmVyLy5sb2NhbC1zdG9yYWdlJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9VUkxfVFdFTlRZXzMwMDAKICAgICAgLSAnU0VSVkVSX1VSTD0ke1NFUlZJQ0VfVVJMX1RXRU5UWX0nCiAgICAgIC0gJ0ZST05UX0JBU0VfVVJMPSR7U0VSVklDRV9VUkxfVFdFTlRZfScKICAgICAgLSAnQVBQX1NFQ1JFVD0ke1NFUlZJQ0VfQkFTRTY0XzMyX1NFQ1JFVH0nCiAgICAgIC0gRU5BQkxFX0RCX01JR1JBVElPTlM9dHJ1ZQogICAgICAtICdDQUNIRV9TVE9SQUdFX1RZUEU9JHtDQUNIRV9TVE9SQUdFX1RZUEU6LXJlZGlzfScKICAgICAgLSAnUkVESVNfVVJMPXJlZGlzOi8vcmVkaXM6NjM3OScKICAgICAgLSAnQVBJX1JBVEVfTElNSVRJTkdfVFRMPSR7QVBJX1JBVEVfTElNSVRJTkdfVFRMOi0xMDB9JwogICAgICAtICdBUElfUkFURV9MSU1JVElOR19MSU1JVD0ke0FQSV9SQVRFX0xJTUlUSU5HX0xJTUlUOi0xMDB9JwogICAgICAtICdQT1NUR1JFU19BRE1JTl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQR19EQVRBQkFTRV9VUkw9cG9zdGdyZXM6Ly8ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU306JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUBwb3N0Z3Jlczo1NDMyLyR7UE9TVEdSRVNfREI6LXR3ZW50eS1kYn0nCiAgICAgIC0gJ0lTX1NJR05fVVBfRElTQUJMRUQ9JHtJU19TSUdOX1VQX0RJU0FCTEVEOi1mYWxzZX0nCiAgICAgIC0gJ1BBU1NXT1JEX1JFU0VUX1RPS0VOX0VYUElSRVNfSU49JHtQQVNTV09SRF9SRVNFVF9UT0tFTl9FWFBJUkVTX0lOOi01bX0nCiAgICAgIC0gJ1dPUktTUEFDRV9JTkFDVElWRV9EQVlTX0JFRk9SRV9OT1RJRklDQVRJT049JHtXT1JLU1BBQ0VfSU5BQ1RJVkVfREFZU19CRUZPUkVfTk9USUZJQ0FUSU9OOi03fScKICAgICAgLSAnV09SS1NQQUNFX0lOQUNUSVZFX0RBWVNfQkVGT1JFX0RFTEVUSU9OPSR7V09SS1NQQUNFX0lOQUNUSVZFX0RBWVNfQkVGT1JFX0RFTEVUSU9OOi0yMX0nCiAgICAgIC0gJ1NUT1JBR0VfVFlQRT0ke1NUT1JBR0VfVFlQRTotbG9jYWx9JwogICAgICAtIFNUT1JBR0VfUzNfUkVHSU9OPSRTVE9SQUdFX1MzX1JFR0lPTgogICAgICAtIFNUT1JBR0VfUzNfTkFNRT0kU1RPUkFHRV9TM19OQU1FCiAgICAgIC0gU1RPUkFHRV9TM19FTkRQT0lOVD0kU1RPUkFHRV9TM19FTkRQT0lOVAogICAgICAtIFNUT1JBR0VfUzNfQUNDRVNTX0tFWV9JRD0kU1RPUkFHRV9TM19BQ0NFU1NfS0VZX0lECiAgICAgIC0gU1RPUkFHRV9TM19TRUNSRVRfQUNDRVNTX0tFWT0kU1RPUkFHRV9TM19TRUNSRVRfQUNDRVNTX0tFWQogICAgICAtICdNRVNTQUdFX1FVRVVFX1RZUEU9JHtNRVNTQUdFX1FVRVVFX1RZUEU6LXBnLWJvc3N9JwogICAgICAtIEVNQUlMX0ZST01fQUREUkVTUz0kRU1BSUxfRlJPTV9BRERSRVNTCiAgICAgIC0gRU1BSUxfRlJPTV9OQU1FPSRFTUFJTF9GUk9NX05BTUUKICAgICAgLSBFTUFJTF9TWVNURU1fQUREUkVTUz0kRU1BSUxfU1lTVEVNX0FERFJFU1MKICAgICAgLSAnRU1BSUxfRFJJVkVSPSR7RU1BSUxfRFJJVkVSOi1sb2dnZXJ9JwogICAgICAtIEVNQUlMX1NNVFBfSE9TVD0kRU1BSUxfU01UUF9IT1NUCiAgICAgIC0gRU1BSUxfU01UUF9QT1JUPSRFTUFJTF9TTVRQX1BPUlQKICAgICAgLSBFTUFJTF9TTVRQX1VTRVI9JEVNQUlMX1NNVFBfVVNFUgogICAgICAtIEVNQUlMX1NNVFBfUEFTU1dPUkQ9JEVNQUlMX1NNVFBfUEFTU1dPUkQKICAgICAgLSBTSUdOX0lOX1BSRUZJTExFRD1mYWxzZQogICAgICAtICdERUJVR19NT0RFPSR7REVCVUdfTU9ERTotZmFsc2V9JwogICAgICAtICdURUxFTUVUUllfRU5BQkxFRD0ke1RFTEVNRVRSWV9FTkFCTEVEOi1mYWxzZX0nCiAgICAgIC0gRElTQUJMRV9EQl9NSUdSQVRJT05TPXRydWUKICAgICAgLSBESVNBQkxFX0NST05fSk9CU19SRUdJU1RSQVRJT049dHJ1ZQogICAgZGVwZW5kc19vbjoKICAgICAgdHdlbnR5OgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotdHdlbnR5LWRifScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Bvc3RncmVzLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczo3LWFscGluZScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3JlZGlzLWRhdGE6L2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSBwaW5nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK", + "tags": [ + "crm", + "self-hosted", + "dashboard" + ], + "category": "cms", + "logo": "svgs/twenty.svg", + "minversion": "0.0.0", + "port": "3000" + }, "typesense": { "documentation": "https://typesense.org/docs?utm_source=coolify.io", "slogan": "Cutting-edge, in-memory search engine for mere mortals. Knowledge of rocket science optional.", @@ -4521,10 +4626,46 @@ "minversion": "0.0.0", "port": "8000" }, + "uptime-kuma-with-mariadb": { + "documentation": "https://github.com/louislam/uptime-kuma?tab=readme-ov-file?utm_source=coolify.io", + "slogan": "Uptime Kuma is a monitoring tool for tracking the status and performance of your applications in real-time.", + "compose": "c2VydmljZXM6CiAgdXB0aW1lLWt1bWE6CiAgICBpbWFnZTogJ2xvdWlzbGFtL3VwdGltZS1rdW1hOjInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX1VSTF9VUFRJTUVLVU1BXzMwMDEKICAgICAgLSAnVFo9JHtUWjotRXRjL1VUQ30nCiAgICB2b2x1bWVzOgogICAgICAtICd1cHRpbWUta3VtYS1kYXRhOi9hcHAvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSBleHRyYS9oZWFsdGhjaGVjawogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTAKICAgIGRlcGVuZHNfb246CiAgICAgIG1hcmlhZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICBtYXJpYWRiOgogICAgaW1hZ2U6ICdtYXJpYWRiOjExJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ01ZU1FMX1VTRVI9JHtTRVJWSUNFX1VTRVJfTUFSSUFEQn0nCiAgICAgIC0gJ01ZU1FMX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NQVJJQURCfScKICAgICAgLSAnTVlTUUxfUk9PVF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUk9PVH0nCiAgICAgIC0gJ01ZU1FMX0RBVEFCQVNFPSR7TVlTUUxfREFUQUJBU0U6LXVwdGltZS1rdW1hLWRifScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBoZWFsdGhjaGVjay5zaAogICAgICAgIC0gJy0tY29ubmVjdCcKICAgICAgICAtICctLWlubm9kYl9pbml0aWFsaXplZCcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogICAgdm9sdW1lczoKICAgICAgLSAnbWFyaWFkYi1kYXRhOi92YXIvbGliL215c3FsJwo=", + "tags": [ + "monitoring", + "status", + "performance", + "web", + "services", + "applications", + "real-time" + ], + "category": "monitoring", + "logo": "svgs/uptime-kuma.svg", + "minversion": "0.0.0", + "port": "3001" + }, + "uptime-kuma-with-mysql": { + "documentation": "https://github.com/louislam/uptime-kuma?tab=readme-ov-file?utm_source=coolify.io", + "slogan": "Uptime Kuma is a monitoring tool for tracking the status and performance of your applications in real-time.", + "compose": "c2VydmljZXM6CiAgdXB0aW1lLWt1bWE6CiAgICBpbWFnZTogJ2xvdWlzbGFtL3VwdGltZS1rdW1hOjInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX1VSTF9VUFRJTUVLVU1BXzMwMDEKICAgICAgLSAnVFo9JHtUWjotRXRjL1VUQ30nCiAgICB2b2x1bWVzOgogICAgICAtICd1cHRpbWUta3VtYS1kYXRhOi9hcHAvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSBleHRyYS9oZWFsdGhjaGVjawogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTAKICAgIGRlcGVuZHNfb246CiAgICAgIG15c3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgbXlzcWw6CiAgICBpbWFnZTogJ215c3FsOjgnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnTVlTUUxfVVNFUj0ke1NFUlZJQ0VfVVNFUl9NWVNRTH0nCiAgICAgIC0gJ01ZU1FMX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NWVNRTH0nCiAgICAgIC0gJ01ZU1FMX1JPT1RfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1JPT1R9JwogICAgICAtICdNWVNRTF9EQVRBQkFTRT0ke01ZU1FMX0RBVEFCQVNFOi11cHRpbWUta3VtYS1kYn0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gbXlzcWxhZG1pbgogICAgICAgIC0gcGluZwogICAgICAgIC0gJy1oJwogICAgICAgIC0gMTI3LjAuMC4xCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICAgIHZvbHVtZXM6CiAgICAgIC0gJ215c3FsLWRhdGE6L3Zhci9saWIvbXlzcWwnCg==", + "tags": [ + "monitoring", + "status", + "performance", + "web", + "services", + "applications", + "real-time" + ], + "category": "monitoring", + "logo": "svgs/uptime-kuma.svg", + "minversion": "0.0.0", + "port": "3001" + }, "uptime-kuma": { "documentation": "https://github.com/louislam/uptime-kuma?tab=readme-ov-file?utm_source=coolify.io", "slogan": "Uptime Kuma is a monitoring tool for tracking the status and performance of your applications in real-time.", - "compose": "c2VydmljZXM6CiAgdXB0aW1lLWt1bWE6CiAgICBpbWFnZTogJ2xvdWlzbGFtL3VwdGltZS1rdW1hOjInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX1VSTF9VUFRJTUVLVU1BXzMwMDEKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3VwdGltZS1rdW1hOi9hcHAvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSBleHRyYS9oZWFsdGhjaGVjawogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDE1Cg==", + "compose": "c2VydmljZXM6CiAgdXB0aW1lLWt1bWE6CiAgICBpbWFnZTogJ2xvdWlzbGFtL3VwdGltZS1rdW1hOjInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX1VSTF9VUFRJTUVLVU1BXzMwMDEKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3VwdGltZS1rdW1hLWRhdGE6L2FwcC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtIGV4dHJhL2hlYWx0aGNoZWNrCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiAxMAo=", "tags": [ "monitoring", "status", diff --git a/templates/service-templates.json b/templates/service-templates.json index ce43c5d45..fa5cfb13d 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -189,6 +189,22 @@ "minversion": "0.0.0", "port": "9000" }, + "autobase": { + "documentation": "https://autobase.tech/docs/?utm_source=coolify.io", + "slogan": "Autobase for PostgreSQL\u00ae is an open-source alternative to cloud-managed databases (self-hosted DBaaS).", + "compose": "c2VydmljZXM6CiAgYXV0b2Jhc2U6CiAgICBpbWFnZTogJ2F1dG9iYXNlL2NvbnNvbGVfdWk6Mi40LjEnCiAgICBwbGF0Zm9ybTogbGludXgvYW1kNjQKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9BVVRPQkFTRV84MAogICAgICAtICdQR19DT05TT0xFX0FVVEhPUklaQVRJT05fVE9LRU49JHtTRVJWSUNFX1BBU1NXT1JEX1VJfScKICAgICAgLSBQR19DT05TT0xFX0FQSV9IT1NUPWF1dG9iYXNlLWFwaQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwLycKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgICBkZXBlbmRzX29uOgogICAgICBhdXRvYmFzZS1hcGk6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICBhdXRvYmFzZS1kYjoKICAgIGltYWdlOiAnYXV0b2Jhc2UvY29uc29sZV9kYjoyLjQuMScKICAgIHBsYXRmb3JtOiBsaW51eC9hbWQ2NAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICB2b2x1bWVzOgogICAgICAtICdhdXRvYmFzZS1kYi1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSBwb3N0Z3JlcycKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgYXV0b2Jhc2UtYXBpOgogICAgaW1hZ2U6ICdhdXRvYmFzZS9jb25zb2xlX2FwaToyLjQuMScKICAgIHBsYXRmb3JtOiBsaW51eC9hbWQ2NAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUEdfQ09OU09MRV9EQl9IT1NUPWF1dG9iYXNlLWRiCiAgICAgIC0gJ1BHX0NPTlNPTEVfREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnUEdfQ09OU09MRV9BVVRIT1JJWkFUSU9OX1RPS0VOPSR7U0VSVklDRV9QQVNTV09SRF9VSX0nCiAgICAgIC0gJ1BHX0NPTlNPTEVfRU5DUllQVElPTktFWT0ke1NFUlZJQ0VfQkFTRTY0X0VOQ1JZUFRJT05LRVl9JwogICAgICAtICdQR19DT05TT0xFX0xPR0dFUl9MRVZFTD0ke1BHX0NPTlNPTEVfTE9HR0VSX0xFVkVMOi1pbmZvfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJy92YXIvcnVuL2RvY2tlci5zb2NrOi92YXIvcnVuL2RvY2tlci5zb2NrJwogICAgICAtICcvdG1wL2Fuc2libGU6L3RtcC9hbnNpYmxlJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZnNTJwogICAgICAgIC0gJy1IJwogICAgICAgIC0gJ2FjY2VwdDogYXBwbGljYXRpb24vanNvbicKICAgICAgICAtICctSCcKICAgICAgICAtICdBdXRob3JpemF0aW9uOiBCZWFyZXIgJHtTRVJWSUNFX1BBU1NXT1JEX1VJfScKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwODAvYXBpL3YxL3ZlcnNpb24nCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogNQogICAgZGVwZW5kc19vbjoKICAgICAgYXV0b2Jhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkK", + "tags": [ + "database", + "postgres", + "automation", + "self-hosted", + "dbaas" + ], + "category": null, + "logo": "svgs/autobase.svg", + "minversion": "0.0.0", + "port": "80" + }, "babybuddy": { "documentation": "https://docs.baby-buddy.net?utm_source=coolify.io", "slogan": "It helps parents track their baby's daily activities, growth, and health with ease.", @@ -263,6 +279,23 @@ "minversion": "0.0.0", "port": "3000" }, + "booklore": { + "documentation": "https://booklore.org/docs/getting-started?utm_source=coolify.io", + "slogan": "Booklore is an open-source library management system for your digital book collection.", + "compose": "c2VydmljZXM6CiAgYm9va2xvcmU6CiAgICBpbWFnZTogJ2Jvb2tsb3JlL2Jvb2tsb3JlOnYxLjE2LjUnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fQk9PS0xPUkVfODAKICAgICAgLSAnVVNFUl9JRD0ke0JPT0tMT1JFX1VTRVJfSUQ6LTB9JwogICAgICAtICdHUk9VUF9JRD0ke0JPT0tMT1JFX0dST1VQX0lEOi0wfScKICAgICAgLSAnVFo9JHtUWjotVVRDfScKICAgICAgLSAnREFUQUJBU0VfVVJMPWpkYmM6bWFyaWFkYjovL21hcmlhZGI6MzMwNi8ke01BUklBREJfREFUQUJBU0U6LWJvb2tsb3JlLWRifScKICAgICAgLSAnREFUQUJBU0VfVVNFUk5BTUU9JHtTRVJWSUNFX1VTRVJfTUFSSUFEQn0nCiAgICAgIC0gJ0RBVEFCQVNFX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NQVJJQURCfScKICAgICAgLSBCT09LTE9SRV9QT1JUPTgwCiAgICB2b2x1bWVzOgogICAgICAtICdib29rbG9yZS1kYXRhOi9hcHAvZGF0YScKICAgICAgLSAnYm9va2xvcmUtYm9va3M6L2Jvb2tzJwogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogfi9ib29rbG9yZQogICAgICAgIHRhcmdldDogL2Jvb2tkcm9wCiAgICAgICAgaXNfZGlyZWN0b3J5OiB0cnVlCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDogJ3dnZXQgLS1uby12ZXJib3NlIC0tdHJpZXM9MSAtLXNwaWRlciBodHRwOi8vbG9jYWxob3N0L2xvZ2luIHx8IGV4aXQgMScKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiAxMAogICAgZGVwZW5kc19vbjoKICAgICAgbWFyaWFkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogIG1hcmlhZGI6CiAgICBpbWFnZTogJ21hcmlhZGI6MTInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnTUFSSUFEQl9VU0VSPSR7U0VSVklDRV9VU0VSX01BUklBREJ9JwogICAgICAtICdNQVJJQURCX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NQVJJQURCfScKICAgICAgLSAnTUFSSUFEQl9ST09UX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NQVJJQURCUk9PVH0nCiAgICAgIC0gJ01BUklBREJfREFUQUJBU0U9JHtNQVJJQURCX0RBVEFCQVNFOi1ib29rbG9yZS1kYn0nCiAgICB2b2x1bWVzOgogICAgICAtICdtYXJpYWRiLWRhdGE6L3Zhci9saWIvbXlzcWwnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gaGVhbHRoY2hlY2suc2gKICAgICAgICAtICctLWNvbm5lY3QnCiAgICAgICAgLSAnLS1pbm5vZGJfaW5pdGlhbGl6ZWQnCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTAK", + "tags": [ + "media", + "books", + "kobo", + "epub", + "ebook", + "koreader" + ], + "category": null, + "logo": "svgs/booklore.svg", + "minversion": "0.0.0", + "port": "80" + }, "bookstack": { "documentation": "https://www.bookstackapp.com/docs/?utm_source=coolify.io", "slogan": "BookStack is a simple, self-hosted, easy-to-use platform for organising and storing information", @@ -363,6 +396,28 @@ "minversion": "0.0.0", "port": "3000" }, + "calibre-web-automated-book-downloader": { + "documentation": "https://github.com/calibrain/calibre-web-automated-book-downloader?utm_source=coolify.io", + "slogan": "An intuitive web interface for searching and requesting book downloads, designed to work seamlessly with Calibre-Web-Automated.", + "compose": "c2VydmljZXM6CiAgY2FsaWJyZS13ZWItYXV0b21hdGVkOgogICAgaW1hZ2U6ICdjcm9jb2RpbGVzdGljay9jYWxpYnJlLXdlYi1hdXRvbWF0ZWQ6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0NXQV84MDgzCiAgICAgIC0gJ1BVSUQ9JHtQVUlEOi0xMDAwfScKICAgICAgLSAnUEdJRD0ke1BHSUQ6LTEwMDB9JwogICAgICAtICdUWj0ke1RaOi1VVEN9JwogICAgICAtICdORVRXT1JLX1NIQVJFX01PREU9JHtORVRXT1JLX1NIQVJFX01PREU6LWZhbHNlfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2N3YS1jb25maWc6L2NvbmZpZycKICAgICAgLSAnY3dhLWJvb2staW5nZXN0Oi9jd2EtYm9vay1pbmdlc3QnCiAgICAgIC0gJ2NhbGlicmUtbGlicmFyeTovY2FsaWJyZS1saWJyYXJ5JwogICAgICAtICdjYWxpYnJlLXBsdWdpbnM6L2NvbmZpZy8uY29uZmlnL2NhbGlicmUvcGx1Z2lucycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnY3VybCAtZnMgaHR0cDovL2xvY2FsaG9zdDo4MDgzIHx8IGV4aXQgMScKICAgICAgaW50ZXJ2YWw6IDMwcwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMwogICAgICBzdGFydF9wZXJpb2Q6IDMwcwogIGNhbGlicmUtd2ViLWRvd25sb2FkZXI6CiAgICBpbWFnZTogJ2doY3IuaW8vY2FsaWJyYWluL2NhbGlicmUtd2ViLWF1dG9tYXRlZC1ib29rLWRvd25sb2FkZXI6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0RPV05MT0FERVJfODA4NAogICAgICAtICdGTEFTS19QT1JUPSR7RkxBU0tfUE9SVDotODA4NH0nCiAgICAgIC0gJ0xPR19MRVZFTD0ke0xPR19MRVZFTDotaW5mb30nCiAgICAgIC0gJ0JPT0tfTEFOR1VBR0U9JHtCT09LX0xBTkdVQUdFOi1lbn0nCiAgICAgIC0gJ1VTRV9CT09LX1RJVExFPSR7VVNFX0JPT0tfVElUTEU6LXRydWV9JwogICAgICAtICdUWj0ke1RaOi1BbWVyaWNhL05ld19Zb3JrfScKICAgICAgLSAnQVBQX0VOVj0ke0FQUF9FTlY6LXByb2R9JwogICAgICAtICdVSUQ9JHtVSUQ6LTEwMDB9JwogICAgICAtICdHSUQ9JHtHSUQ6LTEwMH0nCiAgICAgIC0gJ0NXQV9EQl9QQVRIPSR7Q1dBX0RCX1BBVEg6LS9jd2EtY29uZmlnL2FwcC5kYn0nCiAgICB2b2x1bWVzOgogICAgICAtICdjd2EtYm9vay1pbmdlc3Q6L2N3YS1ib29rLWluZ2VzdCcKICAgICAgLSAnY3dhLWNvbmZpZzovY3dhLWNvbmZpZycK", + "tags": [ + "calibre", + "calibre-web", + "ebook", + "library", + "epub", + "ereader", + "kindle", + "book", + "reader", + "download", + "downloader" + ], + "category": null, + "logo": "svgs/calibre-web-automated-with-downloader.png", + "minversion": "0.0.0", + "port": "8083" + }, "calibre-web": { "documentation": "https://github.com/linuxserver/docker-calibre-web?utm_source=coolify.io", "slogan": "Calibre-web is a web app providing a clean interface for browsing, reading and downloading eBooks.", @@ -2456,17 +2511,40 @@ "minversion": "0.0.0", "port": "3000" }, - "matrix": { - "documentation": "https://matrix.org/docs/chat_basics/matrix-for-im/?utm_source=coolify.io", + "matrix-synapse-with-postgresql": { + "documentation": "https://element-hq.github.io/synapse/latest/welcome_and_overview.html?utm_source=coolify.io", "slogan": "Chat securely with your family, friends, community, or build great apps with Matrix!", - "compose": "c2VydmljZXM6CiAgbWF0cml4OgogICAgaW1hZ2U6ICdtYXRyaXhkb3Rvcmcvc3luYXBzZTpsYXRlc3QnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fTUFUUklYXzgwMDgKICAgICAgLSAnU1lOQVBTRV9TRVJWRVJfTkFNRT0ke1NFUlZJQ0VfRlFETl9NQVRSSVh9JwogICAgICAtICdTWU5BUFNFX1JFUE9SVF9TVEFUUz0ke1NZTkFQU0VfUkVQT1JUX1NUQVRTOi1ub30nCiAgICAgIC0gJ0VOQUJMRV9SRUdJU1RSQVRJT049JHtFTkFCTEVfUkVHSVNUUkFUSU9OOi1mYWxzZX0nCiAgICAgIC0gJ1JFQ0FQVENIQV9QVUJMSUNfS0VZPSR7UkVDQVBUQ0hBX1BVQkxJQ19LRVl9JwogICAgICAtICdSRUNBUFRDSEFfUFJJVkFURV9LRVk9JHtSRUNBUFRDSEFfUFJJVkFURV9LRVl9JwogICAgICAtICdfU0VSVkVSX05BTUU9JHtTRVJWSUNFX0ZRRE5fTUFUUklYfScKICAgICAgLSAnX0FETUlOX05BTUU9JHtTRVJWSUNFX1VTRVJfQURNSU59JwogICAgICAtICdfQURNSU5fUEFTUz0ke1NFUlZJQ0VfUEFTU1dPUkRfQURNSU59JwogICAgdm9sdW1lczoKICAgICAgLSAnbWF0cml4LWRhdGE6L2RhdGEnCiAgICBlbnRyeXBvaW50OgogICAgICAtIC9iaW4vYmFzaAogICAgICAtICctYycKICAgICAgLSAiISB0ZXN0IC1mIC9kYXRhL2hvbWVzZXJ2ZXIueWFtbCAmJiAvc3RhcnQucHkgZ2VuZXJhdGVcblxuIyByZWdpc3RyYXRpb25fc2hhcmVkX3NlY3JldFxuZ3JlcCBcInJlZ2lzdHJhdGlvbl9zaGFyZWRfc2VjcmV0XCIgL2RhdGEvaG9tZXNlcnZlci55YW1sIFxcXG58IGF3ayAne3ByaW50ICQyfScgPiAuL3JlZ2lzdHJhdGlvbl9zaGFyZWRfc2VjcmV0XG5cbiMgbWFjYXJvb25fc2VjcmV0X2tleVxuZ3JlcCBcIm1hY2Fyb29uX3NlY3JldF9rZXlcIiAvZGF0YS9ob21lc2VydmVyLnlhbWwgXFxcbnwgYXdrICd7cHJpbnQgJDJ9JyA+IC4vbWFjYXJvb25fc2VjcmV0X2tleVxuXG4jIGZvcm1fc2VjcmV0XG5ncmVwIFwiZm9ybV9zZWNyZXRcIiAvZGF0YS9ob21lc2VydmVyLnlhbWwgXFxcbnwgYXdrICd7cHJpbnQgJDJ9JyA+IC4vZm9ybV9zZWNyZXRcblxuIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyNcbiMgICAgICAgICAgICAgICAgICAgICAgICAjXG4jIGhvbWVzZXJ2ZXIueWFtbDogc3RhcnQgI1xuIyAgICAgICAgICAgICAgICAgICAgICAgICNcbiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjXG5jYXQgPDxFT0YgPiAvZGF0YS9ob21lc2VydmVyLnlhbWxcbnNlcnZlcl9uYW1lOiBcIiR7U0VSVklDRV9GUUROX01BVFJJWH1cIlxucGlkX2ZpbGU6IC9kYXRhL2hvbWVzZXJ2ZXIucGlkXG5cbiMgc2VydmVyXG5saXN0ZW5lcnM6XG4gIC0gcG9ydDogODAwOFxuICAgIHRsczogZmFsc2VcbiAgICB0eXBlOiBodHRwXG4gICAgeF9mb3J3YXJkZWQ6IHRydWVcbiAgICByZXNvdXJjZXM6XG4gICAgICAtIG5hbWVzOiBbY2xpZW50LCBmZWRlcmF0aW9uXVxuICAgICAgICBjb21wcmVzczogZmFsc2VcblxuIyBkYXRhYmFzZVxuZGF0YWJhc2U6XG4gIG5hbWU6IHNxbGl0ZTNcbiAgYXJnczpcbiAgICBkYXRhYmFzZTogL2RhdGEvaG9tZXNlcnZlci5kYlxuXG4jIGdlbmVyYWxcbmxvZ19jb25maWc6IFwiL2RhdGEvJHtTRVJWSUNFX0ZRRE5fTUFUUklYfS5sb2cuY29uZmlnXCJcbm1lZGlhX3N0b3JlX3BhdGg6IC9kYXRhL21lZGlhX3N0b3JlXG5yZXBvcnRfc3RhdHM6IGZhbHNlXG5cbiMgc2VjcmV0c1xucmVnaXN0cmF0aW9uX3NoYXJlZF9zZWNyZXQ6ICQoPC4vcmVnaXN0cmF0aW9uX3NoYXJlZF9zZWNyZXQpXG5tYWNhcm9vbl9zZWNyZXRfa2V5OiAkKDwuL21hY2Fyb29uX3NlY3JldF9rZXkpXG5mb3JtX3NlY3JldDogJCg8Li9mb3JtX3NlY3JldClcbnNpZ25pbmdfa2V5X3BhdGg6IFwiL2RhdGEvJHtTRVJWSUNFX0ZRRE5fTUFUUklYfS5zaWduaW5nLmtleVwiXG5cbiNyb29tc1xuYXV0b19qb2luX3Jvb21zOlxuICAtIFwiI2dlbmVyYWw6JHtTRVJWSUNFX0ZRRE5fTUFUUklYfVwiXG5cbiMgZmVkZXJhdGlvblxudHJ1c3RlZF9rZXlfc2VydmVyczpcbiAgLSBzZXJ2ZXJfbmFtZTogXCJtYXRyaXgub3JnXCJcbmF1dG9jcmVhdGVfYXV0b19qb2luX3Jvb21zX2ZlZGVyYXRlZDogZmFsc2VcbmFsbG93X3B1YmxpY19yb29tc19vdmVyX2ZlZGVyYXRpb246IGZhbHNlXG5FT0ZcbiMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjI1xuIyAgICAgICAgICAgICAgICAgICAgICAjXG4jIGhvbWVzZXJ2ZXIueWFtbDogZW5kICNcbiMgICAgICAgICAgICAgICAgICAgICAgI1xuIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjXG5cblsgXCIke0VOQUJMRV9SRUdJU1RSQVRJT059XCIgPSBcInRydWVcIiBdICYmICEgZ3JlcCBcIiNyZWdpc3RyYXRpb25cIiAvZGF0YS9ob21lc2VydmVyLnlhbWwgJj4vZGV2L251bGwgXFxcbiYmIGVjaG8gPj4gL2RhdGEvaG9tZXNlcnZlci55YW1sIFxcXG4mJiBjYXQgPDxFT0YgPj4gL2RhdGEvaG9tZXNlcnZlci55YW1sXG4jcmVnaXN0cmF0aW9uXG5lbmFibGVfcmVnaXN0cmF0aW9uOiB0cnVlICAjIEFsbG93cyB1c2VycyB0byByZWdpc3RlciBvbiB5b3VyIHNlcnZlci5cbkVPRlxuXG5bIC1uIFwiJHtSRUNBUFRDSEFfUFVCTElDX0tFWX1cIiBdICYmICEgZ3JlcCBcIiR7UkVDQVBUQ0hBX1BVQkxJQ19LRVl9XCIgL2RhdGEvaG9tZXNlcnZlci55YW1sICY+L2Rldi9udWxsIFxcXG4mJiBlY2hvID4+IC9kYXRhL2hvbWVzZXJ2ZXIueWFtbCBcXFxuJiYgY2F0IDw8RU9GID4+IC9kYXRhL2hvbWVzZXJ2ZXIueWFtbFxuIyByZUNBUFRDSEEgc2V0dGluZ3NcbmVuYWJsZV9yZWdpc3RyYXRpb25fY2FwdGNoYTogdHJ1ZSAgIyBFbmFibGVzIENBUFRDSEEgZm9yIHJlZ2lzdHJhdGlvbnMuXG5yZWNhcHRjaGFfcHVibGljX2tleTogXCIke1JFQ0FQVENIQV9QVUJMSUNfS0VZfVwiXG5yZWNhcHRjaGFfcHJpdmF0ZV9rZXk6IFwiJHtSRUNBUFRDSEFfUFJJVkFURV9LRVl9XCJcbnJlY2FwdGNoYV9zaXRldmVyaWZ5X2FwaTogXCJodHRwczovL3d3dy5nb29nbGUuY29tL3JlY2FwdGNoYS9hcGkvc2l0ZXZlcmlmeVwiXG5FT0ZcblxucmVnaXN0ZXJfYWRtaW4oKXtcbiAgd2hpbGUgISBjdXJsIC1JIGxvY2FsaG9zdDo4MDA4ICY+L2Rldi9udWxsOyBkb1xuICAgIHNsZWVwIDFcbiAgZG9uZVxuICByZWdpc3Rlcl9uZXdfbWF0cml4X3VzZXIgXFxcbiAgICAtYSBcXFxuICAgIC11ICR7U0VSVklDRV9VU0VSX0FETUlOfSBcXFxuICAgIC1wICR7U0VSVklDRV9QQVNTV09SRF9BRE1JTn0gXFxcbiAgICAtYyAvZGF0YS9ob21lc2VydmVyLnlhbWwgXFxcbiAgICBodHRwOi8vbG9jYWxob3N0OjgwMDggJj4vZGV2L251bGxcbn1cbnJlZ2lzdGVyX2FkbWluICZcblxuL3N0YXJ0LnB5XG4iCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1JJwogICAgICAgIC0gJ2xvY2FsaG9zdDo4MDA4JwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogM3MKICAgICAgcmV0cmllczogNQo=", + "compose": "c2VydmljZXM6CiAgc3luYXBzZToKICAgIGltYWdlOiAnbWF0cml4ZG90b3JnL3N5bmFwc2U6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX1NZTkFQU0VfODAwOAogICAgICAtICdTWU5BUFNFX1NFUlZFUl9OQU1FPSR7U1lOQVBTRV9TRVJWRVJfTkFNRTo/fScKICAgICAgLSAnU1lOQVBTRV9SRVBPUlRfU1RBVFM9JHtTWU5BUFNFX1JFUE9SVF9TVEFUUzotbm99JwogICAgICAtICdFTkFCTEVfUkVHSVNUUkFUSU9OPSR7RU5BQkxFX1JFR0lTVFJBVElPTjotZmFsc2V9JwogICAgICAtICdTRVJWSUNFX1VTRVJfQURNSU49JHtTRVJWSUNFX1VTRVJfQURNSU59JwogICAgICAtICdTRVJWSUNFX1BBU1NXT1JEX0FETUlOPSR7U0VSVklDRV9QQVNTV09SRF9BRE1JTn0nCiAgICAgIC0gJ1NFUlZJQ0VfVVNFUl9QT1NUR1JFU1FMPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTUUx9JwogICAgICAtICdTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTUUw9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTUUx9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1zeW5hcHNlLWRifScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3N5bmFwc2UtZGF0YTovZGF0YScKICAgIGVudHJ5cG9pbnQ6CiAgICAgIC0gL2Jpbi9iYXNoCiAgICAgIC0gJy1jJwogICAgICAtICIhIHRlc3QgLWYgL2RhdGEvaG9tZXNlcnZlci55YW1sICYmIC9zdGFydC5weSBnZW5lcmF0ZVxuXG4jIEV4dHJhY3Qgc2VjcmV0cyBmcm9tIGdlbmVyYXRlZCBjb25maWdcbmdyZXAgXCJyZWdpc3RyYXRpb25fc2hhcmVkX3NlY3JldFwiIC9kYXRhL2hvbWVzZXJ2ZXIueWFtbCBcXFxufCBhd2sgJ3twcmludCAkMn0nID4gLi9yZWdpc3RyYXRpb25fc2hhcmVkX3NlY3JldFxuXG5ncmVwIFwibWFjYXJvb25fc2VjcmV0X2tleVwiIC9kYXRhL2hvbWVzZXJ2ZXIueWFtbCBcXFxufCBhd2sgJ3twcmludCAkMn0nID4gLi9tYWNhcm9vbl9zZWNyZXRfa2V5XG5cbmdyZXAgXCJmb3JtX3NlY3JldFwiIC9kYXRhL2hvbWVzZXJ2ZXIueWFtbCBcXFxufCBhd2sgJ3twcmludCAkMn0nID4gLi9mb3JtX3NlY3JldFxuXG4jIENyZWF0ZSBob21lc2VydmVyLnlhbWwgd2l0aCBQb3N0Z3JlU1FMXG5jYXQgPDxFT0YgPiAvZGF0YS9ob21lc2VydmVyLnlhbWxcbnNlcnZlcl9uYW1lOiBcIiR7U1lOQVBTRV9TRVJWRVJfTkFNRX1cIlxucGlkX2ZpbGU6IC9kYXRhL2hvbWVzZXJ2ZXIucGlkXG5wdWJsaWNfYmFzZXVybDogXCIke1NFUlZJQ0VfRlFETl9TWU5BUFNFfS9cIlxuXG5saXN0ZW5lcnM6XG4gIC0gcG9ydDogODAwOFxuICAgIHRsczogZmFsc2VcbiAgICB0eXBlOiBodHRwXG4gICAgeF9mb3J3YXJkZWQ6IHRydWVcbiAgICBiaW5kX2FkZHJlc3NlczogWycwLjAuMC4wJ11cbiAgICByZXNvdXJjZXM6XG4gICAgICAtIG5hbWVzOiBbY2xpZW50LCBmZWRlcmF0aW9uXVxuICAgICAgICBjb21wcmVzczogZmFsc2VcblxuZGF0YWJhc2U6XG4gIG5hbWU6IHBzeWNvcGcyXG4gIGFyZ3M6XG4gICAgdXNlcjogJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVNRTH1cbiAgICBwYXNzd29yZDogJHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTUUx9XG4gICAgZGF0YWJhc2U6ICR7UE9TVEdSRVNfREI6LXN5bmFwc2UtZGJ9XG4gICAgaG9zdDogcG9zdGdyZXNcbiAgICBwb3J0OiA1NDMyXG4gICAgY3BfbWluOiA1XG4gICAgY3BfbWF4OiAxMFxuXG5sb2dfY29uZmlnOiBcIi9kYXRhLyR7U1lOQVBTRV9TRVJWRVJfTkFNRX0ubG9nLmNvbmZpZ1wiXG5tZWRpYV9zdG9yZV9wYXRoOiAvZGF0YS9tZWRpYV9zdG9yZVxucmVwb3J0X3N0YXRzOiAke1NZTkFQU0VfUkVQT1JUX1NUQVRTfVxuXG5yZWdpc3RyYXRpb25fc2hhcmVkX3NlY3JldDogJCg8Li9yZWdpc3RyYXRpb25fc2hhcmVkX3NlY3JldClcbm1hY2Fyb29uX3NlY3JldF9rZXk6ICQoPC4vbWFjYXJvb25fc2VjcmV0X2tleSlcbmZvcm1fc2VjcmV0OiAkKDwuL2Zvcm1fc2VjcmV0KVxuc2lnbmluZ19rZXlfcGF0aDogXCIvZGF0YS8ke1NZTkFQU0VfU0VSVkVSX05BTUV9LnNpZ25pbmcua2V5XCJcblxudHJ1c3RlZF9rZXlfc2VydmVyczpcbiAgLSBzZXJ2ZXJfbmFtZTogXCJtYXRyaXgub3JnXCJcbkVPRlxuXG5bIFwiJHtFTkFCTEVfUkVHSVNUUkFUSU9OfVwiID0gXCJ0cnVlXCIgXSAmJiAhIGdyZXAgXCIjcmVnaXN0cmF0aW9uXCIgL2RhdGEvaG9tZXNlcnZlci55YW1sICY+L2Rldi9udWxsIFxcXG4mJiBlY2hvID4+IC9kYXRhL2hvbWVzZXJ2ZXIueWFtbCBcXFxuJiYgY2F0IDw8RU9GID4+IC9kYXRhL2hvbWVzZXJ2ZXIueWFtbFxuZW5hYmxlX3JlZ2lzdHJhdGlvbjogdHJ1ZVxuRU9GXG5cbiMgUmVnaXN0ZXIgYWRtaW4gdXNlciBpZiBwcm92aWRlZFxucmVnaXN0ZXJfYWRtaW4oKXtcbiAgd2hpbGUgISBjdXJsIC1zZiBodHRwOi8vbG9jYWxob3N0OjgwMDgvaGVhbHRoID4gL2Rldi9udWxsOyBkb1xuICAgIHNsZWVwIDJcbiAgZG9uZVxuICByZWdpc3Rlcl9uZXdfbWF0cml4X3VzZXIgXFxcbiAgICAtYSBcXFxuICAgIC11ICR7U0VSVklDRV9VU0VSX0FETUlOfSBcXFxuICAgIC1wICR7U0VSVklDRV9QQVNTV09SRF9BRE1JTn0gXFxcbiAgICAtYyAvZGF0YS9ob21lc2VydmVyLnlhbWwgXFxcbiAgICBodHRwOi8vbG9jYWxob3N0OjgwMDggJj4vZGV2L251bGxcbn1cblsgLW4gXCIke1NFUlZJQ0VfVVNFUl9BRE1JTn1cIiBdICYmIHJlZ2lzdGVyX2FkbWluICZcblxuL3N0YXJ0LnB5XG4iCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly9sb2NhbGhvc3Q6ODAwOC9oZWFsdGgnCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTAKICAgICAgc3RhcnRfcGVyaW9kOiAxMHMKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTUUx9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNRTH0nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LXN5bmFwc2UtZGJ9JwogICAgICAtICdQT1NUR1JFU19JTklUREJfQVJHUz0tLWVuY29kaW5nPVVURjggLS1sYy1jb2xsYXRlPUMgLS1sYy1jdHlwZT1DJwogICAgdm9sdW1lczoKICAgICAgLSAncG9zdGdyZXMtZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLVUgJCR7UE9TVEdSRVNfVVNFUn0gLWQgJCR7UE9TVEdSRVNfREI6LXN5bmFwc2UtZGJ9JwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTAK", "tags": [ "chat", "slack", "discord", "voip", "video", - "call" + "call", + "matrix", + "synapse", + "postgresql" + ], + "category": "messaging", + "logo": "svgs/matrix.svg", + "minversion": "0.0.0", + "port": "8008" + }, + "matrix-synapse-with-sqlite": { + "documentation": "https://element-hq.github.io/synapse/latest/welcome_and_overview.html?utm_source=coolify.io", + "slogan": "Chat securely with your family, friends, community, or build great apps with Matrix!", + "compose": "c2VydmljZXM6CiAgc3luYXBzZToKICAgIGltYWdlOiAnbWF0cml4ZG90b3JnL3N5bmFwc2U6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX1NZTkFQU0VfODAwOAogICAgICAtICdTWU5BUFNFX1NFUlZFUl9OQU1FPSR7U1lOQVBTRV9TRVJWRVJfTkFNRTo/fScKICAgICAgLSAnU1lOQVBTRV9SRVBPUlRfU1RBVFM9JHtTWU5BUFNFX1JFUE9SVF9TVEFUUzotbm99JwogICAgICAtICdFTkFCTEVfUkVHSVNUUkFUSU9OPSR7RU5BQkxFX1JFR0lTVFJBVElPTjotZmFsc2V9JwogICAgICAtICdTRVJWSUNFX1VTRVJfQURNSU49JHtTRVJWSUNFX1VTRVJfQURNSU59JwogICAgICAtICdTRVJWSUNFX1BBU1NXT1JEX0FETUlOPSR7U0VSVklDRV9QQVNTV09SRF9BRE1JTn0nCiAgICB2b2x1bWVzOgogICAgICAtICdzeW5hcHNlLWRhdGE6L2RhdGEnCiAgICBlbnRyeXBvaW50OiAvYmluL2Jhc2gKICAgIGNvbW1hbmQ6CiAgICAgIC0gJy1jJwogICAgICAtICIjIEdlbmVyYXRlIGNvbmZpZyBvbiBmaXJzdCBydW5cbmlmIFsgISAtZiAvZGF0YS9ob21lc2VydmVyLnlhbWwgXTsgdGhlblxuICAjIEdlbmVyYXRlIGRlZmF1bHQgY29uZmlnIHVzaW5nIFNZTkFQU0VfU0VSVkVSX05BTUUgKHBlcm1hbmVudCwgdXNlZCBpbiB1c2VyIElEcylcbiAgL3N0YXJ0LnB5IGdlbmVyYXRlXG5cbiAgIyBTZXQgcHVibGljX2Jhc2V1cmwgdG8gYWN0dWFsIGRlcGxveW1lbnQgVVJMIChtYXkgZGlmZmVyIGZyb20gc2VydmVyX25hbWUpXG4gICMgVGhpcyBhbGxvd3MgaG9zdGluZyBhdCBtYXRyaXguZXhhbXBsZS5vcmcgd2hpbGUgc2VydmVyX25hbWUgaXMgZXhhbXBsZS5vcmdcbiAgaWYgISBncmVwIC1xIFwicHVibGljX2Jhc2V1cmxcIiAvZGF0YS9ob21lc2VydmVyLnlhbWw7IHRoZW5cbiAgICBzZWQgLWkgXCIvXnNlcnZlcl9uYW1lOi9hIHB1YmxpY19iYXNldXJsOiAke1NFUlZJQ0VfRlFETl9TWU5BUFNFfS9cIiAvZGF0YS9ob21lc2VydmVyLnlhbWxcbiAgZmlcblxuICAjIENvbmZpZ3VyZSBsaXN0ZW5lciBmb3IgcmV2ZXJzZSBwcm94eVxuICBzZWQgLWkgJ3MvYmluZF9hZGRyZXNzZXM6IFxcWy4qXFxdL2JpbmRfYWRkcmVzc2VzOiBbXCIwLjAuMC4wXCJdLycgL2RhdGEvaG9tZXNlcnZlci55YW1sXG4gIHNlZCAtaSAnL3hfZm9yd2FyZGVkOi9kJyAvZGF0YS9ob21lc2VydmVyLnlhbWxcbiAgc2VkIC1pICcvdHlwZTogaHR0cC9hIFxcICAgIHhfZm9yd2FyZGVkOiB0cnVlJyAvZGF0YS9ob21lc2VydmVyLnlhbWxcblxuICAjIEVuYWJsZSByZWdpc3RyYXRpb24gaWYgcmVxdWVzdGVkXG4gIGlmIFsgXCIke0VOQUJMRV9SRUdJU1RSQVRJT059XCIgPSBcInRydWVcIiBdICYmICEgZ3JlcCAtcSBcImVuYWJsZV9yZWdpc3RyYXRpb25cIiAvZGF0YS9ob21lc2VydmVyLnlhbWw7IHRoZW5cbiAgICBlY2hvIFwiZW5hYmxlX3JlZ2lzdHJhdGlvbjogdHJ1ZVwiID4+IC9kYXRhL2hvbWVzZXJ2ZXIueWFtbFxuICBmaVxuZmlcblxuIyBSZWdpc3RlciBhZG1pbiB1c2VyIGlmIGNyZWRlbnRpYWxzIHByb3ZpZGVkXG5pZiBbIC1uIFwiJHtTRVJWSUNFX1VTRVJfQURNSU59XCIgXSAmJiBbIC1uIFwiJHtTRVJWSUNFX1BBU1NXT1JEX0FETUlOfVwiIF07IHRoZW5cbiAgKFxuICAgIHdoaWxlICEgY3VybCAtc2YgaHR0cDovL2xvY2FsaG9zdDo4MDA4L2hlYWx0aCA+IC9kZXYvbnVsbCAyPiYxOyBkb1xuICAgICAgc2xlZXAgMlxuICAgIGRvbmVcbiAgICByZWdpc3Rlcl9uZXdfbWF0cml4X3VzZXIgLWEgXFxcbiAgICAgIC11IFwiJHtTRVJWSUNFX1VTRVJfQURNSU59XCIgXFxcbiAgICAgIC1wIFwiJHtTRVJWSUNFX1BBU1NXT1JEX0FETUlOfVwiIFxcXG4gICAgICAtYyAvZGF0YS9ob21lc2VydmVyLnlhbWwgXFxcbiAgICAgIGh0dHA6Ly9sb2NhbGhvc3Q6ODAwOCAyPi9kZXYvbnVsbCB8fCB0cnVlXG4gICkgJlxuZmlcblxuZXhlYyAvc3RhcnQucHlcbiIKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo4MDA4L2hlYWx0aCcKICAgICAgaW50ZXJ2YWw6IDMwcwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogNQogICAgICBzdGFydF9wZXJpb2Q6IDIwcwo=", + "tags": [ + "chat", + "slack", + "discord", + "voip", + "video", + "call", + "matrix", + "synapse", + "sqlite" ], "category": "messaging", "logo": "svgs/matrix.svg", @@ -3844,6 +3922,19 @@ "minversion": "0.0.0", "port": "8080" }, + "redmine": { + "documentation": "https://www.redmine.org/?utm_source=coolify.io", + "slogan": "Redmine is a flexible project management web application. Written using the Ruby on Rails framework, it is cross-platform and cross-database.", + "compose": "c2VydmljZXM6CiAgcmVkbWluZToKICAgIGltYWdlOiAncmVkbWluZTo2LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9SRURNSU5FXzMwMDAKICAgICAgLSAnU0VDUkVUX0tFWV9CQVNFPSR7U0VSVklDRV9QQVNTV09SRF82NF9SRURNSU5FfScKICAgICAgLSBSRURNSU5FX0RCX1BPU1RHUkVTPXBvc3RncmVzcWwKICAgICAgLSBSRURNSU5FX0RCX1BPUlQ9NTQzMgogICAgICAtICdSRURNSU5FX0RCX1VTRVJOQU1FPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUkVETUlORV9EQl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfNjRfUE9TVEdSRVN9JwogICAgICAtICdSRURNSU5FX0RCX0RBVEFCQVNFPSR7UE9TVEdSRVNfREFUQUJBU0U6LXJlZG1pbmUtZGJ9JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICd3Z2V0IC1xTy0gaHR0cDovLzEyNy4wLjAuMTozMDAwLycKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDUKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3JlZG1pbmUtY29uZmlnOi91c3Ivc3JjL3JlZG1pbmUvY29uZmlnJwogICAgICAtICdyZWRtaW5lLWZpbGVzOi91c3Ivc3JjL3JlZG1pbmUvZmlsZXMnCiAgICAgIC0gJ3JlZG1pbmUtdGhlbWVzOi91c3Ivc3JjL3JlZG1pbmUvdGhlbWVzJwogICAgICAtICdyZWRtaW5lLXBsdWdpbnM6L3Vzci9zcmMvcmVkbWluZS9wbHVnaW5zJwogICAgZGVwZW5kc19vbjoKICAgICAgcG9zdGdyZXNxbDoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogIHBvc3RncmVzcWw6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE3LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQVRBQkFTRTotcmVkbWluZS1kYn0nCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0Z3Jlc3FsLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDUK", + "tags": [ + "redmine", + "project management" + ], + "category": null, + "logo": "svgs/redmine.svg", + "minversion": "0.0.0", + "port": "3000" + }, "rivet-engine": { "documentation": "https://www.rivet.dev/docs?utm_source=coolify.io", "slogan": "Build and scale stateful workloads with long-lived processes", @@ -4195,7 +4286,7 @@ "supabase": { "documentation": "https://supabase.io?utm_source=coolify.io", "slogan": "The open source Firebase alternative.", - "compose": "c2VydmljZXM6CiAgc3VwYWJhc2Uta29uZzoKICAgIGltYWdlOiAna29uZzoyLjguMScKICAgIGVudHJ5cG9pbnQ6ICdiYXNoIC1jICcnZXZhbCAiZWNobyBcIiQkKGNhdCB+L3RlbXAueW1sKVwiIiA+IH4va29uZy55bWwgJiYgL2RvY2tlci1lbnRyeXBvaW50LnNoIGtvbmcgZG9ja2VyLXN0YXJ0JycnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9TVVBBQkFTRUtPTkdfODAwMAogICAgICAtICdLT05HX1BPUlRfTUFQUz00NDM6ODAwMCcKICAgICAgLSAnSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSBLT05HX0RBVEFCQVNFPW9mZgogICAgICAtIEtPTkdfREVDTEFSQVRJVkVfQ09ORklHPS9ob21lL2tvbmcva29uZy55bWwKICAgICAgLSAnS09OR19ETlNfT1JERVI9TEFTVCxBLENOQU1FJwogICAgICAtICdLT05HX1BMVUdJTlM9cmVxdWVzdC10cmFuc2Zvcm1lcixjb3JzLGtleS1hdXRoLGFjbCxiYXNpYy1hdXRoJwogICAgICAtIEtPTkdfTkdJTlhfUFJPWFlfUFJPWFlfQlVGRkVSX1NJWkU9MTYwawogICAgICAtICdLT05HX05HSU5YX1BST1hZX1BST1hZX0JVRkZFUlM9NjQgMTYwaycKICAgICAgLSAnU1VQQUJBU0VfQU5PTl9LRVk9JHtTRVJWSUNFX1NVUEFCQVNFQU5PTl9LRVl9JwogICAgICAtICdTVVBBQkFTRV9TRVJWSUNFX0tFWT0ke1NFUlZJQ0VfU1VQQUJBU0VTRVJWSUNFX0tFWX0nCiAgICAgIC0gJ0RBU0hCT0FSRF9VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9BRE1JTn0nCiAgICAgIC0gJ0RBU0hCT0FSRF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfQURNSU59JwogICAgdm9sdW1lczoKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9hcGkva29uZy55bWwKICAgICAgICB0YXJnZXQ6IC9ob21lL2tvbmcvdGVtcC55bWwKICAgICAgICBjb250ZW50OiAiX2Zvcm1hdF92ZXJzaW9uOiAnMi4xJ1xuX3RyYW5zZm9ybTogdHJ1ZVxuXG4jIyNcbiMjIyBDb25zdW1lcnMgLyBVc2Vyc1xuIyMjXG5jb25zdW1lcnM6XG4gIC0gdXNlcm5hbWU6IERBU0hCT0FSRFxuICAtIHVzZXJuYW1lOiBhbm9uXG4gICAga2V5YXV0aF9jcmVkZW50aWFsczpcbiAgICAgIC0ga2V5OiAkU1VQQUJBU0VfQU5PTl9LRVlcbiAgLSB1c2VybmFtZTogc2VydmljZV9yb2xlXG4gICAga2V5YXV0aF9jcmVkZW50aWFsczpcbiAgICAgIC0ga2V5OiAkU1VQQUJBU0VfU0VSVklDRV9LRVlcblxuIyMjXG4jIyMgQWNjZXNzIENvbnRyb2wgTGlzdFxuIyMjXG5hY2xzOlxuICAtIGNvbnN1bWVyOiBhbm9uXG4gICAgZ3JvdXA6IGFub25cbiAgLSBjb25zdW1lcjogc2VydmljZV9yb2xlXG4gICAgZ3JvdXA6IGFkbWluXG5cbiMjI1xuIyMjIERhc2hib2FyZCBjcmVkZW50aWFsc1xuIyMjXG5iYXNpY2F1dGhfY3JlZGVudGlhbHM6XG4tIGNvbnN1bWVyOiBEQVNIQk9BUkRcbiAgdXNlcm5hbWU6ICREQVNIQk9BUkRfVVNFUk5BTUVcbiAgcGFzc3dvcmQ6ICREQVNIQk9BUkRfUEFTU1dPUkRcblxuXG4jIyNcbiMjIyBBUEkgUm91dGVzXG4jIyNcbnNlcnZpY2VzOlxuXG4gICMjIE9wZW4gQXV0aCByb3V0ZXNcbiAgLSBuYW1lOiBhdXRoLXYxLW9wZW5cbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1hdXRoOjk5OTkvdmVyaWZ5XG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBhdXRoLXYxLW9wZW5cbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9hdXRoL3YxL3ZlcmlmeVxuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgLSBuYW1lOiBhdXRoLXYxLW9wZW4tY2FsbGJhY2tcbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1hdXRoOjk5OTkvY2FsbGJhY2tcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGF1dGgtdjEtb3Blbi1jYWxsYmFja1xuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2F1dGgvdjEvY2FsbGJhY2tcbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gIC0gbmFtZTogYXV0aC12MS1vcGVuLWF1dGhvcml6ZVxuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS9hdXRob3JpemVcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGF1dGgtdjEtb3Blbi1hdXRob3JpemVcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9hdXRoL3YxL2F1dGhvcml6ZVxuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcblxuICAjIyBTZWN1cmUgQXV0aCByb3V0ZXNcbiAgLSBuYW1lOiBhdXRoLXYxXG4gICAgX2NvbW1lbnQ6ICdHb1RydWU6IC9hdXRoL3YxLyogLT4gaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGF1dGgtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvYXV0aC92MS9cbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gICAgICAtIG5hbWU6IGtleS1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiBmYWxzZVxuICAgICAgLSBuYW1lOiBhY2xcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfZ3JvdXBzX2hlYWRlcjogdHJ1ZVxuICAgICAgICAgIGFsbG93OlxuICAgICAgICAgICAgLSBhZG1pblxuICAgICAgICAgICAgLSBhbm9uXG5cbiAgIyMgU2VjdXJlIFJFU1Qgcm91dGVzXG4gIC0gbmFtZTogcmVzdC12MVxuICAgIF9jb21tZW50OiAnUG9zdGdSRVNUOiAvcmVzdC92MS8qIC0+IGh0dHA6Ly9zdXBhYmFzZS1yZXN0OjMwMDAvKidcbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1yZXN0OjMwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiByZXN0LXYxLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL3Jlc3QvdjEvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAgICAgLSBuYW1lOiBrZXktYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogdHJ1ZVxuICAgICAgLSBuYW1lOiBhY2xcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfZ3JvdXBzX2hlYWRlcjogdHJ1ZVxuICAgICAgICAgIGFsbG93OlxuICAgICAgICAgICAgLSBhZG1pblxuICAgICAgICAgICAgLSBhbm9uXG5cbiAgIyMgU2VjdXJlIEdyYXBoUUwgcm91dGVzXG4gIC0gbmFtZTogZ3JhcGhxbC12MVxuICAgIF9jb21tZW50OiAnUG9zdGdSRVNUOiAvZ3JhcGhxbC92MS8qIC0+IGh0dHA6Ly9zdXBhYmFzZS1yZXN0OjMwMDAvcnBjL2dyYXBocWwnXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtcmVzdDozMDAwL3JwYy9ncmFwaHFsXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBncmFwaHFsLXYxLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2dyYXBocWwvdjFcbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gICAgICAtIG5hbWU6IGtleS1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiB0cnVlXG4gICAgICAtIG5hbWU6IHJlcXVlc3QtdHJhbnNmb3JtZXJcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGFkZDpcbiAgICAgICAgICAgIGhlYWRlcnM6XG4gICAgICAgICAgICAgIC0gQ29udGVudC1Qcm9maWxlOmdyYXBocWxfcHVibGljXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG4gICAgICAgICAgICAtIGFub25cblxuICAjIyBTZWN1cmUgUmVhbHRpbWUgcm91dGVzXG4gIC0gbmFtZTogcmVhbHRpbWUtdjEtd3NcbiAgICBfY29tbWVudDogJ1JlYWx0aW1lOiAvcmVhbHRpbWUvdjEvKiAtPiB3czovL3JlYWx0aW1lOjQwMDAvc29ja2V0LyonXG4gICAgdXJsOiBodHRwOi8vcmVhbHRpbWUtZGV2OjQwMDAvc29ja2V0XG4gICAgcHJvdG9jb2w6IHdzXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiByZWFsdGltZS12MS13c1xuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL3JlYWx0aW1lL3YxL1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgICAgIC0gbmFtZToga2V5LWF1dGhcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfY3JlZGVudGlhbHM6IGZhbHNlXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG4gICAgICAgICAgICAtIGFub25cbiAgLSBuYW1lOiByZWFsdGltZS12MS1yZXN0XG4gICAgX2NvbW1lbnQ6ICdSZWFsdGltZTogL3JlYWx0aW1lL3YxLyogLT4gd3M6Ly9yZWFsdGltZTo0MDAwL3NvY2tldC8qJ1xuICAgIHVybDogaHR0cDovL3JlYWx0aW1lLWRldjo0MDAwL2FwaVxuICAgIHByb3RvY29sOiBodHRwXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiByZWFsdGltZS12MS1yZXN0XG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvcmVhbHRpbWUvdjEvYXBpXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAgICAgLSBuYW1lOiBrZXktYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogZmFsc2VcbiAgICAgIC0gbmFtZTogYWNsXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2dyb3Vwc19oZWFkZXI6IHRydWVcbiAgICAgICAgICBhbGxvdzpcbiAgICAgICAgICAgIC0gYWRtaW5cbiAgICAgICAgICAgIC0gYW5vblxuXG4gICMjIFN0b3JhZ2Ugcm91dGVzOiB0aGUgc3RvcmFnZSBzZXJ2ZXIgbWFuYWdlcyBpdHMgb3duIGF1dGhcbiAgLSBuYW1lOiBzdG9yYWdlLXYxXG4gICAgX2NvbW1lbnQ6ICdTdG9yYWdlOiAvc3RvcmFnZS92MS8qIC0+IGh0dHA6Ly9zdXBhYmFzZS1zdG9yYWdlOjUwMDAvKidcbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1zdG9yYWdlOjUwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBzdG9yYWdlLXYxLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL3N0b3JhZ2UvdjEvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuXG4gICMjIEVkZ2UgRnVuY3Rpb25zIHJvdXRlc1xuICAtIG5hbWU6IGZ1bmN0aW9ucy12MVxuICAgIF9jb21tZW50OiAnRWRnZSBGdW5jdGlvbnM6IC9mdW5jdGlvbnMvdjEvKiAtPiBodHRwOi8vc3VwYWJhc2UtZWRnZS1mdW5jdGlvbnM6OTAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWVkZ2UtZnVuY3Rpb25zOjkwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBmdW5jdGlvbnMtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvZnVuY3Rpb25zL3YxL1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcblxuICAjIyBBbmFseXRpY3Mgcm91dGVzXG4gIC0gbmFtZTogYW5hbHl0aWNzLXYxXG4gICAgX2NvbW1lbnQ6ICdBbmFseXRpY3M6IC9hbmFseXRpY3MvdjEvKiAtPiBodHRwOi8vbG9nZmxhcmU6NDAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogYW5hbHl0aWNzLXYxLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2FuYWx5dGljcy92MS9cblxuICAjIyBTZWN1cmUgRGF0YWJhc2Ugcm91dGVzXG4gIC0gbmFtZTogbWV0YVxuICAgIF9jb21tZW50OiAncGctbWV0YTogL3BnLyogLT4gaHR0cDovL3N1cGFiYXNlLW1ldGE6ODA4MC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLW1ldGE6ODA4MC9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IG1ldGEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvcGcvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZToga2V5LWF1dGhcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfY3JlZGVudGlhbHM6IGZhbHNlXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG5cbiAgIyMgUHJvdGVjdGVkIERhc2hib2FyZCAtIGNhdGNoIGFsbCByZW1haW5pbmcgcm91dGVzXG4gIC0gbmFtZTogZGFzaGJvYXJkXG4gICAgX2NvbW1lbnQ6ICdTdHVkaW86IC8qIC0+IGh0dHA6Ly9zdHVkaW86MzAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLXN0dWRpbzozMDAwL1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogZGFzaGJvYXJkLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgICAgIC0gbmFtZTogYmFzaWMtYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogdHJ1ZVxuIgogIHN1cGFiYXNlLXN0dWRpbzoKICAgIGltYWdlOiAnc3VwYWJhc2Uvc3R1ZGlvOjIwMjUuMTIuMTctc2hhLTQzZjRmN2YnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gbm9kZQogICAgICAgIC0gJy1lJwogICAgICAgIC0gImZldGNoKCdodHRwOi8vMTI3LjAuMC4xOjMwMDAvYXBpL3BsYXRmb3JtL3Byb2ZpbGUnKS50aGVuKChyKSA9PiB7aWYgKHIuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihyLnN0YXR1cyl9KSIKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWFuYWx5dGljczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gSE9TVE5BTUU9MC4wLjAuMAogICAgICAtICdTVFVESU9fUEdfTUVUQV9VUkw9aHR0cDovL3N1cGFiYXNlLW1ldGE6ODA4MCcKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnREVGQVVMVF9PUkdBTklaQVRJT05fTkFNRT0ke1NUVURJT19ERUZBVUxUX09SR0FOSVpBVElPTjotRGVmYXVsdCBPcmdhbml6YXRpb259JwogICAgICAtICdERUZBVUxUX1BST0pFQ1RfTkFNRT0ke1NUVURJT19ERUZBVUxUX1BST0pFQ1Q6LURlZmF1bHQgUHJvamVjdH0nCiAgICAgIC0gJ1NVUEFCQVNFX1VSTD1odHRwOi8vc3VwYWJhc2Uta29uZzo4MDAwJwogICAgICAtICdTVVBBQkFTRV9QVUJMSUNfVVJMPSR7U0VSVklDRV9GUUROX1NVUEFCQVNFS09OR30nCiAgICAgIC0gJ1NVUEFCQVNFX0FOT05fS0VZPSR7U0VSVklDRV9TVVBBQkFTRUFOT05fS0VZfScKICAgICAgLSAnU1VQQUJBU0VfU0VSVklDRV9LRVk9JHtTRVJWSUNFX1NVUEFCQVNFU0VSVklDRV9LRVl9JwogICAgICAtICdBVVRIX0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gJ0xPR0ZMQVJFX0FQSV9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEX0xPR0ZMQVJFfScKICAgICAgLSAnTE9HRkxBUkVfVVJMPWh0dHA6Ly9zdXBhYmFzZS1hbmFseXRpY3M6NDAwMCcKICAgICAgLSAnU1VQQUJBU0VfUFVCTElDX0FQST0ke1NFUlZJQ0VfRlFETl9TVVBBQkFTRUtPTkd9JwogICAgICAtIE5FWFRfUFVCTElDX0VOQUJMRV9MT0dTPXRydWUKICAgICAgLSBORVhUX0FOQUxZVElDU19CQUNLRU5EX1BST1ZJREVSPXBvc3RncmVzCiAgICAgIC0gJ09QRU5BSV9BUElfS0VZPSR7T1BFTkFJX0FQSV9LRVl9JwogIHN1cGFiYXNlLWRiOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9wb3N0Z3JlczoxNS44LjEuMDQ4JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6ICdwZ19pc3JlYWR5IC1VIHBvc3RncmVzIC1oIDEyNy4wLjAuMScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS12ZWN0b3I6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGNvbW1hbmQ6CiAgICAgIC0gcG9zdGdyZXMKICAgICAgLSAnLWMnCiAgICAgIC0gY29uZmlnX2ZpbGU9L2V0Yy9wb3N0Z3Jlc3FsL3Bvc3RncmVzcWwuY29uZgogICAgICAtICctYycKICAgICAgLSBsb2dfbWluX21lc3NhZ2VzPWZhdGFsCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBQT1NUR1JFU19IT1NUPS92YXIvcnVuL3Bvc3RncmVzcWwKICAgICAgLSAnUEdQT1JUPSR7UE9TVEdSRVNfUE9SVDotNTQzMn0nCiAgICAgIC0gJ1BPU1RHUkVTX1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSAnUEdQQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQR0RBVEFCQVNFPSR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtICdKV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdKV1RfRVhQPSR7SldUX0VYUElSWTotMzYwMH0nCiAgICB2b2x1bWVzOgogICAgICAtICdzdXBhYmFzZS1kYi1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi9yZWFsdGltZS5zcWwKICAgICAgICB0YXJnZXQ6IC9kb2NrZXItZW50cnlwb2ludC1pbml0ZGIuZC9taWdyYXRpb25zLzk5LXJlYWx0aW1lLnNxbAogICAgICAgIGNvbnRlbnQ6ICJcXHNldCBwZ3VzZXIgYGVjaG8gXCJzdXBhYmFzZV9hZG1pblwiYFxuXG5jcmVhdGUgc2NoZW1hIGlmIG5vdCBleGlzdHMgX3JlYWx0aW1lO1xuYWx0ZXIgc2NoZW1hIF9yZWFsdGltZSBvd25lciB0byA6cGd1c2VyO1xuIgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2RiL19zdXBhYmFzZS5zcWwKICAgICAgICB0YXJnZXQ6IC9kb2NrZXItZW50cnlwb2ludC1pbml0ZGIuZC9taWdyYXRpb25zLzk3LV9zdXBhYmFzZS5zcWwKICAgICAgICBjb250ZW50OiAiXFxzZXQgcGd1c2VyIGBlY2hvIFwiJFBPU1RHUkVTX1VTRVJcImBcblxuQ1JFQVRFIERBVEFCQVNFIF9zdXBhYmFzZSBXSVRIIE9XTkVSIDpwZ3VzZXI7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvcG9vbGVyLnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL21pZ3JhdGlvbnMvOTktcG9vbGVyLnNxbAogICAgICAgIGNvbnRlbnQ6ICJcXHNldCBwZ3VzZXIgYGVjaG8gXCJzdXBhYmFzZV9hZG1pblwiYFxuXFxjIF9zdXBhYmFzZVxuY3JlYXRlIHNjaGVtYSBpZiBub3QgZXhpc3RzIF9zdXBhdmlzb3I7XG5hbHRlciBzY2hlbWEgX3N1cGF2aXNvciBvd25lciB0byA6cGd1c2VyO1xuXFxjIHBvc3RncmVzXG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvd2ViaG9va3Muc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvaW5pdC1zY3JpcHRzLzk4LXdlYmhvb2tzLnNxbAogICAgICAgIGNvbnRlbnQ6ICJCRUdJTjtcbi0tIENyZWF0ZSBwZ19uZXQgZXh0ZW5zaW9uXG5DUkVBVEUgRVhURU5TSU9OIElGIE5PVCBFWElTVFMgcGdfbmV0IFNDSEVNQSBleHRlbnNpb25zO1xuLS0gQ3JlYXRlIHN1cGFiYXNlX2Z1bmN0aW9ucyBzY2hlbWFcbkNSRUFURSBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIEFVVEhPUklaQVRJT04gc3VwYWJhc2VfYWRtaW47XG5HUkFOVCBVU0FHRSBPTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5BTFRFUiBERUZBVUxUIFBSSVZJTEVHRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBHUkFOVCBBTEwgT04gVEFCTEVTIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5BTFRFUiBERUZBVUxUIFBSSVZJTEVHRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBHUkFOVCBBTEwgT04gRlVOQ1RJT05TIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5BTFRFUiBERUZBVUxUIFBSSVZJTEVHRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBHUkFOVCBBTEwgT04gU0VRVUVOQ0VTIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4tLSBzdXBhYmFzZV9mdW5jdGlvbnMubWlncmF0aW9ucyBkZWZpbml0aW9uXG5DUkVBVEUgVEFCTEUgc3VwYWJhc2VfZnVuY3Rpb25zLm1pZ3JhdGlvbnMgKFxuICB2ZXJzaW9uIHRleHQgUFJJTUFSWSBLRVksXG4gIGluc2VydGVkX2F0IHRpbWVzdGFtcHR6IE5PVCBOVUxMIERFRkFVTFQgTk9XKClcbik7XG4tLSBJbml0aWFsIHN1cGFiYXNlX2Z1bmN0aW9ucyBtaWdyYXRpb25cbklOU0VSVCBJTlRPIHN1cGFiYXNlX2Z1bmN0aW9ucy5taWdyYXRpb25zICh2ZXJzaW9uKSBWQUxVRVMgKCdpbml0aWFsJyk7XG4tLSBzdXBhYmFzZV9mdW5jdGlvbnMuaG9va3MgZGVmaW5pdGlvblxuQ1JFQVRFIFRBQkxFIHN1cGFiYXNlX2Z1bmN0aW9ucy5ob29rcyAoXG4gIGlkIGJpZ3NlcmlhbCBQUklNQVJZIEtFWSxcbiAgaG9va190YWJsZV9pZCBpbnRlZ2VyIE5PVCBOVUxMLFxuICBob29rX25hbWUgdGV4dCBOT1QgTlVMTCxcbiAgY3JlYXRlZF9hdCB0aW1lc3RhbXB0eiBOT1QgTlVMTCBERUZBVUxUIE5PVygpLFxuICByZXF1ZXN0X2lkIGJpZ2ludFxuKTtcbkNSRUFURSBJTkRFWCBzdXBhYmFzZV9mdW5jdGlvbnNfaG9va3NfcmVxdWVzdF9pZF9pZHggT04gc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzIFVTSU5HIGJ0cmVlIChyZXF1ZXN0X2lkKTtcbkNSRUFURSBJTkRFWCBzdXBhYmFzZV9mdW5jdGlvbnNfaG9va3NfaF90YWJsZV9pZF9oX25hbWVfaWR4IE9OIHN1cGFiYXNlX2Z1bmN0aW9ucy5ob29rcyBVU0lORyBidHJlZSAoaG9va190YWJsZV9pZCwgaG9va19uYW1lKTtcbkNPTU1FTlQgT04gVEFCTEUgc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzIElTICdTdXBhYmFzZSBGdW5jdGlvbnMgSG9va3M6IEF1ZGl0IHRyYWlsIGZvciB0cmlnZ2VyZWQgaG9va3MuJztcbkNSRUFURSBGVU5DVElPTiBzdXBhYmFzZV9mdW5jdGlvbnMuaHR0cF9yZXF1ZXN0KClcbiAgUkVUVVJOUyB0cmlnZ2VyXG4gIExBTkdVQUdFIHBscGdzcWxcbiAgQVMgJGZ1bmN0aW9uJFxuICBERUNMQVJFXG4gICAgcmVxdWVzdF9pZCBiaWdpbnQ7XG4gICAgcGF5bG9hZCBqc29uYjtcbiAgICB1cmwgdGV4dCA6PSBUR19BUkdWWzBdOjp0ZXh0O1xuICAgIG1ldGhvZCB0ZXh0IDo9IFRHX0FSR1ZbMV06OnRleHQ7XG4gICAgaGVhZGVycyBqc29uYiBERUZBVUxUICd7fSc6Ompzb25iO1xuICAgIHBhcmFtcyBqc29uYiBERUZBVUxUICd7fSc6Ompzb25iO1xuICAgIHRpbWVvdXRfbXMgaW50ZWdlciBERUZBVUxUIDEwMDA7XG4gIEJFR0lOXG4gICAgSUYgdXJsIElTIE5VTEwgT1IgdXJsID0gJ251bGwnIFRIRU5cbiAgICAgIFJBSVNFIEVYQ0VQVElPTiAndXJsIGFyZ3VtZW50IGlzIG1pc3NpbmcnO1xuICAgIEVORCBJRjtcblxuICAgIElGIG1ldGhvZCBJUyBOVUxMIE9SIG1ldGhvZCA9ICdudWxsJyBUSEVOXG4gICAgICBSQUlTRSBFWENFUFRJT04gJ21ldGhvZCBhcmd1bWVudCBpcyBtaXNzaW5nJztcbiAgICBFTkQgSUY7XG5cbiAgICBJRiBUR19BUkdWWzJdIElTIE5VTEwgT1IgVEdfQVJHVlsyXSA9ICdudWxsJyBUSEVOXG4gICAgICBoZWFkZXJzID0gJ3tcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIn0nOjpqc29uYjtcbiAgICBFTFNFXG4gICAgICBoZWFkZXJzID0gVEdfQVJHVlsyXTo6anNvbmI7XG4gICAgRU5EIElGO1xuXG4gICAgSUYgVEdfQVJHVlszXSBJUyBOVUxMIE9SIFRHX0FSR1ZbM10gPSAnbnVsbCcgVEhFTlxuICAgICAgcGFyYW1zID0gJ3t9Jzo6anNvbmI7XG4gICAgRUxTRVxuICAgICAgcGFyYW1zID0gVEdfQVJHVlszXTo6anNvbmI7XG4gICAgRU5EIElGO1xuXG4gICAgSUYgVEdfQVJHVls0XSBJUyBOVUxMIE9SIFRHX0FSR1ZbNF0gPSAnbnVsbCcgVEhFTlxuICAgICAgdGltZW91dF9tcyA9IDEwMDA7XG4gICAgRUxTRVxuICAgICAgdGltZW91dF9tcyA9IFRHX0FSR1ZbNF06OmludGVnZXI7XG4gICAgRU5EIElGO1xuXG4gICAgQ0FTRVxuICAgICAgV0hFTiBtZXRob2QgPSAnR0VUJyBUSEVOXG4gICAgICAgIFNFTEVDVCBodHRwX2dldCBJTlRPIHJlcXVlc3RfaWQgRlJPTSBuZXQuaHR0cF9nZXQoXG4gICAgICAgICAgdXJsLFxuICAgICAgICAgIHBhcmFtcyxcbiAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgIHRpbWVvdXRfbXNcbiAgICAgICAgKTtcbiAgICAgIFdIRU4gbWV0aG9kID0gJ1BPU1QnIFRIRU5cbiAgICAgICAgcGF5bG9hZCA9IGpzb25iX2J1aWxkX29iamVjdChcbiAgICAgICAgICAnb2xkX3JlY29yZCcsIE9MRCxcbiAgICAgICAgICAncmVjb3JkJywgTkVXLFxuICAgICAgICAgICd0eXBlJywgVEdfT1AsXG4gICAgICAgICAgJ3RhYmxlJywgVEdfVEFCTEVfTkFNRSxcbiAgICAgICAgICAnc2NoZW1hJywgVEdfVEFCTEVfU0NIRU1BXG4gICAgICAgICk7XG5cbiAgICAgICAgU0VMRUNUIGh0dHBfcG9zdCBJTlRPIHJlcXVlc3RfaWQgRlJPTSBuZXQuaHR0cF9wb3N0KFxuICAgICAgICAgIHVybCxcbiAgICAgICAgICBwYXlsb2FkLFxuICAgICAgICAgIHBhcmFtcyxcbiAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgIHRpbWVvdXRfbXNcbiAgICAgICAgKTtcbiAgICAgIEVMU0VcbiAgICAgICAgUkFJU0UgRVhDRVBUSU9OICdtZXRob2QgYXJndW1lbnQgJSBpcyBpbnZhbGlkJywgbWV0aG9kO1xuICAgIEVORCBDQVNFO1xuXG4gICAgSU5TRVJUIElOVE8gc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzXG4gICAgICAoaG9va190YWJsZV9pZCwgaG9va19uYW1lLCByZXF1ZXN0X2lkKVxuICAgIFZBTFVFU1xuICAgICAgKFRHX1JFTElELCBUR19OQU1FLCByZXF1ZXN0X2lkKTtcblxuICAgIFJFVFVSTiBORVc7XG4gIEVORFxuJGZ1bmN0aW9uJDtcbi0tIFN1cGFiYXNlIHN1cGVyIGFkbWluXG5ET1xuJCRcbkJFR0lOXG4gIElGIE5PVCBFWElTVFMgKFxuICAgIFNFTEVDVCAxXG4gICAgRlJPTSBwZ19yb2xlc1xuICAgIFdIRVJFIHJvbG5hbWUgPSAnc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluJ1xuICApXG4gIFRIRU5cbiAgICBDUkVBVEUgVVNFUiBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4gTk9JTkhFUklUIENSRUFURVJPTEUgTE9HSU4gTk9SRVBMSUNBVElPTjtcbiAgRU5EIElGO1xuRU5EXG4kJDtcbkdSQU5UIEFMTCBQUklWSUxFR0VTIE9OIFNDSEVNQSBzdXBhYmFzZV9mdW5jdGlvbnMgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluO1xuR1JBTlQgQUxMIFBSSVZJTEVHRVMgT04gQUxMIFRBQkxFUyBJTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbjtcbkdSQU5UIEFMTCBQUklWSUxFR0VTIE9OIEFMTCBTRVFVRU5DRVMgSU4gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW47XG5BTFRFUiBVU0VSIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiBTRVQgc2VhcmNoX3BhdGggPSBcInN1cGFiYXNlX2Z1bmN0aW9uc1wiO1xuQUxURVIgdGFibGUgXCJzdXBhYmFzZV9mdW5jdGlvbnNcIi5taWdyYXRpb25zIE9XTkVSIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbjtcbkFMVEVSIHRhYmxlIFwic3VwYWJhc2VfZnVuY3Rpb25zXCIuaG9va3MgT1dORVIgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluO1xuQUxURVIgZnVuY3Rpb24gXCJzdXBhYmFzZV9mdW5jdGlvbnNcIi5odHRwX3JlcXVlc3QoKSBPV05FUiBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW47XG5HUkFOVCBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4gVE8gcG9zdGdyZXM7XG4tLSBSZW1vdmUgdW51c2VkIHN1cGFiYXNlX3BnX25ldF9hZG1pbiByb2xlXG5ET1xuJCRcbkJFR0lOXG4gIElGIEVYSVNUUyAoXG4gICAgU0VMRUNUIDFcbiAgICBGUk9NIHBnX3JvbGVzXG4gICAgV0hFUkUgcm9sbmFtZSA9ICdzdXBhYmFzZV9wZ19uZXRfYWRtaW4nXG4gIClcbiAgVEhFTlxuICAgIFJFQVNTSUdOIE9XTkVEIEJZIHN1cGFiYXNlX3BnX25ldF9hZG1pbiBUTyBzdXBhYmFzZV9hZG1pbjtcbiAgICBEUk9QIE9XTkVEIEJZIHN1cGFiYXNlX3BnX25ldF9hZG1pbjtcbiAgICBEUk9QIFJPTEUgc3VwYWJhc2VfcGdfbmV0X2FkbWluO1xuICBFTkQgSUY7XG5FTkRcbiQkO1xuLS0gcGdfbmV0IGdyYW50cyB3aGVuIGV4dGVuc2lvbiBpcyBhbHJlYWR5IGVuYWJsZWRcbkRPXG4kJFxuQkVHSU5cbiAgSUYgRVhJU1RTIChcbiAgICBTRUxFQ1QgMVxuICAgIEZST00gcGdfZXh0ZW5zaW9uXG4gICAgV0hFUkUgZXh0bmFtZSA9ICdwZ19uZXQnXG4gIClcbiAgVEhFTlxuICAgIEdSQU5UIFVTQUdFIE9OIFNDSEVNQSBuZXQgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluLCBwb3N0Z3JlcywgYW5vbiwgYXV0aGVudGljYXRlZCwgc2VydmljZV9yb2xlO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRUNVUklUWSBERUZJTkVSO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VDVVJJVFkgREVGSU5FUjtcbiAgICBBTFRFUiBmdW5jdGlvbiBuZXQuaHR0cF9nZXQodXJsIHRleHQsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIEZST00gUFVCTElDO1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBGUk9NIFBVQkxJQztcbiAgICBHUkFOVCBFWEVDVVRFIE9OIEZVTkNUSU9OIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4sIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4gICAgR1JBTlQgRVhFQ1VURSBPTiBGVU5DVElPTiBuZXQuaHR0cF9wb3N0KHVybCB0ZXh0LCBib2R5IGpzb25iLCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiwgcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbiAgRU5EIElGO1xuRU5EXG4kJDtcbi0tIEV2ZW50IHRyaWdnZXIgZm9yIHBnX25ldFxuQ1JFQVRFIE9SIFJFUExBQ0UgRlVOQ1RJT04gZXh0ZW5zaW9ucy5ncmFudF9wZ19uZXRfYWNjZXNzKClcblJFVFVSTlMgZXZlbnRfdHJpZ2dlclxuTEFOR1VBR0UgcGxwZ3NxbFxuQVMgJCRcbkJFR0lOXG4gIElGIEVYSVNUUyAoXG4gICAgU0VMRUNUIDFcbiAgICBGUk9NIHBnX2V2ZW50X3RyaWdnZXJfZGRsX2NvbW1hbmRzKCkgQVMgZXZcbiAgICBKT0lOIHBnX2V4dGVuc2lvbiBBUyBleHRcbiAgICBPTiBldi5vYmppZCA9IGV4dC5vaWRcbiAgICBXSEVSRSBleHQuZXh0bmFtZSA9ICdwZ19uZXQnXG4gIClcbiAgVEhFTlxuICAgIEdSQU5UIFVTQUdFIE9OIFNDSEVNQSBuZXQgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluLCBwb3N0Z3JlcywgYW5vbiwgYXV0aGVudGljYXRlZCwgc2VydmljZV9yb2xlO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRUNVUklUWSBERUZJTkVSO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VDVVJJVFkgREVGSU5FUjtcbiAgICBBTFRFUiBmdW5jdGlvbiBuZXQuaHR0cF9nZXQodXJsIHRleHQsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgU0VUIHNlYXJjaF9wYXRoID0gbmV0O1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIEZST00gUFVCTElDO1xuICAgIFJFVk9LRSBBTEwgT04gRlVOQ1RJT04gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBGUk9NIFBVQkxJQztcbiAgICBHUkFOVCBFWEVDVVRFIE9OIEZVTkNUSU9OIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4sIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4gICAgR1JBTlQgRVhFQ1VURSBPTiBGVU5DVElPTiBuZXQuaHR0cF9wb3N0KHVybCB0ZXh0LCBib2R5IGpzb25iLCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiwgcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbiAgRU5EIElGO1xuRU5EO1xuJCQ7XG5DT01NRU5UIE9OIEZVTkNUSU9OIGV4dGVuc2lvbnMuZ3JhbnRfcGdfbmV0X2FjY2VzcyBJUyAnR3JhbnRzIGFjY2VzcyB0byBwZ19uZXQnO1xuRE9cbiQkXG5CRUdJTlxuICBJRiBOT1QgRVhJU1RTIChcbiAgICBTRUxFQ1QgMVxuICAgIEZST00gcGdfZXZlbnRfdHJpZ2dlclxuICAgIFdIRVJFIGV2dG5hbWUgPSAnaXNzdWVfcGdfbmV0X2FjY2VzcydcbiAgKSBUSEVOXG4gICAgQ1JFQVRFIEVWRU5UIFRSSUdHRVIgaXNzdWVfcGdfbmV0X2FjY2VzcyBPTiBkZGxfY29tbWFuZF9lbmQgV0hFTiBUQUcgSU4gKCdDUkVBVEUgRVhURU5TSU9OJylcbiAgICBFWEVDVVRFIFBST0NFRFVSRSBleHRlbnNpb25zLmdyYW50X3BnX25ldF9hY2Nlc3MoKTtcbiAgRU5EIElGO1xuRU5EXG4kJDtcbklOU0VSVCBJTlRPIHN1cGFiYXNlX2Z1bmN0aW9ucy5taWdyYXRpb25zICh2ZXJzaW9uKSBWQUxVRVMgKCcyMDIxMDgwOTE4MzQyM191cGRhdGVfZ3JhbnRzJyk7XG5BTFRFUiBmdW5jdGlvbiBzdXBhYmFzZV9mdW5jdGlvbnMuaHR0cF9yZXF1ZXN0KCkgU0VDVVJJVFkgREVGSU5FUjtcbkFMVEVSIGZ1bmN0aW9uIHN1cGFiYXNlX2Z1bmN0aW9ucy5odHRwX3JlcXVlc3QoKSBTRVQgc2VhcmNoX3BhdGggPSBzdXBhYmFzZV9mdW5jdGlvbnM7XG5SRVZPS0UgQUxMIE9OIEZVTkNUSU9OIHN1cGFiYXNlX2Z1bmN0aW9ucy5odHRwX3JlcXVlc3QoKSBGUk9NIFBVQkxJQztcbkdSQU5UIEVYRUNVVEUgT04gRlVOQ1RJT04gc3VwYWJhc2VfZnVuY3Rpb25zLmh0dHBfcmVxdWVzdCgpIFRPIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG5DT01NSVQ7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvcm9sZXMuc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvaW5pdC1zY3JpcHRzLzk5LXJvbGVzLnNxbAogICAgICAgIGNvbnRlbnQ6ICItLSBOT1RFOiBjaGFuZ2UgdG8geW91ciBvd24gcGFzc3dvcmRzIGZvciBwcm9kdWN0aW9uIGVudmlyb25tZW50c1xuIFxcc2V0IHBncGFzcyBgZWNobyBcIiRQT1NUR1JFU19QQVNTV09SRFwiYFxuXG4gQUxURVIgVVNFUiBhdXRoZW50aWNhdG9yIFdJVEggUEFTU1dPUkQgOidwZ3Bhc3MnO1xuIEFMVEVSIFVTRVIgcGdib3VuY2VyIFdJVEggUEFTU1dPUkQgOidwZ3Bhc3MnO1xuIEFMVEVSIFVTRVIgc3VwYWJhc2VfYXV0aF9hZG1pbiBXSVRIIFBBU1NXT1JEIDoncGdwYXNzJztcbiBBTFRFUiBVU0VSIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiBXSVRIIFBBU1NXT1JEIDoncGdwYXNzJztcbiBBTFRFUiBVU0VSIHN1cGFiYXNlX3N0b3JhZ2VfYWRtaW4gV0lUSCBQQVNTV09SRCA6J3BncGFzcyc7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvand0LnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL2luaXQtc2NyaXB0cy85OS1qd3Quc3FsCiAgICAgICAgY29udGVudDogIlxcc2V0IGp3dF9zZWNyZXQgYGVjaG8gXCIkSldUX1NFQ1JFVFwiYFxuXFxzZXQgand0X2V4cCBgZWNobyBcIiRKV1RfRVhQXCJgXG5cXHNldCBkYl9uYW1lIGBlY2hvIFwiJHtQT1NUR1JFU19EQjotcG9zdGdyZXN9XCJgXG5cbkFMVEVSIERBVEFCQVNFIDpkYl9uYW1lIFNFVCBcImFwcC5zZXR0aW5ncy5qd3Rfc2VjcmV0XCIgVE8gOidqd3Rfc2VjcmV0JztcbkFMVEVSIERBVEFCQVNFIDpkYl9uYW1lIFNFVCBcImFwcC5zZXR0aW5ncy5qd3RfZXhwXCIgVE8gOidqd3RfZXhwJztcbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi9sb2dzLnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL21pZ3JhdGlvbnMvOTktbG9ncy5zcWwKICAgICAgICBjb250ZW50OiAiXFxzZXQgcGd1c2VyIGBlY2hvIFwic3VwYWJhc2VfYWRtaW5cImBcblxcYyBfc3VwYWJhc2VcbmNyZWF0ZSBzY2hlbWEgaWYgbm90IGV4aXN0cyBfYW5hbHl0aWNzO1xuYWx0ZXIgc2NoZW1hIF9hbmFseXRpY3Mgb3duZXIgdG8gOnBndXNlcjtcblxcYyBwb3N0Z3Jlc1xuIgogICAgICAtICdzdXBhYmFzZS1kYi1jb25maWc6L2V0Yy9wb3N0Z3Jlc3FsLWN1c3RvbScKICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICBpbWFnZTogJ3N1cGFiYXNlL2xvZ2ZsYXJlOjEuNC4wJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjQwMDAvaGVhbHRoJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMTAKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBMT0dGTEFSRV9OT0RFX0hPU1Q9MTI3LjAuMC4xCiAgICAgIC0gREJfVVNFUk5BTUU9c3VwYWJhc2VfYWRtaW4KICAgICAgLSBEQl9EQVRBQkFTRT1fc3VwYWJhc2UKICAgICAgLSAnREJfSE9TVE5BTUU9JHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9JwogICAgICAtICdEQl9QT1JUPSR7UE9TVEdSRVNfUE9SVDotNTQzMn0nCiAgICAgIC0gJ0RCX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gREJfU0NIRU1BPV9hbmFseXRpY3MKICAgICAgLSAnTE9HRkxBUkVfQVBJX0tFWT0ke1NFUlZJQ0VfUEFTU1dPUkRfTE9HRkxBUkV9JwogICAgICAtIExPR0ZMQVJFX1NJTkdMRV9URU5BTlQ9dHJ1ZQogICAgICAtIExPR0ZMQVJFX1NJTkdMRV9URU5BTlRfTU9ERT10cnVlCiAgICAgIC0gTE9HRkxBUkVfU1VQQUJBU0VfTU9ERT10cnVlCiAgICAgIC0gTE9HRkxBUkVfTUlOX0NMVVNURVJfU0laRT0xCiAgICAgIC0gJ1BPU1RHUkVTX0JBQ0tFTkRfVVJMPXBvc3RncmVzcWw6Ly9zdXBhYmFzZV9hZG1pbjoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9L19zdXBhYmFzZScKICAgICAgLSBQT1NUR1JFU19CQUNLRU5EX1NDSEVNQT1fYW5hbHl0aWNzCiAgICAgIC0gTE9HRkxBUkVfRkVBVFVSRV9GTEFHX09WRVJSSURFPW11bHRpYmFja2VuZD10cnVlCiAgc3VwYWJhc2UtdmVjdG9yOgogICAgaW1hZ2U6ICd0aW1iZXJpby92ZWN0b3I6MC4yOC4xLWFscGluZScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLS1uby12ZXJib3NlJwogICAgICAgIC0gJy0tdHJpZXM9MScKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICdodHRwOi8vc3VwYWJhc2UtdmVjdG9yOjkwMDEvaGVhbHRoJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgdm9sdW1lczoKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9sb2dzL3ZlY3Rvci55bWwKICAgICAgICB0YXJnZXQ6IC9ldGMvdmVjdG9yL3ZlY3Rvci55bWwKICAgICAgICByZWFkX29ubHk6IHRydWUKICAgICAgICBjb250ZW50OiAiYXBpOlxuICBlbmFibGVkOiB0cnVlXG4gIGFkZHJlc3M6IDAuMC4wLjA6OTAwMVxuXG5zb3VyY2VzOlxuICBkb2NrZXJfaG9zdDpcbiAgICB0eXBlOiBkb2NrZXJfbG9nc1xuICAgIGV4Y2x1ZGVfY29udGFpbmVyczpcbiAgICAgIC0gc3VwYWJhc2UtdmVjdG9yXG5cbnRyYW5zZm9ybXM6XG4gIHByb2plY3RfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gZG9ja2VyX2hvc3RcbiAgICBzb3VyY2U6IHwtXG4gICAgICAucHJvamVjdCA9IFwiZGVmYXVsdFwiXG4gICAgICAuZXZlbnRfbWVzc2FnZSA9IGRlbCgubWVzc2FnZSlcbiAgICAgIC5hcHBuYW1lID0gZGVsKC5jb250YWluZXJfbmFtZSlcbiAgICAgIGRlbCguY29udGFpbmVyX2NyZWF0ZWRfYXQpXG4gICAgICBkZWwoLmNvbnRhaW5lcl9pZClcbiAgICAgIGRlbCguc291cmNlX3R5cGUpXG4gICAgICBkZWwoLnN0cmVhbSlcbiAgICAgIGRlbCgubGFiZWwpXG4gICAgICBkZWwoLmltYWdlKVxuICAgICAgZGVsKC5ob3N0KVxuICAgICAgZGVsKC5zdHJlYW0pXG4gIHJvdXRlcjpcbiAgICB0eXBlOiByb3V0ZVxuICAgIGlucHV0czpcbiAgICAgIC0gcHJvamVjdF9sb2dzXG4gICAgcm91dGU6XG4gICAgICBrb25nOiAnc3RhcnRzX3dpdGgoc3RyaW5nISguYXBwbmFtZSksIFwic3VwYWJhc2Uta29uZ1wiKSdcbiAgICAgIGF1dGg6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJzdXBhYmFzZS1hdXRoXCIpJ1xuICAgICAgcmVzdDogJ3N0YXJ0c193aXRoKHN0cmluZyEoLmFwcG5hbWUpLCBcInN1cGFiYXNlLXJlc3RcIiknXG4gICAgICByZWFsdGltZTogJ3N0YXJ0c193aXRoKHN0cmluZyEoLmFwcG5hbWUpLCBcInJlYWx0aW1lLWRldlwiKSdcbiAgICAgIHN0b3JhZ2U6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJzdXBhYmFzZS1zdG9yYWdlXCIpJ1xuICAgICAgZnVuY3Rpb25zOiAnc3RhcnRzX3dpdGgoc3RyaW5nISguYXBwbmFtZSksIFwic3VwYWJhc2UtZnVuY3Rpb25zXCIpJ1xuICAgICAgZGI6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJzdXBhYmFzZS1kYlwiKSdcbiAgIyBJZ25vcmVzIG5vbiBuZ2lueCBlcnJvcnMgc2luY2UgdGhleSBhcmUgcmVsYXRlZCB3aXRoIGtvbmcgYm9vdGluZyB1cFxuICBrb25nX2xvZ3M6XG4gICAgdHlwZTogcmVtYXBcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5rb25nXG4gICAgc291cmNlOiB8LVxuICAgICAgcmVxLCBlcnIgPSBwYXJzZV9uZ2lueF9sb2coLmV2ZW50X21lc3NhZ2UsIFwiY29tYmluZWRcIilcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAudGltZXN0YW1wID0gcmVxLnRpbWVzdGFtcFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0LmhlYWRlcnMucmVmZXJlciA9IHJlcS5yZWZlcmVyXG4gICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QuaGVhZGVycy51c2VyX2FnZW50ID0gcmVxLmFnZW50XG4gICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QuaGVhZGVycy5jZl9jb25uZWN0aW5nX2lwID0gcmVxLmNsaWVudFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0Lm1ldGhvZCA9IHJlcS5tZXRob2RcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5wYXRoID0gcmVxLnBhdGhcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5wcm90b2NvbCA9IHJlcS5wcm90b2NvbFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXNwb25zZS5zdGF0dXNfY29kZSA9IHJlcS5zdGF0dXNcbiAgICAgIH1cbiAgICAgIGlmIGVyciAhPSBudWxsIHtcbiAgICAgICAgYWJvcnRcbiAgICAgIH1cbiAgIyBJZ25vcmVzIG5vbiBuZ2lueCBlcnJvcnMgc2luY2UgdGhleSBhcmUgcmVsYXRlZCB3aXRoIGtvbmcgYm9vdGluZyB1cFxuICBrb25nX2VycjpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLmtvbmdcbiAgICBzb3VyY2U6IHwtXG4gICAgICAubWV0YWRhdGEucmVxdWVzdC5tZXRob2QgPSBcIkdFVFwiXG4gICAgICAubWV0YWRhdGEucmVzcG9uc2Uuc3RhdHVzX2NvZGUgPSAyMDBcbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfbmdpbnhfbG9nKC5ldmVudF9tZXNzYWdlLCBcImVycm9yXCIpXG4gICAgICBpZiBlcnIgPT0gbnVsbCB7XG4gICAgICAgICAgLnRpbWVzdGFtcCA9IHBhcnNlZC50aW1lc3RhbXBcbiAgICAgICAgICAuc2V2ZXJpdHkgPSBwYXJzZWQuc2V2ZXJpdHlcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5ob3N0ID0gcGFyc2VkLmhvc3RcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5oZWFkZXJzLmNmX2Nvbm5lY3RpbmdfaXAgPSBwYXJzZWQuY2xpZW50XG4gICAgICAgICAgdXJsLCBlcnIgPSBzcGxpdChwYXJzZWQucmVxdWVzdCwgXCIgXCIpXG4gICAgICAgICAgaWYgZXJyID09IG51bGwge1xuICAgICAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5tZXRob2QgPSB1cmxbMF1cbiAgICAgICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QucGF0aCA9IHVybFsxXVxuICAgICAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5wcm90b2NvbCA9IHVybFsyXVxuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIGVyciAhPSBudWxsIHtcbiAgICAgICAgYWJvcnRcbiAgICAgIH1cbiAgIyBHb3RydWUgbG9ncyBhcmUgc3RydWN0dXJlZCBqc29uIHN0cmluZ3Mgd2hpY2ggZnJvbnRlbmQgcGFyc2VzIGRpcmVjdGx5LiBCdXQgd2Uga2VlcCBtZXRhZGF0YSBmb3IgY29uc2lzdGVuY3kuXG4gIGF1dGhfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLmF1dGhcbiAgICBzb3VyY2U6IHwtXG4gICAgICBwYXJzZWQsIGVyciA9IHBhcnNlX2pzb24oLmV2ZW50X21lc3NhZ2UpXG4gICAgICBpZiBlcnIgPT0gbnVsbCB7XG4gICAgICAgICAgLm1ldGFkYXRhLnRpbWVzdGFtcCA9IHBhcnNlZC50aW1lXG4gICAgICAgICAgLm1ldGFkYXRhID0gbWVyZ2UhKC5tZXRhZGF0YSwgcGFyc2VkKVxuICAgICAgfVxuICAjIFBvc3RnUkVTVCBsb2dzIGFyZSBzdHJ1Y3R1cmVkIHNvIHdlIHNlcGFyYXRlIHRpbWVzdGFtcCBmcm9tIG1lc3NhZ2UgdXNpbmcgcmVnZXhcbiAgcmVzdF9sb2dzOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIucmVzdFxuICAgIHNvdXJjZTogfC1cbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfcmVnZXgoLmV2ZW50X21lc3NhZ2UsIHInXig/UDx0aW1lPi4qKTogKD9QPG1zZz4uKikkJylcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAuZXZlbnRfbWVzc2FnZSA9IHBhcnNlZC5tc2dcbiAgICAgICAgICAudGltZXN0YW1wID0gdG9fdGltZXN0YW1wIShwYXJzZWQudGltZSlcbiAgICAgICAgICAubWV0YWRhdGEuaG9zdCA9IC5wcm9qZWN0XG4gICAgICB9XG4gICMgUmVhbHRpbWUgbG9ncyBhcmUgc3RydWN0dXJlZCBzbyB3ZSBwYXJzZSB0aGUgc2V2ZXJpdHkgbGV2ZWwgdXNpbmcgcmVnZXggKGlnbm9yZSB0aW1lIGJlY2F1c2UgaXQgaGFzIG5vIGRhdGUpXG4gIHJlYWx0aW1lX2xvZ3M6XG4gICAgdHlwZTogcmVtYXBcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5yZWFsdGltZVxuICAgIHNvdXJjZTogfC1cbiAgICAgIC5tZXRhZGF0YS5wcm9qZWN0ID0gZGVsKC5wcm9qZWN0KVxuICAgICAgLm1ldGFkYXRhLmV4dGVybmFsX2lkID0gLm1ldGFkYXRhLnByb2plY3RcbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfcmVnZXgoLmV2ZW50X21lc3NhZ2UsIHInXig/UDx0aW1lPlxcZCs6XFxkKzpcXGQrXFwuXFxkKykgXFxbKD9QPGxldmVsPlxcdyspXFxdICg/UDxtc2c+LiopJCcpXG4gICAgICBpZiBlcnIgPT0gbnVsbCB7XG4gICAgICAgICAgLmV2ZW50X21lc3NhZ2UgPSBwYXJzZWQubXNnXG4gICAgICAgICAgLm1ldGFkYXRhLmxldmVsID0gcGFyc2VkLmxldmVsXG4gICAgICB9XG4gICMgU3RvcmFnZSBsb2dzIG1heSBjb250YWluIGpzb24gb2JqZWN0cyBzbyB3ZSBwYXJzZSB0aGVtIGZvciBjb21wbGV0ZW5lc3NcbiAgc3RvcmFnZV9sb2dzOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIuc3RvcmFnZVxuICAgIHNvdXJjZTogfC1cbiAgICAgIC5tZXRhZGF0YS5wcm9qZWN0ID0gZGVsKC5wcm9qZWN0KVxuICAgICAgLm1ldGFkYXRhLnRlbmFudElkID0gLm1ldGFkYXRhLnByb2plY3RcbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfanNvbiguZXZlbnRfbWVzc2FnZSlcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAuZXZlbnRfbWVzc2FnZSA9IHBhcnNlZC5tc2dcbiAgICAgICAgICAubWV0YWRhdGEubGV2ZWwgPSBwYXJzZWQubGV2ZWxcbiAgICAgICAgICAubWV0YWRhdGEudGltZXN0YW1wID0gcGFyc2VkLnRpbWVcbiAgICAgICAgICAubWV0YWRhdGEuY29udGV4dFswXS5ob3N0ID0gcGFyc2VkLmhvc3RuYW1lXG4gICAgICAgICAgLm1ldGFkYXRhLmNvbnRleHRbMF0ucGlkID0gcGFyc2VkLnBpZFxuICAgICAgfVxuICAjIFBvc3RncmVzIGxvZ3Mgc29tZSBtZXNzYWdlcyB0byBzdGRlcnIgd2hpY2ggd2UgbWFwIHRvIHdhcm5pbmcgc2V2ZXJpdHkgbGV2ZWxcbiAgZGJfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLmRiXG4gICAgc291cmNlOiB8LVxuICAgICAgLm1ldGFkYXRhLmhvc3QgPSBcImRiLWRlZmF1bHRcIlxuICAgICAgLm1ldGFkYXRhLnBhcnNlZC50aW1lc3RhbXAgPSAudGltZXN0YW1wXG5cbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfcmVnZXgoLmV2ZW50X21lc3NhZ2UsIHInLiooP1A8bGV2ZWw+SU5GT3xOT1RJQ0V8V0FSTklOR3xFUlJPUnxMT0d8RkFUQUx8UEFOSUM/KTouKicsIG51bWVyaWNfZ3JvdXBzOiB0cnVlKVxuXG4gICAgICBpZiBlcnIgIT0gbnVsbCB8fCBwYXJzZWQgPT0gbnVsbCB7XG4gICAgICAgIC5tZXRhZGF0YS5wYXJzZWQuZXJyb3Jfc2V2ZXJpdHkgPSBcImluZm9cIlxuICAgICAgfVxuICAgICAgaWYgcGFyc2VkICE9IG51bGwge1xuICAgICAgLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSA9IHBhcnNlZC5sZXZlbFxuICAgICAgfVxuICAgICAgaWYgLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSA9PSBcImluZm9cIiB7XG4gICAgICAgICAgLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSA9IFwibG9nXCJcbiAgICAgIH1cbiAgICAgIC5tZXRhZGF0YS5wYXJzZWQuZXJyb3Jfc2V2ZXJpdHkgPSB1cGNhc2UhKC5tZXRhZGF0YS5wYXJzZWQuZXJyb3Jfc2V2ZXJpdHkpXG5cbnNpbmtzOlxuICBsb2dmbGFyZV9hdXRoOlxuICAgIHR5cGU6ICdodHRwJ1xuICAgIGlucHV0czpcbiAgICAgIC0gYXV0aF9sb2dzXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL2FwaS9sb2dzP3NvdXJjZV9uYW1lPWdvdHJ1ZS5sb2dzLnByb2QmYXBpX2tleT0ke0xPR0ZMQVJFX0FQSV9LRVk/TE9HRkxBUkVfQVBJX0tFWSBpcyByZXF1aXJlZH0nXG4gIGxvZ2ZsYXJlX3JlYWx0aW1lOlxuICAgIHR5cGU6ICdodHRwJ1xuICAgIGlucHV0czpcbiAgICAgIC0gcmVhbHRpbWVfbG9nc1xuICAgIGVuY29kaW5nOlxuICAgICAgY29kZWM6ICdqc29uJ1xuICAgIG1ldGhvZDogJ3Bvc3QnXG4gICAgcmVxdWVzdDpcbiAgICAgIHJldHJ5X21heF9kdXJhdGlvbl9zZWNzOiAxMFxuICAgIHVyaTogJ2h0dHA6Ly9zdXBhYmFzZS1hbmFseXRpY3M6NDAwMC9hcGkvbG9ncz9zb3VyY2VfbmFtZT1yZWFsdGltZS5sb2dzLnByb2QmYXBpX2tleT0ke0xPR0ZMQVJFX0FQSV9LRVk/TE9HRkxBUkVfQVBJX0tFWSBpcyByZXF1aXJlZH0nXG4gIGxvZ2ZsYXJlX3Jlc3Q6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSByZXN0X2xvZ3NcbiAgICBlbmNvZGluZzpcbiAgICAgIGNvZGVjOiAnanNvbidcbiAgICBtZXRob2Q6ICdwb3N0J1xuICAgIHJlcXVlc3Q6XG4gICAgICByZXRyeV9tYXhfZHVyYXRpb25fc2VjczogMTBcbiAgICB1cmk6ICdodHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAvYXBpL2xvZ3M/c291cmNlX25hbWU9cG9zdGdSRVNULmxvZ3MucHJvZCZhcGlfa2V5PSR7TE9HRkxBUkVfQVBJX0tFWT9MT0dGTEFSRV9BUElfS0VZIGlzIHJlcXVpcmVkfSdcbiAgbG9nZmxhcmVfZGI6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSBkYl9sb2dzXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgIyBXZSBtdXN0IHJvdXRlIHRoZSBzaW5rIHRocm91Z2gga29uZyBiZWNhdXNlIGluZ2VzdGluZyBsb2dzIGJlZm9yZSBsb2dmbGFyZSBpcyBmdWxseSBpbml0aWFsaXNlZCB3aWxsXG4gICAgIyBsZWFkIHRvIGJyb2tlbiBxdWVyaWVzIGZyb20gc3R1ZGlvLiBUaGlzIHdvcmtzIGJ5IHRoZSBhc3N1bXB0aW9uIHRoYXQgY29udGFpbmVycyBhcmUgc3RhcnRlZCBpbiB0aGVcbiAgICAjIGZvbGxvd2luZyBvcmRlcjogdmVjdG9yID4gZGIgPiBsb2dmbGFyZSA+IGtvbmdcbiAgICB1cmk6ICdodHRwOi8vc3VwYWJhc2Uta29uZzo4MDAwL2FuYWx5dGljcy92MS9hcGkvbG9ncz9zb3VyY2VfbmFtZT1wb3N0Z3Jlcy5sb2dzJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuICBsb2dmbGFyZV9mdW5jdGlvbnM6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIuZnVuY3Rpb25zXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL2FwaS9sb2dzP3NvdXJjZV9uYW1lPWRlbm8tcmVsYXktbG9ncyZhcGlfa2V5PSR7TE9HRkxBUkVfQVBJX0tFWT9MT0dGTEFSRV9BUElfS0VZIGlzIHJlcXVpcmVkfSdcbiAgbG9nZmxhcmVfc3RvcmFnZTpcbiAgICB0eXBlOiAnaHR0cCdcbiAgICBpbnB1dHM6XG4gICAgICAtIHN0b3JhZ2VfbG9nc1xuICAgIGVuY29kaW5nOlxuICAgICAgY29kZWM6ICdqc29uJ1xuICAgIG1ldGhvZDogJ3Bvc3QnXG4gICAgcmVxdWVzdDpcbiAgICAgIHJldHJ5X21heF9kdXJhdGlvbl9zZWNzOiAxMFxuICAgIHVyaTogJ2h0dHA6Ly9zdXBhYmFzZS1hbmFseXRpY3M6NDAwMC9hcGkvbG9ncz9zb3VyY2VfbmFtZT1zdG9yYWdlLmxvZ3MucHJvZC4yJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuICBsb2dmbGFyZV9rb25nOlxuICAgIHR5cGU6ICdodHRwJ1xuICAgIGlucHV0czpcbiAgICAgIC0ga29uZ19sb2dzXG4gICAgICAtIGtvbmdfZXJyXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL2FwaS9sb2dzP3NvdXJjZV9uYW1lPWNsb3VkZmxhcmUubG9ncy5wcm9kJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuIgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jazpybycKICAgIGVudmlyb25tZW50OgogICAgICAtICdMT0dGTEFSRV9BUElfS0VZPSR7U0VSVklDRV9QQVNTV09SRF9MT0dGTEFSRX0nCiAgICBjb21tYW5kOgogICAgICAtICctLWNvbmZpZycKICAgICAgLSBldGMvdmVjdG9yL3ZlY3Rvci55bWwKICBzdXBhYmFzZS1yZXN0OgogICAgaW1hZ2U6ICdwb3N0Z3Jlc3QvcG9zdGdyZXN0OnYxMi4yLjEyJwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUEdSU1RfREJfVVJJPXBvc3RncmVzOi8vYXV0aGVudGljYXRvcjoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9LyR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnUEdSU1RfREJfU0NIRU1BUz0ke1BHUlNUX0RCX1NDSEVNQVM6LXB1YmxpYyxzdG9yYWdlLGdyYXBocWxfcHVibGljfScKICAgICAgLSBQR1JTVF9EQl9BTk9OX1JPTEU9YW5vbgogICAgICAtICdQR1JTVF9KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtIFBHUlNUX0RCX1VTRV9MRUdBQ1lfR1VDUz1mYWxzZQogICAgICAtICdQR1JTVF9BUFBfU0VUVElOR1NfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSAnUEdSU1RfQVBQX1NFVFRJTkdTX0pXVF9FWFA9JHtKV1RfRVhQSVJZOi0zNjAwfScKICAgIGNvbW1hbmQ6IHBvc3RncmVzdAogICAgZXhjbHVkZV9mcm9tX2hjOiB0cnVlCiAgc3VwYWJhc2UtYXV0aDoKICAgIGltYWdlOiAnc3VwYWJhc2UvZ290cnVlOnYyLjE3NC4wJwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gd2dldAogICAgICAgIC0gJy0tbm8tdmVyYm9zZScKICAgICAgICAtICctLXRyaWVzPTEnCiAgICAgICAgLSAnLS1zcGlkZXInCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo5OTk5L2hlYWx0aCcKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIGVudmlyb25tZW50OgogICAgICAtIEdPVFJVRV9BUElfSE9TVD0wLjAuMC4wCiAgICAgIC0gR09UUlVFX0FQSV9QT1JUPTk5OTkKICAgICAgLSAnQVBJX0VYVEVSTkFMX1VSTD0ke0FQSV9FWFRFUk5BTF9VUkw6LWh0dHA6Ly9zdXBhYmFzZS1rb25nOjgwMDB9JwogICAgICAtIEdPVFJVRV9EQl9EUklWRVI9cG9zdGdyZXMKICAgICAgLSAnR09UUlVFX0RCX0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovL3N1cGFiYXNlX2F1dGhfYWRtaW46JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUAke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn06JHtQT1NUR1JFU19QT1JUOi01NDMyfS8ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gJ0dPVFJVRV9TSVRFX1VSTD0ke1NFUlZJQ0VfRlFETl9TVVBBQkFTRUtPTkd9JwogICAgICAtICdHT1RSVUVfVVJJX0FMTE9XX0xJU1Q9JHtBRERJVElPTkFMX1JFRElSRUNUX1VSTFN9JwogICAgICAtICdHT1RSVUVfRElTQUJMRV9TSUdOVVA9JHtESVNBQkxFX1NJR05VUDotZmFsc2V9JwogICAgICAtIEdPVFJVRV9KV1RfQURNSU5fUk9MRVM9c2VydmljZV9yb2xlCiAgICAgIC0gR09UUlVFX0pXVF9BVUQ9YXV0aGVudGljYXRlZAogICAgICAtIEdPVFJVRV9KV1RfREVGQVVMVF9HUk9VUF9OQU1FPWF1dGhlbnRpY2F0ZWQKICAgICAgLSAnR09UUlVFX0pXVF9FWFA9JHtKV1RfRVhQSVJZOi0zNjAwfScKICAgICAgLSAnR09UUlVFX0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gJ0dPVFJVRV9FWFRFUk5BTF9FTUFJTF9FTkFCTEVEPSR7RU5BQkxFX0VNQUlMX1NJR05VUDotdHJ1ZX0nCiAgICAgIC0gJ0dPVFJVRV9FWFRFUk5BTF9BTk9OWU1PVVNfVVNFUlNfRU5BQkxFRD0ke0VOQUJMRV9BTk9OWU1PVVNfVVNFUlM6LWZhbHNlfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9BVVRPQ09ORklSTT0ke0VOQUJMRV9FTUFJTF9BVVRPQ09ORklSTTotZmFsc2V9JwogICAgICAtICdHT1RSVUVfU01UUF9BRE1JTl9FTUFJTD0ke1NNVFBfQURNSU5fRU1BSUx9JwogICAgICAtICdHT1RSVUVfU01UUF9IT1NUPSR7U01UUF9IT1NUfScKICAgICAgLSAnR09UUlVFX1NNVFBfUE9SVD0ke1NNVFBfUE9SVDotNTg3fScKICAgICAgLSAnR09UUlVFX1NNVFBfVVNFUj0ke1NNVFBfVVNFUn0nCiAgICAgIC0gJ0dPVFJVRV9TTVRQX1BBU1M9JHtTTVRQX1BBU1N9JwogICAgICAtICdHT1RSVUVfU01UUF9TRU5ERVJfTkFNRT0ke1NNVFBfU0VOREVSX05BTUV9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1VSTFBBVEhTX0lOVklURT0ke01BSUxFUl9VUkxQQVRIU19JTlZJVEU6LS9hdXRoL3YxL3ZlcmlmeX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVVJMUEFUSFNfQ09ORklSTUFUSU9OPSR7TUFJTEVSX1VSTFBBVEhTX0NPTkZJUk1BVElPTjotL2F1dGgvdjEvdmVyaWZ5fScKICAgICAgLSAnR09UUlVFX01BSUxFUl9VUkxQQVRIU19SRUNPVkVSWT0ke01BSUxFUl9VUkxQQVRIU19SRUNPVkVSWTotL2F1dGgvdjEvdmVyaWZ5fScKICAgICAgLSAnR09UUlVFX01BSUxFUl9VUkxQQVRIU19FTUFJTF9DSEFOR0U9JHtNQUlMRVJfVVJMUEFUSFNfRU1BSUxfQ0hBTkdFOi0vYXV0aC92MS92ZXJpZnl9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1RFTVBMQVRFU19JTlZJVEU9JHtNQUlMRVJfVEVNUExBVEVTX0lOVklURX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVEVNUExBVEVTX0NPTkZJUk1BVElPTj0ke01BSUxFUl9URU1QTEFURVNfQ09ORklSTUFUSU9OfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9URU1QTEFURVNfUkVDT1ZFUlk9JHtNQUlMRVJfVEVNUExBVEVTX1JFQ09WRVJZfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9URU1QTEFURVNfTUFHSUNfTElOSz0ke01BSUxFUl9URU1QTEFURVNfTUFHSUNfTElOS30nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVEVNUExBVEVTX0VNQUlMX0NIQU5HRT0ke01BSUxFUl9URU1QTEFURVNfRU1BSUxfQ0hBTkdFfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9TVUJKRUNUU19DT05GSVJNQVRJT049JHtNQUlMRVJfU1VCSkVDVFNfQ09ORklSTUFUSU9OfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9TVUJKRUNUU19SRUNPVkVSWT0ke01BSUxFUl9TVUJKRUNUU19SRUNPVkVSWX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfU1VCSkVDVFNfTUFHSUNfTElOSz0ke01BSUxFUl9TVUJKRUNUU19NQUdJQ19MSU5LfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9TVUJKRUNUU19FTUFJTF9DSEFOR0U9JHtNQUlMRVJfU1VCSkVDVFNfRU1BSUxfQ0hBTkdFfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9TVUJKRUNUU19JTlZJVEU9JHtNQUlMRVJfU1VCSkVDVFNfSU5WSVRFfScKICAgICAgLSAnR09UUlVFX0VYVEVSTkFMX1BIT05FX0VOQUJMRUQ9JHtFTkFCTEVfUEhPTkVfU0lHTlVQOi10cnVlfScKICAgICAgLSAnR09UUlVFX1NNU19BVVRPQ09ORklSTT0ke0VOQUJMRV9QSE9ORV9BVVRPQ09ORklSTTotdHJ1ZX0nCiAgcmVhbHRpbWUtZGV2OgogICAgaW1hZ2U6ICdzdXBhYmFzZS9yZWFsdGltZTp2Mi4zNC40NycKICAgIGNvbnRhaW5lcl9uYW1lOiByZWFsdGltZS1kZXYuc3VwYWJhc2UtcmVhbHRpbWUKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHN1cGFiYXNlLWFuYWx5dGljczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctc1NmTCcKICAgICAgICAtICctLWhlYWQnCiAgICAgICAgLSAnLW8nCiAgICAgICAgLSAvZGV2L251bGwKICAgICAgICAtICctSCcKICAgICAgICAtICdBdXRob3JpemF0aW9uOiBCZWFyZXIgJHtTRVJWSUNFX1NVUEFCQVNFQU5PTl9LRVl9JwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6NDAwMC9hcGkvdGVuYW50cy9yZWFsdGltZS1kZXYvaGVhbHRoJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUE9SVD00MDAwCiAgICAgIC0gJ0RCX0hPU1Q9JHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9JwogICAgICAtICdEQl9QT1JUPSR7UE9TVEdSRVNfUE9SVDotNTQzMn0nCiAgICAgIC0gREJfVVNFUj1zdXBhYmFzZV9hZG1pbgogICAgICAtICdEQl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdEQl9OQU1FPSR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnREJfQUZURVJfQ09OTkVDVF9RVUVSWT1TRVQgc2VhcmNoX3BhdGggVE8gX3JlYWx0aW1lJwogICAgICAtIERCX0VOQ19LRVk9c3VwYWJhc2VyZWFsdGltZQogICAgICAtICdBUElfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSBGTFlfQUxMT0NfSUQ9Zmx5MTIzCiAgICAgIC0gRkxZX0FQUF9OQU1FPXJlYWx0aW1lCiAgICAgIC0gJ1NFQ1JFVF9LRVlfQkFTRT0ke1NFQ1JFVF9QQVNTV09SRF9SRUFMVElNRX0nCiAgICAgIC0gJ0VSTF9BRkxBR1M9LXByb3RvX2Rpc3QgaW5ldF90Y3AnCiAgICAgIC0gRU5BQkxFX1RBSUxTQ0FMRT1mYWxzZQogICAgICAtICJETlNfTk9ERVM9JyciCiAgICAgIC0gUkxJTUlUX05PRklMRT0xMDAwMAogICAgICAtIEFQUF9OQU1FPXJlYWx0aW1lCiAgICAgIC0gU0VFRF9TRUxGX0hPU1Q9dHJ1ZQogICAgICAtIExPR19MRVZFTD1lcnJvcgogICAgICAtIFJVTl9KQU5JVE9SPXRydWUKICAgICAgLSBKQU5JVE9SX0lOVEVSVkFMPTYwMDAwCiAgICBjb21tYW5kOiAic2ggLWMgXCIvYXBwL2Jpbi9taWdyYXRlICYmIC9hcHAvYmluL3JlYWx0aW1lIGV2YWwgJ1JlYWx0aW1lLlJlbGVhc2Uuc2VlZHMoUmVhbHRpbWUuUmVwbyknICYmIC9hcHAvYmluL3NlcnZlclwiXG4iCiAgc3VwYWJhc2UtbWluaW86CiAgICBpbWFnZTogJ2doY3IuaW8vY29vbGxhYnNpby9taW5pbzpSRUxFQVNFLjIwMjUtMTAtMTVUMTctMjktNTVaJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ01JTklPX1JPT1RfVVNFUj0ke1NFUlZJQ0VfVVNFUl9NSU5JT30nCiAgICAgIC0gJ01JTklPX1JPT1RfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01JTklPfScKICAgIGNvbW1hbmQ6ICdzZXJ2ZXIgLS1jb25zb2xlLWFkZHJlc3MgIjo5MDAxIiAvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBtYwogICAgICAgIC0gcmVhZHkKICAgICAgICAtIGxvY2FsCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICAgIHZvbHVtZXM6CiAgICAgIC0gJy4vdm9sdW1lcy9zdG9yYWdlOi9kYXRhJwogIG1pbmlvLWNyZWF0ZWJ1Y2tldDoKICAgIGltYWdlOiBtaW5pby9tYwogICAgcmVzdGFydDogJ25vJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ01JTklPX1JPT1RfVVNFUj0ke1NFUlZJQ0VfVVNFUl9NSU5JT30nCiAgICAgIC0gJ01JTklPX1JPT1RfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01JTklPfScKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLW1pbmlvOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnRyeXBvaW50OgogICAgICAtIC9lbnRyeXBvaW50LnNoCiAgICB2b2x1bWVzOgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi9lbnRyeXBvaW50LnNoCiAgICAgICAgdGFyZ2V0OiAvZW50cnlwb2ludC5zaAogICAgICAgIGNvbnRlbnQ6ICIjIS9iaW4vc2hcbi91c3IvYmluL21jIGFsaWFzIHNldCBzdXBhYmFzZS1taW5pbyBodHRwOi8vc3VwYWJhc2UtbWluaW86OTAwMCAke01JTklPX1JPT1RfVVNFUn0gJHtNSU5JT19ST09UX1BBU1NXT1JEfTtcbi91c3IvYmluL21jIG1iIC0taWdub3JlLWV4aXN0aW5nIHN1cGFiYXNlLW1pbmlvL3N0dWI7XG5leGl0IDBcbiIKICBzdXBhYmFzZS1zdG9yYWdlOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9zdG9yYWdlLWFwaTp2MS4xNC42JwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgc3VwYWJhc2UtcmVzdDoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2Vfc3RhcnRlZAogICAgICBpbWdwcm94eToKICAgICAgICBjb25kaXRpb246IHNlcnZpY2Vfc3RhcnRlZAogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctLW5vLXZlcmJvc2UnCiAgICAgICAgLSAnLS10cmllcz0xJwogICAgICAgIC0gJy0tc3BpZGVyJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6NTAwMC9zdGF0dXMnCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIGludGVydmFsOiA1cwogICAgICByZXRyaWVzOiAzCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWRVJfUE9SVD01MDAwCiAgICAgIC0gU0VSVkVSX1JFR0lPTj1sb2NhbAogICAgICAtIE1VTFRJX1RFTkFOVD1mYWxzZQogICAgICAtICdBVVRIX0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovL3N1cGFiYXNlX3N0b3JhZ2VfYWRtaW46JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUAke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn06JHtQT1NUR1JFU19QT1JUOi01NDMyfS8ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gREJfSU5TVEFMTF9ST0xFUz1mYWxzZQogICAgICAtIFNUT1JBR0VfQkFDS0VORD1zMwogICAgICAtIFNUT1JBR0VfUzNfQlVDS0VUPXN0dWIKICAgICAgLSAnU1RPUkFHRV9TM19FTkRQT0lOVD1odHRwOi8vc3VwYWJhc2UtbWluaW86OTAwMCcKICAgICAgLSBTVE9SQUdFX1MzX0ZPUkNFX1BBVEhfU1RZTEU9dHJ1ZQogICAgICAtIFNUT1JBR0VfUzNfUkVHSU9OPXVzLWVhc3QtMQogICAgICAtICdBV1NfQUNDRVNTX0tFWV9JRD0ke1NFUlZJQ0VfVVNFUl9NSU5JT30nCiAgICAgIC0gJ0FXU19TRUNSRVRfQUNDRVNTX0tFWT0ke1NFUlZJQ0VfUEFTU1dPUkRfTUlOSU99JwogICAgICAtIFVQTE9BRF9GSUxFX1NJWkVfTElNSVQ9NTI0Mjg4MDAwCiAgICAgIC0gVVBMT0FEX0ZJTEVfU0laRV9MSU1JVF9TVEFOREFSRD01MjQyODgwMDAKICAgICAgLSBVUExPQURfU0lHTkVEX1VSTF9FWFBJUkFUSU9OX1RJTUU9MTIwCiAgICAgIC0gVFVTX1VSTF9QQVRIPXVwbG9hZC9yZXN1bWFibGUKICAgICAgLSBUVVNfTUFYX1NJWkU9MzYwMDAwMAogICAgICAtIEVOQUJMRV9JTUFHRV9UUkFOU0ZPUk1BVElPTj10cnVlCiAgICAgIC0gJ0lNR1BST1hZX1VSTD1odHRwOi8vaW1ncHJveHk6ODA4MCcKICAgICAgLSBJTUdQUk9YWV9SRVFVRVNUX1RJTUVPVVQ9MTUKICAgICAgLSBEQVRBQkFTRV9TRUFSQ0hfUEFUSD1zdG9yYWdlCiAgICAgIC0gTk9ERV9FTlY9cHJvZHVjdGlvbgogICAgICAtIFJFUVVFU1RfQUxMT1dfWF9GT1JXQVJERURfUEFUSD10cnVlCiAgICB2b2x1bWVzOgogICAgICAtICcuL3ZvbHVtZXMvc3RvcmFnZTovdmFyL2xpYi9zdG9yYWdlJwogIGltZ3Byb3h5OgogICAgaW1hZ2U6ICdkYXJ0aHNpbS9pbWdwcm94eTp2My44LjAnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gaW1ncHJveHkKICAgICAgICAtIGhlYWx0aAogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gSU1HUFJPWFlfTE9DQUxfRklMRVNZU1RFTV9ST09UPS8KICAgICAgLSBJTUdQUk9YWV9VU0VfRVRBRz10cnVlCiAgICAgIC0gJ0lNR1BST1hZX0VOQUJMRV9XRUJQX0RFVEVDVElPTj0ke0lNR1BST1hZX0VOQUJMRV9XRUJQX0RFVEVDVElPTjotdHJ1ZX0nCiAgICB2b2x1bWVzOgogICAgICAtICcuL3ZvbHVtZXMvc3RvcmFnZTovdmFyL2xpYi9zdG9yYWdlJwogIHN1cGFiYXNlLW1ldGE6CiAgICBpbWFnZTogJ3N1cGFiYXNlL3Bvc3RncmVzLW1ldGE6djAuODkuMycKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHN1cGFiYXNlLWFuYWx5dGljczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUEdfTUVUQV9QT1JUPTgwODAKICAgICAgLSAnUEdfTUVUQV9EQl9IT1NUPSR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifScKICAgICAgLSAnUEdfTUVUQV9EQl9QT1JUPSR7UE9TVEdSRVNfUE9SVDotNTQzMn0nCiAgICAgIC0gJ1BHX01FVEFfREJfTkFNRT0ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gUEdfTUVUQV9EQl9VU0VSPXN1cGFiYXNlX2FkbWluCiAgICAgIC0gJ1BHX01FVEFfREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICBzdXBhYmFzZS1lZGdlLWZ1bmN0aW9uczoKICAgIGltYWdlOiAnc3VwYWJhc2UvZWRnZS1ydW50aW1lOnYxLjY3LjQnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBlY2hvCiAgICAgICAgLSAnRWRnZSBGdW5jdGlvbnMgaXMgaGVhbHRoeScKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIGVudmlyb25tZW50OgogICAgICAtICdKV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdTVVBBQkFTRV9VUkw9JHtTRVJWSUNFX0ZRRE5fU1VQQUJBU0VLT05HfScKICAgICAgLSAnU1VQQUJBU0VfQU5PTl9LRVk9JHtTRVJWSUNFX1NVUEFCQVNFQU5PTl9LRVl9JwogICAgICAtICdTVVBBQkFTRV9TRVJWSUNFX1JPTEVfS0VZPSR7U0VSVklDRV9TVVBBQkFTRVNFUlZJQ0VfS0VZfScKICAgICAgLSAnU1VQQUJBU0VfREJfVVJMPXBvc3RncmVzcWw6Ly9wb3N0Z3Jlczoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9LyR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnVkVSSUZZX0pXVD0ke0ZVTkNUSU9OU19WRVJJRllfSldUOi1mYWxzZX0nCiAgICB2b2x1bWVzOgogICAgICAtICcuL3ZvbHVtZXMvZnVuY3Rpb25zOi9ob21lL2Rlbm8vZnVuY3Rpb25zJwogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2Z1bmN0aW9ucy9tYWluL2luZGV4LnRzCiAgICAgICAgdGFyZ2V0OiAvaG9tZS9kZW5vL2Z1bmN0aW9ucy9tYWluL2luZGV4LnRzCiAgICAgICAgY29udGVudDogImltcG9ydCB7IHNlcnZlIH0gZnJvbSAnaHR0cHM6Ly9kZW5vLmxhbmQvc3RkQDAuMTMxLjAvaHR0cC9zZXJ2ZXIudHMnXG5pbXBvcnQgKiBhcyBqb3NlIGZyb20gJ2h0dHBzOi8vZGVuby5sYW5kL3gvam9zZUB2NC4xNC40L2luZGV4LnRzJ1xuXG5jb25zb2xlLmxvZygnbWFpbiBmdW5jdGlvbiBzdGFydGVkJylcblxuY29uc3QgSldUX1NFQ1JFVCA9IERlbm8uZW52LmdldCgnSldUX1NFQ1JFVCcpXG5jb25zdCBWRVJJRllfSldUID0gRGVuby5lbnYuZ2V0KCdWRVJJRllfSldUJykgPT09ICd0cnVlJ1xuXG5mdW5jdGlvbiBnZXRBdXRoVG9rZW4ocmVxOiBSZXF1ZXN0KSB7XG4gIGNvbnN0IGF1dGhIZWFkZXIgPSByZXEuaGVhZGVycy5nZXQoJ2F1dGhvcml6YXRpb24nKVxuICBpZiAoIWF1dGhIZWFkZXIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ01pc3NpbmcgYXV0aG9yaXphdGlvbiBoZWFkZXInKVxuICB9XG4gIGNvbnN0IFtiZWFyZXIsIHRva2VuXSA9IGF1dGhIZWFkZXIuc3BsaXQoJyAnKVxuICBpZiAoYmVhcmVyICE9PSAnQmVhcmVyJykge1xuICAgIHRocm93IG5ldyBFcnJvcihgQXV0aCBoZWFkZXIgaXMgbm90ICdCZWFyZXIge3Rva2VufSdgKVxuICB9XG4gIHJldHVybiB0b2tlblxufVxuXG5hc3luYyBmdW5jdGlvbiB2ZXJpZnlKV1Qoand0OiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3QgZW5jb2RlciA9IG5ldyBUZXh0RW5jb2RlcigpXG4gIGNvbnN0IHNlY3JldEtleSA9IGVuY29kZXIuZW5jb2RlKEpXVF9TRUNSRVQpXG4gIHRyeSB7XG4gICAgYXdhaXQgam9zZS5qd3RWZXJpZnkoand0LCBzZWNyZXRLZXkpXG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGNvbnNvbGUuZXJyb3IoZXJyKVxuICAgIHJldHVybiBmYWxzZVxuICB9XG4gIHJldHVybiB0cnVlXG59XG5cbnNlcnZlKGFzeW5jIChyZXE6IFJlcXVlc3QpID0+IHtcbiAgaWYgKHJlcS5tZXRob2QgIT09ICdPUFRJT05TJyAmJiBWRVJJRllfSldUKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRva2VuID0gZ2V0QXV0aFRva2VuKHJlcSlcbiAgICAgIGNvbnN0IGlzVmFsaWRKV1QgPSBhd2FpdCB2ZXJpZnlKV1QodG9rZW4pXG5cbiAgICAgIGlmICghaXNWYWxpZEpXVCkge1xuICAgICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KHsgbXNnOiAnSW52YWxpZCBKV1QnIH0pLCB7XG4gICAgICAgICAgc3RhdHVzOiA0MDEsXG4gICAgICAgICAgaGVhZGVyczogeyAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nIH0sXG4gICAgICAgIH0pXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgY29uc29sZS5lcnJvcihlKVxuICAgICAgcmV0dXJuIG5ldyBSZXNwb25zZShKU09OLnN0cmluZ2lmeSh7IG1zZzogZS50b1N0cmluZygpIH0pLCB7XG4gICAgICAgIHN0YXR1czogNDAxLFxuICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgY29uc3QgdXJsID0gbmV3IFVSTChyZXEudXJsKVxuICBjb25zdCB7IHBhdGhuYW1lIH0gPSB1cmxcbiAgY29uc3QgcGF0aF9wYXJ0cyA9IHBhdGhuYW1lLnNwbGl0KCcvJylcbiAgY29uc3Qgc2VydmljZV9uYW1lID0gcGF0aF9wYXJ0c1sxXVxuXG4gIGlmICghc2VydmljZV9uYW1lIHx8IHNlcnZpY2VfbmFtZSA9PT0gJycpIHtcbiAgICBjb25zdCBlcnJvciA9IHsgbXNnOiAnbWlzc2luZyBmdW5jdGlvbiBuYW1lIGluIHJlcXVlc3QnIH1cbiAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KGVycm9yKSwge1xuICAgICAgc3RhdHVzOiA0MDAsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICB9KVxuICB9XG5cbiAgY29uc3Qgc2VydmljZVBhdGggPSBgL2hvbWUvZGVuby9mdW5jdGlvbnMvJHtzZXJ2aWNlX25hbWV9YFxuICBjb25zb2xlLmVycm9yKGBzZXJ2aW5nIHRoZSByZXF1ZXN0IHdpdGggJHtzZXJ2aWNlUGF0aH1gKVxuXG4gIGNvbnN0IG1lbW9yeUxpbWl0TWIgPSAxNTBcbiAgY29uc3Qgd29ya2VyVGltZW91dE1zID0gMSAqIDYwICogMTAwMFxuICBjb25zdCBub01vZHVsZUNhY2hlID0gZmFsc2VcbiAgY29uc3QgaW1wb3J0TWFwUGF0aCA9IG51bGxcbiAgY29uc3QgZW52VmFyc09iaiA9IERlbm8uZW52LnRvT2JqZWN0KClcbiAgY29uc3QgZW52VmFycyA9IE9iamVjdC5rZXlzKGVudlZhcnNPYmopLm1hcCgoaykgPT4gW2ssIGVudlZhcnNPYmpba11dKVxuXG4gIHRyeSB7XG4gICAgY29uc3Qgd29ya2VyID0gYXdhaXQgRWRnZVJ1bnRpbWUudXNlcldvcmtlcnMuY3JlYXRlKHtcbiAgICAgIHNlcnZpY2VQYXRoLFxuICAgICAgbWVtb3J5TGltaXRNYixcbiAgICAgIHdvcmtlclRpbWVvdXRNcyxcbiAgICAgIG5vTW9kdWxlQ2FjaGUsXG4gICAgICBpbXBvcnRNYXBQYXRoLFxuICAgICAgZW52VmFycyxcbiAgICB9KVxuICAgIHJldHVybiBhd2FpdCB3b3JrZXIuZmV0Y2gocmVxKVxuICB9IGNhdGNoIChlKSB7XG4gICAgY29uc3QgZXJyb3IgPSB7IG1zZzogZS50b1N0cmluZygpIH1cbiAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KGVycm9yKSwge1xuICAgICAgc3RhdHVzOiA1MDAsXG4gICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICB9KVxuICB9XG59KSIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9mdW5jdGlvbnMvaGVsbG8vaW5kZXgudHMKICAgICAgICB0YXJnZXQ6IC9ob21lL2Rlbm8vZnVuY3Rpb25zL2hlbGxvL2luZGV4LnRzCiAgICAgICAgY29udGVudDogIi8vIEZvbGxvdyB0aGlzIHNldHVwIGd1aWRlIHRvIGludGVncmF0ZSB0aGUgRGVubyBsYW5ndWFnZSBzZXJ2ZXIgd2l0aCB5b3VyIGVkaXRvcjpcbi8vIGh0dHBzOi8vZGVuby5sYW5kL21hbnVhbC9nZXR0aW5nX3N0YXJ0ZWQvc2V0dXBfeW91cl9lbnZpcm9ubWVudFxuLy8gVGhpcyBlbmFibGVzIGF1dG9jb21wbGV0ZSwgZ28gdG8gZGVmaW5pdGlvbiwgZXRjLlxuXG5pbXBvcnQgeyBzZXJ2ZSB9IGZyb20gXCJodHRwczovL2Rlbm8ubGFuZC9zdGRAMC4xNzcuMS9odHRwL3NlcnZlci50c1wiXG5cbnNlcnZlKGFzeW5jICgpID0+IHtcbiAgcmV0dXJuIG5ldyBSZXNwb25zZShcbiAgICBgXCJIZWxsbyBmcm9tIEVkZ2UgRnVuY3Rpb25zIVwiYCxcbiAgICB7IGhlYWRlcnM6IHsgXCJDb250ZW50LVR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIgfSB9LFxuICApXG59KVxuXG4vLyBUbyBpbnZva2U6XG4vLyBjdXJsICdodHRwOi8vbG9jYWxob3N0OjxLT05HX0hUVFBfUE9SVD4vZnVuY3Rpb25zL3YxL2hlbGxvJyBcXFxuLy8gICAtLWhlYWRlciAnQXV0aG9yaXphdGlvbjogQmVhcmVyIDxhbm9uL3NlcnZpY2Vfcm9sZSBBUEkga2V5PidcbiIKICAgIGNvbW1hbmQ6CiAgICAgIC0gc3RhcnQKICAgICAgLSAnLS1tYWluLXNlcnZpY2UnCiAgICAgIC0gL2hvbWUvZGVuby9mdW5jdGlvbnMvbWFpbgogIHN1cGFiYXNlLXN1cGF2aXNvcjoKICAgIGltYWdlOiAnc3VwYWJhc2Uvc3VwYXZpc29yOjIuNS4xJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctc1NmTCcKICAgICAgICAtICctbycKICAgICAgICAtIC9kZXYvbnVsbAogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6NDAwMC9hcGkvaGVhbHRoJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMTAKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHN1cGFiYXNlLWFuYWx5dGljczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gUE9PTEVSX1RFTkFOVF9JRD1kZXZfdGVuYW50CiAgICAgIC0gUE9PTEVSX1BPT0xfTU9ERT10cmFuc2FjdGlvbgogICAgICAtICdQT09MRVJfREVGQVVMVF9QT09MX1NJWkU9JHtQT09MRVJfREVGQVVMVF9QT09MX1NJWkU6LTIwfScKICAgICAgLSAnUE9PTEVSX01BWF9DTElFTlRfQ09OTj0ke1BPT0xFUl9NQVhfQ0xJRU5UX0NPTk46LTEwMH0nCiAgICAgIC0gUE9SVD00MDAwCiAgICAgIC0gJ1BPU1RHUkVTX1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSAnUE9TVEdSRVNfSE9TVE5BTUU9JHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1lY3RvOi8vc3VwYWJhc2VfYWRtaW46JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUAke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn06JHtQT1NUR1JFU19QT1JUOi01NDMyfS9fc3VwYWJhc2UnCiAgICAgIC0gQ0xVU1RFUl9QT1NUR1JFUz10cnVlCiAgICAgIC0gJ1NFQ1JFVF9LRVlfQkFTRT0ke1NFUlZJQ0VfUEFTU1dPUkRfU1VQQVZJU09SU0VDUkVUfScKICAgICAgLSAnVkFVTFRfRU5DX0tFWT0ke1NFUlZJQ0VfUEFTU1dPUkRfVkFVTFRFTkN9JwogICAgICAtICdBUElfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSAnTUVUUklDU19KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtIFJFR0lPTj1sb2NhbAogICAgICAtICdFUkxfQUZMQUdTPS1wcm90b19kaXN0IGluZXRfdGNwJwogICAgY29tbWFuZDoKICAgICAgLSAvYmluL3NoCiAgICAgIC0gJy1jJwogICAgICAtICcvYXBwL2Jpbi9taWdyYXRlICYmIC9hcHAvYmluL3N1cGF2aXNvciBldmFsICIkJChjYXQgL2V0Yy9wb29sZXIvcG9vbGVyLmV4cykiICYmIC9hcHAvYmluL3NlcnZlcicKICAgIHZvbHVtZXM6CiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvcG9vbGVyL3Bvb2xlci5leHMKICAgICAgICB0YXJnZXQ6IC9ldGMvcG9vbGVyL3Bvb2xlci5leHMKICAgICAgICBjb250ZW50OiAiezpvaywgX30gPSBBcHBsaWNhdGlvbi5lbnN1cmVfYWxsX3N0YXJ0ZWQoOnN1cGF2aXNvcilcbns6b2ssIHZlcnNpb259ID1cbiAgICBjYXNlIFN1cGF2aXNvci5SZXBvLnF1ZXJ5IShcInNlbGVjdCB2ZXJzaW9uKClcIikgZG9cbiAgICAle3Jvd3M6IFtbdmVyXV19IC0+IFN1cGF2aXNvci5IZWxwZXJzLnBhcnNlX3BnX3ZlcnNpb24odmVyKVxuICAgIF8gLT4gbmlsXG4gICAgZW5kXG5wYXJhbXMgPSAle1xuICAgIFwiZXh0ZXJuYWxfaWRcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPT0xFUl9URU5BTlRfSURcIiksXG4gICAgXCJkYl9ob3N0XCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT1NUR1JFU19IT1NUTkFNRVwiKSxcbiAgICBcImRiX3BvcnRcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPU1RHUkVTX1BPUlRcIikgfD4gU3RyaW5nLnRvX2ludGVnZXIoKSxcbiAgICBcImRiX2RhdGFiYXNlXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT1NUR1JFU19EQlwiKSxcbiAgICBcInJlcXVpcmVfdXNlclwiID0+IGZhbHNlLFxuICAgIFwiYXV0aF9xdWVyeVwiID0+IFwiU0VMRUNUICogRlJPTSBwZ2JvdW5jZXIuZ2V0X2F1dGgoJDEpXCIsXG4gICAgXCJkZWZhdWx0X21heF9jbGllbnRzXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT09MRVJfTUFYX0NMSUVOVF9DT05OXCIpLFxuICAgIFwiZGVmYXVsdF9wb29sX3NpemVcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPT0xFUl9ERUZBVUxUX1BPT0xfU0laRVwiKSxcbiAgICBcImRlZmF1bHRfcGFyYW1ldGVyX3N0YXR1c1wiID0+ICV7XCJzZXJ2ZXJfdmVyc2lvblwiID0+IHZlcnNpb259LFxuICAgIFwidXNlcnNcIiA9PiBbJXtcbiAgICBcImRiX3VzZXJcIiA9PiBcInBnYm91bmNlclwiLFxuICAgIFwiZGJfcGFzc3dvcmRcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPU1RHUkVTX1BBU1NXT1JEXCIpLFxuICAgIFwibW9kZV90eXBlXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT09MRVJfUE9PTF9NT0RFXCIpLFxuICAgIFwicG9vbF9zaXplXCIgPT4gU3lzdGVtLmdldF9lbnYoXCJQT09MRVJfREVGQVVMVF9QT09MX1NJWkVcIiksXG4gICAgXCJpc19tYW5hZ2VyXCIgPT4gdHJ1ZVxuICAgIH1dXG59XG5cbnRlbmFudCA9IFN1cGF2aXNvci5UZW5hbnRzLmdldF90ZW5hbnRfYnlfZXh0ZXJuYWxfaWQocGFyYW1zW1wiZXh0ZXJuYWxfaWRcIl0pXG5cbmlmIHRlbmFudCBkb1xuICB7Om9rLCBffSA9IFN1cGF2aXNvci5UZW5hbnRzLnVwZGF0ZV90ZW5hbnQodGVuYW50LCBwYXJhbXMpXG5lbHNlXG4gIHs6b2ssIF99ID0gU3VwYXZpc29yLlRlbmFudHMuY3JlYXRlX3RlbmFudChwYXJhbXMpXG5lbmRcbiIK", + "compose": "c2VydmljZXM6CiAgc3VwYWJhc2Uta29uZzoKICAgIGltYWdlOiAna29uZzoyLjguMScKICAgIGVudHJ5cG9pbnQ6ICdiYXNoIC1jICcnZXZhbCAiZWNobyBcIiQkKGNhdCB+L3RlbXAueW1sKVwiIiA+IH4va29uZy55bWwgJiYgL2RvY2tlci1lbnRyeXBvaW50LnNoIGtvbmcgZG9ja2VyLXN0YXJ0JycnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9TVVBBQkFTRUtPTkdfODAwMAogICAgICAtICdLT05HX1BPUlRfTUFQUz00NDM6ODAwMCcKICAgICAgLSAnSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSBLT05HX0RBVEFCQVNFPW9mZgogICAgICAtIEtPTkdfREVDTEFSQVRJVkVfQ09ORklHPS9ob21lL2tvbmcva29uZy55bWwKICAgICAgLSAnS09OR19ETlNfT1JERVI9TEFTVCxBLENOQU1FJwogICAgICAtICdLT05HX1BMVUdJTlM9cmVxdWVzdC10cmFuc2Zvcm1lcixjb3JzLGtleS1hdXRoLGFjbCxiYXNpYy1hdXRoJwogICAgICAtIEtPTkdfTkdJTlhfUFJPWFlfUFJPWFlfQlVGRkVSX1NJWkU9MTYwawogICAgICAtICdLT05HX05HSU5YX1BST1hZX1BST1hZX0JVRkZFUlM9NjQgMTYwaycKICAgICAgLSAnU1VQQUJBU0VfQU5PTl9LRVk9JHtTRVJWSUNFX1NVUEFCQVNFQU5PTl9LRVl9JwogICAgICAtICdTVVBBQkFTRV9TRVJWSUNFX0tFWT0ke1NFUlZJQ0VfU1VQQUJBU0VTRVJWSUNFX0tFWX0nCiAgICAgIC0gJ0RBU0hCT0FSRF9VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9BRE1JTn0nCiAgICAgIC0gJ0RBU0hCT0FSRF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfQURNSU59JwogICAgdm9sdW1lczoKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9hcGkva29uZy55bWwKICAgICAgICB0YXJnZXQ6IC9ob21lL2tvbmcvdGVtcC55bWwKICAgICAgICBjb250ZW50OiAiX2Zvcm1hdF92ZXJzaW9uOiAnMi4xJ1xuX3RyYW5zZm9ybTogdHJ1ZVxuXG4jIyNcbiMjIyBDb25zdW1lcnMgLyBVc2Vyc1xuIyMjXG5jb25zdW1lcnM6XG4gIC0gdXNlcm5hbWU6IERBU0hCT0FSRFxuICAtIHVzZXJuYW1lOiBhbm9uXG4gICAga2V5YXV0aF9jcmVkZW50aWFsczpcbiAgICAgIC0ga2V5OiAkU1VQQUJBU0VfQU5PTl9LRVlcbiAgLSB1c2VybmFtZTogc2VydmljZV9yb2xlXG4gICAga2V5YXV0aF9jcmVkZW50aWFsczpcbiAgICAgIC0ga2V5OiAkU1VQQUJBU0VfU0VSVklDRV9LRVlcblxuIyMjXG4jIyMgQWNjZXNzIENvbnRyb2wgTGlzdFxuIyMjXG5hY2xzOlxuICAtIGNvbnN1bWVyOiBhbm9uXG4gICAgZ3JvdXA6IGFub25cbiAgLSBjb25zdW1lcjogc2VydmljZV9yb2xlXG4gICAgZ3JvdXA6IGFkbWluXG5cbiMjI1xuIyMjIERhc2hib2FyZCBjcmVkZW50aWFsc1xuIyMjXG5iYXNpY2F1dGhfY3JlZGVudGlhbHM6XG4tIGNvbnN1bWVyOiBEQVNIQk9BUkRcbiAgdXNlcm5hbWU6ICREQVNIQk9BUkRfVVNFUk5BTUVcbiAgcGFzc3dvcmQ6ICREQVNIQk9BUkRfUEFTU1dPUkRcblxuXG4jIyNcbiMjIyBBUEkgUm91dGVzXG4jIyNcbnNlcnZpY2VzOlxuXG4gICMjIE9wZW4gQXV0aCByb3V0ZXNcbiAgLSBuYW1lOiBhdXRoLXYxLW9wZW5cbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1hdXRoOjk5OTkvdmVyaWZ5XG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBhdXRoLXYxLW9wZW5cbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9hdXRoL3YxL3ZlcmlmeVxuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgLSBuYW1lOiBhdXRoLXYxLW9wZW4tY2FsbGJhY2tcbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1hdXRoOjk5OTkvY2FsbGJhY2tcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGF1dGgtdjEtb3Blbi1jYWxsYmFja1xuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2F1dGgvdjEvY2FsbGJhY2tcbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gIC0gbmFtZTogYXV0aC12MS1vcGVuLWF1dGhvcml6ZVxuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS9hdXRob3JpemVcbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGF1dGgtdjEtb3Blbi1hdXRob3JpemVcbiAgICAgICAgc3RyaXBfcGF0aDogdHJ1ZVxuICAgICAgICBwYXRoczpcbiAgICAgICAgICAtIC9hdXRoL3YxL2F1dGhvcml6ZVxuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcblxuICAjIyBTZWN1cmUgQXV0aCByb3V0ZXNcbiAgLSBuYW1lOiBhdXRoLXYxXG4gICAgX2NvbW1lbnQ6ICdHb1RydWU6IC9hdXRoL3YxLyogLT4gaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWF1dGg6OTk5OS9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IGF1dGgtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvYXV0aC92MS9cbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gICAgICAtIG5hbWU6IGtleS1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiBmYWxzZVxuICAgICAgLSBuYW1lOiBhY2xcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfZ3JvdXBzX2hlYWRlcjogdHJ1ZVxuICAgICAgICAgIGFsbG93OlxuICAgICAgICAgICAgLSBhZG1pblxuICAgICAgICAgICAgLSBhbm9uXG5cbiAgIyMgU2VjdXJlIFJFU1Qgcm91dGVzXG4gIC0gbmFtZTogcmVzdC12MVxuICAgIF9jb21tZW50OiAnUG9zdGdSRVNUOiAvcmVzdC92MS8qIC0+IGh0dHA6Ly9zdXBhYmFzZS1yZXN0OjMwMDAvKidcbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1yZXN0OjMwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiByZXN0LXYxLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL3Jlc3QvdjEvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAgICAgLSBuYW1lOiBrZXktYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogdHJ1ZVxuICAgICAgLSBuYW1lOiBhY2xcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfZ3JvdXBzX2hlYWRlcjogdHJ1ZVxuICAgICAgICAgIGFsbG93OlxuICAgICAgICAgICAgLSBhZG1pblxuICAgICAgICAgICAgLSBhbm9uXG5cbiAgIyMgU2VjdXJlIEdyYXBoUUwgcm91dGVzXG4gIC0gbmFtZTogZ3JhcGhxbC12MVxuICAgIF9jb21tZW50OiAnUG9zdGdSRVNUOiAvZ3JhcGhxbC92MS8qIC0+IGh0dHA6Ly9zdXBhYmFzZS1yZXN0OjMwMDAvcnBjL2dyYXBocWwnXG4gICAgdXJsOiBodHRwOi8vc3VwYWJhc2UtcmVzdDozMDAwL3JwYy9ncmFwaHFsXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBncmFwaHFsLXYxLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2dyYXBocWwvdjFcbiAgICBwbHVnaW5zOlxuICAgICAgLSBuYW1lOiBjb3JzXG4gICAgICAtIG5hbWU6IGtleS1hdXRoXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2NyZWRlbnRpYWxzOiB0cnVlXG4gICAgICAtIG5hbWU6IHJlcXVlc3QtdHJhbnNmb3JtZXJcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGFkZDpcbiAgICAgICAgICAgIGhlYWRlcnM6XG4gICAgICAgICAgICAgIC0gQ29udGVudC1Qcm9maWxlOmdyYXBocWxfcHVibGljXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG4gICAgICAgICAgICAtIGFub25cblxuICAjIyBTZWN1cmUgUmVhbHRpbWUgcm91dGVzXG4gIC0gbmFtZTogcmVhbHRpbWUtdjEtd3NcbiAgICBfY29tbWVudDogJ1JlYWx0aW1lOiAvcmVhbHRpbWUvdjEvKiAtPiB3czovL3JlYWx0aW1lOjQwMDAvc29ja2V0LyonXG4gICAgdXJsOiBodHRwOi8vcmVhbHRpbWUtZGV2OjQwMDAvc29ja2V0XG4gICAgcHJvdG9jb2w6IHdzXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiByZWFsdGltZS12MS13c1xuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL3JlYWx0aW1lL3YxL1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgICAgIC0gbmFtZToga2V5LWF1dGhcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfY3JlZGVudGlhbHM6IGZhbHNlXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG4gICAgICAgICAgICAtIGFub25cbiAgLSBuYW1lOiByZWFsdGltZS12MS1yZXN0XG4gICAgX2NvbW1lbnQ6ICdSZWFsdGltZTogL3JlYWx0aW1lL3YxLyogLT4gd3M6Ly9yZWFsdGltZTo0MDAwL3NvY2tldC8qJ1xuICAgIHVybDogaHR0cDovL3JlYWx0aW1lLWRldjo0MDAwL2FwaVxuICAgIHByb3RvY29sOiBodHRwXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiByZWFsdGltZS12MS1yZXN0XG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvcmVhbHRpbWUvdjEvYXBpXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuICAgICAgLSBuYW1lOiBrZXktYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogZmFsc2VcbiAgICAgIC0gbmFtZTogYWNsXG4gICAgICAgIGNvbmZpZzpcbiAgICAgICAgICBoaWRlX2dyb3Vwc19oZWFkZXI6IHRydWVcbiAgICAgICAgICBhbGxvdzpcbiAgICAgICAgICAgIC0gYWRtaW5cbiAgICAgICAgICAgIC0gYW5vblxuXG4gICMjIFN0b3JhZ2Ugcm91dGVzOiB0aGUgc3RvcmFnZSBzZXJ2ZXIgbWFuYWdlcyBpdHMgb3duIGF1dGhcbiAgLSBuYW1lOiBzdG9yYWdlLXYxXG4gICAgX2NvbW1lbnQ6ICdTdG9yYWdlOiAvc3RvcmFnZS92MS8qIC0+IGh0dHA6Ly9zdXBhYmFzZS1zdG9yYWdlOjUwMDAvKidcbiAgICB1cmw6IGh0dHA6Ly9zdXBhYmFzZS1zdG9yYWdlOjUwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBzdG9yYWdlLXYxLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL3N0b3JhZ2UvdjEvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZTogY29yc1xuXG4gICMjIEVkZ2UgRnVuY3Rpb25zIHJvdXRlc1xuICAtIG5hbWU6IGZ1bmN0aW9ucy12MVxuICAgIF9jb21tZW50OiAnRWRnZSBGdW5jdGlvbnM6IC9mdW5jdGlvbnMvdjEvKiAtPiBodHRwOi8vc3VwYWJhc2UtZWRnZS1mdW5jdGlvbnM6OTAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWVkZ2UtZnVuY3Rpb25zOjkwMDAvXG4gICAgcm91dGVzOlxuICAgICAgLSBuYW1lOiBmdW5jdGlvbnMtdjEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvZnVuY3Rpb25zL3YxL1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcblxuICAjIyBBbmFseXRpY3Mgcm91dGVzXG4gIC0gbmFtZTogYW5hbHl0aWNzLXYxXG4gICAgX2NvbW1lbnQ6ICdBbmFseXRpY3M6IC9hbmFseXRpY3MvdjEvKiAtPiBodHRwOi8vbG9nZmxhcmU6NDAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogYW5hbHl0aWNzLXYxLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL2FuYWx5dGljcy92MS9cblxuICAjIyBTZWN1cmUgRGF0YWJhc2Ugcm91dGVzXG4gIC0gbmFtZTogbWV0YVxuICAgIF9jb21tZW50OiAncGctbWV0YTogL3BnLyogLT4gaHR0cDovL3N1cGFiYXNlLW1ldGE6ODA4MC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLW1ldGE6ODA4MC9cbiAgICByb3V0ZXM6XG4gICAgICAtIG5hbWU6IG1ldGEtYWxsXG4gICAgICAgIHN0cmlwX3BhdGg6IHRydWVcbiAgICAgICAgcGF0aHM6XG4gICAgICAgICAgLSAvcGcvXG4gICAgcGx1Z2luczpcbiAgICAgIC0gbmFtZToga2V5LWF1dGhcbiAgICAgICAgY29uZmlnOlxuICAgICAgICAgIGhpZGVfY3JlZGVudGlhbHM6IGZhbHNlXG4gICAgICAtIG5hbWU6IGFjbFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9ncm91cHNfaGVhZGVyOiB0cnVlXG4gICAgICAgICAgYWxsb3c6XG4gICAgICAgICAgICAtIGFkbWluXG5cbiAgIyMgUHJvdGVjdGVkIERhc2hib2FyZCAtIGNhdGNoIGFsbCByZW1haW5pbmcgcm91dGVzXG4gIC0gbmFtZTogZGFzaGJvYXJkXG4gICAgX2NvbW1lbnQ6ICdTdHVkaW86IC8qIC0+IGh0dHA6Ly9zdHVkaW86MzAwMC8qJ1xuICAgIHVybDogaHR0cDovL3N1cGFiYXNlLXN0dWRpbzozMDAwL1xuICAgIHJvdXRlczpcbiAgICAgIC0gbmFtZTogZGFzaGJvYXJkLWFsbFxuICAgICAgICBzdHJpcF9wYXRoOiB0cnVlXG4gICAgICAgIHBhdGhzOlxuICAgICAgICAgIC0gL1xuICAgIHBsdWdpbnM6XG4gICAgICAtIG5hbWU6IGNvcnNcbiAgICAgIC0gbmFtZTogYmFzaWMtYXV0aFxuICAgICAgICBjb25maWc6XG4gICAgICAgICAgaGlkZV9jcmVkZW50aWFsczogdHJ1ZVxuIgogIHN1cGFiYXNlLXN0dWRpbzoKICAgIGltYWdlOiAnc3VwYWJhc2Uvc3R1ZGlvOjIwMjYuMDEuMDctc2hhLTAzN2U1ZjknCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gbm9kZQogICAgICAgIC0gJy1lJwogICAgICAgIC0gImZldGNoKCdodHRwOi8vMTI3LjAuMC4xOjMwMDAvYXBpL3BsYXRmb3JtL3Byb2ZpbGUnKS50aGVuKChyKSA9PiB7aWYgKHIuc3RhdHVzICE9PSAyMDApIHRocm93IG5ldyBFcnJvcihyLnN0YXR1cyl9KSIKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWFuYWx5dGljczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gSE9TVE5BTUU9MC4wLjAuMAogICAgICAtICdTVFVESU9fUEdfTUVUQV9VUkw9aHR0cDovL3N1cGFiYXNlLW1ldGE6ODA4MCcKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfSE9TVD0ke1BPU1RHUkVTX0hPU1Q6LXN1cGFiYXNlLWRifScKICAgICAgLSBDVVJSRU5UX0NMSV9WRVJTSU9OPTIuNjcuMQogICAgICAtICdERUZBVUxUX09SR0FOSVpBVElPTl9OQU1FPSR7U1RVRElPX0RFRkFVTFRfT1JHQU5JWkFUSU9OOi1EZWZhdWx0IE9yZ2FuaXphdGlvbn0nCiAgICAgIC0gJ0RFRkFVTFRfUFJPSkVDVF9OQU1FPSR7U1RVRElPX0RFRkFVTFRfUFJPSkVDVDotRGVmYXVsdCBQcm9qZWN0fScKICAgICAgLSAnU1VQQUJBU0VfVVJMPWh0dHA6Ly9zdXBhYmFzZS1rb25nOjgwMDAnCiAgICAgIC0gJ1NVUEFCQVNFX1BVQkxJQ19VUkw9JHtTRVJWSUNFX0ZRRE5fU1VQQUJBU0VLT05HfScKICAgICAgLSAnU1VQQUJBU0VfQU5PTl9LRVk9JHtTRVJWSUNFX1NVUEFCQVNFQU5PTl9LRVl9JwogICAgICAtICdTVVBBQkFTRV9TRVJWSUNFX0tFWT0ke1NFUlZJQ0VfU1VQQUJBU0VTRVJWSUNFX0tFWX0nCiAgICAgIC0gJ0FVVEhfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSAnTE9HRkxBUkVfQVBJX0tFWT0ke1NFUlZJQ0VfUEFTU1dPUkRfTE9HRkxBUkV9JwogICAgICAtICdMT0dGTEFSRV9VUkw9aHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwJwogICAgICAtICdTVVBBQkFTRV9QVUJMSUNfQVBJPSR7U0VSVklDRV9GUUROX1NVUEFCQVNFS09OR30nCiAgICAgIC0gTkVYVF9QVUJMSUNfRU5BQkxFX0xPR1M9dHJ1ZQogICAgICAtIE5FWFRfQU5BTFlUSUNTX0JBQ0tFTkRfUFJPVklERVI9cG9zdGdyZXMKICAgICAgLSAnT1BFTkFJX0FQSV9LRVk9JHtPUEVOQUlfQVBJX0tFWX0nCiAgc3VwYWJhc2UtZGI6CiAgICBpbWFnZTogJ3N1cGFiYXNlL3Bvc3RncmVzOjE1LjguMS4wNDgnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDogJ3BnX2lzcmVhZHkgLVUgcG9zdGdyZXMgLWggMTI3LjAuMC4xJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTAKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLXZlY3RvcjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgY29tbWFuZDoKICAgICAgLSBwb3N0Z3JlcwogICAgICAtICctYycKICAgICAgLSBjb25maWdfZmlsZT0vZXRjL3Bvc3RncmVzcWwvcG9zdGdyZXNxbC5jb25mCiAgICAgIC0gJy1jJwogICAgICAtIGxvZ19taW5fbWVzc2FnZXM9ZmF0YWwKICAgIGVudmlyb25tZW50OgogICAgICAtIFBPU1RHUkVTX0hPU1Q9L3Zhci9ydW4vcG9zdGdyZXNxbAogICAgICAtICdQR1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSAnUE9TVEdSRVNfUE9SVD0ke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9JwogICAgICAtICdQR1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BHREFUQUJBU0U9JHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc30nCiAgICAgIC0gJ0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gJ0pXVF9FWFA9JHtKV1RfRVhQSVJZOi0zNjAwfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3N1cGFiYXNlLWRiLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2RiL3JlYWx0aW1lLnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL21pZ3JhdGlvbnMvOTktcmVhbHRpbWUuc3FsCiAgICAgICAgY29udGVudDogIlxcc2V0IHBndXNlciBgZWNobyBcInN1cGFiYXNlX2FkbWluXCJgXG5cbmNyZWF0ZSBzY2hlbWEgaWYgbm90IGV4aXN0cyBfcmVhbHRpbWU7XG5hbHRlciBzY2hlbWEgX3JlYWx0aW1lIG93bmVyIHRvIDpwZ3VzZXI7XG4iCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZGIvX3N1cGFiYXNlLnNxbAogICAgICAgIHRhcmdldDogL2RvY2tlci1lbnRyeXBvaW50LWluaXRkYi5kL21pZ3JhdGlvbnMvOTctX3N1cGFiYXNlLnNxbAogICAgICAgIGNvbnRlbnQ6ICJcXHNldCBwZ3VzZXIgYGVjaG8gXCIkUE9TVEdSRVNfVVNFUlwiYFxuXG5DUkVBVEUgREFUQUJBU0UgX3N1cGFiYXNlIFdJVEggT1dORVIgOnBndXNlcjtcbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi9wb29sZXIuc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvbWlncmF0aW9ucy85OS1wb29sZXIuc3FsCiAgICAgICAgY29udGVudDogIlxcc2V0IHBndXNlciBgZWNobyBcInN1cGFiYXNlX2FkbWluXCJgXG5cXGMgX3N1cGFiYXNlXG5jcmVhdGUgc2NoZW1hIGlmIG5vdCBleGlzdHMgX3N1cGF2aXNvcjtcbmFsdGVyIHNjaGVtYSBfc3VwYXZpc29yIG93bmVyIHRvIDpwZ3VzZXI7XG5cXGMgcG9zdGdyZXNcbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi93ZWJob29rcy5zcWwKICAgICAgICB0YXJnZXQ6IC9kb2NrZXItZW50cnlwb2ludC1pbml0ZGIuZC9pbml0LXNjcmlwdHMvOTgtd2ViaG9va3Muc3FsCiAgICAgICAgY29udGVudDogIkJFR0lOO1xuLS0gQ3JlYXRlIHBnX25ldCBleHRlbnNpb25cbkNSRUFURSBFWFRFTlNJT04gSUYgTk9UIEVYSVNUUyBwZ19uZXQgU0NIRU1BIGV4dGVuc2lvbnM7XG4tLSBDcmVhdGUgc3VwYWJhc2VfZnVuY3Rpb25zIHNjaGVtYVxuQ1JFQVRFIFNDSEVNQSBzdXBhYmFzZV9mdW5jdGlvbnMgQVVUSE9SSVpBVElPTiBzdXBhYmFzZV9hZG1pbjtcbkdSQU5UIFVTQUdFIE9OIFNDSEVNQSBzdXBhYmFzZV9mdW5jdGlvbnMgVE8gcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbkFMVEVSIERFRkFVTFQgUFJJVklMRUdFUyBJTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIEdSQU5UIEFMTCBPTiBUQUJMRVMgVE8gcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbkFMVEVSIERFRkFVTFQgUFJJVklMRUdFUyBJTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIEdSQU5UIEFMTCBPTiBGVU5DVElPTlMgVE8gcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbkFMVEVSIERFRkFVTFQgUFJJVklMRUdFUyBJTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIEdSQU5UIEFMTCBPTiBTRVFVRU5DRVMgVE8gcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbi0tIHN1cGFiYXNlX2Z1bmN0aW9ucy5taWdyYXRpb25zIGRlZmluaXRpb25cbkNSRUFURSBUQUJMRSBzdXBhYmFzZV9mdW5jdGlvbnMubWlncmF0aW9ucyAoXG4gIHZlcnNpb24gdGV4dCBQUklNQVJZIEtFWSxcbiAgaW5zZXJ0ZWRfYXQgdGltZXN0YW1wdHogTk9UIE5VTEwgREVGQVVMVCBOT1coKVxuKTtcbi0tIEluaXRpYWwgc3VwYWJhc2VfZnVuY3Rpb25zIG1pZ3JhdGlvblxuSU5TRVJUIElOVE8gc3VwYWJhc2VfZnVuY3Rpb25zLm1pZ3JhdGlvbnMgKHZlcnNpb24pIFZBTFVFUyAoJ2luaXRpYWwnKTtcbi0tIHN1cGFiYXNlX2Z1bmN0aW9ucy5ob29rcyBkZWZpbml0aW9uXG5DUkVBVEUgVEFCTEUgc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzIChcbiAgaWQgYmlnc2VyaWFsIFBSSU1BUlkgS0VZLFxuICBob29rX3RhYmxlX2lkIGludGVnZXIgTk9UIE5VTEwsXG4gIGhvb2tfbmFtZSB0ZXh0IE5PVCBOVUxMLFxuICBjcmVhdGVkX2F0IHRpbWVzdGFtcHR6IE5PVCBOVUxMIERFRkFVTFQgTk9XKCksXG4gIHJlcXVlc3RfaWQgYmlnaW50XG4pO1xuQ1JFQVRFIElOREVYIHN1cGFiYXNlX2Z1bmN0aW9uc19ob29rc19yZXF1ZXN0X2lkX2lkeCBPTiBzdXBhYmFzZV9mdW5jdGlvbnMuaG9va3MgVVNJTkcgYnRyZWUgKHJlcXVlc3RfaWQpO1xuQ1JFQVRFIElOREVYIHN1cGFiYXNlX2Z1bmN0aW9uc19ob29rc19oX3RhYmxlX2lkX2hfbmFtZV9pZHggT04gc3VwYWJhc2VfZnVuY3Rpb25zLmhvb2tzIFVTSU5HIGJ0cmVlIChob29rX3RhYmxlX2lkLCBob29rX25hbWUpO1xuQ09NTUVOVCBPTiBUQUJMRSBzdXBhYmFzZV9mdW5jdGlvbnMuaG9va3MgSVMgJ1N1cGFiYXNlIEZ1bmN0aW9ucyBIb29rczogQXVkaXQgdHJhaWwgZm9yIHRyaWdnZXJlZCBob29rcy4nO1xuQ1JFQVRFIEZVTkNUSU9OIHN1cGFiYXNlX2Z1bmN0aW9ucy5odHRwX3JlcXVlc3QoKVxuICBSRVRVUk5TIHRyaWdnZXJcbiAgTEFOR1VBR0UgcGxwZ3NxbFxuICBBUyAkZnVuY3Rpb24kXG4gIERFQ0xBUkVcbiAgICByZXF1ZXN0X2lkIGJpZ2ludDtcbiAgICBwYXlsb2FkIGpzb25iO1xuICAgIHVybCB0ZXh0IDo9IFRHX0FSR1ZbMF06OnRleHQ7XG4gICAgbWV0aG9kIHRleHQgOj0gVEdfQVJHVlsxXTo6dGV4dDtcbiAgICBoZWFkZXJzIGpzb25iIERFRkFVTFQgJ3t9Jzo6anNvbmI7XG4gICAgcGFyYW1zIGpzb25iIERFRkFVTFQgJ3t9Jzo6anNvbmI7XG4gICAgdGltZW91dF9tcyBpbnRlZ2VyIERFRkFVTFQgMTAwMDtcbiAgQkVHSU5cbiAgICBJRiB1cmwgSVMgTlVMTCBPUiB1cmwgPSAnbnVsbCcgVEhFTlxuICAgICAgUkFJU0UgRVhDRVBUSU9OICd1cmwgYXJndW1lbnQgaXMgbWlzc2luZyc7XG4gICAgRU5EIElGO1xuXG4gICAgSUYgbWV0aG9kIElTIE5VTEwgT1IgbWV0aG9kID0gJ251bGwnIFRIRU5cbiAgICAgIFJBSVNFIEVYQ0VQVElPTiAnbWV0aG9kIGFyZ3VtZW50IGlzIG1pc3NpbmcnO1xuICAgIEVORCBJRjtcblxuICAgIElGIFRHX0FSR1ZbMl0gSVMgTlVMTCBPUiBUR19BUkdWWzJdID0gJ251bGwnIFRIRU5cbiAgICAgIGhlYWRlcnMgPSAne1wiQ29udGVudC1UeXBlXCI6IFwiYXBwbGljYXRpb24vanNvblwifSc6Ompzb25iO1xuICAgIEVMU0VcbiAgICAgIGhlYWRlcnMgPSBUR19BUkdWWzJdOjpqc29uYjtcbiAgICBFTkQgSUY7XG5cbiAgICBJRiBUR19BUkdWWzNdIElTIE5VTEwgT1IgVEdfQVJHVlszXSA9ICdudWxsJyBUSEVOXG4gICAgICBwYXJhbXMgPSAne30nOjpqc29uYjtcbiAgICBFTFNFXG4gICAgICBwYXJhbXMgPSBUR19BUkdWWzNdOjpqc29uYjtcbiAgICBFTkQgSUY7XG5cbiAgICBJRiBUR19BUkdWWzRdIElTIE5VTEwgT1IgVEdfQVJHVls0XSA9ICdudWxsJyBUSEVOXG4gICAgICB0aW1lb3V0X21zID0gMTAwMDtcbiAgICBFTFNFXG4gICAgICB0aW1lb3V0X21zID0gVEdfQVJHVls0XTo6aW50ZWdlcjtcbiAgICBFTkQgSUY7XG5cbiAgICBDQVNFXG4gICAgICBXSEVOIG1ldGhvZCA9ICdHRVQnIFRIRU5cbiAgICAgICAgU0VMRUNUIGh0dHBfZ2V0IElOVE8gcmVxdWVzdF9pZCBGUk9NIG5ldC5odHRwX2dldChcbiAgICAgICAgICB1cmwsXG4gICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgdGltZW91dF9tc1xuICAgICAgICApO1xuICAgICAgV0hFTiBtZXRob2QgPSAnUE9TVCcgVEhFTlxuICAgICAgICBwYXlsb2FkID0ganNvbmJfYnVpbGRfb2JqZWN0KFxuICAgICAgICAgICdvbGRfcmVjb3JkJywgT0xELFxuICAgICAgICAgICdyZWNvcmQnLCBORVcsXG4gICAgICAgICAgJ3R5cGUnLCBUR19PUCxcbiAgICAgICAgICAndGFibGUnLCBUR19UQUJMRV9OQU1FLFxuICAgICAgICAgICdzY2hlbWEnLCBUR19UQUJMRV9TQ0hFTUFcbiAgICAgICAgKTtcblxuICAgICAgICBTRUxFQ1QgaHR0cF9wb3N0IElOVE8gcmVxdWVzdF9pZCBGUk9NIG5ldC5odHRwX3Bvc3QoXG4gICAgICAgICAgdXJsLFxuICAgICAgICAgIHBheWxvYWQsXG4gICAgICAgICAgcGFyYW1zLFxuICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgdGltZW91dF9tc1xuICAgICAgICApO1xuICAgICAgRUxTRVxuICAgICAgICBSQUlTRSBFWENFUFRJT04gJ21ldGhvZCBhcmd1bWVudCAlIGlzIGludmFsaWQnLCBtZXRob2Q7XG4gICAgRU5EIENBU0U7XG5cbiAgICBJTlNFUlQgSU5UTyBzdXBhYmFzZV9mdW5jdGlvbnMuaG9va3NcbiAgICAgIChob29rX3RhYmxlX2lkLCBob29rX25hbWUsIHJlcXVlc3RfaWQpXG4gICAgVkFMVUVTXG4gICAgICAoVEdfUkVMSUQsIFRHX05BTUUsIHJlcXVlc3RfaWQpO1xuXG4gICAgUkVUVVJOIE5FVztcbiAgRU5EXG4kZnVuY3Rpb24kO1xuLS0gU3VwYWJhc2Ugc3VwZXIgYWRtaW5cbkRPXG4kJFxuQkVHSU5cbiAgSUYgTk9UIEVYSVNUUyAoXG4gICAgU0VMRUNUIDFcbiAgICBGUk9NIHBnX3JvbGVzXG4gICAgV0hFUkUgcm9sbmFtZSA9ICdzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4nXG4gIClcbiAgVEhFTlxuICAgIENSRUFURSBVU0VSIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiBOT0lOSEVSSVQgQ1JFQVRFUk9MRSBMT0dJTiBOT1JFUExJQ0FUSU9OO1xuICBFTkQgSUY7XG5FTkRcbiQkO1xuR1JBTlQgQUxMIFBSSVZJTEVHRVMgT04gU0NIRU1BIHN1cGFiYXNlX2Z1bmN0aW9ucyBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW47XG5HUkFOVCBBTEwgUFJJVklMRUdFUyBPTiBBTEwgVEFCTEVTIElOIFNDSEVNQSBzdXBhYmFzZV9mdW5jdGlvbnMgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluO1xuR1JBTlQgQUxMIFBSSVZJTEVHRVMgT04gQUxMIFNFUVVFTkNFUyBJTiBTQ0hFTUEgc3VwYWJhc2VfZnVuY3Rpb25zIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbjtcbkFMVEVSIFVTRVIgc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluIFNFVCBzZWFyY2hfcGF0aCA9IFwic3VwYWJhc2VfZnVuY3Rpb25zXCI7XG5BTFRFUiB0YWJsZSBcInN1cGFiYXNlX2Z1bmN0aW9uc1wiLm1pZ3JhdGlvbnMgT1dORVIgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluO1xuQUxURVIgdGFibGUgXCJzdXBhYmFzZV9mdW5jdGlvbnNcIi5ob29rcyBPV05FUiBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW47XG5BTFRFUiBmdW5jdGlvbiBcInN1cGFiYXNlX2Z1bmN0aW9uc1wiLmh0dHBfcmVxdWVzdCgpIE9XTkVSIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbjtcbkdSQU5UIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiBUTyBwb3N0Z3Jlcztcbi0tIFJlbW92ZSB1bnVzZWQgc3VwYWJhc2VfcGdfbmV0X2FkbWluIHJvbGVcbkRPXG4kJFxuQkVHSU5cbiAgSUYgRVhJU1RTIChcbiAgICBTRUxFQ1QgMVxuICAgIEZST00gcGdfcm9sZXNcbiAgICBXSEVSRSByb2xuYW1lID0gJ3N1cGFiYXNlX3BnX25ldF9hZG1pbidcbiAgKVxuICBUSEVOXG4gICAgUkVBU1NJR04gT1dORUQgQlkgc3VwYWJhc2VfcGdfbmV0X2FkbWluIFRPIHN1cGFiYXNlX2FkbWluO1xuICAgIERST1AgT1dORUQgQlkgc3VwYWJhc2VfcGdfbmV0X2FkbWluO1xuICAgIERST1AgUk9MRSBzdXBhYmFzZV9wZ19uZXRfYWRtaW47XG4gIEVORCBJRjtcbkVORFxuJCQ7XG4tLSBwZ19uZXQgZ3JhbnRzIHdoZW4gZXh0ZW5zaW9uIGlzIGFscmVhZHkgZW5hYmxlZFxuRE9cbiQkXG5CRUdJTlxuICBJRiBFWElTVFMgKFxuICAgIFNFTEVDVCAxXG4gICAgRlJPTSBwZ19leHRlbnNpb25cbiAgICBXSEVSRSBleHRuYW1lID0gJ3BnX25ldCdcbiAgKVxuICBUSEVOXG4gICAgR1JBTlQgVVNBR0UgT04gU0NIRU1BIG5ldCBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4sIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4gICAgQUxURVIgZnVuY3Rpb24gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFNFQ1VSSVRZIERFRklORVI7XG4gICAgQUxURVIgZnVuY3Rpb24gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRUNVUklUWSBERUZJTkVSO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRVQgc2VhcmNoX3BhdGggPSBuZXQ7XG4gICAgQUxURVIgZnVuY3Rpb24gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRVQgc2VhcmNoX3BhdGggPSBuZXQ7XG4gICAgUkVWT0tFIEFMTCBPTiBGVU5DVElPTiBuZXQuaHR0cF9nZXQodXJsIHRleHQsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgRlJPTSBQVUJMSUM7XG4gICAgUkVWT0tFIEFMTCBPTiBGVU5DVElPTiBuZXQuaHR0cF9wb3N0KHVybCB0ZXh0LCBib2R5IGpzb25iLCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIEZST00gUFVCTElDO1xuICAgIEdSQU5UIEVYRUNVVEUgT04gRlVOQ1RJT04gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiwgcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbiAgICBHUkFOVCBFWEVDVVRFIE9OIEZVTkNUSU9OIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluLCBwb3N0Z3JlcywgYW5vbiwgYXV0aGVudGljYXRlZCwgc2VydmljZV9yb2xlO1xuICBFTkQgSUY7XG5FTkRcbiQkO1xuLS0gRXZlbnQgdHJpZ2dlciBmb3IgcGdfbmV0XG5DUkVBVEUgT1IgUkVQTEFDRSBGVU5DVElPTiBleHRlbnNpb25zLmdyYW50X3BnX25ldF9hY2Nlc3MoKVxuUkVUVVJOUyBldmVudF90cmlnZ2VyXG5MQU5HVUFHRSBwbHBnc3FsXG5BUyAkJFxuQkVHSU5cbiAgSUYgRVhJU1RTIChcbiAgICBTRUxFQ1QgMVxuICAgIEZST00gcGdfZXZlbnRfdHJpZ2dlcl9kZGxfY29tbWFuZHMoKSBBUyBldlxuICAgIEpPSU4gcGdfZXh0ZW5zaW9uIEFTIGV4dFxuICAgIE9OIGV2Lm9iamlkID0gZXh0Lm9pZFxuICAgIFdIRVJFIGV4dC5leHRuYW1lID0gJ3BnX25ldCdcbiAgKVxuICBUSEVOXG4gICAgR1JBTlQgVVNBR0UgT04gU0NIRU1BIG5ldCBUTyBzdXBhYmFzZV9mdW5jdGlvbnNfYWRtaW4sIHBvc3RncmVzLCBhbm9uLCBhdXRoZW50aWNhdGVkLCBzZXJ2aWNlX3JvbGU7XG4gICAgQUxURVIgZnVuY3Rpb24gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFNFQ1VSSVRZIERFRklORVI7XG4gICAgQUxURVIgZnVuY3Rpb24gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRUNVUklUWSBERUZJTkVSO1xuICAgIEFMVEVSIGZ1bmN0aW9uIG5ldC5odHRwX2dldCh1cmwgdGV4dCwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRVQgc2VhcmNoX3BhdGggPSBuZXQ7XG4gICAgQUxURVIgZnVuY3Rpb24gbmV0Lmh0dHBfcG9zdCh1cmwgdGV4dCwgYm9keSBqc29uYiwgcGFyYW1zIGpzb25iLCBoZWFkZXJzIGpzb25iLCB0aW1lb3V0X21pbGxpc2Vjb25kcyBpbnRlZ2VyKSBTRVQgc2VhcmNoX3BhdGggPSBuZXQ7XG4gICAgUkVWT0tFIEFMTCBPTiBGVU5DVElPTiBuZXQuaHR0cF9nZXQodXJsIHRleHQsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgRlJPTSBQVUJMSUM7XG4gICAgUkVWT0tFIEFMTCBPTiBGVU5DVElPTiBuZXQuaHR0cF9wb3N0KHVybCB0ZXh0LCBib2R5IGpzb25iLCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIEZST00gUFVCTElDO1xuICAgIEdSQU5UIEVYRUNVVEUgT04gRlVOQ1RJT04gbmV0Lmh0dHBfZ2V0KHVybCB0ZXh0LCBwYXJhbXMganNvbmIsIGhlYWRlcnMganNvbmIsIHRpbWVvdXRfbWlsbGlzZWNvbmRzIGludGVnZXIpIFRPIHN1cGFiYXNlX2Z1bmN0aW9uc19hZG1pbiwgcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbiAgICBHUkFOVCBFWEVDVVRFIE9OIEZVTkNUSU9OIG5ldC5odHRwX3Bvc3QodXJsIHRleHQsIGJvZHkganNvbmIsIHBhcmFtcyBqc29uYiwgaGVhZGVycyBqc29uYiwgdGltZW91dF9taWxsaXNlY29uZHMgaW50ZWdlcikgVE8gc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluLCBwb3N0Z3JlcywgYW5vbiwgYXV0aGVudGljYXRlZCwgc2VydmljZV9yb2xlO1xuICBFTkQgSUY7XG5FTkQ7XG4kJDtcbkNPTU1FTlQgT04gRlVOQ1RJT04gZXh0ZW5zaW9ucy5ncmFudF9wZ19uZXRfYWNjZXNzIElTICdHcmFudHMgYWNjZXNzIHRvIHBnX25ldCc7XG5ET1xuJCRcbkJFR0lOXG4gIElGIE5PVCBFWElTVFMgKFxuICAgIFNFTEVDVCAxXG4gICAgRlJPTSBwZ19ldmVudF90cmlnZ2VyXG4gICAgV0hFUkUgZXZ0bmFtZSA9ICdpc3N1ZV9wZ19uZXRfYWNjZXNzJ1xuICApIFRIRU5cbiAgICBDUkVBVEUgRVZFTlQgVFJJR0dFUiBpc3N1ZV9wZ19uZXRfYWNjZXNzIE9OIGRkbF9jb21tYW5kX2VuZCBXSEVOIFRBRyBJTiAoJ0NSRUFURSBFWFRFTlNJT04nKVxuICAgIEVYRUNVVEUgUFJPQ0VEVVJFIGV4dGVuc2lvbnMuZ3JhbnRfcGdfbmV0X2FjY2VzcygpO1xuICBFTkQgSUY7XG5FTkRcbiQkO1xuSU5TRVJUIElOVE8gc3VwYWJhc2VfZnVuY3Rpb25zLm1pZ3JhdGlvbnMgKHZlcnNpb24pIFZBTFVFUyAoJzIwMjEwODA5MTgzNDIzX3VwZGF0ZV9ncmFudHMnKTtcbkFMVEVSIGZ1bmN0aW9uIHN1cGFiYXNlX2Z1bmN0aW9ucy5odHRwX3JlcXVlc3QoKSBTRUNVUklUWSBERUZJTkVSO1xuQUxURVIgZnVuY3Rpb24gc3VwYWJhc2VfZnVuY3Rpb25zLmh0dHBfcmVxdWVzdCgpIFNFVCBzZWFyY2hfcGF0aCA9IHN1cGFiYXNlX2Z1bmN0aW9ucztcblJFVk9LRSBBTEwgT04gRlVOQ1RJT04gc3VwYWJhc2VfZnVuY3Rpb25zLmh0dHBfcmVxdWVzdCgpIEZST00gUFVCTElDO1xuR1JBTlQgRVhFQ1VURSBPTiBGVU5DVElPTiBzdXBhYmFzZV9mdW5jdGlvbnMuaHR0cF9yZXF1ZXN0KCkgVE8gcG9zdGdyZXMsIGFub24sIGF1dGhlbnRpY2F0ZWQsIHNlcnZpY2Vfcm9sZTtcbkNPTU1JVDtcbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi9yb2xlcy5zcWwKICAgICAgICB0YXJnZXQ6IC9kb2NrZXItZW50cnlwb2ludC1pbml0ZGIuZC9pbml0LXNjcmlwdHMvOTktcm9sZXMuc3FsCiAgICAgICAgY29udGVudDogIi0tIE5PVEU6IGNoYW5nZSB0byB5b3VyIG93biBwYXNzd29yZHMgZm9yIHByb2R1Y3Rpb24gZW52aXJvbm1lbnRzXG4gXFxzZXQgcGdwYXNzIGBlY2hvIFwiJFBPU1RHUkVTX1BBU1NXT1JEXCJgXG5cbiBBTFRFUiBVU0VSIGF1dGhlbnRpY2F0b3IgV0lUSCBQQVNTV09SRCA6J3BncGFzcyc7XG4gQUxURVIgVVNFUiBwZ2JvdW5jZXIgV0lUSCBQQVNTV09SRCA6J3BncGFzcyc7XG4gQUxURVIgVVNFUiBzdXBhYmFzZV9hdXRoX2FkbWluIFdJVEggUEFTU1dPUkQgOidwZ3Bhc3MnO1xuIEFMVEVSIFVTRVIgc3VwYWJhc2VfZnVuY3Rpb25zX2FkbWluIFdJVEggUEFTU1dPUkQgOidwZ3Bhc3MnO1xuIEFMVEVSIFVTRVIgc3VwYWJhc2Vfc3RvcmFnZV9hZG1pbiBXSVRIIFBBU1NXT1JEIDoncGdwYXNzJztcbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9kYi9qd3Quc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvaW5pdC1zY3JpcHRzLzk5LWp3dC5zcWwKICAgICAgICBjb250ZW50OiAiXFxzZXQgand0X3NlY3JldCBgZWNobyBcIiRKV1RfU0VDUkVUXCJgXG5cXHNldCBqd3RfZXhwIGBlY2hvIFwiJEpXVF9FWFBcImBcblxcc2V0IGRiX25hbWUgYGVjaG8gXCIke1BPU1RHUkVTX0RCOi1wb3N0Z3Jlc31cImBcblxuQUxURVIgREFUQUJBU0UgOmRiX25hbWUgU0VUIFwiYXBwLnNldHRpbmdzLmp3dF9zZWNyZXRcIiBUTyA6J2p3dF9zZWNyZXQnO1xuQUxURVIgREFUQUJBU0UgOmRiX25hbWUgU0VUIFwiYXBwLnNldHRpbmdzLmp3dF9leHBcIiBUTyA6J2p3dF9leHAnO1xuIgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2RiL2xvZ3Muc3FsCiAgICAgICAgdGFyZ2V0OiAvZG9ja2VyLWVudHJ5cG9pbnQtaW5pdGRiLmQvbWlncmF0aW9ucy85OS1sb2dzLnNxbAogICAgICAgIGNvbnRlbnQ6ICJcXHNldCBwZ3VzZXIgYGVjaG8gXCJzdXBhYmFzZV9hZG1pblwiYFxuXFxjIF9zdXBhYmFzZVxuY3JlYXRlIHNjaGVtYSBpZiBub3QgZXhpc3RzIF9hbmFseXRpY3M7XG5hbHRlciBzY2hlbWEgX2FuYWx5dGljcyBvd25lciB0byA6cGd1c2VyO1xuXFxjIHBvc3RncmVzXG4iCiAgICAgIC0gJ3N1cGFiYXNlLWRiLWNvbmZpZzovZXRjL3Bvc3RncmVzcWwtY3VzdG9tJwogIHN1cGFiYXNlLWFuYWx5dGljczoKICAgIGltYWdlOiAnc3VwYWJhc2UvbG9nZmxhcmU6MS40LjAnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6NDAwMC9oZWFsdGgnCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIGludGVydmFsOiA1cwogICAgICByZXRyaWVzOiAxMAogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudmlyb25tZW50OgogICAgICAtIExPR0ZMQVJFX05PREVfSE9TVD0xMjcuMC4wLjEKICAgICAgLSBEQl9VU0VSTkFNRT1zdXBhYmFzZV9hZG1pbgogICAgICAtIERCX0RBVEFCQVNFPV9zdXBhYmFzZQogICAgICAtICdEQl9IT1NUTkFNRT0ke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn0nCiAgICAgIC0gJ0RCX1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSAnREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSBEQl9TQ0hFTUE9X2FuYWx5dGljcwogICAgICAtICdMT0dGTEFSRV9BUElfS0VZPSR7U0VSVklDRV9QQVNTV09SRF9MT0dGTEFSRX0nCiAgICAgIC0gTE9HRkxBUkVfU0lOR0xFX1RFTkFOVD10cnVlCiAgICAgIC0gTE9HRkxBUkVfU0lOR0xFX1RFTkFOVF9NT0RFPXRydWUKICAgICAgLSBMT0dGTEFSRV9TVVBBQkFTRV9NT0RFPXRydWUKICAgICAgLSBMT0dGTEFSRV9NSU5fQ0xVU1RFUl9TSVpFPTEKICAgICAgLSAnUE9TVEdSRVNfQkFDS0VORF9VUkw9cG9zdGdyZXNxbDovL3N1cGFiYXNlX2FkbWluOiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AJHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9OiR7UE9TVEdSRVNfUE9SVDotNTQzMn0vX3N1cGFiYXNlJwogICAgICAtIFBPU1RHUkVTX0JBQ0tFTkRfU0NIRU1BPV9hbmFseXRpY3MKICAgICAgLSBMT0dGTEFSRV9GRUFUVVJFX0ZMQUdfT1ZFUlJJREU9bXVsdGliYWNrZW5kPXRydWUKICBzdXBhYmFzZS12ZWN0b3I6CiAgICBpbWFnZTogJ3RpbWJlcmlvL3ZlY3RvcjowLjI4LjEtYWxwaW5lJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctLW5vLXZlcmJvc2UnCiAgICAgICAgLSAnLS10cmllcz0xJwogICAgICAgIC0gJy0tc3BpZGVyJwogICAgICAgIC0gJ2h0dHA6Ly9zdXBhYmFzZS12ZWN0b3I6OTAwMS9oZWFsdGgnCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIGludGVydmFsOiA1cwogICAgICByZXRyaWVzOiAzCiAgICB2b2x1bWVzOgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2xvZ3MvdmVjdG9yLnltbAogICAgICAgIHRhcmdldDogL2V0Yy92ZWN0b3IvdmVjdG9yLnltbAogICAgICAgIHJlYWRfb25seTogdHJ1ZQogICAgICAgIGNvbnRlbnQ6ICJhcGk6XG4gIGVuYWJsZWQ6IHRydWVcbiAgYWRkcmVzczogMC4wLjAuMDo5MDAxXG5cbnNvdXJjZXM6XG4gIGRvY2tlcl9ob3N0OlxuICAgIHR5cGU6IGRvY2tlcl9sb2dzXG4gICAgZXhjbHVkZV9jb250YWluZXJzOlxuICAgICAgLSBzdXBhYmFzZS12ZWN0b3JcblxudHJhbnNmb3JtczpcbiAgcHJvamVjdF9sb2dzOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSBkb2NrZXJfaG9zdFxuICAgIHNvdXJjZTogfC1cbiAgICAgIC5wcm9qZWN0ID0gXCJkZWZhdWx0XCJcbiAgICAgIC5ldmVudF9tZXNzYWdlID0gZGVsKC5tZXNzYWdlKVxuICAgICAgLmFwcG5hbWUgPSBkZWwoLmNvbnRhaW5lcl9uYW1lKVxuICAgICAgZGVsKC5jb250YWluZXJfY3JlYXRlZF9hdClcbiAgICAgIGRlbCguY29udGFpbmVyX2lkKVxuICAgICAgZGVsKC5zb3VyY2VfdHlwZSlcbiAgICAgIGRlbCguc3RyZWFtKVxuICAgICAgZGVsKC5sYWJlbClcbiAgICAgIGRlbCguaW1hZ2UpXG4gICAgICBkZWwoLmhvc3QpXG4gICAgICBkZWwoLnN0cmVhbSlcbiAgcm91dGVyOlxuICAgIHR5cGU6IHJvdXRlXG4gICAgaW5wdXRzOlxuICAgICAgLSBwcm9qZWN0X2xvZ3NcbiAgICByb3V0ZTpcbiAgICAgIGtvbmc6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJzdXBhYmFzZS1rb25nXCIpJ1xuICAgICAgYXV0aDogJ3N0YXJ0c193aXRoKHN0cmluZyEoLmFwcG5hbWUpLCBcInN1cGFiYXNlLWF1dGhcIiknXG4gICAgICByZXN0OiAnc3RhcnRzX3dpdGgoc3RyaW5nISguYXBwbmFtZSksIFwic3VwYWJhc2UtcmVzdFwiKSdcbiAgICAgIHJlYWx0aW1lOiAnc3RhcnRzX3dpdGgoc3RyaW5nISguYXBwbmFtZSksIFwicmVhbHRpbWUtZGV2XCIpJ1xuICAgICAgc3RvcmFnZTogJ3N0YXJ0c193aXRoKHN0cmluZyEoLmFwcG5hbWUpLCBcInN1cGFiYXNlLXN0b3JhZ2VcIiknXG4gICAgICBmdW5jdGlvbnM6ICdzdGFydHNfd2l0aChzdHJpbmchKC5hcHBuYW1lKSwgXCJzdXBhYmFzZS1mdW5jdGlvbnNcIiknXG4gICAgICBkYjogJ3N0YXJ0c193aXRoKHN0cmluZyEoLmFwcG5hbWUpLCBcInN1cGFiYXNlLWRiXCIpJ1xuICAjIElnbm9yZXMgbm9uIG5naW54IGVycm9ycyBzaW5jZSB0aGV5IGFyZSByZWxhdGVkIHdpdGgga29uZyBib290aW5nIHVwXG4gIGtvbmdfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLmtvbmdcbiAgICBzb3VyY2U6IHwtXG4gICAgICByZXEsIGVyciA9IHBhcnNlX25naW54X2xvZyguZXZlbnRfbWVzc2FnZSwgXCJjb21iaW5lZFwiKVxuICAgICAgaWYgZXJyID09IG51bGwge1xuICAgICAgICAgIC50aW1lc3RhbXAgPSByZXEudGltZXN0YW1wXG4gICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QuaGVhZGVycy5yZWZlcmVyID0gcmVxLnJlZmVyZXJcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5oZWFkZXJzLnVzZXJfYWdlbnQgPSByZXEuYWdlbnRcbiAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5oZWFkZXJzLmNmX2Nvbm5lY3RpbmdfaXAgPSByZXEuY2xpZW50XG4gICAgICAgICAgLm1ldGFkYXRhLnJlcXVlc3QubWV0aG9kID0gcmVxLm1ldGhvZFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0LnBhdGggPSByZXEucGF0aFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0LnByb3RvY29sID0gcmVxLnByb3RvY29sXG4gICAgICAgICAgLm1ldGFkYXRhLnJlc3BvbnNlLnN0YXR1c19jb2RlID0gcmVxLnN0YXR1c1xuICAgICAgfVxuICAgICAgaWYgZXJyICE9IG51bGwge1xuICAgICAgICBhYm9ydFxuICAgICAgfVxuICAjIElnbm9yZXMgbm9uIG5naW54IGVycm9ycyBzaW5jZSB0aGV5IGFyZSByZWxhdGVkIHdpdGgga29uZyBib290aW5nIHVwXG4gIGtvbmdfZXJyOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIua29uZ1xuICAgIHNvdXJjZTogfC1cbiAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0Lm1ldGhvZCA9IFwiR0VUXCJcbiAgICAgIC5tZXRhZGF0YS5yZXNwb25zZS5zdGF0dXNfY29kZSA9IDIwMFxuICAgICAgcGFyc2VkLCBlcnIgPSBwYXJzZV9uZ2lueF9sb2coLmV2ZW50X21lc3NhZ2UsIFwiZXJyb3JcIilcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAudGltZXN0YW1wID0gcGFyc2VkLnRpbWVzdGFtcFxuICAgICAgICAgIC5zZXZlcml0eSA9IHBhcnNlZC5zZXZlcml0eVxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0Lmhvc3QgPSBwYXJzZWQuaG9zdFxuICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0LmhlYWRlcnMuY2ZfY29ubmVjdGluZ19pcCA9IHBhcnNlZC5jbGllbnRcbiAgICAgICAgICB1cmwsIGVyciA9IHNwbGl0KHBhcnNlZC5yZXF1ZXN0LCBcIiBcIilcbiAgICAgICAgICBpZiBlcnIgPT0gbnVsbCB7XG4gICAgICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0Lm1ldGhvZCA9IHVybFswXVxuICAgICAgICAgICAgICAubWV0YWRhdGEucmVxdWVzdC5wYXRoID0gdXJsWzFdXG4gICAgICAgICAgICAgIC5tZXRhZGF0YS5yZXF1ZXN0LnByb3RvY29sID0gdXJsWzJdXG4gICAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgZXJyICE9IG51bGwge1xuICAgICAgICBhYm9ydFxuICAgICAgfVxuICAjIEdvdHJ1ZSBsb2dzIGFyZSBzdHJ1Y3R1cmVkIGpzb24gc3RyaW5ncyB3aGljaCBmcm9udGVuZCBwYXJzZXMgZGlyZWN0bHkuIEJ1dCB3ZSBrZWVwIG1ldGFkYXRhIGZvciBjb25zaXN0ZW5jeS5cbiAgYXV0aF9sb2dzOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIuYXV0aFxuICAgIHNvdXJjZTogfC1cbiAgICAgIHBhcnNlZCwgZXJyID0gcGFyc2VfanNvbiguZXZlbnRfbWVzc2FnZSlcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAubWV0YWRhdGEudGltZXN0YW1wID0gcGFyc2VkLnRpbWVcbiAgICAgICAgICAubWV0YWRhdGEgPSBtZXJnZSEoLm1ldGFkYXRhLCBwYXJzZWQpXG4gICAgICB9XG4gICMgUG9zdGdSRVNUIGxvZ3MgYXJlIHN0cnVjdHVyZWQgc28gd2Ugc2VwYXJhdGUgdGltZXN0YW1wIGZyb20gbWVzc2FnZSB1c2luZyByZWdleFxuICByZXN0X2xvZ3M6XG4gICAgdHlwZTogcmVtYXBcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5yZXN0XG4gICAgc291cmNlOiB8LVxuICAgICAgcGFyc2VkLCBlcnIgPSBwYXJzZV9yZWdleCguZXZlbnRfbWVzc2FnZSwgcideKD9QPHRpbWU+LiopOiAoP1A8bXNnPi4qKSQnKVxuICAgICAgaWYgZXJyID09IG51bGwge1xuICAgICAgICAgIC5ldmVudF9tZXNzYWdlID0gcGFyc2VkLm1zZ1xuICAgICAgICAgIC50aW1lc3RhbXAgPSB0b190aW1lc3RhbXAhKHBhcnNlZC50aW1lKVxuICAgICAgICAgIC5tZXRhZGF0YS5ob3N0ID0gLnByb2plY3RcbiAgICAgIH1cbiAgIyBSZWFsdGltZSBsb2dzIGFyZSBzdHJ1Y3R1cmVkIHNvIHdlIHBhcnNlIHRoZSBzZXZlcml0eSBsZXZlbCB1c2luZyByZWdleCAoaWdub3JlIHRpbWUgYmVjYXVzZSBpdCBoYXMgbm8gZGF0ZSlcbiAgcmVhbHRpbWVfbG9nczpcbiAgICB0eXBlOiByZW1hcFxuICAgIGlucHV0czpcbiAgICAgIC0gcm91dGVyLnJlYWx0aW1lXG4gICAgc291cmNlOiB8LVxuICAgICAgLm1ldGFkYXRhLnByb2plY3QgPSBkZWwoLnByb2plY3QpXG4gICAgICAubWV0YWRhdGEuZXh0ZXJuYWxfaWQgPSAubWV0YWRhdGEucHJvamVjdFxuICAgICAgcGFyc2VkLCBlcnIgPSBwYXJzZV9yZWdleCguZXZlbnRfbWVzc2FnZSwgcideKD9QPHRpbWU+XFxkKzpcXGQrOlxcZCtcXC5cXGQrKSBcXFsoP1A8bGV2ZWw+XFx3KylcXF0gKD9QPG1zZz4uKikkJylcbiAgICAgIGlmIGVyciA9PSBudWxsIHtcbiAgICAgICAgICAuZXZlbnRfbWVzc2FnZSA9IHBhcnNlZC5tc2dcbiAgICAgICAgICAubWV0YWRhdGEubGV2ZWwgPSBwYXJzZWQubGV2ZWxcbiAgICAgIH1cbiAgIyBTdG9yYWdlIGxvZ3MgbWF5IGNvbnRhaW4ganNvbiBvYmplY3RzIHNvIHdlIHBhcnNlIHRoZW0gZm9yIGNvbXBsZXRlbmVzc1xuICBzdG9yYWdlX2xvZ3M6XG4gICAgdHlwZTogcmVtYXBcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5zdG9yYWdlXG4gICAgc291cmNlOiB8LVxuICAgICAgLm1ldGFkYXRhLnByb2plY3QgPSBkZWwoLnByb2plY3QpXG4gICAgICAubWV0YWRhdGEudGVuYW50SWQgPSAubWV0YWRhdGEucHJvamVjdFxuICAgICAgcGFyc2VkLCBlcnIgPSBwYXJzZV9qc29uKC5ldmVudF9tZXNzYWdlKVxuICAgICAgaWYgZXJyID09IG51bGwge1xuICAgICAgICAgIC5ldmVudF9tZXNzYWdlID0gcGFyc2VkLm1zZ1xuICAgICAgICAgIC5tZXRhZGF0YS5sZXZlbCA9IHBhcnNlZC5sZXZlbFxuICAgICAgICAgIC5tZXRhZGF0YS50aW1lc3RhbXAgPSBwYXJzZWQudGltZVxuICAgICAgICAgIC5tZXRhZGF0YS5jb250ZXh0WzBdLmhvc3QgPSBwYXJzZWQuaG9zdG5hbWVcbiAgICAgICAgICAubWV0YWRhdGEuY29udGV4dFswXS5waWQgPSBwYXJzZWQucGlkXG4gICAgICB9XG4gICMgUG9zdGdyZXMgbG9ncyBzb21lIG1lc3NhZ2VzIHRvIHN0ZGVyciB3aGljaCB3ZSBtYXAgdG8gd2FybmluZyBzZXZlcml0eSBsZXZlbFxuICBkYl9sb2dzOlxuICAgIHR5cGU6IHJlbWFwXG4gICAgaW5wdXRzOlxuICAgICAgLSByb3V0ZXIuZGJcbiAgICBzb3VyY2U6IHwtXG4gICAgICAubWV0YWRhdGEuaG9zdCA9IFwiZGItZGVmYXVsdFwiXG4gICAgICAubWV0YWRhdGEucGFyc2VkLnRpbWVzdGFtcCA9IC50aW1lc3RhbXBcblxuICAgICAgcGFyc2VkLCBlcnIgPSBwYXJzZV9yZWdleCguZXZlbnRfbWVzc2FnZSwgcicuKig/UDxsZXZlbD5JTkZPfE5PVElDRXxXQVJOSU5HfEVSUk9SfExPR3xGQVRBTHxQQU5JQz8pOi4qJywgbnVtZXJpY19ncm91cHM6IHRydWUpXG5cbiAgICAgIGlmIGVyciAhPSBudWxsIHx8IHBhcnNlZCA9PSBudWxsIHtcbiAgICAgICAgLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSA9IFwiaW5mb1wiXG4gICAgICB9XG4gICAgICBpZiBwYXJzZWQgIT0gbnVsbCB7XG4gICAgICAubWV0YWRhdGEucGFyc2VkLmVycm9yX3NldmVyaXR5ID0gcGFyc2VkLmxldmVsXG4gICAgICB9XG4gICAgICBpZiAubWV0YWRhdGEucGFyc2VkLmVycm9yX3NldmVyaXR5ID09IFwiaW5mb1wiIHtcbiAgICAgICAgICAubWV0YWRhdGEucGFyc2VkLmVycm9yX3NldmVyaXR5ID0gXCJsb2dcIlxuICAgICAgfVxuICAgICAgLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSA9IHVwY2FzZSEoLm1ldGFkYXRhLnBhcnNlZC5lcnJvcl9zZXZlcml0eSlcblxuc2lua3M6XG4gIGxvZ2ZsYXJlX2F1dGg6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSBhdXRoX2xvZ3NcbiAgICBlbmNvZGluZzpcbiAgICAgIGNvZGVjOiAnanNvbidcbiAgICBtZXRob2Q6ICdwb3N0J1xuICAgIHJlcXVlc3Q6XG4gICAgICByZXRyeV9tYXhfZHVyYXRpb25fc2VjczogMTBcbiAgICB1cmk6ICdodHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAvYXBpL2xvZ3M/c291cmNlX25hbWU9Z290cnVlLmxvZ3MucHJvZCZhcGlfa2V5PSR7TE9HRkxBUkVfQVBJX0tFWT9MT0dGTEFSRV9BUElfS0VZIGlzIHJlcXVpcmVkfSdcbiAgbG9nZmxhcmVfcmVhbHRpbWU6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSByZWFsdGltZV9sb2dzXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL2FwaS9sb2dzP3NvdXJjZV9uYW1lPXJlYWx0aW1lLmxvZ3MucHJvZCZhcGlfa2V5PSR7TE9HRkxBUkVfQVBJX0tFWT9MT0dGTEFSRV9BUElfS0VZIGlzIHJlcXVpcmVkfSdcbiAgbG9nZmxhcmVfcmVzdDpcbiAgICB0eXBlOiAnaHR0cCdcbiAgICBpbnB1dHM6XG4gICAgICAtIHJlc3RfbG9nc1xuICAgIGVuY29kaW5nOlxuICAgICAgY29kZWM6ICdqc29uJ1xuICAgIG1ldGhvZDogJ3Bvc3QnXG4gICAgcmVxdWVzdDpcbiAgICAgIHJldHJ5X21heF9kdXJhdGlvbl9zZWNzOiAxMFxuICAgIHVyaTogJ2h0dHA6Ly9zdXBhYmFzZS1hbmFseXRpY3M6NDAwMC9hcGkvbG9ncz9zb3VyY2VfbmFtZT1wb3N0Z1JFU1QubG9ncy5wcm9kJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuICBsb2dmbGFyZV9kYjpcbiAgICB0eXBlOiAnaHR0cCdcbiAgICBpbnB1dHM6XG4gICAgICAtIGRiX2xvZ3NcbiAgICBlbmNvZGluZzpcbiAgICAgIGNvZGVjOiAnanNvbidcbiAgICBtZXRob2Q6ICdwb3N0J1xuICAgIHJlcXVlc3Q6XG4gICAgICByZXRyeV9tYXhfZHVyYXRpb25fc2VjczogMTBcbiAgICAjIFdlIG11c3Qgcm91dGUgdGhlIHNpbmsgdGhyb3VnaCBrb25nIGJlY2F1c2UgaW5nZXN0aW5nIGxvZ3MgYmVmb3JlIGxvZ2ZsYXJlIGlzIGZ1bGx5IGluaXRpYWxpc2VkIHdpbGxcbiAgICAjIGxlYWQgdG8gYnJva2VuIHF1ZXJpZXMgZnJvbSBzdHVkaW8uIFRoaXMgd29ya3MgYnkgdGhlIGFzc3VtcHRpb24gdGhhdCBjb250YWluZXJzIGFyZSBzdGFydGVkIGluIHRoZVxuICAgICMgZm9sbG93aW5nIG9yZGVyOiB2ZWN0b3IgPiBkYiA+IGxvZ2ZsYXJlID4ga29uZ1xuICAgIHVyaTogJ2h0dHA6Ly9zdXBhYmFzZS1rb25nOjgwMDAvYW5hbHl0aWNzL3YxL2FwaS9sb2dzP3NvdXJjZV9uYW1lPXBvc3RncmVzLmxvZ3MmYXBpX2tleT0ke0xPR0ZMQVJFX0FQSV9LRVk/TE9HRkxBUkVfQVBJX0tFWSBpcyByZXF1aXJlZH0nXG4gIGxvZ2ZsYXJlX2Z1bmN0aW9uczpcbiAgICB0eXBlOiAnaHR0cCdcbiAgICBpbnB1dHM6XG4gICAgICAtIHJvdXRlci5mdW5jdGlvbnNcbiAgICBlbmNvZGluZzpcbiAgICAgIGNvZGVjOiAnanNvbidcbiAgICBtZXRob2Q6ICdwb3N0J1xuICAgIHJlcXVlc3Q6XG4gICAgICByZXRyeV9tYXhfZHVyYXRpb25fc2VjczogMTBcbiAgICB1cmk6ICdodHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAvYXBpL2xvZ3M/c291cmNlX25hbWU9ZGVuby1yZWxheS1sb2dzJmFwaV9rZXk9JHtMT0dGTEFSRV9BUElfS0VZP0xPR0ZMQVJFX0FQSV9LRVkgaXMgcmVxdWlyZWR9J1xuICBsb2dmbGFyZV9zdG9yYWdlOlxuICAgIHR5cGU6ICdodHRwJ1xuICAgIGlucHV0czpcbiAgICAgIC0gc3RvcmFnZV9sb2dzXG4gICAgZW5jb2Rpbmc6XG4gICAgICBjb2RlYzogJ2pzb24nXG4gICAgbWV0aG9kOiAncG9zdCdcbiAgICByZXF1ZXN0OlxuICAgICAgcmV0cnlfbWF4X2R1cmF0aW9uX3NlY3M6IDEwXG4gICAgdXJpOiAnaHR0cDovL3N1cGFiYXNlLWFuYWx5dGljczo0MDAwL2FwaS9sb2dzP3NvdXJjZV9uYW1lPXN0b3JhZ2UubG9ncy5wcm9kLjImYXBpX2tleT0ke0xPR0ZMQVJFX0FQSV9LRVk/TE9HRkxBUkVfQVBJX0tFWSBpcyByZXF1aXJlZH0nXG4gIGxvZ2ZsYXJlX2tvbmc6XG4gICAgdHlwZTogJ2h0dHAnXG4gICAgaW5wdXRzOlxuICAgICAgLSBrb25nX2xvZ3NcbiAgICAgIC0ga29uZ19lcnJcbiAgICBlbmNvZGluZzpcbiAgICAgIGNvZGVjOiAnanNvbidcbiAgICBtZXRob2Q6ICdwb3N0J1xuICAgIHJlcXVlc3Q6XG4gICAgICByZXRyeV9tYXhfZHVyYXRpb25fc2VjczogMTBcbiAgICB1cmk6ICdodHRwOi8vc3VwYWJhc2UtYW5hbHl0aWNzOjQwMDAvYXBpL2xvZ3M/c291cmNlX25hbWU9Y2xvdWRmbGFyZS5sb2dzLnByb2QmYXBpX2tleT0ke0xPR0ZMQVJFX0FQSV9LRVk/TE9HRkxBUkVfQVBJX0tFWSBpcyByZXF1aXJlZH0nXG4iCiAgICAgIC0gJy92YXIvcnVuL2RvY2tlci5zb2NrOi92YXIvcnVuL2RvY2tlci5zb2NrOnJvJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0xPR0ZMQVJFX0FQSV9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEX0xPR0ZMQVJFfScKICAgIGNvbW1hbmQ6CiAgICAgIC0gJy0tY29uZmlnJwogICAgICAtIGV0Yy92ZWN0b3IvdmVjdG9yLnltbAogIHN1cGFiYXNlLXJlc3Q6CiAgICBpbWFnZTogJ3Bvc3RncmVzdC9wb3N0Z3Jlc3Q6djEyLjIuMTInCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudmlyb25tZW50OgogICAgICAtICdQR1JTVF9EQl9VUkk9cG9zdGdyZXM6Ly9hdXRoZW50aWNhdG9yOiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AJHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9OiR7UE9TVEdSRVNfUE9SVDotNTQzMn0vJHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtICdQR1JTVF9EQl9TQ0hFTUFTPSR7UEdSU1RfREJfU0NIRU1BUzotcHVibGljLHN0b3JhZ2UsZ3JhcGhxbF9wdWJsaWN9JwogICAgICAtIFBHUlNUX0RCX0FOT05fUk9MRT1hbm9uCiAgICAgIC0gJ1BHUlNUX0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gUEdSU1RfREJfVVNFX0xFR0FDWV9HVUNTPWZhbHNlCiAgICAgIC0gJ1BHUlNUX0FQUF9TRVRUSU5HU19KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdQR1JTVF9BUFBfU0VUVElOR1NfSldUX0VYUD0ke0pXVF9FWFBJUlk6LTM2MDB9JwogICAgY29tbWFuZDogcG9zdGdyZXN0CiAgICBleGNsdWRlX2Zyb21faGM6IHRydWUKICBzdXBhYmFzZS1hdXRoOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9nb3RydWU6djIuMTc0LjAnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBzdXBhYmFzZS1hbmFseXRpY3M6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLS1uby12ZXJib3NlJwogICAgICAgIC0gJy0tdHJpZXM9MScKICAgICAgICAtICctLXNwaWRlcicKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjk5OTkvaGVhbHRoJwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gR09UUlVFX0FQSV9IT1NUPTAuMC4wLjAKICAgICAgLSBHT1RSVUVfQVBJX1BPUlQ9OTk5OQogICAgICAtICdBUElfRVhURVJOQUxfVVJMPSR7QVBJX0VYVEVSTkFMX1VSTDotaHR0cDovL3N1cGFiYXNlLWtvbmc6ODAwMH0nCiAgICAgIC0gR09UUlVFX0RCX0RSSVZFUj1wb3N0Z3JlcwogICAgICAtICdHT1RSVUVfREJfREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vc3VwYWJhc2VfYXV0aF9hZG1pbjoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9LyR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnR09UUlVFX1NJVEVfVVJMPSR7U0VSVklDRV9GUUROX1NVUEFCQVNFS09OR30nCiAgICAgIC0gJ0dPVFJVRV9VUklfQUxMT1dfTElTVD0ke0FERElUSU9OQUxfUkVESVJFQ1RfVVJMU30nCiAgICAgIC0gJ0dPVFJVRV9ESVNBQkxFX1NJR05VUD0ke0RJU0FCTEVfU0lHTlVQOi1mYWxzZX0nCiAgICAgIC0gR09UUlVFX0pXVF9BRE1JTl9ST0xFUz1zZXJ2aWNlX3JvbGUKICAgICAgLSBHT1RSVUVfSldUX0FVRD1hdXRoZW50aWNhdGVkCiAgICAgIC0gR09UUlVFX0pXVF9ERUZBVUxUX0dST1VQX05BTUU9YXV0aGVudGljYXRlZAogICAgICAtICdHT1RSVUVfSldUX0VYUD0ke0pXVF9FWFBJUlk6LTM2MDB9JwogICAgICAtICdHT1RSVUVfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSAnR09UUlVFX0VYVEVSTkFMX0VNQUlMX0VOQUJMRUQ9JHtFTkFCTEVfRU1BSUxfU0lHTlVQOi10cnVlfScKICAgICAgLSAnR09UUlVFX0VYVEVSTkFMX0FOT05ZTU9VU19VU0VSU19FTkFCTEVEPSR7RU5BQkxFX0FOT05ZTU9VU19VU0VSUzotZmFsc2V9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX0FVVE9DT05GSVJNPSR7RU5BQkxFX0VNQUlMX0FVVE9DT05GSVJNOi1mYWxzZX0nCiAgICAgIC0gJ0dPVFJVRV9TTVRQX0FETUlOX0VNQUlMPSR7U01UUF9BRE1JTl9FTUFJTH0nCiAgICAgIC0gJ0dPVFJVRV9TTVRQX0hPU1Q9JHtTTVRQX0hPU1R9JwogICAgICAtICdHT1RSVUVfU01UUF9QT1JUPSR7U01UUF9QT1JUOi01ODd9JwogICAgICAtICdHT1RSVUVfU01UUF9VU0VSPSR7U01UUF9VU0VSfScKICAgICAgLSAnR09UUlVFX1NNVFBfUEFTUz0ke1NNVFBfUEFTU30nCiAgICAgIC0gJ0dPVFJVRV9TTVRQX1NFTkRFUl9OQU1FPSR7U01UUF9TRU5ERVJfTkFNRX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVVJMUEFUSFNfSU5WSVRFPSR7TUFJTEVSX1VSTFBBVEhTX0lOVklURTotL2F1dGgvdjEvdmVyaWZ5fScKICAgICAgLSAnR09UUlVFX01BSUxFUl9VUkxQQVRIU19DT05GSVJNQVRJT049JHtNQUlMRVJfVVJMUEFUSFNfQ09ORklSTUFUSU9OOi0vYXV0aC92MS92ZXJpZnl9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1VSTFBBVEhTX1JFQ09WRVJZPSR7TUFJTEVSX1VSTFBBVEhTX1JFQ09WRVJZOi0vYXV0aC92MS92ZXJpZnl9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1VSTFBBVEhTX0VNQUlMX0NIQU5HRT0ke01BSUxFUl9VUkxQQVRIU19FTUFJTF9DSEFOR0U6LS9hdXRoL3YxL3ZlcmlmeX0nCiAgICAgIC0gJ0dPVFJVRV9NQUlMRVJfVEVNUExBVEVTX0lOVklURT0ke01BSUxFUl9URU1QTEFURVNfSU5WSVRFfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9URU1QTEFURVNfQ09ORklSTUFUSU9OPSR7TUFJTEVSX1RFTVBMQVRFU19DT05GSVJNQVRJT059JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1RFTVBMQVRFU19SRUNPVkVSWT0ke01BSUxFUl9URU1QTEFURVNfUkVDT1ZFUll9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1RFTVBMQVRFU19NQUdJQ19MSU5LPSR7TUFJTEVSX1RFTVBMQVRFU19NQUdJQ19MSU5LfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9URU1QTEFURVNfRU1BSUxfQ0hBTkdFPSR7TUFJTEVSX1RFTVBMQVRFU19FTUFJTF9DSEFOR0V9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1NVQkpFQ1RTX0NPTkZJUk1BVElPTj0ke01BSUxFUl9TVUJKRUNUU19DT05GSVJNQVRJT059JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1NVQkpFQ1RTX1JFQ09WRVJZPSR7TUFJTEVSX1NVQkpFQ1RTX1JFQ09WRVJZfScKICAgICAgLSAnR09UUlVFX01BSUxFUl9TVUJKRUNUU19NQUdJQ19MSU5LPSR7TUFJTEVSX1NVQkpFQ1RTX01BR0lDX0xJTkt9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1NVQkpFQ1RTX0VNQUlMX0NIQU5HRT0ke01BSUxFUl9TVUJKRUNUU19FTUFJTF9DSEFOR0V9JwogICAgICAtICdHT1RSVUVfTUFJTEVSX1NVQkpFQ1RTX0lOVklURT0ke01BSUxFUl9TVUJKRUNUU19JTlZJVEV9JwogICAgICAtICdHT1RSVUVfRVhURVJOQUxfUEhPTkVfRU5BQkxFRD0ke0VOQUJMRV9QSE9ORV9TSUdOVVA6LXRydWV9JwogICAgICAtICdHT1RSVUVfU01TX0FVVE9DT05GSVJNPSR7RU5BQkxFX1BIT05FX0FVVE9DT05GSVJNOi10cnVlfScKICByZWFsdGltZS1kZXY6CiAgICBpbWFnZTogJ3N1cGFiYXNlL3JlYWx0aW1lOnYyLjM0LjQ3JwogICAgY29udGFpbmVyX25hbWU6IHJlYWx0aW1lLWRldi5zdXBhYmFzZS1yZWFsdGltZQogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1zU2ZMJwogICAgICAgIC0gJy0taGVhZCcKICAgICAgICAtICctbycKICAgICAgICAtIC9kZXYvbnVsbAogICAgICAgIC0gJy1IJwogICAgICAgIC0gJ0F1dGhvcml6YXRpb246IEJlYXJlciAke1NFUlZJQ0VfU1VQQUJBU0VBTk9OX0tFWX0nCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo0MDAwL2FwaS90ZW5hbnRzL3JlYWx0aW1lLWRldi9oZWFsdGgnCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIGludGVydmFsOiA1cwogICAgICByZXRyaWVzOiAzCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBQT1JUPTQwMDAKICAgICAgLSAnREJfSE9TVD0ke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn0nCiAgICAgIC0gJ0RCX1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSBEQl9VU0VSPXN1cGFiYXNlX2FkbWluCiAgICAgIC0gJ0RCX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ0RCX05BTUU9JHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtICdEQl9BRlRFUl9DT05ORUNUX1FVRVJZPVNFVCBzZWFyY2hfcGF0aCBUTyBfcmVhbHRpbWUnCiAgICAgIC0gREJfRU5DX0tFWT1zdXBhYmFzZXJlYWx0aW1lCiAgICAgIC0gJ0FQSV9KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtIEZMWV9BTExPQ19JRD1mbHkxMjMKICAgICAgLSBGTFlfQVBQX05BTUU9cmVhbHRpbWUKICAgICAgLSAnU0VDUkVUX0tFWV9CQVNFPSR7U0VDUkVUX1BBU1NXT1JEX1JFQUxUSU1FfScKICAgICAgLSAnRVJMX0FGTEFHUz0tcHJvdG9fZGlzdCBpbmV0X3RjcCcKICAgICAgLSBFTkFCTEVfVEFJTFNDQUxFPWZhbHNlCiAgICAgIC0gIkROU19OT0RFUz0nJyIKICAgICAgLSBSTElNSVRfTk9GSUxFPTEwMDAwCiAgICAgIC0gQVBQX05BTUU9cmVhbHRpbWUKICAgICAgLSBTRUVEX1NFTEZfSE9TVD10cnVlCiAgICAgIC0gTE9HX0xFVkVMPWVycm9yCiAgICAgIC0gUlVOX0pBTklUT1I9dHJ1ZQogICAgICAtIEpBTklUT1JfSU5URVJWQUw9NjAwMDAKICAgIGNvbW1hbmQ6ICJzaCAtYyBcIi9hcHAvYmluL21pZ3JhdGUgJiYgL2FwcC9iaW4vcmVhbHRpbWUgZXZhbCAnUmVhbHRpbWUuUmVsZWFzZS5zZWVkcyhSZWFsdGltZS5SZXBvKScgJiYgL2FwcC9iaW4vc2VydmVyXCJcbiIKICBzdXBhYmFzZS1taW5pbzoKICAgIGltYWdlOiAnZ2hjci5pby9jb29sbGFic2lvL21pbmlvOlJFTEVBU0UuMjAyNS0xMC0xNVQxNy0yOS01NVonCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnTUlOSU9fUk9PVF9VU0VSPSR7U0VSVklDRV9VU0VSX01JTklPfScKICAgICAgLSAnTUlOSU9fUk9PVF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfTUlOSU99JwogICAgY29tbWFuZDogJ3NlcnZlciAtLWNvbnNvbGUtYWRkcmVzcyAiOjkwMDEiIC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIG1jCiAgICAgICAgLSByZWFkeQogICAgICAgIC0gbG9jYWwKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogICAgdm9sdW1lczoKICAgICAgLSAnLi92b2x1bWVzL3N0b3JhZ2U6L2RhdGEnCiAgbWluaW8tY3JlYXRlYnVja2V0OgogICAgaW1hZ2U6IG1pbmlvL21jCiAgICByZXN0YXJ0OiAnbm8nCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnTUlOSU9fUk9PVF9VU0VSPSR7U0VSVklDRV9VU0VSX01JTklPfScKICAgICAgLSAnTUlOSU9fUk9PVF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfTUlOSU99JwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtbWluaW86CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIGVudHJ5cG9pbnQ6CiAgICAgIC0gL2VudHJ5cG9pbnQuc2gKICAgIHZvbHVtZXM6CiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL2VudHJ5cG9pbnQuc2gKICAgICAgICB0YXJnZXQ6IC9lbnRyeXBvaW50LnNoCiAgICAgICAgY29udGVudDogIiMhL2Jpbi9zaFxuL3Vzci9iaW4vbWMgYWxpYXMgc2V0IHN1cGFiYXNlLW1pbmlvIGh0dHA6Ly9zdXBhYmFzZS1taW5pbzo5MDAwICR7TUlOSU9fUk9PVF9VU0VSfSAke01JTklPX1JPT1RfUEFTU1dPUkR9O1xuL3Vzci9iaW4vbWMgbWIgLS1pZ25vcmUtZXhpc3Rpbmcgc3VwYWJhc2UtbWluaW8vc3R1YjtcbmV4aXQgMFxuIgogIHN1cGFiYXNlLXN0b3JhZ2U6CiAgICBpbWFnZTogJ3N1cGFiYXNlL3N0b3JhZ2UtYXBpOnYxLjE0LjYnCiAgICBkZXBlbmRzX29uOgogICAgICBzdXBhYmFzZS1kYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICBzdXBhYmFzZS1yZXN0OgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9zdGFydGVkCiAgICAgIGltZ3Byb3h5OgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9zdGFydGVkCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gd2dldAogICAgICAgIC0gJy0tbm8tdmVyYm9zZScKICAgICAgICAtICctLXRyaWVzPTEnCiAgICAgICAgLSAnLS1zcGlkZXInCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo1MDAwL3N0YXR1cycKICAgICAgdGltZW91dDogNXMKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHJldHJpZXM6IDMKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZFUl9QT1JUPTUwMDAKICAgICAgLSBTRVJWRVJfUkVHSU9OPWxvY2FsCiAgICAgIC0gTVVMVElfVEVOQU5UPWZhbHNlCiAgICAgIC0gJ0FVVEhfSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUfScKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vc3VwYWJhc2Vfc3RvcmFnZV9hZG1pbjoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9LyR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSBEQl9JTlNUQUxMX1JPTEVTPWZhbHNlCiAgICAgIC0gU1RPUkFHRV9CQUNLRU5EPXMzCiAgICAgIC0gU1RPUkFHRV9TM19CVUNLRVQ9c3R1YgogICAgICAtICdTVE9SQUdFX1MzX0VORFBPSU5UPWh0dHA6Ly9zdXBhYmFzZS1taW5pbzo5MDAwJwogICAgICAtIFNUT1JBR0VfUzNfRk9SQ0VfUEFUSF9TVFlMRT10cnVlCiAgICAgIC0gU1RPUkFHRV9TM19SRUdJT049dXMtZWFzdC0xCiAgICAgIC0gJ0FXU19BQ0NFU1NfS0VZX0lEPSR7U0VSVklDRV9VU0VSX01JTklPfScKICAgICAgLSAnQVdTX1NFQ1JFVF9BQ0NFU1NfS0VZPSR7U0VSVklDRV9QQVNTV09SRF9NSU5JT30nCiAgICAgIC0gVVBMT0FEX0ZJTEVfU0laRV9MSU1JVD01MjQyODgwMDAKICAgICAgLSBVUExPQURfRklMRV9TSVpFX0xJTUlUX1NUQU5EQVJEPTUyNDI4ODAwMAogICAgICAtIFVQTE9BRF9TSUdORURfVVJMX0VYUElSQVRJT05fVElNRT0xMjAKICAgICAgLSBUVVNfVVJMX1BBVEg9dXBsb2FkL3Jlc3VtYWJsZQogICAgICAtIFRVU19NQVhfU0laRT0zNjAwMDAwCiAgICAgIC0gRU5BQkxFX0lNQUdFX1RSQU5TRk9STUFUSU9OPXRydWUKICAgICAgLSAnSU1HUFJPWFlfVVJMPWh0dHA6Ly9pbWdwcm94eTo4MDgwJwogICAgICAtIElNR1BST1hZX1JFUVVFU1RfVElNRU9VVD0xNQogICAgICAtIERBVEFCQVNFX1NFQVJDSF9QQVRIPXN0b3JhZ2UKICAgICAgLSBOT0RFX0VOVj1wcm9kdWN0aW9uCiAgICAgIC0gUkVRVUVTVF9BTExPV19YX0ZPUldBUkRFRF9QQVRIPXRydWUKICAgIHZvbHVtZXM6CiAgICAgIC0gJy4vdm9sdW1lcy9zdG9yYWdlOi92YXIvbGliL3N0b3JhZ2UnCiAgaW1ncHJveHk6CiAgICBpbWFnZTogJ2RhcnRoc2ltL2ltZ3Byb3h5OnYzLjguMCcKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBpbWdwcm94eQogICAgICAgIC0gaGVhbHRoCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIGludGVydmFsOiA1cwogICAgICByZXRyaWVzOiAzCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBJTUdQUk9YWV9MT0NBTF9GSUxFU1lTVEVNX1JPT1Q9LwogICAgICAtIElNR1BST1hZX1VTRV9FVEFHPXRydWUKICAgICAgLSAnSU1HUFJPWFlfRU5BQkxFX1dFQlBfREVURUNUSU9OPSR7SU1HUFJPWFlfRU5BQkxFX1dFQlBfREVURUNUSU9OOi10cnVlfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJy4vdm9sdW1lcy9zdG9yYWdlOi92YXIvbGliL3N0b3JhZ2UnCiAgc3VwYWJhc2UtbWV0YToKICAgIGltYWdlOiAnc3VwYWJhc2UvcG9zdGdyZXMtbWV0YTp2MC44OS4zJwogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBQR19NRVRBX1BPUlQ9ODA4MAogICAgICAtICdQR19NRVRBX0RCX0hPU1Q9JHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9JwogICAgICAtICdQR19NRVRBX0RCX1BPUlQ9JHtQT1NUR1JFU19QT1JUOi01NDMyfScKICAgICAgLSAnUEdfTUVUQV9EQl9OQU1FPSR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSBQR19NRVRBX0RCX1VTRVI9c3VwYWJhc2VfYWRtaW4KICAgICAgLSAnUEdfTUVUQV9EQl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogIHN1cGFiYXNlLWVkZ2UtZnVuY3Rpb25zOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9lZGdlLXJ1bnRpbWU6djEuNjcuNCcKICAgIGRlcGVuZHNfb246CiAgICAgIHN1cGFiYXNlLWFuYWx5dGljczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGVjaG8KICAgICAgICAtICdFZGdlIEZ1bmN0aW9ucyBpcyBoZWFsdGh5JwogICAgICB0aW1lb3V0OiA1cwogICAgICBpbnRlcnZhbDogNXMKICAgICAgcmV0cmllczogMwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gJ1NVUEFCQVNFX1VSTD0ke1NFUlZJQ0VfRlFETl9TVVBBQkFTRUtPTkd9JwogICAgICAtICdTVVBBQkFTRV9BTk9OX0tFWT0ke1NFUlZJQ0VfU1VQQUJBU0VBTk9OX0tFWX0nCiAgICAgIC0gJ1NVUEFCQVNFX1NFUlZJQ0VfUk9MRV9LRVk9JHtTRVJWSUNFX1NVUEFCQVNFU0VSVklDRV9LRVl9JwogICAgICAtICdTVVBBQkFTRV9EQl9VUkw9cG9zdGdyZXNxbDovL3Bvc3RncmVzOiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AJHtQT1NUR1JFU19IT1NUTkFNRTotc3VwYWJhc2UtZGJ9OiR7UE9TVEdSRVNfUE9SVDotNTQzMn0vJHtQT1NUR1JFU19EQjotcG9zdGdyZXN9JwogICAgICAtICdWRVJJRllfSldUPSR7RlVOQ1RJT05TX1ZFUklGWV9KV1Q6LWZhbHNlfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJy4vdm9sdW1lcy9mdW5jdGlvbnM6L2hvbWUvZGVuby9mdW5jdGlvbnMnCiAgICAgIC0KICAgICAgICB0eXBlOiBiaW5kCiAgICAgICAgc291cmNlOiAuL3ZvbHVtZXMvZnVuY3Rpb25zL21haW4vaW5kZXgudHMKICAgICAgICB0YXJnZXQ6IC9ob21lL2Rlbm8vZnVuY3Rpb25zL21haW4vaW5kZXgudHMKICAgICAgICBjb250ZW50OiAiaW1wb3J0IHsgc2VydmUgfSBmcm9tICdodHRwczovL2Rlbm8ubGFuZC9zdGRAMC4xMzEuMC9odHRwL3NlcnZlci50cydcbmltcG9ydCAqIGFzIGpvc2UgZnJvbSAnaHR0cHM6Ly9kZW5vLmxhbmQveC9qb3NlQHY0LjE0LjQvaW5kZXgudHMnXG5cbmNvbnNvbGUubG9nKCdtYWluIGZ1bmN0aW9uIHN0YXJ0ZWQnKVxuXG5jb25zdCBKV1RfU0VDUkVUID0gRGVuby5lbnYuZ2V0KCdKV1RfU0VDUkVUJylcbmNvbnN0IFZFUklGWV9KV1QgPSBEZW5vLmVudi5nZXQoJ1ZFUklGWV9KV1QnKSA9PT0gJ3RydWUnXG5cbmZ1bmN0aW9uIGdldEF1dGhUb2tlbihyZXE6IFJlcXVlc3QpIHtcbiAgY29uc3QgYXV0aEhlYWRlciA9IHJlcS5oZWFkZXJzLmdldCgnYXV0aG9yaXphdGlvbicpXG4gIGlmICghYXV0aEhlYWRlcikge1xuICAgIHRocm93IG5ldyBFcnJvcignTWlzc2luZyBhdXRob3JpemF0aW9uIGhlYWRlcicpXG4gIH1cbiAgY29uc3QgW2JlYXJlciwgdG9rZW5dID0gYXV0aEhlYWRlci5zcGxpdCgnICcpXG4gIGlmIChiZWFyZXIgIT09ICdCZWFyZXInKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBBdXRoIGhlYWRlciBpcyBub3QgJ0JlYXJlciB7dG9rZW59J2ApXG4gIH1cbiAgcmV0dXJuIHRva2VuXG59XG5cbmFzeW5jIGZ1bmN0aW9uIHZlcmlmeUpXVChqd3Q6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICBjb25zdCBlbmNvZGVyID0gbmV3IFRleHRFbmNvZGVyKClcbiAgY29uc3Qgc2VjcmV0S2V5ID0gZW5jb2Rlci5lbmNvZGUoSldUX1NFQ1JFVClcbiAgdHJ5IHtcbiAgICBhd2FpdCBqb3NlLmp3dFZlcmlmeShqd3QsIHNlY3JldEtleSlcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgY29uc29sZS5lcnJvcihlcnIpXG4gICAgcmV0dXJuIGZhbHNlXG4gIH1cbiAgcmV0dXJuIHRydWVcbn1cblxuc2VydmUoYXN5bmMgKHJlcTogUmVxdWVzdCkgPT4ge1xuICBpZiAocmVxLm1ldGhvZCAhPT0gJ09QVElPTlMnICYmIFZFUklGWV9KV1QpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgdG9rZW4gPSBnZXRBdXRoVG9rZW4ocmVxKVxuICAgICAgY29uc3QgaXNWYWxpZEpXVCA9IGF3YWl0IHZlcmlmeUpXVCh0b2tlbilcblxuICAgICAgaWYgKCFpc1ZhbGlkSldUKSB7XG4gICAgICAgIHJldHVybiBuZXcgUmVzcG9uc2UoSlNPTi5zdHJpbmdpZnkoeyBtc2c6ICdJbnZhbGlkIEpXVCcgfSksIHtcbiAgICAgICAgICBzdGF0dXM6IDQwMSxcbiAgICAgICAgICBoZWFkZXJzOiB7ICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicgfSxcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGUpXG4gICAgICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KHsgbXNnOiBlLnRvU3RyaW5nKCkgfSksIHtcbiAgICAgICAgc3RhdHVzOiA0MDEsXG4gICAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICBjb25zdCB1cmwgPSBuZXcgVVJMKHJlcS51cmwpXG4gIGNvbnN0IHsgcGF0aG5hbWUgfSA9IHVybFxuICBjb25zdCBwYXRoX3BhcnRzID0gcGF0aG5hbWUuc3BsaXQoJy8nKVxuICBjb25zdCBzZXJ2aWNlX25hbWUgPSBwYXRoX3BhcnRzWzFdXG5cbiAgaWYgKCFzZXJ2aWNlX25hbWUgfHwgc2VydmljZV9uYW1lID09PSAnJykge1xuICAgIGNvbnN0IGVycm9yID0geyBtc2c6ICdtaXNzaW5nIGZ1bmN0aW9uIG5hbWUgaW4gcmVxdWVzdCcgfVxuICAgIHJldHVybiBuZXcgUmVzcG9uc2UoSlNPTi5zdHJpbmdpZnkoZXJyb3IpLCB7XG4gICAgICBzdGF0dXM6IDQwMCxcbiAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgIH0pXG4gIH1cblxuICBjb25zdCBzZXJ2aWNlUGF0aCA9IGAvaG9tZS9kZW5vL2Z1bmN0aW9ucy8ke3NlcnZpY2VfbmFtZX1gXG4gIGNvbnNvbGUuZXJyb3IoYHNlcnZpbmcgdGhlIHJlcXVlc3Qgd2l0aCAke3NlcnZpY2VQYXRofWApXG5cbiAgY29uc3QgbWVtb3J5TGltaXRNYiA9IDE1MFxuICBjb25zdCB3b3JrZXJUaW1lb3V0TXMgPSAxICogNjAgKiAxMDAwXG4gIGNvbnN0IG5vTW9kdWxlQ2FjaGUgPSBmYWxzZVxuICBjb25zdCBpbXBvcnRNYXBQYXRoID0gbnVsbFxuICBjb25zdCBlbnZWYXJzT2JqID0gRGVuby5lbnYudG9PYmplY3QoKVxuICBjb25zdCBlbnZWYXJzID0gT2JqZWN0LmtleXMoZW52VmFyc09iaikubWFwKChrKSA9PiBbaywgZW52VmFyc09ialtrXV0pXG5cbiAgdHJ5IHtcbiAgICBjb25zdCB3b3JrZXIgPSBhd2FpdCBFZGdlUnVudGltZS51c2VyV29ya2Vycy5jcmVhdGUoe1xuICAgICAgc2VydmljZVBhdGgsXG4gICAgICBtZW1vcnlMaW1pdE1iLFxuICAgICAgd29ya2VyVGltZW91dE1zLFxuICAgICAgbm9Nb2R1bGVDYWNoZSxcbiAgICAgIGltcG9ydE1hcFBhdGgsXG4gICAgICBlbnZWYXJzLFxuICAgIH0pXG4gICAgcmV0dXJuIGF3YWl0IHdvcmtlci5mZXRjaChyZXEpXG4gIH0gY2F0Y2ggKGUpIHtcbiAgICBjb25zdCBlcnJvciA9IHsgbXNnOiBlLnRvU3RyaW5nKCkgfVxuICAgIHJldHVybiBuZXcgUmVzcG9uc2UoSlNPTi5zdHJpbmdpZnkoZXJyb3IpLCB7XG4gICAgICBzdGF0dXM6IDUwMCxcbiAgICAgIGhlYWRlcnM6IHsgJ0NvbnRlbnQtVHlwZSc6ICdhcHBsaWNhdGlvbi9qc29uJyB9LFxuICAgIH0pXG4gIH1cbn0pIgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi92b2x1bWVzL2Z1bmN0aW9ucy9oZWxsby9pbmRleC50cwogICAgICAgIHRhcmdldDogL2hvbWUvZGVuby9mdW5jdGlvbnMvaGVsbG8vaW5kZXgudHMKICAgICAgICBjb250ZW50OiAiLy8gRm9sbG93IHRoaXMgc2V0dXAgZ3VpZGUgdG8gaW50ZWdyYXRlIHRoZSBEZW5vIGxhbmd1YWdlIHNlcnZlciB3aXRoIHlvdXIgZWRpdG9yOlxuLy8gaHR0cHM6Ly9kZW5vLmxhbmQvbWFudWFsL2dldHRpbmdfc3RhcnRlZC9zZXR1cF95b3VyX2Vudmlyb25tZW50XG4vLyBUaGlzIGVuYWJsZXMgYXV0b2NvbXBsZXRlLCBnbyB0byBkZWZpbml0aW9uLCBldGMuXG5cbmltcG9ydCB7IHNlcnZlIH0gZnJvbSBcImh0dHBzOi8vZGVuby5sYW5kL3N0ZEAwLjE3Ny4xL2h0dHAvc2VydmVyLnRzXCJcblxuc2VydmUoYXN5bmMgKCkgPT4ge1xuICByZXR1cm4gbmV3IFJlc3BvbnNlKFxuICAgIGBcIkhlbGxvIGZyb20gRWRnZSBGdW5jdGlvbnMhXCJgLFxuICAgIHsgaGVhZGVyczogeyBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIiB9IH0sXG4gIClcbn0pXG5cbi8vIFRvIGludm9rZTpcbi8vIGN1cmwgJ2h0dHA6Ly9sb2NhbGhvc3Q6PEtPTkdfSFRUUF9QT1JUPi9mdW5jdGlvbnMvdjEvaGVsbG8nIFxcXG4vLyAgIC0taGVhZGVyICdBdXRob3JpemF0aW9uOiBCZWFyZXIgPGFub24vc2VydmljZV9yb2xlIEFQSSBrZXk+J1xuIgogICAgY29tbWFuZDoKICAgICAgLSBzdGFydAogICAgICAtICctLW1haW4tc2VydmljZScKICAgICAgLSAvaG9tZS9kZW5vL2Z1bmN0aW9ucy9tYWluCiAgc3VwYWJhc2Utc3VwYXZpc29yOgogICAgaW1hZ2U6ICdzdXBhYmFzZS9zdXBhdmlzb3I6Mi41LjEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1zU2ZMJwogICAgICAgIC0gJy1vJwogICAgICAgIC0gL2Rldi9udWxsCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo0MDAwL2FwaS9oZWFsdGgnCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIGludGVydmFsOiA1cwogICAgICByZXRyaWVzOiAxMAogICAgZGVwZW5kc19vbjoKICAgICAgc3VwYWJhc2UtZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgc3VwYWJhc2UtYW5hbHl0aWNzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBQT09MRVJfVEVOQU5UX0lEPWRldl90ZW5hbnQKICAgICAgLSBQT09MRVJfUE9PTF9NT0RFPXRyYW5zYWN0aW9uCiAgICAgIC0gJ1BPT0xFUl9ERUZBVUxUX1BPT0xfU0laRT0ke1BPT0xFUl9ERUZBVUxUX1BPT0xfU0laRTotMjB9JwogICAgICAtICdQT09MRVJfTUFYX0NMSUVOVF9DT05OPSR7UE9PTEVSX01BWF9DTElFTlRfQ09OTjotMTAwfScKICAgICAgLSBQT1JUPTQwMDAKICAgICAgLSAnUE9TVEdSRVNfUE9SVD0ke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9JwogICAgICAtICdQT1NUR1JFU19IT1NUTkFNRT0ke1BPU1RHUkVTX0hPU1ROQU1FOi1zdXBhYmFzZS1kYn0nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LXBvc3RncmVzfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnREFUQUJBU0VfVVJMPWVjdG86Ly9zdXBhYmFzZV9hZG1pbjoke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7UE9TVEdSRVNfSE9TVE5BTUU6LXN1cGFiYXNlLWRifToke1BPU1RHUkVTX1BPUlQ6LTU0MzJ9L19zdXBhYmFzZScKICAgICAgLSBDTFVTVEVSX1BPU1RHUkVTPXRydWUKICAgICAgLSAnU0VDUkVUX0tFWV9CQVNFPSR7U0VSVklDRV9QQVNTV09SRF9TVVBBVklTT1JTRUNSRVR9JwogICAgICAtICdWQVVMVF9FTkNfS0VZPSR7U0VSVklDRV9QQVNTV09SRF9WQVVMVEVOQ30nCiAgICAgIC0gJ0FQSV9KV1RfU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9KV1R9JwogICAgICAtICdNRVRSSUNTX0pXVF9TRUNSRVQ9JHtTRVJWSUNFX1BBU1NXT1JEX0pXVH0nCiAgICAgIC0gUkVHSU9OPWxvY2FsCiAgICAgIC0gJ0VSTF9BRkxBR1M9LXByb3RvX2Rpc3QgaW5ldF90Y3AnCiAgICBjb21tYW5kOgogICAgICAtIC9iaW4vc2gKICAgICAgLSAnLWMnCiAgICAgIC0gJy9hcHAvYmluL21pZ3JhdGUgJiYgL2FwcC9iaW4vc3VwYXZpc29yIGV2YWwgIiQkKGNhdCAvZXRjL3Bvb2xlci9wb29sZXIuZXhzKSIgJiYgL2FwcC9iaW4vc2VydmVyJwogICAgdm9sdW1lczoKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vdm9sdW1lcy9wb29sZXIvcG9vbGVyLmV4cwogICAgICAgIHRhcmdldDogL2V0Yy9wb29sZXIvcG9vbGVyLmV4cwogICAgICAgIGNvbnRlbnQ6ICJ7Om9rLCBffSA9IEFwcGxpY2F0aW9uLmVuc3VyZV9hbGxfc3RhcnRlZCg6c3VwYXZpc29yKVxuezpvaywgdmVyc2lvbn0gPVxuICAgIGNhc2UgU3VwYXZpc29yLlJlcG8ucXVlcnkhKFwic2VsZWN0IHZlcnNpb24oKVwiKSBkb1xuICAgICV7cm93czogW1t2ZXJdXX0gLT4gU3VwYXZpc29yLkhlbHBlcnMucGFyc2VfcGdfdmVyc2lvbih2ZXIpXG4gICAgXyAtPiBuaWxcbiAgICBlbmRcbnBhcmFtcyA9ICV7XG4gICAgXCJleHRlcm5hbF9pZFwiID0+IFN5c3RlbS5nZXRfZW52KFwiUE9PTEVSX1RFTkFOVF9JRFwiKSxcbiAgICBcImRiX2hvc3RcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPU1RHUkVTX0hPU1ROQU1FXCIpLFxuICAgIFwiZGJfcG9ydFwiID0+IFN5c3RlbS5nZXRfZW52KFwiUE9TVEdSRVNfUE9SVFwiKSB8PiBTdHJpbmcudG9faW50ZWdlcigpLFxuICAgIFwiZGJfZGF0YWJhc2VcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPU1RHUkVTX0RCXCIpLFxuICAgIFwicmVxdWlyZV91c2VyXCIgPT4gZmFsc2UsXG4gICAgXCJhdXRoX3F1ZXJ5XCIgPT4gXCJTRUxFQ1QgKiBGUk9NIHBnYm91bmNlci5nZXRfYXV0aCgkMSlcIixcbiAgICBcImRlZmF1bHRfbWF4X2NsaWVudHNcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPT0xFUl9NQVhfQ0xJRU5UX0NPTk5cIiksXG4gICAgXCJkZWZhdWx0X3Bvb2xfc2l6ZVwiID0+IFN5c3RlbS5nZXRfZW52KFwiUE9PTEVSX0RFRkFVTFRfUE9PTF9TSVpFXCIpLFxuICAgIFwiZGVmYXVsdF9wYXJhbWV0ZXJfc3RhdHVzXCIgPT4gJXtcInNlcnZlcl92ZXJzaW9uXCIgPT4gdmVyc2lvbn0sXG4gICAgXCJ1c2Vyc1wiID0+IFsle1xuICAgIFwiZGJfdXNlclwiID0+IFwicGdib3VuY2VyXCIsXG4gICAgXCJkYl9wYXNzd29yZFwiID0+IFN5c3RlbS5nZXRfZW52KFwiUE9TVEdSRVNfUEFTU1dPUkRcIiksXG4gICAgXCJtb2RlX3R5cGVcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPT0xFUl9QT09MX01PREVcIiksXG4gICAgXCJwb29sX3NpemVcIiA9PiBTeXN0ZW0uZ2V0X2VudihcIlBPT0xFUl9ERUZBVUxUX1BPT0xfU0laRVwiKSxcbiAgICBcImlzX21hbmFnZXJcIiA9PiB0cnVlXG4gICAgfV1cbn1cblxudGVuYW50ID0gU3VwYXZpc29yLlRlbmFudHMuZ2V0X3RlbmFudF9ieV9leHRlcm5hbF9pZChwYXJhbXNbXCJleHRlcm5hbF9pZFwiXSlcblxuaWYgdGVuYW50IGRvXG4gIHs6b2ssIF99ID0gU3VwYXZpc29yLlRlbmFudHMudXBkYXRlX3RlbmFudCh0ZW5hbnQsIHBhcmFtcylcbmVsc2VcbiAgezpvaywgX30gPSBTdXBhdmlzb3IuVGVuYW50cy5jcmVhdGVfdGVuYW50KHBhcmFtcylcbmVuZFxuIgo=", "tags": [ "firebase", "alternative", @@ -4438,6 +4529,20 @@ "minversion": "0.0.0", "port": "8080" }, + "twenty": { + "documentation": "https://docs.twenty.com?utm_source=coolify.io", + "slogan": "Twenty is a CRM designed to fit your unique business needs.", + "compose": "c2VydmljZXM6CiAgdHdlbnR5OgogICAgaW1hZ2U6ICd0d2VudHljcm0vdHdlbnR5OnYxLjE1JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX1RXRU5UWV8zMDAwCiAgICAgIC0gJ1NFUlZFUl9VUkw9JHtTRVJWSUNFX0ZRRE5fVFdFTlRZfScKICAgICAgLSAnRlJPTlRfQkFTRV9VUkw9JHtTRVJWSUNFX0ZRRE5fVFdFTlRZfScKICAgICAgLSAnQVBQX1NFQ1JFVD0ke1NFUlZJQ0VfQkFTRTY0XzMyX1NFQ1JFVH0nCiAgICAgIC0gRU5BQkxFX0RCX01JR1JBVElPTlM9dHJ1ZQogICAgICAtICdDQUNIRV9TVE9SQUdFX1RZUEU9JHtDQUNIRV9TVE9SQUdFX1RZUEU6LXJlZGlzfScKICAgICAgLSAnUkVESVNfVVJMPXJlZGlzOi8vcmVkaXM6NjM3OScKICAgICAgLSAnQVBJX1JBVEVfTElNSVRJTkdfVFRMPSR7QVBJX1JBVEVfTElNSVRJTkdfVFRMOi0xMDB9JwogICAgICAtICdBUElfUkFURV9MSU1JVElOR19MSU1JVD0ke0FQSV9SQVRFX0xJTUlUSU5HX0xJTUlUOi0xMDB9JwogICAgICAtICdQT1NUR1JFU19BRE1JTl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQR19EQVRBQkFTRV9VUkw9cG9zdGdyZXM6Ly8ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU306JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUBwb3N0Z3Jlczo1NDMyLyR7UE9TVEdSRVNfREI6LXR3ZW50eS1kYn0nCiAgICAgIC0gJ0lTX1NJR05fVVBfRElTQUJMRUQ9JHtJU19TSUdOX1VQX0RJU0FCTEVEOi1mYWxzZX0nCiAgICAgIC0gJ1BBU1NXT1JEX1JFU0VUX1RPS0VOX0VYUElSRVNfSU49JHtQQVNTV09SRF9SRVNFVF9UT0tFTl9FWFBJUkVTX0lOOi01bX0nCiAgICAgIC0gJ1dPUktTUEFDRV9JTkFDVElWRV9EQVlTX0JFRk9SRV9OT1RJRklDQVRJT049JHtXT1JLU1BBQ0VfSU5BQ1RJVkVfREFZU19CRUZPUkVfTk9USUZJQ0FUSU9OOi03fScKICAgICAgLSAnV09SS1NQQUNFX0lOQUNUSVZFX0RBWVNfQkVGT1JFX0RFTEVUSU9OPSR7V09SS1NQQUNFX0lOQUNUSVZFX0RBWVNfQkVGT1JFX0RFTEVUSU9OOi0yMX0nCiAgICAgIC0gJ1NUT1JBR0VfVFlQRT0ke1NUT1JBR0VfVFlQRTotbG9jYWx9JwogICAgICAtIFNUT1JBR0VfUzNfUkVHSU9OPSRTVE9SQUdFX1MzX1JFR0lPTgogICAgICAtIFNUT1JBR0VfUzNfTkFNRT0kU1RPUkFHRV9TM19OQU1FCiAgICAgIC0gU1RPUkFHRV9TM19FTkRQT0lOVD0kU1RPUkFHRV9TM19FTkRQT0lOVAogICAgICAtIFNUT1JBR0VfUzNfQUNDRVNTX0tFWV9JRD0kU1RPUkFHRV9TM19BQ0NFU1NfS0VZX0lECiAgICAgIC0gU1RPUkFHRV9TM19TRUNSRVRfQUNDRVNTX0tFWT0kU1RPUkFHRV9TM19TRUNSRVRfQUNDRVNTX0tFWQogICAgICAtICdNRVNTQUdFX1FVRVVFX1RZUEU9JHtNRVNTQUdFX1FVRVVFX1RZUEU6LXBnLWJvc3N9JwogICAgICAtIEVNQUlMX0ZST01fQUREUkVTUz0kRU1BSUxfRlJPTV9BRERSRVNTCiAgICAgIC0gRU1BSUxfRlJPTV9OQU1FPSRFTUFJTF9GUk9NX05BTUUKICAgICAgLSBFTUFJTF9TWVNURU1fQUREUkVTUz0kRU1BSUxfU1lTVEVNX0FERFJFU1MKICAgICAgLSAnRU1BSUxfRFJJVkVSPSR7RU1BSUxfRFJJVkVSOi1sb2dnZXJ9JwogICAgICAtIEVNQUlMX1NNVFBfSE9TVD0kRU1BSUxfU01UUF9IT1NUCiAgICAgIC0gRU1BSUxfU01UUF9QT1JUPSRFTUFJTF9TTVRQX1BPUlQKICAgICAgLSBFTUFJTF9TTVRQX1VTRVI9JEVNQUlMX1NNVFBfVVNFUgogICAgICAtIEVNQUlMX1NNVFBfUEFTU1dPUkQ9JEVNQUlMX1NNVFBfUEFTU1dPUkQKICAgICAgLSBTSUdOX0lOX1BSRUZJTExFRD1mYWxzZQogICAgICAtICdERUJVR19NT0RFPSR7REVCVUdfTU9ERTotZmFsc2V9JwogICAgICAtICdURUxFTUVUUllfRU5BQkxFRD0ke1RFTEVNRVRSWV9FTkFCTEVEOi1mYWxzZX0nCiAgICB2b2x1bWVzOgogICAgICAtICd0d2VudHktbG9jYWwtc3RvcmFnZTovYXBwL3BhY2thZ2VzL3R3ZW50eS1zZXJ2ZXIvLmxvY2FsLXN0b3JhZ2UnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6MzAwMC9oZWFsdGh6JwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTAKICAgICAgc3RhcnRfcGVyaW9kOiAxMHMKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgd29ya2VyOgogICAgaW1hZ2U6ICd0d2VudHljcm0vdHdlbnR5OnYxLjE1JwogICAgY29tbWFuZDoKICAgICAgLSB5YXJuCiAgICAgIC0gJ3dvcmtlcjpwcm9kJwogICAgdm9sdW1lczoKICAgICAgLSAndHdlbnR5LWxvY2FsLXN0b3JhZ2U6L2FwcC9wYWNrYWdlcy90d2VudHktc2VydmVyLy5sb2NhbC1zdG9yYWdlJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX1RXRU5UWV8zMDAwCiAgICAgIC0gJ1NFUlZFUl9VUkw9JHtTRVJWSUNFX0ZRRE5fVFdFTlRZfScKICAgICAgLSAnRlJPTlRfQkFTRV9VUkw9JHtTRVJWSUNFX0ZRRE5fVFdFTlRZfScKICAgICAgLSAnQVBQX1NFQ1JFVD0ke1NFUlZJQ0VfQkFTRTY0XzMyX1NFQ1JFVH0nCiAgICAgIC0gRU5BQkxFX0RCX01JR1JBVElPTlM9dHJ1ZQogICAgICAtICdDQUNIRV9TVE9SQUdFX1RZUEU9JHtDQUNIRV9TVE9SQUdFX1RZUEU6LXJlZGlzfScKICAgICAgLSAnUkVESVNfVVJMPXJlZGlzOi8vcmVkaXM6NjM3OScKICAgICAgLSAnQVBJX1JBVEVfTElNSVRJTkdfVFRMPSR7QVBJX1JBVEVfTElNSVRJTkdfVFRMOi0xMDB9JwogICAgICAtICdBUElfUkFURV9MSU1JVElOR19MSU1JVD0ke0FQSV9SQVRFX0xJTUlUSU5HX0xJTUlUOi0xMDB9JwogICAgICAtICdQT1NUR1JFU19BRE1JTl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQR19EQVRBQkFTRV9VUkw9cG9zdGdyZXM6Ly8ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU306JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfUBwb3N0Z3Jlczo1NDMyLyR7UE9TVEdSRVNfREI6LXR3ZW50eS1kYn0nCiAgICAgIC0gJ0lTX1NJR05fVVBfRElTQUJMRUQ9JHtJU19TSUdOX1VQX0RJU0FCTEVEOi1mYWxzZX0nCiAgICAgIC0gJ1BBU1NXT1JEX1JFU0VUX1RPS0VOX0VYUElSRVNfSU49JHtQQVNTV09SRF9SRVNFVF9UT0tFTl9FWFBJUkVTX0lOOi01bX0nCiAgICAgIC0gJ1dPUktTUEFDRV9JTkFDVElWRV9EQVlTX0JFRk9SRV9OT1RJRklDQVRJT049JHtXT1JLU1BBQ0VfSU5BQ1RJVkVfREFZU19CRUZPUkVfTk9USUZJQ0FUSU9OOi03fScKICAgICAgLSAnV09SS1NQQUNFX0lOQUNUSVZFX0RBWVNfQkVGT1JFX0RFTEVUSU9OPSR7V09SS1NQQUNFX0lOQUNUSVZFX0RBWVNfQkVGT1JFX0RFTEVUSU9OOi0yMX0nCiAgICAgIC0gJ1NUT1JBR0VfVFlQRT0ke1NUT1JBR0VfVFlQRTotbG9jYWx9JwogICAgICAtIFNUT1JBR0VfUzNfUkVHSU9OPSRTVE9SQUdFX1MzX1JFR0lPTgogICAgICAtIFNUT1JBR0VfUzNfTkFNRT0kU1RPUkFHRV9TM19OQU1FCiAgICAgIC0gU1RPUkFHRV9TM19FTkRQT0lOVD0kU1RPUkFHRV9TM19FTkRQT0lOVAogICAgICAtIFNUT1JBR0VfUzNfQUNDRVNTX0tFWV9JRD0kU1RPUkFHRV9TM19BQ0NFU1NfS0VZX0lECiAgICAgIC0gU1RPUkFHRV9TM19TRUNSRVRfQUNDRVNTX0tFWT0kU1RPUkFHRV9TM19TRUNSRVRfQUNDRVNTX0tFWQogICAgICAtICdNRVNTQUdFX1FVRVVFX1RZUEU9JHtNRVNTQUdFX1FVRVVFX1RZUEU6LXBnLWJvc3N9JwogICAgICAtIEVNQUlMX0ZST01fQUREUkVTUz0kRU1BSUxfRlJPTV9BRERSRVNTCiAgICAgIC0gRU1BSUxfRlJPTV9OQU1FPSRFTUFJTF9GUk9NX05BTUUKICAgICAgLSBFTUFJTF9TWVNURU1fQUREUkVTUz0kRU1BSUxfU1lTVEVNX0FERFJFU1MKICAgICAgLSAnRU1BSUxfRFJJVkVSPSR7RU1BSUxfRFJJVkVSOi1sb2dnZXJ9JwogICAgICAtIEVNQUlMX1NNVFBfSE9TVD0kRU1BSUxfU01UUF9IT1NUCiAgICAgIC0gRU1BSUxfU01UUF9QT1JUPSRFTUFJTF9TTVRQX1BPUlQKICAgICAgLSBFTUFJTF9TTVRQX1VTRVI9JEVNQUlMX1NNVFBfVVNFUgogICAgICAtIEVNQUlMX1NNVFBfUEFTU1dPUkQ9JEVNQUlMX1NNVFBfUEFTU1dPUkQKICAgICAgLSBTSUdOX0lOX1BSRUZJTExFRD1mYWxzZQogICAgICAtICdERUJVR19NT0RFPSR7REVCVUdfTU9ERTotZmFsc2V9JwogICAgICAtICdURUxFTUVUUllfRU5BQkxFRD0ke1RFTEVNRVRSWV9FTkFCTEVEOi1mYWxzZX0nCiAgICAgIC0gRElTQUJMRV9EQl9NSUdSQVRJT05TPXRydWUKICAgICAgLSBESVNBQkxFX0NST05fSk9CU19SRUdJU1RSQVRJT049dHJ1ZQogICAgZGVwZW5kc19vbjoKICAgICAgdHdlbnR5OgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotdHdlbnR5LWRifScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3Bvc3RncmVzLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczo3LWFscGluZScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3JlZGlzLWRhdGE6L2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gcmVkaXMtY2xpCiAgICAgICAgLSBwaW5nCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK", + "tags": [ + "crm", + "self-hosted", + "dashboard" + ], + "category": "cms", + "logo": "svgs/twenty.svg", + "minversion": "0.0.0", + "port": "3000" + }, "typesense": { "documentation": "https://typesense.org/docs?utm_source=coolify.io", "slogan": "Cutting-edge, in-memory search engine for mere mortals. Knowledge of rocket science optional.", @@ -4521,10 +4626,46 @@ "minversion": "0.0.0", "port": "8000" }, + "uptime-kuma-with-mariadb": { + "documentation": "https://github.com/louislam/uptime-kuma?tab=readme-ov-file?utm_source=coolify.io", + "slogan": "Uptime Kuma is a monitoring tool for tracking the status and performance of your applications in real-time.", + "compose": "c2VydmljZXM6CiAgdXB0aW1lLWt1bWE6CiAgICBpbWFnZTogJ2xvdWlzbGFtL3VwdGltZS1rdW1hOjInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fVVBUSU1FS1VNQV8zMDAxCiAgICAgIC0gJ1RaPSR7VFo6LUV0Yy9VVEN9JwogICAgdm9sdW1lczoKICAgICAgLSAndXB0aW1lLWt1bWEtZGF0YTovYXBwL2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gZXh0cmEvaGVhbHRoY2hlY2sKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICBkZXBlbmRzX29uOgogICAgICBtYXJpYWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgbWFyaWFkYjoKICAgIGltYWdlOiAnbWFyaWFkYjoxMScKICAgIGVudmlyb25tZW50OgogICAgICAtICdNWVNRTF9VU0VSPSR7U0VSVklDRV9VU0VSX01BUklBREJ9JwogICAgICAtICdNWVNRTF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfTUFSSUFEQn0nCiAgICAgIC0gJ01ZU1FMX1JPT1RfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1JPT1R9JwogICAgICAtICdNWVNRTF9EQVRBQkFTRT0ke01ZU1FMX0RBVEFCQVNFOi11cHRpbWUta3VtYS1kYn0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gaGVhbHRoY2hlY2suc2gKICAgICAgICAtICctLWNvbm5lY3QnCiAgICAgICAgLSAnLS1pbm5vZGJfaW5pdGlhbGl6ZWQnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICAgIHZvbHVtZXM6CiAgICAgIC0gJ21hcmlhZGItZGF0YTovdmFyL2xpYi9teXNxbCcK", + "tags": [ + "monitoring", + "status", + "performance", + "web", + "services", + "applications", + "real-time" + ], + "category": "monitoring", + "logo": "svgs/uptime-kuma.svg", + "minversion": "0.0.0", + "port": "3001" + }, + "uptime-kuma-with-mysql": { + "documentation": "https://github.com/louislam/uptime-kuma?tab=readme-ov-file?utm_source=coolify.io", + "slogan": "Uptime Kuma is a monitoring tool for tracking the status and performance of your applications in real-time.", + "compose": "c2VydmljZXM6CiAgdXB0aW1lLWt1bWE6CiAgICBpbWFnZTogJ2xvdWlzbGFtL3VwdGltZS1rdW1hOjInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fVVBUSU1FS1VNQV8zMDAxCiAgICAgIC0gJ1RaPSR7VFo6LUV0Yy9VVEN9JwogICAgdm9sdW1lczoKICAgICAgLSAndXB0aW1lLWt1bWEtZGF0YTovYXBwL2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gZXh0cmEvaGVhbHRoY2hlY2sKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDEwCiAgICBkZXBlbmRzX29uOgogICAgICBteXNxbDoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogIG15c3FsOgogICAgaW1hZ2U6ICdteXNxbDo4JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ01ZU1FMX1VTRVI9JHtTRVJWSUNFX1VTRVJfTVlTUUx9JwogICAgICAtICdNWVNRTF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfTVlTUUx9JwogICAgICAtICdNWVNRTF9ST09UX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9ST09UfScKICAgICAgLSAnTVlTUUxfREFUQUJBU0U9JHtNWVNRTF9EQVRBQkFTRTotdXB0aW1lLWt1bWEtZGJ9JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIG15c3FsYWRtaW4KICAgICAgICAtIHBpbmcKICAgICAgICAtICctaCcKICAgICAgICAtIDEyNy4wLjAuMQogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgICB2b2x1bWVzOgogICAgICAtICdteXNxbC1kYXRhOi92YXIvbGliL215c3FsJwo=", + "tags": [ + "monitoring", + "status", + "performance", + "web", + "services", + "applications", + "real-time" + ], + "category": "monitoring", + "logo": "svgs/uptime-kuma.svg", + "minversion": "0.0.0", + "port": "3001" + }, "uptime-kuma": { "documentation": "https://github.com/louislam/uptime-kuma?tab=readme-ov-file?utm_source=coolify.io", "slogan": "Uptime Kuma is a monitoring tool for tracking the status and performance of your applications in real-time.", - "compose": "c2VydmljZXM6CiAgdXB0aW1lLWt1bWE6CiAgICBpbWFnZTogJ2xvdWlzbGFtL3VwdGltZS1rdW1hOjInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fVVBUSU1FS1VNQV8zMDAxCiAgICB2b2x1bWVzOgogICAgICAtICd1cHRpbWUta3VtYTovYXBwL2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gZXh0cmEvaGVhbHRoY2hlY2sKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQo=", + "compose": "c2VydmljZXM6CiAgdXB0aW1lLWt1bWE6CiAgICBpbWFnZTogJ2xvdWlzbGFtL3VwdGltZS1rdW1hOjInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fVVBUSU1FS1VNQV8zMDAxCiAgICB2b2x1bWVzOgogICAgICAtICd1cHRpbWUta3VtYS1kYXRhOi9hcHAvZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSBleHRyYS9oZWFsdGhjaGVjawogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogMTAK", "tags": [ "monitoring", "status", From e7db637a5da6ccba168a75d8db29efd46c71b082 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Fri, 9 Jan 2026 10:04:42 +0100 Subject: [PATCH 033/191] fix(docker): use dynamic OS ID for Docker repository URL Replace hardcoded 'debian' with ${ID} from /etc/os-release to use the correct Docker repository for Ubuntu, Debian, and Raspbian servers. Co-Authored-By: Claude Opus 4.5 --- app/Actions/Server/InstallDocker.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/Actions/Server/InstallDocker.php b/app/Actions/Server/InstallDocker.php index eb53b32ee..d718d3735 100644 --- a/app/Actions/Server/InstallDocker.php +++ b/app/Actions/Server/InstallDocker.php @@ -117,11 +117,11 @@ class InstallDocker private function getDebianDockerInstallCommand(): string { return "curl --max-time 300 --retry 3 https://releases.rancher.com/install-docker/{$this->dockerVersion}.sh | sh || curl --max-time 300 --retry 3 https://get.docker.com | sh -s -- --version {$this->dockerVersion} || (". - 'install -m 0755 -d /etc/apt/keyrings && '. - 'curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc && '. - 'chmod a+r /etc/apt/keyrings/docker.asc && '. '. /etc/os-release && '. - 'echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list && '. + 'install -m 0755 -d /etc/apt/keyrings && '. + 'curl -fsSL https://download.docker.com/linux/${ID}/gpg -o /etc/apt/keyrings/docker.asc && '. + 'chmod a+r /etc/apt/keyrings/docker.asc && '. + 'echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/${ID} ${VERSION_CODENAME} stable" > /etc/apt/sources.list.d/docker.list && '. 'apt-get update && '. 'apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin'. ')'; From 00416888b8d4ce387409ac88acf39d9ac7d34fbb Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Fri, 9 Jan 2026 10:10:34 +0100 Subject: [PATCH 034/191] docs: remove git worktree symlink instructions from CLAUDE.md Remove the 'Git Worktree Shared Dependencies' section which contained Conductor-specific setup instructions that are not relevant to the main repository documentation. Co-Authored-By: Claude Opus 4.5 --- CLAUDE.md | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 4be85fcc9..5cddb7fd0 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -10,42 +10,6 @@ This file provides guidance to **Claude Code** (claude.ai/code) when working wit Coolify is an open-source, self-hostable platform for deploying applications and managing servers - an alternative to Heroku/Netlify/Vercel. It's built with Laravel (PHP) and uses Docker for containerization. -## Git Worktree Shared Dependencies - -This repository uses git worktrees for parallel development with **automatic shared dependency setup** via Conductor. - -### How It Works - -The `conductor.json` setup script (`scripts/conductor-setup.sh`) automatically: -1. Creates symlinks from worktree's `node_modules` and `vendor` to the main repository's directories -2. All worktrees share the same dependencies from the main repository -3. This happens automatically when Conductor creates a new worktree - -### Benefits - -- **Save disk space**: Only one copy of dependencies across all worktrees -- **Faster setup**: No need to run `npm install` or `composer install` for each worktree -- **Consistent versions**: All worktrees use the same dependency versions -- **Auto-configured**: Handled by Conductor's setup script -- **Simple**: Uses the main repo's existing directories, no extra folders - -### Manual Setup (If Needed) - -If you need to set up symlinks manually or for non-Conductor worktrees: - -```bash -# From the worktree directory -rm -rf node_modules vendor -ln -sf ../../node_modules node_modules -ln -sf ../../vendor vendor -``` - -### Important Notes - -- Dependencies are shared from the main repository (`$CONDUCTOR_ROOT_PATH`) -- Run `npm install` or `composer install` from the main repo or any worktree to update all -- If different branches need different dependency versions, this won't work - remove symlinks and use separate directories - ## Development Commands ### Frontend Development From 75d10bb7bf15eb5ec6e0599c6cadd3adcc3f9f7b Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Fri, 9 Jan 2026 10:20:56 +0100 Subject: [PATCH 035/191] fix(scripts): add jean run --- jean.json | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/jean.json b/jean.json index 4e5c788ed..402bcd02d 100644 --- a/jean.json +++ b/jean.json @@ -1,5 +1,6 @@ { "scripts": { - "setup": "cp $JEAN_ROOT_PATH/.env . && mkdir -p .claude && cp $JEAN_ROOT_PATH/.claude/settings.local.json .claude/settings.local.json" + "setup": "cp $JEAN_ROOT_PATH/.env . && mkdir -p .claude && cp $JEAN_ROOT_PATH/.claude/settings.local.json .claude/settings.local.json", + "run": "docker rm -f coolify coolify-minio-init coolify-realtime coolify-minio coolify-testing-host coolify-redis coolify-db coolify-mail coolify-vite; spin up; spin down" } -} +} \ No newline at end of file From 9962ca8ba9fdbb2e5f01aeda92c7e289f97be791 Mon Sep 17 00:00:00 2001 From: "Christopher N. KATOYI" Date: Sat, 10 Jan 2026 10:43:20 -0500 Subject: [PATCH 036/191] feat(service): add seaweedfs template (#7617) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 🏔️ Peak <122374094+peaklabs-dev@users.noreply.github.com> --- public/seaweedfs.png | Bin 0 -> 78638 bytes templates/compose/seaweedfs.yaml | 87 +++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) create mode 100644 public/seaweedfs.png create mode 100644 templates/compose/seaweedfs.yaml diff --git a/public/seaweedfs.png b/public/seaweedfs.png new file mode 100644 index 0000000000000000000000000000000000000000..74bfb12a0d20cf54080980e7d4fe1a7d6597c36a GIT binary patch literal 78638 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 Ds*%E} literal 0 HcmV?d00001 diff --git a/templates/compose/seaweedfs.yaml b/templates/compose/seaweedfs.yaml new file mode 100644 index 000000000..a1147da9c --- /dev/null +++ b/templates/compose/seaweedfs.yaml @@ -0,0 +1,87 @@ +# documentation: https://github.com/seaweedfs/seaweedfs +# slogan: SeaweedFS is a simple and highly scalable distributed file system. Compatible with S3, with an admin web interface. +# category: storage +# tags: object, storage, server, s3, api +# logo: svgs/garage.svg +# port: 8333 + +services: + seaweedfs-master: + image: chrislusf/seaweedfs:4.05 + environment: + - SERVICE_URL_S3_8333 + - AWS_ACCESS_KEY_ID=${SERVICE_USER_S3} + - AWS_SECRET_ACCESS_KEY=${SERVICE_PASSWORD_S3} + volumes: + - seaweedfs-s3-data:/data + - type: bind + source: ./base-config.json + target: /base-config.json + content: | + { + "identities": [ + { + "name": "anonymous", + "actions": [ + "Read" + ] + }, + { + "name": "admin", + "credentials": [ + { + "accessKey": "env:AWS_ACCESS_KEY_ID", + "secretKey": "env:AWS_SECRET_ACCESS_KEY" + } + ], + "actions": [ + "Admin", + "Read", + "ReadAcp", + "List", + "Tagging", + "Write", + "WriteAcp" + ] + } + ] + } + entrypoint: | + sh -c '\ + sed "s/env:AWS_ACCESS_KEY_ID/$AWS_ACCESS_KEY_ID/g" /base-config.json > /base1-config.json; \ + sed "s/env:AWS_SECRET_ACCESS_KEY/$AWS_SECRET_ACCESS_KEY/g" /base1-config.json > /config.json; \ + weed server -dir=/data -master.port=9333 -s3 -s3.port=8333 -s3.config=/config.json\ + ' + healthcheck: + test: + - CMD-SHELL + - "wget --spider -q http://0.0.0.0:8333; [ $$? -le 8 ]" + interval: 10s + timeout: 5s + retries: 10 + + seaweedfs-admin: + image: chrislusf/seaweedfs:4.05 + environment: + - SERVICE_URL_ADMIN_23646 + - SEAWEED_USER_ADMIN=${SERVICE_USER_ADMIN} + - SEAWEED_PASSWORD_ADMIN=${SERVICE_PASSWORD_ADMIN} + command: + - admin + - "-master=seaweedfs-master:9333" + - "-adminUser=${SEAWEED_USER_ADMIN}" + - "-adminPassword=${SEAWEED_PASSWORD_ADMIN}" + - "-port=23646" + - "-dataDir=/data" + volumes: + - seaweedfs-admin-data:/data + healthcheck: + test: + - CMD-SHELL + - "wget --spider -q http://0.0.0.0:23646; [ $$? -le 8 ]" + interval: 10s + timeout: 5s + retries: 10 + depends_on: + seaweedfs-master: + condition: service_healthy From 2f5e879b73ca750a22a65a6a08bd5e3da2583bcf Mon Sep 17 00:00:00 2001 From: Hendrik Kleinwaechter Date: Sat, 10 Jan 2026 17:34:13 +0100 Subject: [PATCH 037/191] feat: add application logs link to preview deployments PR comment (#7906) --- app/Jobs/ApplicationPullRequestUpdateJob.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/Jobs/ApplicationPullRequestUpdateJob.php b/app/Jobs/ApplicationPullRequestUpdateJob.php index d2e3cc964..05453b6a3 100755 --- a/app/Jobs/ApplicationPullRequestUpdateJob.php +++ b/app/Jobs/ApplicationPullRequestUpdateJob.php @@ -54,8 +54,9 @@ class ApplicationPullRequestUpdateJob implements ShouldBeEncrypted, ShouldQueue ProcessStatus::CLOSED => '', // Already handled above, but included for completeness }; $this->build_logs_url = base_url()."/project/{$this->application->environment->project->uuid}/environment/{$this->application->environment->uuid}/application/{$this->application->uuid}/deployment/{$this->deployment_uuid}"; + $application_logs_url = base_url()."/project/{$this->application->environment->project->uuid}/environment/{$this->application->environment->uuid}/application/{$this->application->uuid}/logs"; - $this->body .= '[Open Build Logs]('.$this->build_logs_url.")\n\n\n"; + $this->body .= '[Open Build Logs]('.$this->build_logs_url.') | [Open Application Logs]('.$application_logs_url.")\n\n\n"; $this->body .= 'Last updated at: '.now()->toDateTimeString().' CET'; if ($this->preview->pull_request_issue_comment_id) { $this->update_comment(); From 31ba241d973e7ce40a18c2280f047e32ccfeaaff Mon Sep 17 00:00:00 2001 From: Yassine Benh <43334826+YassineBenh@users.noreply.github.com> Date: Sat, 10 Jan 2026 20:22:29 +0100 Subject: [PATCH 038/191] feat(api): add tag filtering on the applications list endpoint (#7360) --- .../Api/ApplicationsController.php | 31 ++++++++++++++----- openapi.json | 11 +++++++ openapi.yaml | 8 +++++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index b7e9ac6ff..0ec63562e 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -64,6 +64,17 @@ class ApplicationsController extends Controller ['bearerAuth' => []], ], tags: ['Applications'], + parameters: [ + new OA\Parameter( + name: 'tag', + in: 'query', + description: 'Filter applications by tag name.', + required: false, + schema: new OA\Schema( + type: 'string', + ) + ), + ], responses: [ new OA\Response( response: 200, @@ -94,13 +105,19 @@ class ApplicationsController extends Controller if (is_null($teamId)) { return invalidTokenResponse(); } - $projects = Project::where('team_id', $teamId)->get(); - $applications = collect(); - $applications->push($projects->pluck('applications')->flatten()); - $applications = $applications->flatten(); - $applications = $applications->map(function ($application) { - return $this->removeSensitiveData($application); - }); + + $tagName = $request->query('tag'); + + $applications = Application::ownedByCurrentTeamAPI($teamId) + ->when($tagName, function ($query, $tagName) { + $query->whereHas('tags', function ($query) use ($tagName) { + $query->where('name', $tagName); + }); + }) + ->get() + ->map(function ($application) { + return $this->removeSensitiveData($application); + }); return response()->json($applications); } diff --git a/openapi.json b/openapi.json index 9bbae8154..5a2465a10 100644 --- a/openapi.json +++ b/openapi.json @@ -19,6 +19,17 @@ "summary": "List", "description": "List all applications.", "operationId": "list-applications", + "parameters": [ + { + "name": "tag", + "in": "query", + "description": "Filter applications by tag name.", + "required": false, + "schema": { + "type": "string" + } + } + ], "responses": { "200": { "description": "Get all applications.", diff --git a/openapi.yaml b/openapi.yaml index 4a68857fb..28aba508f 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -14,6 +14,14 @@ paths: summary: List description: 'List all applications.' operationId: list-applications + parameters: + - + name: tag + in: query + description: 'Filter applications by tag name.' + required: false + schema: + type: string responses: '200': description: 'Get all applications.' From 7c7c09aa3d0f996e91525a35ae66e9e0818e4c91 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Sat, 10 Jan 2026 22:29:11 +0100 Subject: [PATCH 039/191] fix(api): create service validation and docs - if service type and docker_compose_raw is filled show an error - if service type is not valid show an error with all valid service types - remove enum from service type docs as it always gets outdated --- .../Controllers/Api/ServicesController.php | 107 +++--------------- 1 file changed, 13 insertions(+), 94 deletions(-) diff --git a/app/Http/Controllers/Api/ServicesController.php b/app/Http/Controllers/Api/ServicesController.php index 6a00818aa..ec3d036bc 100644 --- a/app/Http/Controllers/Api/ServicesController.php +++ b/app/Http/Controllers/Api/ServicesController.php @@ -105,98 +105,7 @@ class ServicesController extends Controller type: 'object', required: ['server_uuid', 'project_uuid', 'environment_name', 'environment_uuid'], properties: [ - 'type' => [ - 'description' => 'The one-click service type', - 'type' => 'string', - 'enum' => [ - 'activepieces', - 'appsmith', - 'appwrite', - 'authentik', - 'babybuddy', - 'budge', - 'changedetection', - 'chatwoot', - 'classicpress-with-mariadb', - 'classicpress-with-mysql', - 'classicpress-without-database', - 'cloudflared', - 'code-server', - 'dashboard', - 'directus', - 'directus-with-postgresql', - 'docker-registry', - 'docuseal', - 'docuseal-with-postgres', - 'dokuwiki', - 'duplicati', - 'emby', - 'embystat', - 'fider', - 'filebrowser', - 'firefly', - 'formbricks', - 'ghost', - 'gitea', - 'gitea-with-mariadb', - 'gitea-with-mysql', - 'gitea-with-postgresql', - 'glance', - 'glances', - 'glitchtip', - 'grafana', - 'grafana-with-postgresql', - 'grocy', - 'heimdall', - 'homepage', - 'jellyfin', - 'kuzzle', - 'listmonk', - 'logto', - 'mediawiki', - 'meilisearch', - 'metabase', - 'metube', - 'minio', - 'moodle', - 'n8n', - 'n8n-with-postgresql', - 'next-image-transformation', - 'nextcloud', - 'nocodb', - 'odoo', - 'openblocks', - 'pairdrop', - 'penpot', - 'phpmyadmin', - 'pocketbase', - 'posthog', - 'reactive-resume', - 'rocketchat', - 'shlink', - 'slash', - 'snapdrop', - 'statusnook', - 'stirling-pdf', - 'supabase', - 'syncthing', - 'tolgee', - 'trigger', - 'trigger-with-external-database', - 'twenty', - 'umami', - 'unleash-with-postgresql', - 'unleash-without-database', - 'uptime-kuma', - 'vaultwarden', - 'vikunja', - 'weblate', - 'whoogle', - 'wordpress-with-mariadb', - 'wordpress-with-mysql', - 'wordpress-without-database', - ], - ], + 'type' => ['description' => 'The one-click service type (e.g. "actualbudget", "calibre-web", "gitea-with-mysql" ...)', 'type' => 'string'], 'name' => ['type' => 'string', 'maxLength' => 255, 'description' => 'Name of the service.'], 'description' => ['type' => 'string', 'nullable' => true, 'description' => 'Description of the service.'], 'project_uuid' => ['type' => 'string', 'description' => 'Project UUID.'], @@ -283,6 +192,13 @@ class ServicesController extends Controller 'errors' => $errors, ], 422); } + + if (filled($request->type) && filled($request->docker_compose_raw)) { + return response()->json([ + 'message' => 'You cannot provide both service type and docker_compose_raw. Use one or the other.', + ], 422); + } + $environmentUuid = $request->environment_uuid; $environmentName = $request->environment_name; if (blank($environmentUuid) && blank($environmentName)) { @@ -524,8 +440,11 @@ class ServicesController extends Controller 'uuid' => $service->uuid, 'domains' => $domains, ])->setStatusCode(201); - } else { - return response()->json(['message' => 'No service type or docker_compose_raw provided.'], 400); + } elseif (filled($request->type)) { + return response()->json([ + 'message' => 'Invalid service type.', + 'valid_service_types' => $serviceKeys, + ], 404); } } From 27a4cb47ef3b9243bb3af4de1dc3d93d7abe45ec Mon Sep 17 00:00:00 2001 From: ShadowArcanist <162910371+ShadowArcanist@users.noreply.github.com> Date: Sun, 11 Jan 2026 17:51:10 +0100 Subject: [PATCH 040/191] fix(service): signoz metrics env (#7927) --- templates/compose/signoz.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/signoz.yaml b/templates/compose/signoz.yaml index 42e21790c..c7e044947 100644 --- a/templates/compose/signoz.yaml +++ b/templates/compose/signoz.yaml @@ -450,7 +450,7 @@ services: - SIGNOZ_ALERTMANAGER_SIGNOZ_GLOBAL_SMTP__AUTH__USERNAME=${SIGNOZ_ALERTMANAGER_SIGNOZ_GLOBAL_SMTP__AUTH__USERNAME} - SIGNOZ_ALERTMANAGER_SIGNOZ_GLOBAL_SMTP__FROM=${SIGNOZ_ALERTMANAGER_SIGNOZ_GLOBAL_SMTP__FROM} - SIGNOZ_ALERTMANAGER_SIGNOZ_GLOBAL_SMTP__SMARTHOST=${SIGNOZ_ALERTMANAGER_SIGNOZ_GLOBAL_SMTP__SMARTHOST} - - DOT_METRICS_ENABELD=true + - DOT_METRICS_ENABLED=true healthcheck: test: - CMD From 7556ce2f66cfc7b92dab18af8a7371eb30ea45b8 Mon Sep 17 00:00:00 2001 From: Vitaliy Kukharik <37010174+vitabaks@users.noreply.github.com> Date: Sun, 11 Jan 2026 21:56:05 +0500 Subject: [PATCH 041/191] feat(service): update autobase to version 2.5 (#7923) --- templates/compose/autobase.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/compose/autobase.yaml b/templates/compose/autobase.yaml index 5ee398f3e..caafa8cce 100644 --- a/templates/compose/autobase.yaml +++ b/templates/compose/autobase.yaml @@ -6,7 +6,7 @@ services: autobase: - image: autobase/console_ui:2.4.1 + image: autobase/console_ui:2.5.2 platform: linux/amd64 environment: - SERVICE_FQDN_AUTOBASE_80 @@ -22,7 +22,7 @@ services: condition: service_healthy autobase-db: - image: autobase/console_db:2.4.1 + image: autobase/console_db:2.5.2 platform: linux/amd64 environment: - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} @@ -35,7 +35,7 @@ services: retries: 10 autobase-api: - image: autobase/console_api:2.4.1 + image: autobase/console_api:2.5.2 platform: linux/amd64 environment: - PG_CONSOLE_DB_HOST=autobase-db From abd2df312c1a06654911d1d2873eae2a01bb0fed Mon Sep 17 00:00:00 2001 From: Dominic Schmid <45590457+dominic-schmid@users.noreply.github.com> Date: Sun, 11 Jan 2026 18:06:30 +0100 Subject: [PATCH 042/191] fix(ui): hide already registered button when there are 0 users (#7918) --- resources/views/auth/register.blade.php | 28 +++++++++++++------------ 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php index cdfa52a98..0cf1a2772 100644 --- a/resources/views/auth/register.blade.php +++ b/resources/views/auth/register.blade.php @@ -73,21 +73,23 @@ $email = getOldOrLocal('email', 'test3@example.com'); -

From a0c307ac450bf8544fef936fec99875f35bc5482 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Sun, 11 Jan 2026 18:18:36 +0100 Subject: [PATCH 043/191] fix(api): add custom_network_aliases to allowed fields --- app/Http/Controllers/Api/ApplicationsController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index 0ec63562e..ca782651a 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -955,7 +955,7 @@ class ApplicationsController extends Controller if ($return instanceof \Illuminate\Http\JsonResponse) { return $return; } - $allowedFields = ['project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'private_key_uuid', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'redirect', 'github_app_uuid', 'instant_deploy', 'dockerfile', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'watch_paths', 'use_build_server', 'static_image', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network', 'force_domain_override', 'autogenerate_domain', 'is_container_label_escape_enabled']; + $allowedFields = ['project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'type', 'name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'private_key_uuid', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'custom_network_aliases', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'redirect', 'github_app_uuid', 'instant_deploy', 'dockerfile', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'watch_paths', 'use_build_server', 'static_image', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network', 'force_domain_override', 'autogenerate_domain', 'is_container_label_escape_enabled']; $validator = customApiValidator($request->all(), [ 'name' => 'string|max:255', @@ -2180,7 +2180,7 @@ class ApplicationsController extends Controller $this->authorize('update', $application); $server = $application->destination->server; - $allowedFields = ['name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'redirect', 'instant_deploy', 'use_build_server', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network', 'force_domain_override', 'is_container_label_escape_enabled']; + $allowedFields = ['name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings','custom_network_aliases', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'redirect', 'instant_deploy', 'use_build_server', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network', 'force_domain_override', 'is_container_label_escape_enabled']; $validationRules = [ 'name' => 'string|max:255', From 9c0e308dd35aae4ff06d4c7e3552f281e894c24e Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Sun, 11 Jan 2026 18:26:11 +0100 Subject: [PATCH 044/191] refactor(api): make docker_compose_raw description more clear --- app/Http/Controllers/Api/ServicesController.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/ServicesController.php b/app/Http/Controllers/Api/ServicesController.php index ec3d036bc..4025898b9 100644 --- a/app/Http/Controllers/Api/ServicesController.php +++ b/app/Http/Controllers/Api/ServicesController.php @@ -114,7 +114,7 @@ class ServicesController extends Controller 'server_uuid' => ['type' => 'string', 'description' => 'Server UUID.'], 'destination_uuid' => ['type' => 'string', 'description' => 'Destination UUID. Required if server has multiple destinations.'], 'instant_deploy' => ['type' => 'boolean', 'default' => false, 'description' => 'Start the service immediately after creation.'], - 'docker_compose_raw' => ['type' => 'string', 'description' => 'The Docker Compose raw content.'], + 'docker_compose_raw' => ['type' => 'string', 'description' => 'The base64 encoded Docker Compose content.'], ], ), ), @@ -621,7 +621,7 @@ class ServicesController extends Controller 'destination_uuid' => ['type' => 'string', 'description' => 'The destination UUID.'], 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the service should be deployed instantly.'], 'connect_to_docker_network' => ['type' => 'boolean', 'default' => false, 'description' => 'Connect the service to the predefined docker network.'], - 'docker_compose_raw' => ['type' => 'string', 'description' => 'The Docker Compose raw content.'], + 'docker_compose_raw' => ['type' => 'string', 'description' => 'The base64 encoded Docker Compose content.'], ], ) ), From ca2d02d8a344a039a8fc8863a78831bd6aa4ac52 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Sat, 10 Jan 2026 22:31:06 +0100 Subject: [PATCH 045/191] chore(api): update openapi json and yaml --- openapi.json | 96 +++------------------------------------------------- openapi.yaml | 7 ++-- 2 files changed, 7 insertions(+), 96 deletions(-) diff --git a/openapi.json b/openapi.json index 5a2465a10..9c31f7628 100644 --- a/openapi.json +++ b/openapi.json @@ -8809,96 +8809,8 @@ ], "properties": { "type": { - "description": "The one-click service type", - "type": "string", - "enum": [ - "activepieces", - "appsmith", - "appwrite", - "authentik", - "babybuddy", - "budge", - "changedetection", - "chatwoot", - "classicpress-with-mariadb", - "classicpress-with-mysql", - "classicpress-without-database", - "cloudflared", - "code-server", - "dashboard", - "directus", - "directus-with-postgresql", - "docker-registry", - "docuseal", - "docuseal-with-postgres", - "dokuwiki", - "duplicati", - "emby", - "embystat", - "fider", - "filebrowser", - "firefly", - "formbricks", - "ghost", - "gitea", - "gitea-with-mariadb", - "gitea-with-mysql", - "gitea-with-postgresql", - "glance", - "glances", - "glitchtip", - "grafana", - "grafana-with-postgresql", - "grocy", - "heimdall", - "homepage", - "jellyfin", - "kuzzle", - "listmonk", - "logto", - "mediawiki", - "meilisearch", - "metabase", - "metube", - "minio", - "moodle", - "n8n", - "n8n-with-postgresql", - "next-image-transformation", - "nextcloud", - "nocodb", - "odoo", - "openblocks", - "pairdrop", - "penpot", - "phpmyadmin", - "pocketbase", - "posthog", - "reactive-resume", - "rocketchat", - "shlink", - "slash", - "snapdrop", - "statusnook", - "stirling-pdf", - "supabase", - "syncthing", - "tolgee", - "trigger", - "trigger-with-external-database", - "twenty", - "umami", - "unleash-with-postgresql", - "unleash-without-database", - "uptime-kuma", - "vaultwarden", - "vikunja", - "weblate", - "whoogle", - "wordpress-with-mariadb", - "wordpress-with-mysql", - "wordpress-without-database" - ] + "description": "The one-click service type (e.g. \"actualbudget\", \"calibre-web\", \"gitea-with-mysql\" ...)", + "type": "string" }, "name": { "type": "string", @@ -8937,7 +8849,7 @@ }, "docker_compose_raw": { "type": "string", - "description": "The Docker Compose raw content." + "description": "The base64 encoded Docker Compose content." } }, "type": "object" @@ -9187,7 +9099,7 @@ }, "docker_compose_raw": { "type": "string", - "description": "The Docker Compose raw content." + "description": "The base64 encoded Docker Compose content." } }, "type": "object" diff --git a/openapi.yaml b/openapi.yaml index 28aba508f..198322328 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -5581,9 +5581,8 @@ paths: - environment_uuid properties: type: - description: 'The one-click service type' + description: 'The one-click service type (e.g. "actualbudget", "calibre-web", "gitea-with-mysql" ...)' type: string - enum: [activepieces, appsmith, appwrite, authentik, babybuddy, budge, changedetection, chatwoot, classicpress-with-mariadb, classicpress-with-mysql, classicpress-without-database, cloudflared, code-server, dashboard, directus, directus-with-postgresql, docker-registry, docuseal, docuseal-with-postgres, dokuwiki, duplicati, emby, embystat, fider, filebrowser, firefly, formbricks, ghost, gitea, gitea-with-mariadb, gitea-with-mysql, gitea-with-postgresql, glance, glances, glitchtip, grafana, grafana-with-postgresql, grocy, heimdall, homepage, jellyfin, kuzzle, listmonk, logto, mediawiki, meilisearch, metabase, metube, minio, moodle, n8n, n8n-with-postgresql, next-image-transformation, nextcloud, nocodb, odoo, openblocks, pairdrop, penpot, phpmyadmin, pocketbase, posthog, reactive-resume, rocketchat, shlink, slash, snapdrop, statusnook, stirling-pdf, supabase, syncthing, tolgee, trigger, trigger-with-external-database, twenty, umami, unleash-with-postgresql, unleash-without-database, uptime-kuma, vaultwarden, vikunja, weblate, whoogle, wordpress-with-mariadb, wordpress-with-mysql, wordpress-without-database] name: type: string maxLength: 255 @@ -5613,7 +5612,7 @@ paths: description: 'Start the service immediately after creation.' docker_compose_raw: type: string - description: 'The Docker Compose raw content.' + description: 'The base64 encoded Docker Compose content.' type: object responses: '201': @@ -5780,7 +5779,7 @@ paths: description: 'Connect the service to the predefined docker network.' docker_compose_raw: type: string - description: 'The Docker Compose raw content.' + description: 'The base64 encoded Docker Compose content.' type: object responses: '200': From 9253586f8fa545040388a3394c8c895b8b9da443 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Sat, 10 Jan 2026 22:41:20 +0100 Subject: [PATCH 046/191] refactor(api): update application create endpoints docs --- app/Http/Controllers/Api/ApplicationsController.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index ca782651a..b1ca08051 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -579,8 +579,8 @@ class ApplicationsController extends Controller } #[OA\Post( - summary: 'Create (Dockerfile)', - description: 'Create new application based on a simple Dockerfile.', + summary: 'Create (Dockerfile without git)', + description: 'Create new application based on a simple Dockerfile (without git).', path: '/applications/dockerfile', operationId: 'create-dockerfile-application', security: [ @@ -715,8 +715,8 @@ class ApplicationsController extends Controller } #[OA\Post( - summary: 'Create (Docker Image)', - description: 'Create new application based on a prebuilt docker image', + summary: 'Create (Docker Image without git)', + description: 'Create new application based on a prebuilt docker image (without git).', path: '/applications/dockerimage', operationId: 'create-dockerimage-application', security: [ @@ -2180,7 +2180,7 @@ class ApplicationsController extends Controller $this->authorize('update', $application); $server = $application->destination->server; - $allowedFields = ['name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings','custom_network_aliases', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'docker_compose_location', 'docker_compose_raw', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'redirect', 'instant_deploy', 'use_build_server', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network', 'force_domain_override', 'is_container_label_escape_enabled']; + $allowedFields = ['name', 'description', 'is_static', 'domains', 'git_repository', 'git_branch', 'git_commit_sha', 'docker_registry_image_name', 'docker_registry_image_tag', 'build_pack', 'static_image', 'install_command', 'build_command', 'start_command', 'ports_exposes', 'ports_mappings','custom_network_aliases', 'base_directory', 'publish_directory', 'health_check_enabled', 'health_check_path', 'health_check_port', 'health_check_host', 'health_check_method', 'health_check_return_code', 'health_check_scheme', 'health_check_response_text', 'health_check_interval', 'health_check_timeout', 'health_check_retries', 'health_check_start_period', 'limits_memory', 'limits_memory_swap', 'limits_memory_swappiness', 'limits_memory_reservation', 'limits_cpus', 'limits_cpuset', 'limits_cpu_shares', 'custom_labels', 'custom_docker_run_options', 'post_deployment_command', 'post_deployment_command_container', 'pre_deployment_command', 'pre_deployment_command_container', 'watch_paths', 'manual_webhook_secret_github', 'manual_webhook_secret_gitlab', 'manual_webhook_secret_bitbucket', 'manual_webhook_secret_gitea', 'docker_compose_location', 'docker_compose_custom_start_command', 'docker_compose_custom_build_command', 'docker_compose_domains', 'redirect', 'instant_deploy', 'use_build_server', 'custom_nginx_configuration', 'is_http_basic_auth_enabled', 'http_basic_auth_username', 'http_basic_auth_password', 'connect_to_docker_network', 'force_domain_override', 'is_container_label_escape_enabled']; $validationRules = [ 'name' => 'string|max:255', From 7c0cb2f59d0e71df3a4f0c39c94b3db97f233f45 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Sat, 10 Jan 2026 22:44:52 +0100 Subject: [PATCH 047/191] fix(api): deprecate applications compose endpoint - this endpoint is a duplicate of the services endpoint and also updates fields that do not exist which makes it unstable --- app/Http/Controllers/Api/ApplicationsController.php | 8 ++++++-- routes/api.php | 4 ++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index b1ca08051..a08143022 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -847,11 +847,15 @@ class ApplicationsController extends Controller return $this->create_application($request, 'dockerimage'); } + /** + * @deprecated Use POST /api/v1/services instead. This endpoint creates a Service, not an Application and is an unstable duplicate of POST /api/v1/services. + */ #[OA\Post( - summary: 'Create (Docker Compose)', - description: 'Create new application based on a docker-compose file.', + summary: 'Create (Docker Compose) (Deprecated)', + description: 'Create new application based on a docker-compose file (without git).', path: '/applications/dockercompose', operationId: 'create-dockercompose-application', + deprecated: true, security: [ ['bearerAuth' => []], ], diff --git a/routes/api.php b/routes/api.php index aaf7d794b..8ff1fd1cc 100644 --- a/routes/api.php +++ b/routes/api.php @@ -103,6 +103,10 @@ Route::group([ Route::post('/applications/private-deploy-key', [ApplicationsController::class, 'create_private_deploy_key_application'])->middleware(['api.ability:write']); Route::post('/applications/dockerfile', [ApplicationsController::class, 'create_dockerfile_application'])->middleware(['api.ability:write']); Route::post('/applications/dockerimage', [ApplicationsController::class, 'create_dockerimage_application'])->middleware(['api.ability:write']); + + /** + * @deprecated Use POST /api/v1/services instead. This endpoint creates a Service, not an Application and is a unstable duplicate of POST /api/v1/services. + */ Route::post('/applications/dockercompose', [ApplicationsController::class, 'create_dockercompose_application'])->middleware(['api.ability:write']); Route::get('/applications/{uuid}', [ApplicationsController::class, 'application_by_uuid'])->middleware(['api.ability:read']); From ce3cae3ff9bf3f1580427df21c7883b7f19e4e0f Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 12 Jan 2026 21:42:20 +0100 Subject: [PATCH 048/191] fix(api): applications post and patch endpoints - remove `docker_compose_raw` from post and patch endpoints, as the compose file is sourced from git and should not be manually settable via the api - improve the documentation for `docker_compose_domains` (URLs) - enhanced array validation for `docker_compose_domains` by validating each array field and verifying which fields are allowed - set a custom array validation error message, as the default message is not really clear - show an error if the user attempts to set `domains` when the build pack is `dockercompose` - validate that the `domains` in `docker_compose_domains` are proper URLs and include a valid scheme (`http` or `https`) --- .../Api/ApplicationsController.php | 364 ++++++++++++------ bootstrap/helpers/api.php | 2 +- 2 files changed, 254 insertions(+), 112 deletions(-) diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index a08143022..099b3d124 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -19,6 +19,7 @@ use App\Rules\ValidGitBranch; use App\Rules\ValidGitRepositoryUrl; use App\Services\DockerImageParser; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Validator; use Illuminate\Validation\Rule; use OpenApi\Attributes as OA; use Spatie\Url\Url; @@ -198,10 +199,19 @@ class ApplicationsController extends Controller 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application should be deployed instantly.'], 'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'], 'docker_compose_location' => ['type' => 'string', 'description' => 'The Docker Compose location.'], - 'docker_compose_raw' => ['type' => 'string', 'description' => 'The Docker Compose raw content.'], 'docker_compose_custom_start_command' => ['type' => 'string', 'description' => 'The Docker Compose custom start command.'], 'docker_compose_custom_build_command' => ['type' => 'string', 'description' => 'The Docker Compose custom build command.'], - 'docker_compose_domains' => ['type' => 'array', 'description' => 'The Docker Compose domains.'], + 'docker_compose_domains' => [ + 'type' => 'array', + 'description' => 'Array of URLs to be applied to containers of a dockercompose application.', + 'items' => new OA\Schema( + type: 'object', + properties: [ + 'name' => ['type' => 'string', 'description' => 'The service name as defined in docker-compose.'], + 'domain' => ['type' => 'string', 'description' => 'Comma-separated list of URLs (e.g. "http://app.coolify.io,https://app2.coolify.io")'], + ], + ), + ], 'watch_paths' => ['type' => 'string', 'description' => 'The watch paths.'], 'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'], 'is_http_basic_auth_enabled' => ['type' => 'boolean', 'description' => 'HTTP Basic Authentication enabled.'], @@ -350,10 +360,19 @@ class ApplicationsController extends Controller 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application should be deployed instantly.'], 'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'], 'docker_compose_location' => ['type' => 'string', 'description' => 'The Docker Compose location.'], - 'docker_compose_raw' => ['type' => 'string', 'description' => 'The Docker Compose raw content.'], 'docker_compose_custom_start_command' => ['type' => 'string', 'description' => 'The Docker Compose custom start command.'], 'docker_compose_custom_build_command' => ['type' => 'string', 'description' => 'The Docker Compose custom build command.'], - 'docker_compose_domains' => ['type' => 'array', 'description' => 'The Docker Compose domains.'], + 'docker_compose_domains' => [ + 'type' => 'array', + 'description' => 'Array of URLs to be applied to containers of a dockercompose application.', + 'items' => new OA\Schema( + type: 'object', + properties: [ + 'name' => ['type' => 'string', 'description' => 'The service name as defined in docker-compose.'], + 'domain' => ['type' => 'string', 'description' => 'Comma-separated list of URLs (e.g. "http://app.coolify.io,https://app2.coolify.io")'], + ], + ), + ], 'watch_paths' => ['type' => 'string', 'description' => 'The watch paths.'], 'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'], 'is_http_basic_auth_enabled' => ['type' => 'boolean', 'description' => 'HTTP Basic Authentication enabled.'], @@ -502,10 +521,19 @@ class ApplicationsController extends Controller 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application should be deployed instantly.'], 'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'], 'docker_compose_location' => ['type' => 'string', 'description' => 'The Docker Compose location.'], - 'docker_compose_raw' => ['type' => 'string', 'description' => 'The Docker Compose raw content.'], 'docker_compose_custom_start_command' => ['type' => 'string', 'description' => 'The Docker Compose custom start command.'], 'docker_compose_custom_build_command' => ['type' => 'string', 'description' => 'The Docker Compose custom build command.'], - 'docker_compose_domains' => ['type' => 'array', 'description' => 'The Docker Compose domains.'], + 'docker_compose_domains' => [ + 'type' => 'array', + 'description' => 'Array of URLs to be applied to containers of a dockercompose application.', + 'items' => new OA\Schema( + type: 'object', + properties: [ + 'name' => ['type' => 'string', 'description' => 'The service name as defined in docker-compose.'], + 'domain' => ['type' => 'string', 'description' => 'Comma-separated list of URLs (e.g. "http://app.coolify.io,https://app2.coolify.io")'], + ], + ), + ], 'watch_paths' => ['type' => 'string', 'description' => 'The watch paths.'], 'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'], 'is_http_basic_auth_enabled' => ['type' => 'boolean', 'description' => 'HTTP Basic Authentication enabled.'], @@ -1056,8 +1084,10 @@ class ApplicationsController extends Controller 'build_pack' => ['required', Rule::enum(BuildPackTypes::class)], 'ports_exposes' => 'string|regex:/^(\d+)(,\d+)*$/|required', 'docker_compose_location' => 'string', - 'docker_compose_raw' => 'string|nullable', 'docker_compose_domains' => 'array|nullable', + 'docker_compose_domains.*' => 'array:name,domain', + 'docker_compose_domains.*.name' => 'string|required', + 'docker_compose_domains.*.domain' => 'string|nullable', ]; // ports_exposes is not required for dockercompose if ($request->build_pack === 'dockercompose') { @@ -1065,13 +1095,26 @@ class ApplicationsController extends Controller $request->offsetSet('ports_exposes', '80'); } $validationRules = array_merge(sharedDataApplications(), $validationRules); - $validator = customApiValidator($request->all(), $validationRules); + $validationMessages = [ + 'docker_compose_domains.*.array' => 'An item in the docker_compose_domains array has invalid fields. Only a name and domain field are supported.', + ]; + $validator = Validator::make($request->all(), $validationRules, $validationMessages); if ($validator->fails()) { return response()->json([ 'message' => 'Validation failed.', 'errors' => $validator->errors(), ], 422); } + // For dockercompose applications, domains (fqdn) field should not be used + // Only docker_compose_domains should be used to set domains for individual services + if ($request->build_pack === 'dockercompose' && $request->has('domains')) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'domains' => 'The domains field cannot be used for dockercompose applications. Use docker_compose_domains instead to set domains for individual services.', + ], + ], 422); + } if (! $request->has('name')) { $request->offsetSet('name', generate_application_name($request->git_repository, $request->git_branch)); } @@ -1087,11 +1130,42 @@ class ApplicationsController extends Controller $dockerComposeDomainsJson = collect(); if ($request->has('docker_compose_domains')) { $dockerComposeDomains = collect($request->docker_compose_domains); - if ($dockerComposeDomains->count() > 0) { - $dockerComposeDomains->each(function ($domain, $key) use ($dockerComposeDomainsJson) { - $dockerComposeDomainsJson->put(data_get($domain, 'name'), ['domain' => data_get($domain, 'domain')]); - }); + $domainErrors = []; + + foreach ($dockerComposeDomains as $index => $item) { + $domainValue = data_get($item, 'domain'); + if (filled($domainValue)) { + $urls = str($domainValue)->replaceStart(',', '')->replaceEnd(',', '')->trim(); + str($urls)->explode(',')->each(function ($url) use (&$domainErrors) { + $url = trim($url); + if (empty($url)) { + return; + } + if (! filter_var($url, FILTER_VALIDATE_URL)) { + $domainErrors[] = "Invalid URL: {$url}"; + + return; + } + $scheme = parse_url($url, PHP_URL_SCHEME) ?? ''; + if (! in_array(strtolower($scheme), ['http', 'https'])) { + $domainErrors[] = "Invalid URL scheme: {$scheme} for URL: {$url}. Only http and https are supported."; + } + }); + } } + + if (! empty($domainErrors)) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'docker_compose_domains' => $domainErrors, + ], + ], 422); + } + + $dockerComposeDomains->each(function ($domain) use ($dockerComposeDomainsJson) { + $dockerComposeDomainsJson->put(data_get($domain, 'name'), ['domain' => data_get($domain, 'domain')]); + }); $request->offsetUnset('docker_compose_domains'); } if ($dockerComposeDomainsJson->count() > 0) { @@ -1170,17 +1244,32 @@ class ApplicationsController extends Controller 'github_app_uuid' => 'string|required', 'watch_paths' => 'string|nullable', 'docker_compose_location' => 'string', - 'docker_compose_raw' => 'string|nullable', + 'docker_compose_domains' => 'array|nullable', + 'docker_compose_domains.*' => 'array:name,domain', + 'docker_compose_domains.*.name' => 'string|required', + 'docker_compose_domains.*.domain' => 'string|nullable', ]; $validationRules = array_merge(sharedDataApplications(), $validationRules); - - $validator = customApiValidator($request->all(), $validationRules); + $validationMessages = [ + 'docker_compose_domains.*.array' => 'An item in the docker_compose_domains array has invalid fields. Only a name and domain field are supported.', + ]; + $validator = Validator::make($request->all(), $validationRules, $validationMessages); if ($validator->fails()) { return response()->json([ 'message' => 'Validation failed.', 'errors' => $validator->errors(), ], 422); } + // For dockercompose applications, domains (fqdn) field should not be used + // Only docker_compose_domains should be used to set domains for individual services + if ($request->build_pack === 'dockercompose' && $request->has('domains')) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'domains' => 'The domains field cannot be used for dockercompose applications. Use docker_compose_domains instead to set domains for individual services.', + ], + ], 422); + } if (! $request->has('name')) { $request->offsetSet('name', generate_application_name($request->git_repository, $request->git_branch)); @@ -1229,43 +1318,43 @@ class ApplicationsController extends Controller $dockerComposeDomainsJson = collect(); if ($request->has('docker_compose_domains')) { - if (! $request->has('docker_compose_raw')) { + $dockerComposeDomains = collect($request->docker_compose_domains); + $domainErrors = []; + + foreach ($dockerComposeDomains as $index => $item) { + $domainValue = data_get($item, 'domain'); + if (filled($domainValue)) { + $urls = str($domainValue)->replaceStart(',', '')->replaceEnd(',', '')->trim(); + str($urls)->explode(',')->each(function ($url) use (&$domainErrors) { + $url = trim($url); + if (empty($url)) { + return; + } + if (! filter_var($url, FILTER_VALIDATE_URL)) { + $domainErrors[] = "Invalid URL: {$url}"; + + return; + } + $scheme = parse_url($url, PHP_URL_SCHEME) ?? ''; + if (! in_array(strtolower($scheme), ['http', 'https'])) { + $domainErrors[] = "Invalid URL scheme: {$scheme} for URL: {$url}. Only http and https are supported."; + } + }); + } + } + + if (! empty($domainErrors)) { return response()->json([ 'message' => 'Validation failed.', 'errors' => [ - 'docker_compose_raw' => 'The base64 encoded docker_compose_raw is required.', + 'docker_compose_domains' => $domainErrors, ], ], 422); } - if (! isBase64Encoded($request->docker_compose_raw)) { - return response()->json([ - 'message' => 'Validation failed.', - 'errors' => [ - 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', - ], - ], 422); - } - $dockerComposeRaw = base64_decode($request->docker_compose_raw); - if (mb_detect_encoding($dockerComposeRaw, 'ASCII', true) === false) { - return response()->json([ - 'message' => 'Validation failed.', - 'errors' => [ - 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', - ], - ], 422); - } - $yaml = Yaml::parse($dockerComposeRaw); - $services = data_get($yaml, 'services'); - $dockerComposeDomains = collect($request->docker_compose_domains); - if ($dockerComposeDomains->count() > 0) { - $dockerComposeDomains->each(function ($domain, $key) use ($services, $dockerComposeDomainsJson) { - $name = data_get($domain, 'name'); - if (data_get($services, $name)) { - $dockerComposeDomainsJson->put($name, ['domain' => data_get($domain, 'domain')]); - } - }); - } + $dockerComposeDomains->each(function ($domain) use ($dockerComposeDomainsJson) { + $dockerComposeDomainsJson->put(data_get($domain, 'name'), ['domain' => data_get($domain, 'domain')]); + }); $request->offsetUnset('docker_compose_domains'); } if ($dockerComposeDomainsJson->count() > 0) { @@ -1335,11 +1424,17 @@ class ApplicationsController extends Controller 'private_key_uuid' => 'string|required', 'watch_paths' => 'string|nullable', 'docker_compose_location' => 'string', - 'docker_compose_raw' => 'string|nullable', + 'docker_compose_domains' => 'array|nullable', + 'docker_compose_domains.*' => 'array:name,domain', + 'docker_compose_domains.*.name' => 'string|required', + 'docker_compose_domains.*.domain' => 'string|nullable', ]; $validationRules = array_merge(sharedDataApplications(), $validationRules); - $validator = customApiValidator($request->all(), $validationRules); + $validationMessages = [ + 'docker_compose_domains.*.array' => 'An item in the docker_compose_domains array has invalid fields. Only a name and domain field are supported.', + ]; + $validator = Validator::make($request->all(), $validationRules, $validationMessages); if ($validator->fails()) { return response()->json([ @@ -1347,6 +1442,16 @@ class ApplicationsController extends Controller 'errors' => $validator->errors(), ], 422); } + // For dockercompose applications, domains (fqdn) field should not be used + // Only docker_compose_domains should be used to set domains for individual services + if ($request->build_pack === 'dockercompose' && $request->has('domains')) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'domains' => 'The domains field cannot be used for dockercompose applications. Use docker_compose_domains instead to set domains for individual services.', + ], + ], 422); + } if (! $request->has('name')) { $request->offsetSet('name', generate_application_name($request->git_repository, $request->git_branch)); } @@ -1370,44 +1475,43 @@ class ApplicationsController extends Controller $dockerComposeDomainsJson = collect(); if ($request->has('docker_compose_domains')) { - if (! $request->has('docker_compose_raw')) { + $dockerComposeDomains = collect($request->docker_compose_domains); + $domainErrors = []; + + foreach ($dockerComposeDomains as $index => $item) { + $domainValue = data_get($item, 'domain'); + if (filled($domainValue)) { + $urls = str($domainValue)->replaceStart(',', '')->replaceEnd(',', '')->trim(); + str($urls)->explode(',')->each(function ($url) use (&$domainErrors) { + $url = trim($url); + if (empty($url)) { + return; + } + if (! filter_var($url, FILTER_VALIDATE_URL)) { + $domainErrors[] = "Invalid URL: {$url}"; + + return; + } + $scheme = parse_url($url, PHP_URL_SCHEME) ?? ''; + if (! in_array(strtolower($scheme), ['http', 'https'])) { + $domainErrors[] = "Invalid URL scheme: {$scheme} for URL: {$url}. Only http and https are supported."; + } + }); + } + } + + if (! empty($domainErrors)) { return response()->json([ 'message' => 'Validation failed.', 'errors' => [ - 'docker_compose_raw' => 'The base64 encoded docker_compose_raw is required.', + 'docker_compose_domains' => $domainErrors, ], ], 422); } - if (! isBase64Encoded($request->docker_compose_raw)) { - return response()->json([ - 'message' => 'Validation failed.', - 'errors' => [ - 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', - ], - ], 422); - } - $dockerComposeRaw = base64_decode($request->docker_compose_raw); - if (mb_detect_encoding($dockerComposeRaw, 'ASCII', true) === false) { - return response()->json([ - 'message' => 'Validation failed.', - 'errors' => [ - 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', - ], - ], 422); - } - $dockerComposeRaw = base64_decode($request->docker_compose_raw); - $yaml = Yaml::parse($dockerComposeRaw); - $services = data_get($yaml, 'services'); - $dockerComposeDomains = collect($request->docker_compose_domains); - if ($dockerComposeDomains->count() > 0) { - $dockerComposeDomains->each(function ($domain, $key) use ($services, $dockerComposeDomainsJson) { - $name = data_get($domain, 'name'); - if (data_get($services, $name)) { - $dockerComposeDomainsJson->put($name, ['domain' => data_get($domain, 'domain')]); - } - }); - } + $dockerComposeDomains->each(function ($domain) use ($dockerComposeDomainsJson) { + $dockerComposeDomainsJson->put(data_get($domain, 'name'), ['domain' => data_get($domain, 'domain')]); + }); $request->offsetUnset('docker_compose_domains'); } if ($dockerComposeDomainsJson->count() > 0) { @@ -2090,10 +2194,19 @@ class ApplicationsController extends Controller 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the application should be deployed instantly.'], 'dockerfile' => ['type' => 'string', 'description' => 'The Dockerfile content.'], 'docker_compose_location' => ['type' => 'string', 'description' => 'The Docker Compose location.'], - 'docker_compose_raw' => ['type' => 'string', 'description' => 'The Docker Compose raw content.'], 'docker_compose_custom_start_command' => ['type' => 'string', 'description' => 'The Docker Compose custom start command.'], 'docker_compose_custom_build_command' => ['type' => 'string', 'description' => 'The Docker Compose custom build command.'], - 'docker_compose_domains' => ['type' => 'array', 'description' => 'The Docker Compose domains.'], + 'docker_compose_domains' => [ + 'type' => 'array', + 'description' => 'Array of URLs to be applied to containers of a dockercompose application.', + 'items' => new OA\Schema( + type: 'object', + properties: [ + 'name' => ['type' => 'string', 'description' => 'The service name as defined in docker-compose.'], + 'domain' => ['type' => 'string', 'description' => 'Comma-separated list of URLs (e.g. "http://app.coolify.io,https://app2.coolify.io")'], + ], + ), + ], 'watch_paths' => ['type' => 'string', 'description' => 'The watch paths.'], 'use_build_server' => ['type' => 'boolean', 'nullable' => true, 'description' => 'Use build server.'], 'connect_to_docker_network' => ['type' => 'boolean', 'description' => 'The flag to connect the service to the predefined Docker network.'], @@ -2192,8 +2305,10 @@ class ApplicationsController extends Controller 'static_image' => 'string', 'watch_paths' => 'string|nullable', 'docker_compose_location' => 'string', - 'docker_compose_raw' => 'string|nullable', 'docker_compose_domains' => 'array|nullable', + 'docker_compose_domains.*' => 'array:name,domain', + 'docker_compose_domains.*.name' => 'string|required', + 'docker_compose_domains.*.domain' => 'string|nullable', 'docker_compose_custom_start_command' => 'string|nullable', 'docker_compose_custom_build_command' => 'string|nullable', 'custom_nginx_configuration' => 'string|nullable', @@ -2202,7 +2317,10 @@ class ApplicationsController extends Controller 'http_basic_auth_password' => 'string', ]; $validationRules = array_merge(sharedDataApplications(), $validationRules); - $validator = customApiValidator($request->all(), $validationRules); + $validationMessages = [ + 'docker_compose_domains.*.array' => 'An item in the docker_compose_domains array has invalid fields. Only a name and domain field are supported.', + ]; + $validator = Validator::make($request->all(), $validationRules, $validationMessages); // Validate ports_exposes if ($request->has('ports_exposes')) { @@ -2278,6 +2396,17 @@ class ApplicationsController extends Controller $application->save(); } + // For dockercompose applications, domains (fqdn) field should not be used + // Only docker_compose_domains should be used to set domains for individual services + if ($application->build_pack === 'dockercompose' && $request->has('domains')) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'domains' => 'The domains field cannot be used for dockercompose applications. Use docker_compose_domains instead to set domains for individual services.', + ], + ], 422); + } + $domains = $request->domains; $requestHasDomains = $request->has('domains'); if ($requestHasDomains && $server->isProxyShouldRun()) { @@ -2321,44 +2450,57 @@ class ApplicationsController extends Controller $dockerComposeDomainsJson = collect(); if ($request->has('docker_compose_domains')) { - if (! $request->has('docker_compose_raw')) { + if (empty($application->docker_compose_raw)) { return response()->json([ 'message' => 'Validation failed.', 'errors' => [ - 'docker_compose_raw' => 'The base64 encoded docker_compose_raw is required.', + 'docker_compose_domains' => 'Cannot set docker_compose_domains without docker_compose_raw. Reload the compose file from the git repository first.', ], ], 422); } - if (! isBase64Encoded($request->docker_compose_raw)) { - return response()->json([ - 'message' => 'Validation failed.', - 'errors' => [ - 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', - ], - ], 422); - } - $dockerComposeRaw = base64_decode($request->docker_compose_raw); - if (mb_detect_encoding($dockerComposeRaw, 'ASCII', true) === false) { - return response()->json([ - 'message' => 'Validation failed.', - 'errors' => [ - 'docker_compose_raw' => 'The docker_compose_raw should be base64 encoded.', - ], - ], 422); - } - $dockerComposeRaw = base64_decode($request->docker_compose_raw); - $yaml = Yaml::parse($dockerComposeRaw); - $services = data_get($yaml, 'services'); $dockerComposeDomains = collect($request->docker_compose_domains); - if ($dockerComposeDomains->count() > 0) { - $dockerComposeDomains->each(function ($domain, $key) use ($services, $dockerComposeDomainsJson) { - $name = data_get($domain, 'name'); - if (data_get($services, $name)) { - $dockerComposeDomainsJson->put($name, ['domain' => data_get($domain, 'domain')]); - } - }); + $domainErrors = []; + + foreach ($dockerComposeDomains as $item) { + $domainValue = data_get($item, 'domain'); + if (filled($domainValue)) { + $urls = str($domainValue)->replaceStart(',', '')->replaceEnd(',', '')->trim(); + str($urls)->explode(',')->each(function ($url) use (&$domainErrors) { + $url = trim($url); + if (empty($url)) { + return; + } + if (! filter_var($url, FILTER_VALIDATE_URL)) { + $domainErrors[] = "Invalid URL: {$url}"; + + return; + } + $scheme = parse_url($url, PHP_URL_SCHEME) ?? ''; + if (! in_array(strtolower($scheme), ['http', 'https'])) { + $domainErrors[] = "Invalid URL scheme: {$scheme} for URL: {$url}. Only http and https are supported."; + } + }); + } } + + if (! empty($domainErrors)) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'docker_compose_domains' => $domainErrors, + ], + ], 422); + } + + $yaml = Yaml::parse($application->docker_compose_raw); + $services = data_get($yaml, 'services', []); + $dockerComposeDomains->each(function ($domain) use ($services, $dockerComposeDomainsJson) { + $name = data_get($domain, 'name'); + if ($name && is_array($services) && isset($services[$name])) { + $dockerComposeDomainsJson->put($name, ['domain' => data_get($domain, 'domain')]); + } + }); $request->offsetUnset('docker_compose_domains'); } $instantDeploy = $request->instant_deploy; diff --git a/bootstrap/helpers/api.php b/bootstrap/helpers/api.php index d9d6f40d8..55cff42d0 100644 --- a/bootstrap/helpers/api.php +++ b/bootstrap/helpers/api.php @@ -131,7 +131,6 @@ function sharedDataApplications() 'manual_webhook_secret_gitea' => 'string|nullable', 'docker_compose_location' => 'string', 'docker_compose' => 'string|nullable', - 'docker_compose_raw' => 'string|nullable', 'docker_compose_domains' => 'array|nullable', 'docker_compose_custom_start_command' => 'string|nullable', 'docker_compose_custom_build_command' => 'string|nullable', @@ -181,4 +180,5 @@ function removeUnnecessaryFieldsFromRequest(Request $request) $request->offsetUnset('force_domain_override'); $request->offsetUnset('autogenerate_domain'); $request->offsetUnset('is_container_label_escape_enabled'); + $request->offsetUnset('docker_compose_raw'); } From bc575f1560460ebd45c843ac1686d605fb9a898a Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 12 Jan 2026 21:42:46 +0100 Subject: [PATCH 049/191] chore(api): regenerate openapi docs --- openapi.json | 89 +++++++++++++++++++++++++++++++++++++--------------- openapi.yaml | 37 +++++++++------------- 2 files changed, 78 insertions(+), 48 deletions(-) diff --git a/openapi.json b/openapi.json index 9c31f7628..9fdec634f 100644 --- a/openapi.json +++ b/openapi.json @@ -326,10 +326,6 @@ "type": "string", "description": "The Docker Compose location." }, - "docker_compose_raw": { - "type": "string", - "description": "The Docker Compose raw content." - }, "docker_compose_custom_start_command": { "type": "string", "description": "The Docker Compose custom start command." @@ -340,7 +336,20 @@ }, "docker_compose_domains": { "type": "array", - "description": "The Docker Compose domains." + "description": "Array of URLs to be applied to containers of a dockercompose application.", + "items": { + "properties": { + "name": { + "type": "string", + "description": "The service name as defined in docker-compose." + }, + "domain": { + "type": "string", + "description": "Comma-separated list of URLs (e.g. \"http:\/\/app.coolify.io,https:\/\/app2.coolify.io\")" + } + }, + "type": "object" + } }, "watch_paths": { "type": "string", @@ -746,10 +755,6 @@ "type": "string", "description": "The Docker Compose location." }, - "docker_compose_raw": { - "type": "string", - "description": "The Docker Compose raw content." - }, "docker_compose_custom_start_command": { "type": "string", "description": "The Docker Compose custom start command." @@ -760,7 +765,20 @@ }, "docker_compose_domains": { "type": "array", - "description": "The Docker Compose domains." + "description": "Array of URLs to be applied to containers of a dockercompose application.", + "items": { + "properties": { + "name": { + "type": "string", + "description": "The service name as defined in docker-compose." + }, + "domain": { + "type": "string", + "description": "Comma-separated list of URLs (e.g. \"http:\/\/app.coolify.io,https:\/\/app2.coolify.io\")" + } + }, + "type": "object" + } }, "watch_paths": { "type": "string", @@ -1166,10 +1184,6 @@ "type": "string", "description": "The Docker Compose location." }, - "docker_compose_raw": { - "type": "string", - "description": "The Docker Compose raw content." - }, "docker_compose_custom_start_command": { "type": "string", "description": "The Docker Compose custom start command." @@ -1180,7 +1194,20 @@ }, "docker_compose_domains": { "type": "array", - "description": "The Docker Compose domains." + "description": "Array of URLs to be applied to containers of a dockercompose application.", + "items": { + "properties": { + "name": { + "type": "string", + "description": "The service name as defined in docker-compose." + }, + "domain": { + "type": "string", + "description": "Comma-separated list of URLs (e.g. \"http:\/\/app.coolify.io,https:\/\/app2.coolify.io\")" + } + }, + "type": "object" + } }, "watch_paths": { "type": "string", @@ -1318,8 +1345,8 @@ "tags": [ "Applications" ], - "summary": "Create (Dockerfile)", - "description": "Create new application based on a simple Dockerfile.", + "summary": "Create (Dockerfile without git)", + "description": "Create new application based on a simple Dockerfile (without git).", "operationId": "create-dockerfile-application", "requestBody": { "description": "Application object that needs to be created.", @@ -1667,8 +1694,8 @@ "tags": [ "Applications" ], - "summary": "Create (Docker Image)", - "description": "Create new application based on a prebuilt docker image", + "summary": "Create (Docker Image without git)", + "description": "Create new application based on a prebuilt docker image (without git).", "operationId": "create-dockerimage-application", "requestBody": { "description": "Application object that needs to be created.", @@ -1999,8 +2026,8 @@ "tags": [ "Applications" ], - "summary": "Create (Docker Compose)", - "description": "Create new application based on a docker-compose file.", + "summary": "Create (Docker Compose) (Deprecated)", + "description": "Create new application based on a docker-compose file (without git).", "operationId": "create-dockercompose-application", "requestBody": { "description": "Application object that needs to be created.", @@ -2153,6 +2180,7 @@ } } }, + "deprecated": true, "security": [ { "bearerAuth": [] @@ -2558,10 +2586,6 @@ "type": "string", "description": "The Docker Compose location." }, - "docker_compose_raw": { - "type": "string", - "description": "The Docker Compose raw content." - }, "docker_compose_custom_start_command": { "type": "string", "description": "The Docker Compose custom start command." @@ -2572,7 +2596,20 @@ }, "docker_compose_domains": { "type": "array", - "description": "The Docker Compose domains." + "description": "Array of URLs to be applied to containers of a dockercompose application.", + "items": { + "properties": { + "name": { + "type": "string", + "description": "The service name as defined in docker-compose." + }, + "domain": { + "type": "string", + "description": "Comma-separated list of URLs (e.g. \"http:\/\/app.coolify.io,https:\/\/app2.coolify.io\")" + } + }, + "type": "object" + } }, "watch_paths": { "type": "string", diff --git a/openapi.yaml b/openapi.yaml index 198322328..383481a8d 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -237,9 +237,6 @@ paths: docker_compose_location: type: string description: 'The Docker Compose location.' - docker_compose_raw: - type: string - description: 'The Docker Compose raw content.' docker_compose_custom_start_command: type: string description: 'The Docker Compose custom start command.' @@ -248,7 +245,8 @@ paths: description: 'The Docker Compose custom build command.' docker_compose_domains: type: array - description: 'The Docker Compose domains.' + description: 'Array of URLs to be applied to containers of a dockercompose application.' + items: { properties: { name: { type: string, description: 'The service name as defined in docker-compose.' }, domain: { type: string, description: 'Comma-separated list of URLs (e.g. "http://app.coolify.io,https://app2.coolify.io")' } }, type: object } watch_paths: type: string description: 'The watch paths.' @@ -511,9 +509,6 @@ paths: docker_compose_location: type: string description: 'The Docker Compose location.' - docker_compose_raw: - type: string - description: 'The Docker Compose raw content.' docker_compose_custom_start_command: type: string description: 'The Docker Compose custom start command.' @@ -522,7 +517,8 @@ paths: description: 'The Docker Compose custom build command.' docker_compose_domains: type: array - description: 'The Docker Compose domains.' + description: 'Array of URLs to be applied to containers of a dockercompose application.' + items: { properties: { name: { type: string, description: 'The service name as defined in docker-compose.' }, domain: { type: string, description: 'Comma-separated list of URLs (e.g. "http://app.coolify.io,https://app2.coolify.io")' } }, type: object } watch_paths: type: string description: 'The watch paths.' @@ -785,9 +781,6 @@ paths: docker_compose_location: type: string description: 'The Docker Compose location.' - docker_compose_raw: - type: string - description: 'The Docker Compose raw content.' docker_compose_custom_start_command: type: string description: 'The Docker Compose custom start command.' @@ -796,7 +789,8 @@ paths: description: 'The Docker Compose custom build command.' docker_compose_domains: type: array - description: 'The Docker Compose domains.' + description: 'Array of URLs to be applied to containers of a dockercompose application.' + items: { properties: { name: { type: string, description: 'The service name as defined in docker-compose.' }, domain: { type: string, description: 'Comma-separated list of URLs (e.g. "http://app.coolify.io,https://app2.coolify.io")' } }, type: object } watch_paths: type: string description: 'The watch paths.' @@ -860,8 +854,8 @@ paths: post: tags: - Applications - summary: 'Create (Dockerfile)' - description: 'Create new application based on a simple Dockerfile.' + summary: 'Create (Dockerfile without git)' + description: 'Create new application based on a simple Dockerfile (without git).' operationId: create-dockerfile-application requestBody: description: 'Application object that needs to be created.' @@ -1081,8 +1075,8 @@ paths: post: tags: - Applications - summary: 'Create (Docker Image)' - description: 'Create new application based on a prebuilt docker image' + summary: 'Create (Docker Image without git)' + description: 'Create new application based on a prebuilt docker image (without git).' operationId: create-dockerimage-application requestBody: description: 'Application object that needs to be created.' @@ -1293,8 +1287,8 @@ paths: post: tags: - Applications - summary: 'Create (Docker Compose)' - description: 'Create new application based on a docker-compose file.' + summary: 'Create (Docker Compose) (Deprecated)' + description: 'Create new application based on a docker-compose file (without git).' operationId: create-dockercompose-application requestBody: description: 'Application object that needs to be created.' @@ -1374,6 +1368,7 @@ paths: warning: { type: string, example: 'Using the same domain for multiple resources can cause routing conflicts and unpredictable behavior.' } conflicts: { type: array, items: { properties: { domain: { type: string, example: example.com }, resource_name: { type: string, example: 'My Application' }, resource_uuid: { type: string, nullable: true, example: abc123-def456 }, resource_type: { type: string, enum: [application, service, instance], example: application }, message: { type: string, example: "Domain example.com is already in use by application 'My Application'" } }, type: object } } type: object + deprecated: true security: - bearerAuth: [] @@ -1665,9 +1660,6 @@ paths: docker_compose_location: type: string description: 'The Docker Compose location.' - docker_compose_raw: - type: string - description: 'The Docker Compose raw content.' docker_compose_custom_start_command: type: string description: 'The Docker Compose custom start command.' @@ -1676,7 +1668,8 @@ paths: description: 'The Docker Compose custom build command.' docker_compose_domains: type: array - description: 'The Docker Compose domains.' + description: 'Array of URLs to be applied to containers of a dockercompose application.' + items: { properties: { name: { type: string, description: 'The service name as defined in docker-compose.' }, domain: { type: string, description: 'Comma-separated list of URLs (e.g. "http://app.coolify.io,https://app2.coolify.io")' } }, type: object } watch_paths: type: string description: 'The watch paths.' From 764d8861f6ef0755d07b5c9c22ada2ae63993954 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Sun, 11 Jan 2026 22:19:09 +0100 Subject: [PATCH 050/191] feat(api): add update urls support to services api - added update urls support to services api - remove old stale domains update code --- .../Controllers/Api/ServicesController.php | 192 ++++++++++++++---- openapi.json | 34 ++++ openapi.yaml | 8 + 3 files changed, 195 insertions(+), 39 deletions(-) diff --git a/app/Http/Controllers/Api/ServicesController.php b/app/Http/Controllers/Api/ServicesController.php index 4025898b9..56812c94c 100644 --- a/app/Http/Controllers/Api/ServicesController.php +++ b/app/Http/Controllers/Api/ServicesController.php @@ -12,6 +12,7 @@ use App\Models\Project; use App\Models\Server; use App\Models\Service; use Illuminate\Http\Request; +use Illuminate\Support\Facades\Validator; use OpenApi\Attributes as OA; use Symfony\Component\Yaml\Yaml; @@ -37,6 +38,67 @@ class ServicesController extends Controller return serializeApiResponse($service); } + private function applyServiceUrls(Service $service, array $urls, string $teamId): ?array + { + $errors = []; + + foreach ($urls as $item) { + $name = data_get($item, 'name'); + $urls = data_get($item, 'url'); + + if (blank($name)) { + $errors[] = 'Service container name is required to apply URLs.'; + + continue; + } + + $application = $service->applications()->where('name', $name)->first(); + if (! $application) { + $errors[] = "Service container with '{$name}' not found."; + + continue; + } + + if (filled($urls)) { + $urls = str($urls)->replaceStart(',', '')->replaceEnd(',', '')->trim(); + $urls = str($urls)->explode(',')->map(function ($url) use (&$errors) { + $url = trim($url); + if (! filter_var($url, FILTER_VALIDATE_URL)) { + $errors[] = 'Invalid URL: '.$url; + + return str($url)->lower(); + } + $scheme = parse_url($url, PHP_URL_SCHEME) ?? ''; + if (! in_array(strtolower($scheme), ['http', 'https'])) { + $errors[] = "Invalid URL scheme: {$scheme} for URL: {$url}. Only http and https are supported."; + } + + return str($url)->lower(); + })->filter(fn ($u) => $u->isNotEmpty())->unique()->implode(','); + + if ($urls && empty($errors)) { + $result = checkIfDomainIsAlreadyUsedViaAPI(collect(explode(',', $urls)), $teamId, $application->uuid); + if ($result['hasConflicts']) { + foreach ($result['conflicts'] as $conflict) { + $errors[] = $conflict['message']; + } + } + } + } else { + $urls = null; + } + + $application->fqdn = $urls; + $application->save(); + } + + if (! empty($errors)) { + return ['errors' => $errors]; + } + + return null; + } + #[OA\Get( summary: 'List', description: 'List all services.', @@ -115,6 +177,17 @@ class ServicesController extends Controller 'destination_uuid' => ['type' => 'string', 'description' => 'Destination UUID. Required if server has multiple destinations.'], 'instant_deploy' => ['type' => 'boolean', 'default' => false, 'description' => 'Start the service immediately after creation.'], 'docker_compose_raw' => ['type' => 'string', 'description' => 'The base64 encoded Docker Compose content.'], + 'urls' => [ + 'type' => 'array', + 'description' => 'Array of URLs to be applied to containers of a service.', + 'items' => new OA\Schema( + type: 'object', + properties: [ + 'name' => ['type' => 'string', 'description' => 'The service name as defined in docker-compose.'], + 'url' => ['type' => 'string', 'description' => 'Comma-separated list of domains (e.g. "http://app.coolify.io,https://app2.coolify.io").'], + ], + ), + ], ], ), ), @@ -152,7 +225,7 @@ class ServicesController extends Controller )] public function create_service(Request $request) { - $allowedFields = ['type', 'name', 'description', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'docker_compose_raw']; + $allowedFields = ['type', 'name', 'description', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'docker_compose_raw', 'urls']; $teamId = getTeamIdFromToken(); if (is_null($teamId)) { @@ -165,7 +238,7 @@ class ServicesController extends Controller if ($return instanceof \Illuminate\Http\JsonResponse) { return $return; } - $validator = customApiValidator($request->all(), [ + $validationRules = [ 'type' => 'string|required_without:docker_compose_raw', 'docker_compose_raw' => 'string|required_without:type', 'project_uuid' => 'string|required', @@ -176,7 +249,15 @@ class ServicesController extends Controller 'name' => 'string|max:255', 'description' => 'string|nullable', 'instant_deploy' => 'boolean', - ]); + 'urls' => 'array|nullable', + 'urls.*' => 'array:name,url', + 'urls.*.name' => 'string|required', + 'urls.*.url' => 'string|nullable', + ]; + $validationMessages = [ + 'urls.*.array' => 'An item in the urls array has invalid fields. Only name and url fields are supported.', + ]; + $validator = Validator::make($request->all(), $validationRules, $validationMessages); $extraFields = array_diff(array_keys($request->all()), $allowedFields); if ($validator->fails() || ! empty($extraFields)) { @@ -296,29 +377,31 @@ class ServicesController extends Controller // Apply service-specific application prerequisites applyServiceApplicationPrerequisites($service); + if ($request->has('urls') && is_array($request->urls)) { + $urlResult = $this->applyServiceUrls($service, $request->urls, $teamId); + if ($urlResult !== null) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => $urlResult['errors'], + ], 422); + } + } + if ($instantDeploy) { StartService::dispatch($service); } - $domains = $service->applications()->get()->pluck('fqdn')->sort(); - $domains = $domains->map(function ($domain) { - if (count(explode(':', $domain)) > 2) { - return str($domain)->beforeLast(':')->value(); - } - - return $domain; - }); return response()->json([ 'uuid' => $service->uuid, - 'domains' => $domains, - ]); + 'domains' => $service->applications()->pluck('fqdn')->filter()->sort()->values(), + ])->setStatusCode(201); } return response()->json(['message' => 'Service not found.', 'valid_service_types' => $serviceKeys], 404); } elseif (filled($request->docker_compose_raw)) { - $allowedFields = ['name', 'description', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'docker_compose_raw', 'connect_to_docker_network']; + $allowedFields = ['name', 'description', 'project_uuid', 'environment_name', 'environment_uuid', 'server_uuid', 'destination_uuid', 'instant_deploy', 'docker_compose_raw', 'connect_to_docker_network', 'urls']; - $validator = customApiValidator($request->all(), [ + $validationRules = [ 'project_uuid' => 'string|required', 'environment_name' => 'string|nullable', 'environment_uuid' => 'string|nullable', @@ -329,7 +412,15 @@ class ServicesController extends Controller 'instant_deploy' => 'boolean', 'connect_to_docker_network' => 'boolean', 'docker_compose_raw' => 'string|required', - ]); + 'urls' => 'array|nullable', + 'urls.*' => 'array:name,url', + 'urls.*.name' => 'string|required', + 'urls.*.url' => 'string|nullable', + ]; + $validationMessages = [ + 'urls.*.array' => 'An item in the urls array has invalid fields. Only name and url fields are supported.', + ]; + $validator = Validator::make($request->all(), $validationRules, $validationMessages); $extraFields = array_diff(array_keys($request->all()), $allowedFields); if ($validator->fails() || ! empty($extraFields)) { @@ -423,22 +514,24 @@ class ServicesController extends Controller $service->save(); $service->parse(isNew: true); + + if ($request->has('urls') && is_array($request->urls)) { + $urlResult = $this->applyServiceUrls($service, $request->urls, $teamId); + if ($urlResult !== null) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => $urlResult['errors'], + ], 422); + } + } + if ($instantDeploy) { StartService::dispatch($service); } - $domains = $service->applications()->get()->pluck('fqdn')->sort(); - $domains = $domains->map(function ($domain) { - if (count(explode(':', $domain)) > 2) { - return str($domain)->beforeLast(':')->value(); - } - - return $domain; - })->values(); - return response()->json([ 'uuid' => $service->uuid, - 'domains' => $domains, + 'domains' => $service->applications()->pluck('fqdn')->filter()->sort()->values(), ])->setStatusCode(201); } elseif (filled($request->type)) { return response()->json([ @@ -622,6 +715,17 @@ class ServicesController extends Controller 'instant_deploy' => ['type' => 'boolean', 'description' => 'The flag to indicate if the service should be deployed instantly.'], 'connect_to_docker_network' => ['type' => 'boolean', 'default' => false, 'description' => 'Connect the service to the predefined docker network.'], 'docker_compose_raw' => ['type' => 'string', 'description' => 'The base64 encoded Docker Compose content.'], + 'urls' => [ + 'type' => 'array', + 'description' => 'Array of URLs to be applied to containers of a service.', + 'items' => new OA\Schema( + type: 'object', + properties: [ + 'name' => ['type' => 'string', 'description' => 'The service name as defined in docker-compose.'], + 'url' => ['type' => 'string', 'description' => 'Comma-separated list of domains (e.g. "http://app.coolify.io,https://app2.coolify.io").'], + ], + ), + ], ], ) ), @@ -681,15 +785,23 @@ class ServicesController extends Controller $this->authorize('update', $service); - $allowedFields = ['name', 'description', 'instant_deploy', 'docker_compose_raw', 'connect_to_docker_network']; + $allowedFields = ['name', 'description', 'instant_deploy', 'docker_compose_raw', 'connect_to_docker_network', 'urls']; - $validator = customApiValidator($request->all(), [ + $validationRules = [ 'name' => 'string|max:255', 'description' => 'string|nullable', 'instant_deploy' => 'boolean', 'connect_to_docker_network' => 'boolean', 'docker_compose_raw' => 'string|nullable', - ]); + 'urls' => 'array|nullable', + 'urls.*' => 'array:name,url', + 'urls.*.name' => 'string|required', + 'urls.*.url' => 'string|nullable', + ]; + $validationMessages = [ + 'urls.*.array' => 'An item in the urls array has invalid fields. Only name and url fields are supported.', + ]; + $validator = Validator::make($request->all(), $validationRules, $validationMessages); $extraFields = array_diff(array_keys($request->all()), $allowedFields); if ($validator->fails() || ! empty($extraFields)) { @@ -753,22 +865,24 @@ class ServicesController extends Controller $service->save(); $service->parse(); + + if ($request->has('urls') && is_array($request->urls)) { + $urlResult = $this->applyServiceUrls($service, $request->urls, $teamId); + if ($urlResult !== null) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => $urlResult['errors'], + ], 422); + } + } + if ($request->instant_deploy) { StartService::dispatch($service); } - $domains = $service->applications()->get()->pluck('fqdn')->sort(); - $domains = $domains->map(function ($domain) { - if (count(explode(':', $domain)) > 2) { - return str($domain)->beforeLast(':')->value(); - } - - return $domain; - })->values(); - return response()->json([ 'uuid' => $service->uuid, - 'domains' => $domains, + 'domains' => $service->applications()->pluck('fqdn')->filter()->sort()->values(), ])->setStatusCode(200); } diff --git a/openapi.json b/openapi.json index 9fdec634f..e9207e5b9 100644 --- a/openapi.json +++ b/openapi.json @@ -8887,6 +8887,23 @@ "docker_compose_raw": { "type": "string", "description": "The base64 encoded Docker Compose content." + }, + "urls": { + "type": "array", + "description": "Array of URLs to be applied to containers of a service.", + "items": { + "properties": { + "name": { + "type": "string", + "description": "The service name as defined in docker-compose." + }, + "url": { + "type": "string", + "description": "Comma-separated list of domains (e.g. \"http:\/\/app.coolify.io,https:\/\/app2.coolify.io\")." + } + }, + "type": "object" + } } }, "type": "object" @@ -9137,6 +9154,23 @@ "docker_compose_raw": { "type": "string", "description": "The base64 encoded Docker Compose content." + }, + "urls": { + "type": "array", + "description": "Array of URLs to be applied to containers of a service.", + "items": { + "properties": { + "name": { + "type": "string", + "description": "The service name as defined in docker-compose." + }, + "url": { + "type": "string", + "description": "Comma-separated list of domains (e.g. \"http:\/\/app.coolify.io,https:\/\/app2.coolify.io\")." + } + }, + "type": "object" + } } }, "type": "object" diff --git a/openapi.yaml b/openapi.yaml index 383481a8d..735ebad21 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -5606,6 +5606,10 @@ paths: docker_compose_raw: type: string description: 'The base64 encoded Docker Compose content.' + urls: + type: array + description: 'Array of URLs to be applied to containers of a service.' + items: { properties: { name: { type: string, description: 'The service name as defined in docker-compose.' }, url: { type: string, description: 'Comma-separated list of domains (e.g. "http://app.coolify.io,https://app2.coolify.io").' } }, type: object } type: object responses: '201': @@ -5773,6 +5777,10 @@ paths: docker_compose_raw: type: string description: 'The base64 encoded Docker Compose content.' + urls: + type: array + description: 'Array of URLs to be applied to containers of a service.' + items: { properties: { name: { type: string, description: 'The service name as defined in docker-compose.' }, url: { type: string, description: 'Comma-separated list of domains (e.g. "http://app.coolify.io,https://app2.coolify.io").' } }, type: object } type: object responses: '200': From cd1c333a6f2235767a329c4aa21aa53aad4729d6 Mon Sep 17 00:00:00 2001 From: Khiet Tam Nguyen <86177399+nktnet1@users.noreply.github.com> Date: Tue, 13 Jan 2026 08:51:57 +1100 Subject: [PATCH 051/191] feat(service): add chibisafe template (#5808) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 🏔️ Peak <122374094+peaklabs-dev@users.noreply.github.com> Co-authored-by: ShadowArcanist <162910371+ShadowArcanist@users.noreply.github.com> --- public/svgs/chibisafe.svg | 90 ++++++++++++++++++++++++++++++++ templates/compose/chibisafe.yaml | 80 ++++++++++++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 public/svgs/chibisafe.svg create mode 100644 templates/compose/chibisafe.yaml diff --git a/public/svgs/chibisafe.svg b/public/svgs/chibisafe.svg new file mode 100644 index 000000000..03fc3709a --- /dev/null +++ b/public/svgs/chibisafe.svg @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/templates/compose/chibisafe.yaml b/templates/compose/chibisafe.yaml new file mode 100644 index 000000000..62ced7a80 --- /dev/null +++ b/templates/compose/chibisafe.yaml @@ -0,0 +1,80 @@ +# documentation: https://chibisafe.app/docs/intro +# slogan: A beautiful and performant vault to save all your files in the cloud. +# tags: storage,file-sharing,upload,sharing +# logo: svgs/chibisafe.svg +# port: 80 + +## This service includes its own reverse proxy because the application routing is broken, also it needs caddy for serving static files https://github.com/coollabsio/coolify/pull/5808#pullrequestreview-3340419006 + +services: + chibisafe: + image: chibisafe/chibisafe:v6.5.5 + environment: + - BASE_API_URL=http://chibisafe-server:8000 + healthcheck: + test: ["CMD", "wget", "--spider", "--quiet", "http://127.0.0.1:8001"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s + + chibisafe-server: + image: chibisafe/chibisafe-server:v6.5.5 + volumes: + - chibisafe-database:/app/database:rw + - chibisafe-uploads:/app/uploads:rw + - chibisafe-logs:/app/logs:rw + healthcheck: + test: + [ + "CMD", + "wget", + "--spider", + "--quiet", + "http://127.0.0.1:8000/api/health", + ] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s + + caddy: + image: caddy:2-alpine + environment: + - SERVICE_URL_CHIBISAFE_80 + healthcheck: + test: ["CMD", "wget", "--spider", "--quiet", "http://127.0.0.1:80"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 10s + volumes: + - uploads:/app/uploads:ro + - type: bind + source: ./Caddyfile + target: /etc/caddy/Caddyfile + content: | + # chibisafe/Caddyfile + # https://chibisafe.moe/guides/running-with-docker + :80 { + route { + file_server * { + root /app/uploads + pass_thru + } + @api path /api/* + reverse_proxy @api http://chibisafe-server:8000 { + header_up Host {http.reverse_proxy.upstream.hostport} + header_up X-Real-IP {http.request.header.X-Real-IP} + } + @docs path /docs* + reverse_proxy @docs http://chibisafe-server:8000 { + header_up Host {http.reverse_proxy.upstream.hostport} + header_up X-Real-IP {http.request.header.X-Real-IP} + } + reverse_proxy http://chibisafe:8001 { + header_up Host {http.reverse_proxy.upstream.hostport} + header_up X-Real-IP {http.request.header.X-Real-IP} + } + } + } From d4957ff3d1146c005c7d57bd283e31ac933daed3 Mon Sep 17 00:00:00 2001 From: Dominic Schmid <45590457+dominic-schmid@users.noreply.github.com> Date: Mon, 12 Jan 2026 23:09:56 +0100 Subject: [PATCH 052/191] feat(ui): improve sidebar menu items styling (#7928) --- resources/css/utilities.css | 25 +++++- resources/views/components/navbar.blade.php | 82 +++++++++---------- .../components/server/sidebar-proxy.blade.php | 14 ++-- .../server/sidebar-security.blade.php | 10 +-- .../views/components/server/sidebar.blade.php | 56 ++++++------- .../service-database/sidebar.blade.php | 21 +++-- .../components/settings/sidebar.blade.php | 14 ++-- resources/views/layouts/app.blade.php | 8 +- .../application/configuration.blade.php | 81 ++++++++---------- .../project/database/configuration.blade.php | 52 ++++++------ .../project/service/configuration.blade.php | 41 ++++------ .../livewire/project/service/index.blade.php | 11 ++- resources/views/livewire/upgrade.blade.php | 2 +- 13 files changed, 210 insertions(+), 207 deletions(-) diff --git a/resources/css/utilities.css b/resources/css/utilities.css index 7978b2d19..c7b77022f 100644 --- a/resources/css/utilities.css +++ b/resources/css/utilities.css @@ -174,15 +174,34 @@ } @utility menu-item { - @apply flex gap-3 items-center px-2 py-1 w-full text-sm sm:pr-0 dark:hover:bg-coolgray-100 dark:hover:text-white hover:bg-neutral-300 min-w-fit sm:min-w-64; + @apply flex gap-3 items-center px-2 py-1 w-full text-sm dark:hover:bg-coolgray-100 dark:hover:text-white hover:bg-neutral-300 rounded-sm truncate min-w-0; +} +@utility menu-item-icon { + @apply flex-shrink-0 w-6 h-6 dark:hover:text-white; +} + +@utility menu-item-label { + @apply min-w-0 flex-1 truncate; } @utility menu-item-active { - @apply text-black rounded-none dark:bg-coolgray-200 dark:text-warning bg-neutral-200; + @apply text-black rounded-sm dark:bg-coolgray-200 dark:text-warning bg-neutral-200 overflow-hidden; +} + +@utility sub-menu-wrapper { + @apply flex flex-col items-start gap-2 min-w-40 sm:min-w-48 w-auto max-w-full sm:flex-shrink; +} + +@utility sub-menu-item { + @apply flex gap-2 items-center px-2 py-1 w-full text-sm dark:hover:bg-coolgray-100 dark:hover:text-white hover:bg-neutral-300 rounded-sm truncate min-w-0; +} + +@utility sub-menu-item-icon { + @apply flex-shrink-0 w-4 h-4 dark:hover:text-white; } @utility heading-item-active { - @apply text-black rounded-none dark:bg-coolgray-200 dark:text-warning; + @apply text-black rounded-sm dark:bg-coolgray-200 dark:text-warning; } @utility icon { diff --git a/resources/views/components/navbar.blade.php b/resources/views/components/navbar.blade.php index e351a4480..48b544ebb 100644 --- a/resources/views/components/navbar.blade.php +++ b/resources/views/components/navbar.blade.php @@ -62,11 +62,11 @@ html { font-size: 93.75%; } - + :root { --vh: 1vh; } - + @media (min-width: 1024px) { html { font-size: 87.5%; @@ -107,19 +107,19 @@
  • - - Dashboard + Dashboard
  • - @@ -127,14 +127,14 @@ - Projects + Projects
  • - @@ -145,7 +145,7 @@ - Servers + Servers
  • @@ -153,11 +153,11 @@ - + - Sources + Sources
  • @@ -165,19 +165,19 @@ class="{{ request()->is('destination*') ? 'menu-item-active menu-item' : 'menu-item' }}" href="{{ route('destination.index') }}"> - + - Destinations + Destinations
  • - + @@ -185,14 +185,14 @@ - S3 Storages + S3 Storages
  • - + - Shared Variables + Shared Variables
  • - + - Notifications + Notifications
  • - + - Keys & Tokens + Keys & Tokens
  • - + - Tags + Tags
  • @can('canAccessTerminal') @@ -247,14 +247,14 @@ - - Terminal + Terminal @endcan @@ -262,7 +262,7 @@ - @@ -270,14 +270,14 @@ - Profile + Profile
  • - @@ -288,7 +288,7 @@ - Teams + Teams
  • @if (isCloud() && auth()->user()->isAdmin()) @@ -296,12 +296,12 @@ - + - Subscription + Subscription @endif @@ -311,7 +311,7 @@ - @@ -319,7 +319,7 @@ d="M10.325 4.317c.426 -1.756 2.924 -1.756 3.35 0a1.724 1.724 0 0 0 2.573 1.066c1.543 -.94 3.31 .826 2.37 2.37a1.724 1.724 0 0 0 1.065 2.572c1.756 .426 1.756 2.924 0 3.35a1.724 1.724 0 0 0 -1.066 2.573c.94 1.543 -.826 3.31 -2.37 2.37a1.724 1.724 0 0 0 -2.572 1.065c-.426 1.756 -2.924 1.756 -3.35 0a1.724 1.724 0 0 0 -2.573 -1.066c-1.543 .94 -3.31 -.826 -2.37 -2.37a1.724 1.724 0 0 0 -1.065 -2.572c-1.756 -.426 -1.756 -2.924 0 -3.35a1.724 1.724 0 0 0 1.066 -2.573c-.94 -1.543 .826 -3.31 2.37 -2.37c1 .608 2.296 .07 2.572 -1.065z" /> - Settings + Settings @endif @@ -328,12 +328,12 @@ @if (isInstanceAdmin() || session('impersonating'))
  • - - Admin + Admin
  • @endif @@ -350,7 +350,7 @@ - + @@ -360,7 +360,7 @@
  • - + @@ -368,7 +368,7 @@ d="M12 6L8.707 9.293a1 1 0 0 0 0 1.414l.543.543c.69.69 1.81.69 2.5 0l1-1a3.182 3.182 0 0 1 4.5 0l2.25 2.25m-7 3l2 2M15 13l2 2" /> - Sponsor us + Sponsor us
  • @endif @@ -380,11 +380,11 @@ @@ -394,11 +394,11 @@
    @csrf
    diff --git a/resources/views/components/server/sidebar-proxy.blade.php b/resources/views/components/server/sidebar-proxy.blade.php index 5a76a2f1a..00bb3ee2a 100644 --- a/resources/views/components/server/sidebar-proxy.blade.php +++ b/resources/views/components/server/sidebar-proxy.blade.php @@ -1,16 +1,16 @@ - diff --git a/resources/views/components/server/sidebar-security.blade.php b/resources/views/components/server/sidebar-security.blade.php index 995d258cf..e61d23c89 100644 --- a/resources/views/components/server/sidebar-security.blade.php +++ b/resources/views/components/server/sidebar-security.blade.php @@ -1,10 +1,10 @@ - diff --git a/resources/views/components/server/sidebar.blade.php b/resources/views/components/server/sidebar.blade.php index e485ec545..2d7649fab 100644 --- a/resources/views/components/server/sidebar.blade.php +++ b/resources/views/components/server/sidebar.blade.php @@ -1,53 +1,51 @@ -
    - General + diff --git a/resources/views/components/service-database/sidebar.blade.php b/resources/views/components/service-database/sidebar.blade.php index 728df3a7b..9d31fc634 100644 --- a/resources/views/components/service-database/sidebar.blade.php +++ b/resources/views/components/service-database/sidebar.blade.php @@ -4,21 +4,24 @@ 'isImportSupported' => false, ]) -
    - + - + + + + Back - General + General @if ($serviceDatabase?->isBackupSolutionAvailable() || $serviceDatabase?->is_migrated) - Backups + Backups @endif @if ($isImportSupported) - Import Backup + Import Backup @endif
    diff --git a/resources/views/components/settings/sidebar.blade.php b/resources/views/components/settings/sidebar.blade.php index 8b564880c..0a68a9155 100644 --- a/resources/views/components/settings/sidebar.blade.php +++ b/resources/views/components/settings/sidebar.blade.php @@ -1,8 +1,8 @@ -
    - General - Advanced - Updates + diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php index 0ef021458..93d6fe413 100644 --- a/resources/views/layouts/app.blade.php +++ b/resources/views/layouts/app.blade.php @@ -22,7 +22,7 @@