From ea5363a775f6fc1b91050d5ef0c09854a53ea21a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Martin?= <7238941+LeoMartinDev@users.noreply.github.com> Date: Wed, 22 Jan 2025 17:24:08 +0100 Subject: [PATCH 01/20] feat(service): Update affine.yaml with AI environment variables (#4918) --- templates/compose/affine.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/templates/compose/affine.yaml b/templates/compose/affine.yaml index 97be09cdb..0bac71e63 100644 --- a/templates/compose/affine.yaml +++ b/templates/compose/affine.yaml @@ -37,6 +37,9 @@ services: - MAILER_USER=${MAILER_USER} - MAILER_PASSWORD=${MAILER_PASSWORD} - MAILER_SENDER=${MAILER_SENDER} + - COPILOT_FAL_API_KEY=${COPILOT_FAL_API_KEY} + - COPILOT_PERPLEXITY_API_KEY=${COPILOT_PERPLEXITY_API_KEY} + - COPILOT_OPENAI_API_KEY=${COPILOT_OPENAI_API_KEY} healthcheck: test: ["CMD-SHELL", "bash -c ':> /dev/tcp/127.0.0.1/3010' || exit 1"] interval: 5s From 3d68996900f87102293b6acca18b25fb5fe67938 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Wed, 22 Jan 2025 17:24:41 +0100 Subject: [PATCH 02/20] Update service-templates.json --- templates/service-templates.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/service-templates.json b/templates/service-templates.json index b95f9a032..34cb88652 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -33,7 +33,7 @@ "affine": { "documentation": "https://docs.affine.pro/docs/self-host-affine?utm_source=coolify.io", "slogan": "Affine is an open-source, all-in-one workspace and OS for knowledge management, a Notion/Miro alternative.", - "compose": "c2VydmljZXM6CiAgYWZmaW5lOgogICAgaW1hZ2U6ICdnaGNyLmlvL3RvZXZlcnl0aGluZy9hZmZpbmUtZ3JhcGhxbDpzdGFibGUnCiAgICBjb21tYW5kOgogICAgICAtIHNoCiAgICAgIC0gJy1jJwogICAgICAtICdub2RlIC4vc2NyaXB0cy9zZWxmLWhvc3QtcHJlZGVwbG95ICYmIG5vZGUgLi9kaXN0L2luZGV4LmpzJwogICAgZGVwZW5kc19vbjoKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcG9zdGdyZXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2FmZmluZS1jb25maWc6L3Jvb3QvLmFmZmluZS9jb25maWcnCiAgICAgIC0gJ2FmZmluZS1zdG9yYWdlOi9yb290Ly5hZmZpbmUvc3RvcmFnZScKICAgIGxvZ2dpbmc6CiAgICAgIGRyaXZlcjoganNvbi1maWxlCiAgICAgIG9wdGlvbnM6CiAgICAgICAgbWF4LXNpemU6IDEwMDBtCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fQUZGSU5FXzMwMTAKICAgICAgLSBOT0RFX09QVElPTlM9LS1pbXBvcnQ9Li9zY3JpcHRzL3JlZ2lzdGVyLmpzCiAgICAgIC0gQUZGSU5FX0NPTkZJR19QQVRIPS9yb290Ly5hZmZpbmUvY29uZmlnCiAgICAgIC0gUkVESVNfU0VSVkVSX0hPU1Q9cmVkaXMKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AcG9zdGdyZXM6NTQzMi8ke1BPU1RHUkVTX0RCOi1hZmZpbmV9JwogICAgICAtIE5PREVfRU5WPXByb2R1Y3Rpb24KICAgICAgLSBBRkZJTkVfU0VSVkVSX0hPU1Q9JFNFUlZJQ0VfRlFETl9BRkZJTkUKICAgICAgLSBBRkZJTkVfU0VSVkVSX0VYVEVSTkFMX1VSTD0kU0VSVklDRV9GUUROX0FGRklORQogICAgICAtICdNQUlMRVJfSE9TVD0ke01BSUxFUl9IT1NUfScKICAgICAgLSAnTUFJTEVSX1BPUlQ9JHtNQUlMRVJfUE9SVH0nCiAgICAgIC0gJ01BSUxFUl9VU0VSPSR7TUFJTEVSX1VTRVJ9JwogICAgICAtICdNQUlMRVJfUEFTU1dPUkQ9JHtNQUlMRVJfUEFTU1dPUkR9JwogICAgICAtICdNQUlMRVJfU0VOREVSPSR7TUFJTEVSX1NFTkRFUn0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gImJhc2ggLWMgJzo+IC9kZXYvdGNwLzEyNy4wLjAuMS8zMDEwJyB8fCBleGl0IDEiCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMwogIHJlZGlzOgogICAgaW1hZ2U6IHJlZGlzCiAgICB2b2x1bWVzOgogICAgICAtICdhZmZpbmUtcmVkaXMtZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtICctLXJhdycKICAgICAgICAtIGluY3IKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2JwogICAgdm9sdW1lczoKICAgICAgLSAnYWZmaW5lLXBvc3RncmVzLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VIGFmZmluZScKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LWFmZmluZX0nCiAgICAgIC0gUEdEQVRBPS92YXIvbGliL3Bvc3RncmVzcWwvZGF0YS9wZ2RhdGEK", + "compose": "c2VydmljZXM6CiAgYWZmaW5lOgogICAgaW1hZ2U6ICdnaGNyLmlvL3RvZXZlcnl0aGluZy9hZmZpbmUtZ3JhcGhxbDpzdGFibGUnCiAgICBjb21tYW5kOgogICAgICAtIHNoCiAgICAgIC0gJy1jJwogICAgICAtICdub2RlIC4vc2NyaXB0cy9zZWxmLWhvc3QtcHJlZGVwbG95ICYmIG5vZGUgLi9kaXN0L2luZGV4LmpzJwogICAgZGVwZW5kc19vbjoKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcG9zdGdyZXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2FmZmluZS1jb25maWc6L3Jvb3QvLmFmZmluZS9jb25maWcnCiAgICAgIC0gJ2FmZmluZS1zdG9yYWdlOi9yb290Ly5hZmZpbmUvc3RvcmFnZScKICAgIGxvZ2dpbmc6CiAgICAgIGRyaXZlcjoganNvbi1maWxlCiAgICAgIG9wdGlvbnM6CiAgICAgICAgbWF4LXNpemU6IDEwMDBtCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fQUZGSU5FXzMwMTAKICAgICAgLSBOT0RFX09QVElPTlM9LS1pbXBvcnQ9Li9zY3JpcHRzL3JlZ2lzdGVyLmpzCiAgICAgIC0gQUZGSU5FX0NPTkZJR19QQVRIPS9yb290Ly5hZmZpbmUvY29uZmlnCiAgICAgIC0gUkVESVNfU0VSVkVSX0hPU1Q9cmVkaXMKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AcG9zdGdyZXM6NTQzMi8ke1BPU1RHUkVTX0RCOi1hZmZpbmV9JwogICAgICAtIE5PREVfRU5WPXByb2R1Y3Rpb24KICAgICAgLSBBRkZJTkVfU0VSVkVSX0hPU1Q9JFNFUlZJQ0VfRlFETl9BRkZJTkUKICAgICAgLSBBRkZJTkVfU0VSVkVSX0VYVEVSTkFMX1VSTD0kU0VSVklDRV9GUUROX0FGRklORQogICAgICAtICdNQUlMRVJfSE9TVD0ke01BSUxFUl9IT1NUfScKICAgICAgLSAnTUFJTEVSX1BPUlQ9JHtNQUlMRVJfUE9SVH0nCiAgICAgIC0gJ01BSUxFUl9VU0VSPSR7TUFJTEVSX1VTRVJ9JwogICAgICAtICdNQUlMRVJfUEFTU1dPUkQ9JHtNQUlMRVJfUEFTU1dPUkR9JwogICAgICAtICdNQUlMRVJfU0VOREVSPSR7TUFJTEVSX1NFTkRFUn0nCiAgICAgIC0gJ0NPUElMT1RfRkFMX0FQSV9LRVk9JHtDT1BJTE9UX0ZBTF9BUElfS0VZfScKICAgICAgLSAnQ09QSUxPVF9QRVJQTEVYSVRZX0FQSV9LRVk9JHtDT1BJTE9UX1BFUlBMRVhJVFlfQVBJX0tFWX0nCiAgICAgIC0gJ0NPUElMT1RfT1BFTkFJX0FQSV9LRVk9JHtDT1BJTE9UX09QRU5BSV9BUElfS0VZfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAiYmFzaCAtYyAnOj4gL2Rldi90Y3AvMTI3LjAuMC4xLzMwMTAnIHx8IGV4aXQgMSIKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAzCiAgcmVkaXM6CiAgICBpbWFnZTogcmVkaXMKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2FmZmluZS1yZWRpcy1kYXRhOi9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHJlZGlzLWNsaQogICAgICAgIC0gJy0tcmF3JwogICAgICAgIC0gaW5jcgogICAgICAgIC0gcGluZwogICAgICBpbnRlcnZhbDogMTBzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDUKICBwb3N0Z3JlczoKICAgIGltYWdlOiAncG9zdGdyZXM6MTYnCiAgICB2b2x1bWVzOgogICAgICAtICdhZmZpbmUtcG9zdGdyZXMtZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLVUgYWZmaW5lJwogICAgICBpbnRlcnZhbDogMTBzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDUKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTfScKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotYWZmaW5lfScKICAgICAgLSBQR0RBVEE9L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhL3BnZGF0YQo=", "tags": [ "knowledge-management", "notion", From ac5d0aa116b47ac25e264471089f3d7c2d1bf034 Mon Sep 17 00:00:00 2001 From: Zairig Imad Date: Wed, 22 Jan 2025 17:58:15 +0100 Subject: [PATCH 03/20] feat(service): Add new service Flipt (#4875) --- public/svgs/flipt.svg | 21 +++++++++++++++++++++ templates/compose/flipt.yaml | 23 +++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 public/svgs/flipt.svg create mode 100644 templates/compose/flipt.yaml diff --git a/public/svgs/flipt.svg b/public/svgs/flipt.svg new file mode 100644 index 000000000..8c8164f8f --- /dev/null +++ b/public/svgs/flipt.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/templates/compose/flipt.yaml b/templates/compose/flipt.yaml new file mode 100644 index 000000000..74a72d9f6 --- /dev/null +++ b/templates/compose/flipt.yaml @@ -0,0 +1,23 @@ +# documentation: https://docs.flipt.io/cloud/overview +# slogan: Flipt is a fully managed feature flag solution that enables you to keep your feature flags and remote config next to your code in Git. +# tags: feature flags,devops, CI, CD +# logo: svgs/flipt.svg +# port: 8080 + +services: + flipt: + image: 'docker.flipt.io/flipt/flipt:latest' + volumes: + - 'flipt-data:/var/opt/flipt' + environment: + - SERVICE_FQDN_FLIPT_8080 + healthcheck: + test: + - CMD + - wget + - '--spider' + - '--quiet' + - 'http://127.0.0.1:8080' + interval: 2s + timeout: 10s + retries: 15 \ No newline at end of file From 7cc90f02c5e80b290875651a30c03251f2b9fa8f Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Wed, 22 Jan 2025 18:07:57 +0100 Subject: [PATCH 04/20] fix(ui): metrics stuck in loading state --- resources/views/components/server/sidebar.blade.php | 2 +- .../views/livewire/project/application/configuration.blade.php | 3 +-- .../views/livewire/project/database/configuration.blade.php | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/resources/views/components/server/sidebar.blade.php b/resources/views/components/server/sidebar.blade.php index 092e306a5..ecc5785aa 100644 --- a/resources/views/components/server/sidebar.blade.php +++ b/resources/views/components/server/sidebar.blade.php @@ -22,7 +22,7 @@ Log Drains - Metrics @endif @if (!$server->isLocalhost()) diff --git a/resources/views/livewire/project/application/configuration.blade.php b/resources/views/livewire/project/application/configuration.blade.php index c6f27d3f3..7fcbbd691 100644 --- a/resources/views/livewire/project/application/configuration.blade.php +++ b/resources/views/livewire/project/application/configuration.blade.php @@ -74,8 +74,7 @@ href="{{ route('project.application.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}" wire:navigate>Resource Operations Metrics + href="{{ route('project.application.metrics', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'application_uuid' => $application->uuid]) }}" >Metrics Tags diff --git a/resources/views/livewire/project/database/configuration.blade.php b/resources/views/livewire/project/database/configuration.blade.php index d3649f94a..cce8a5a20 100644 --- a/resources/views/livewire/project/database/configuration.blade.php +++ b/resources/views/livewire/project/database/configuration.blade.php @@ -32,8 +32,7 @@ href="{{ route('project.database.resource-operations', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}" wire:navigate>Resource Operations Metrics + href="{{ route('project.database.metrics', ['project_uuid' => $project->uuid, 'environment_uuid' => $environment->uuid, 'database_uuid' => $database->uuid]) }}">Metrics Tags From 08e6c685137bc9dab2ea0f9d6cf4e8311c525ae8 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Wed, 22 Jan 2025 18:08:23 +0100 Subject: [PATCH 05/20] fix(ui): use `wire:navigate` to navigate to the server settings page --- resources/views/livewire/project/shared/metrics.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/livewire/project/shared/metrics.blade.php b/resources/views/livewire/project/shared/metrics.blade.php index cfe83ded6..645de8331 100644 --- a/resources/views/livewire/project/shared/metrics.blade.php +++ b/resources/views/livewire/project/shared/metrics.blade.php @@ -8,7 +8,7 @@ @elseif(!$resource->destination->server->isMetricsEnabled())
Metrics are only available for servers with Sentinel & Metrics enabled!
Go to Server settings to + wire:navigate href="{{ route('server.show', $resource->destination->server->uuid) }}">Server settings to enable it.
@else From b5e88adc2bc93f4bee403cf3c7dfc72e8369714f Mon Sep 17 00:00:00 2001 From: Arxk <121711454+arxkdev@users.noreply.github.com> Date: Wed, 22 Jan 2025 12:09:46 -0500 Subject: [PATCH 06/20] fix(service): Plunk API & health check endpoint (#4925) - Add health endpoint to Plunk healthcheck - Add NODE_OPTIONS common fix --- templates/compose/plunk.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/compose/plunk.yaml b/templates/compose/plunk.yaml index 4b356720a..60c2ee850 100644 --- a/templates/compose/plunk.yaml +++ b/templates/compose/plunk.yaml @@ -25,9 +25,10 @@ services: - APP_URI=${SERVICE_FQDN_PLUNK} - API_URI=${SERVICE_FQDN_PLUNK}/api - DISABLE_SIGNUPS=${DISABLE_SIGNUPS:-False} + - NODE_OPTIONS=--no-network-family-autoselection entrypoint: [ "/app/entry.sh" ] healthcheck: - test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1:3000"] + test: ["CMD-SHELL", "(wget -S --spider http://127.0.0.1:3000/api/health 2>&1 | grep -q \"HTTP/1.1 [1-3]\")"] interval: 2s timeout: 10s retries: 15 From 0d85f57db26b4e4c37f2f4a8c2bca68714942023 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Wed, 22 Jan 2025 18:13:44 +0100 Subject: [PATCH 07/20] chore(versions): update coolify versions to v4.0.0-beta.389 --- config/constants.php | 2 +- versions.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/constants.php b/config/constants.php index c463824d0..dd8759e14 100644 --- a/config/constants.php +++ b/config/constants.php @@ -2,7 +2,7 @@ return [ 'coolify' => [ - 'version' => '4.0.0-beta.388', + 'version' => '4.0.0-beta.389', 'helper_version' => '1.0.5', 'realtime_version' => '1.0.5', 'self_hosted' => env('SELF_HOSTED', true), diff --git a/versions.json b/versions.json index ecc443965..e27d8adc2 100644 --- a/versions.json +++ b/versions.json @@ -1,10 +1,10 @@ { "coolify": { "v4": { - "version": "4.0.0-beta.388" + "version": "4.0.0-beta.389" }, "nightly": { - "version": "4.0.0-beta.389" + "version": "4.0.0-beta.390" }, "helper": { "version": "1.0.5" From 131216dd0c480279bbb9aba26b391e6472e00d74 Mon Sep 17 00:00:00 2001 From: "@PwnedC99" <720seyed@gmail.com> Date: Wed, 22 Jan 2025 18:35:16 +0100 Subject: [PATCH 08/20] fix(service): infinite loading and lag with invoiceninja service (#4876) - fix infinite loading and lag caused by a bug in the invoiceninja docker compose file - fix pdf not showing --- templates/compose/invoice-ninja.yaml | 57 +++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/templates/compose/invoice-ninja.yaml b/templates/compose/invoice-ninja.yaml index beb05d983..9b7ac9b3f 100644 --- a/templates/compose/invoice-ninja.yaml +++ b/templates/compose/invoice-ninja.yaml @@ -6,27 +6,52 @@ services: invoice-ninja: - image: invoiceninja/invoiceninja:5 + image: "invoiceninja/invoiceninja:5" environment: - SERVICE_FQDN_INVOICENINJA + - APP_NAME=${APP_NAME:-"Invoice Ninja"} - APP_ENV=${APP_ENV:-production} - APP_URL=${SERVICE_FQDN_INVOICENINJA} - APP_KEY=base64:${SERVICE_REALBASE64_INVOICENINJA} - APP_DEBUG=${APP_DEBUG:-false} - - REQUIRE_HTTPS=${REQUIRE_HTTPS:-false} - - PHANTOMJS_PDF_GENERATION=${PHANTOMJS_PDF_GENERATION:-false} - - PDF_GENERATOR=${PDF_GENERATOR:-snappdf} - - TRUSTED_PROXIES=${TRUSTED_PROXIES:-*} - - QUEUE_CONNECTION=${QUEUE_CONNECTION:-database} - - IN_USER_EMAIL=${IN_USER_EMAIL:-admin@example.com} - - IN_PASSWORD=${SERVICE_PASSWORD_INVOICENINJAUSER} + - "REQUIRE_HTTPS=${REQUIRE_HTTPS:-false}" + - PHANTOMJS_PDF_GENERATION=false + - PDF_GENERATOR=hosted_ninja + - "TRUSTED_PROXIES=${TRUSTED_PROXIES:-*}" + - CACHE_DRIVER=redis + - "QUEUE_CONNECTION=${QUEUE_CONNECTION:-redis}" + - SESSION_DRIVER=redis + - "REDIS_HOST=${REDIS_HOST:-redis}" + - "REDIS_PASSWORD=${REDIS_PASSWORD:-null}" + - "REDIS_PORT=${REDIS_PORT:-6379}" - DB_HOST=${DB_HOST:-mariadb} - DB_PORT=${DB_PORT:-3306} - DB_DATABASE=${DB_DATABASE:-invoiceninja} - DB_USERNAME=$SERVICE_USER_MARIADB - DB_PASSWORD=$SERVICE_PASSWORD_MARIADB + - "IN_USER_EMAIL=${IN_USER_EMAIL:-admin@example.com}" + - "IN_PASSWORD=${SERVICE_PASSWORD_INVOICENINJAUSER:-changeme!}" + - MAIL_MAILER=${MAIL_MAILER:-log} + - MAIL_HOST=${MAIL_HOST:-smtp.mailtrap.io} + - MAIL_PORT=${MAIL_PORT:-2525} + - MAIL_USERNAME=${MAIL_USERNAME:-null} + - MAIL_PASSWORD=${MAIL_PASSWORD:-null} + - MAIL_ENCRYPTION=${MAIL_ENCRYPTION:-null} + - MAIL_FROM_ADDRESS=${MAIL_FROM_ADDRESS:-'user@example.com'} + - MAIL_FROM_NAME=${MAIL_FROM_NAME:-'SelfHostedUser'} + - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} + - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} + - AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION} + - AWS_BUCKET=${AWS_BUCKET} + - AWS_URL=${AWS_URL} + - AWS_ENDPOINT=${AWS_ENDPOINT} + - NORDIGEN_SECRET_ID=${NORDIGEN_SECRET_ID:-} + - NORDIGEN_SECRET_KEY=${NORDIGEN_SECRET_KEY:-} + - IS_DOCKER=true + - SCOUT_DRIVER=${SCOUT_DRIVER:-null} + - LICENSE_KEY=${LICENSE_KEY} healthcheck: - test: ['CMD', 'echo', 'ok'] + test: ["CMD", "echo", "ok"] interval: 5s timeout: 20s retries: 10 @@ -142,3 +167,17 @@ services: interval: 5s timeout: 20s retries: 10 + + redis: + image: "redis:alpine" + restart: unless-stopped + volumes: + - "redis_data:/data" + healthcheck: + test: + - CMD + - redis-cli + - ping + interval: 10s + timeout: 5s + retries: 5 From f10a34534f8e3cf02b5facc9c6afee091772d844 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Wed, 22 Jan 2025 18:51:13 +0100 Subject: [PATCH 09/20] fix(service): invoiceninja service --- templates/compose/invoice-ninja.yaml | 65 ++++++++++++++-------------- templates/service-templates.json | 18 +++++++- 2 files changed, 48 insertions(+), 35 deletions(-) diff --git a/templates/compose/invoice-ninja.yaml b/templates/compose/invoice-ninja.yaml index 9b7ac9b3f..4ccd94b6c 100644 --- a/templates/compose/invoice-ninja.yaml +++ b/templates/compose/invoice-ninja.yaml @@ -6,7 +6,7 @@ services: invoice-ninja: - image: "invoiceninja/invoiceninja:5" + image: invoiceninja/invoiceninja:5 environment: - SERVICE_FQDN_INVOICENINJA - APP_NAME=${APP_NAME:-"Invoice Ninja"} @@ -14,41 +14,41 @@ services: - APP_URL=${SERVICE_FQDN_INVOICENINJA} - APP_KEY=base64:${SERVICE_REALBASE64_INVOICENINJA} - APP_DEBUG=${APP_DEBUG:-false} - - "REQUIRE_HTTPS=${REQUIRE_HTTPS:-false}" - - PHANTOMJS_PDF_GENERATION=false - - PDF_GENERATOR=hosted_ninja - - "TRUSTED_PROXIES=${TRUSTED_PROXIES:-*}" + - REQUIRE_HTTPS=${REQUIRE_HTTPS:-false} + - PHANTOMJS_PDF_GENERATION=${PHANTOMJS_PDF_GENERATION:-false} + - PDF_GENERATOR=${PDF_GENERATOR:-hosted_ninja} + - TRUSTED_PROXIES=${TRUSTED_PROXIES:-*} - CACHE_DRIVER=redis - - "QUEUE_CONNECTION=${QUEUE_CONNECTION:-redis}" + - QUEUE_CONNECTION=${QUEUE_CONNECTION:-redis} - SESSION_DRIVER=redis - - "REDIS_HOST=${REDIS_HOST:-redis}" - - "REDIS_PASSWORD=${REDIS_PASSWORD:-null}" - - "REDIS_PORT=${REDIS_PORT:-6379}" + - REDIS_HOST=${REDIS_HOST:-redis} + - REDIS_PASSWORD=${SERVICE_PASSWORD_REDIS} + - REDIS_PORT=${REDIS_PORT:-6379} - DB_HOST=${DB_HOST:-mariadb} - DB_PORT=${DB_PORT:-3306} - DB_DATABASE=${DB_DATABASE:-invoiceninja} - - DB_USERNAME=$SERVICE_USER_MARIADB - - DB_PASSWORD=$SERVICE_PASSWORD_MARIADB - - "IN_USER_EMAIL=${IN_USER_EMAIL:-admin@example.com}" - - "IN_PASSWORD=${SERVICE_PASSWORD_INVOICENINJAUSER:-changeme!}" + - DB_USERNAME=${SERVICE_USER_MARIADB} + - DB_PASSWORD=${SERVICE_PASSWORD_MARIADB} + - IN_USER_EMAIL=${IN_USER_EMAIL:-admin@example.com} + - IN_PASSWORD=${SERVICE_PASSWORD_INVOICENINJAUSER} - MAIL_MAILER=${MAIL_MAILER:-log} - - MAIL_HOST=${MAIL_HOST:-smtp.mailtrap.io} - - MAIL_PORT=${MAIL_PORT:-2525} - - MAIL_USERNAME=${MAIL_USERNAME:-null} - - MAIL_PASSWORD=${MAIL_PASSWORD:-null} - - MAIL_ENCRYPTION=${MAIL_ENCRYPTION:-null} - - MAIL_FROM_ADDRESS=${MAIL_FROM_ADDRESS:-'user@example.com'} - - MAIL_FROM_NAME=${MAIL_FROM_NAME:-'SelfHostedUser'} + - MAIL_HOST=${MAIL_HOST} + - MAIL_PORT=${MAIL_PORT} + - MAIL_USERNAME=${MAIL_USERNAME} + - MAIL_PASSWORD=${MAIL_PASSWORD} + - MAIL_ENCRYPTION=${MAIL_ENCRYPTION} + - MAIL_FROM_ADDRESS=${MAIL_FROM_ADDRESS} + - MAIL_FROM_NAME=${MAIL_FROM_NAME} - AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID} - AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} - AWS_DEFAULT_REGION=${AWS_DEFAULT_REGION} - AWS_BUCKET=${AWS_BUCKET} - AWS_URL=${AWS_URL} - AWS_ENDPOINT=${AWS_ENDPOINT} - - NORDIGEN_SECRET_ID=${NORDIGEN_SECRET_ID:-} - - NORDIGEN_SECRET_KEY=${NORDIGEN_SECRET_KEY:-} + - NORDIGEN_SECRET_ID=${NORDIGEN_SECRET_ID} + - NORDIGEN_SECRET_KEY=${NORDIGEN_SECRET_KEY} - IS_DOCKER=true - - SCOUT_DRIVER=${SCOUT_DRIVER:-null} + - SCOUT_DRIVER=${SCOUT_DRIVER} - LICENSE_KEY=${LICENSE_KEY} healthcheck: test: ["CMD", "echo", "ok"] @@ -158,10 +158,10 @@ services: volumes: - mariadb-data:/var/lib/mysql environment: - - MYSQL_ROOT_PASSWORD=$SERVICE_PASSWORD_MARIADBROOT + - MYSQL_ROOT_PASSWORD=${SERVICE_PASSWORD_MARIADBROOT} - MYSQL_DATABASE=${DB_DATABASE:-invoiceninja} - - MYSQL_USER=$SERVICE_USER_MARIADB - - MYSQL_PASSWORD=$SERVICE_PASSWORD_MARIADB + - MYSQL_USER=${SERVICE_USER_MARIADB} + - MYSQL_PASSWORD=${SERVICE_PASSWORD_MARIADB} healthcheck: test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] interval: 5s @@ -169,15 +169,14 @@ services: retries: 10 redis: - image: "redis:alpine" - restart: unless-stopped + image: "redis:7.4-alpine" + command: redis-server --requirepass ${SERVICE_PASSWORD_REDIS} + environment: + - REDIS_PASSWORD=${SERVICE_PASSWORD_REDIS} volumes: - - "redis_data:/data" + - "invoice-ninja-redis-data:/data" healthcheck: - test: - - CMD - - redis-cli - - ping + test: ["CMD", "redis-cli", "-a", "${SERVICE_PASSWORD_REDIS}", "ping"] interval: 10s timeout: 5s retries: 5 diff --git a/templates/service-templates.json b/templates/service-templates.json index 34cb88652..2c2ed2e54 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -832,6 +832,20 @@ "minversion": "0.0.0", "port": "5800" }, + "flipt": { + "documentation": "https://docs.flipt.io/cloud/overview?utm_source=coolify.io", + "slogan": "Flipt is a fully managed feature flag solution that enables you to keep your feature flags and remote config next to your code in Git.", + "compose": "c2VydmljZXM6CiAgZmxpcHQ6CiAgICBpbWFnZTogJ2RvY2tlci5mbGlwdC5pby9mbGlwdC9mbGlwdDpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtICdmbGlwdC1kYXRhOi92YXIvb3B0L2ZsaXB0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0ZMSVBUXzgwODAKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLS1zcGlkZXInCiAgICAgICAgLSAnLS1xdWlldCcKICAgICAgICAtICdodHRwOi8vMTI3LjAuMC4xOjgwODAnCiAgICAgIGludGVydmFsOiAycwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTUK", + "tags": [ + "feature flags", + "devops", + "ci", + "cd" + ], + "logo": "svgs/flipt.svg", + "minversion": "0.0.0", + "port": "8080" + }, "flowise-with-databases": { "documentation": "https://docs.flowiseai.com/?utm_source=coolify.io", "slogan": "Flowise is an open source low-code tool for developers to build customized LLM orchestration flows & AI agents. Also deploys Redis, Postgres and other services.", @@ -1367,7 +1381,7 @@ "invoice-ninja": { "documentation": "https://invoiceninja.github.io/selfhost.html?utm_source=coolify.io", "slogan": "The leading open-source invoicing platform", - "compose": "c2VydmljZXM6CiAgaW52b2ljZS1uaW5qYToKICAgIGltYWdlOiAnaW52b2ljZW5pbmphL2ludm9pY2VuaW5qYTo1JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0lOVk9JQ0VOSU5KQQogICAgICAtICdBUFBfRU5WPSR7QVBQX0VOVjotcHJvZHVjdGlvbn0nCiAgICAgIC0gJ0FQUF9VUkw9JHtTRVJWSUNFX0ZRRE5fSU5WT0lDRU5JTkpBfScKICAgICAgLSAnQVBQX0tFWT1iYXNlNjQ6JHtTRVJWSUNFX1JFQUxCQVNFNjRfSU5WT0lDRU5JTkpBfScKICAgICAgLSAnQVBQX0RFQlVHPSR7QVBQX0RFQlVHOi1mYWxzZX0nCiAgICAgIC0gJ1JFUVVJUkVfSFRUUFM9JHtSRVFVSVJFX0hUVFBTOi1mYWxzZX0nCiAgICAgIC0gJ1BIQU5UT01KU19QREZfR0VORVJBVElPTj0ke1BIQU5UT01KU19QREZfR0VORVJBVElPTjotZmFsc2V9JwogICAgICAtICdQREZfR0VORVJBVE9SPSR7UERGX0dFTkVSQVRPUjotc25hcHBkZn0nCiAgICAgIC0gJ1RSVVNURURfUFJPWElFUz0ke1RSVVNURURfUFJPWElFUzotKn0nCiAgICAgIC0gJ1FVRVVFX0NPTk5FQ1RJT049JHtRVUVVRV9DT05ORUNUSU9OOi1kYXRhYmFzZX0nCiAgICAgIC0gJ0lOX1VTRVJfRU1BSUw9JHtJTl9VU0VSX0VNQUlMOi1hZG1pbkBleGFtcGxlLmNvbX0nCiAgICAgIC0gJ0lOX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9JTlZPSUNFTklOSkFVU0VSfScKICAgICAgLSAnREJfSE9TVD0ke0RCX0hPU1Q6LW1hcmlhZGJ9JwogICAgICAtICdEQl9QT1JUPSR7REJfUE9SVDotMzMwNn0nCiAgICAgIC0gJ0RCX0RBVEFCQVNFPSR7REJfREFUQUJBU0U6LWludm9pY2VuaW5qYX0nCiAgICAgIC0gREJfVVNFUk5BTUU9JFNFUlZJQ0VfVVNFUl9NQVJJQURCCiAgICAgIC0gREJfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfTUFSSUFEQgogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGVjaG8KICAgICAgICAtIG9rCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2ludm9pY2UtbmluamEtcHVibGljOi92YXIvd3d3L2FwcC9wdWJsaWMnCiAgICAgIC0gJ2ludm9pY2UtbmluamEtc3RvcmFnZTovdmFyL3d3dy9hcHAvc3RvcmFnZScKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vc3VwZXJ2aXNvcmQuY29uZgogICAgICAgIHRhcmdldDogL2V0Yy9zdXBlcnZpc29yZC5jb25mCiAgICAgICAgY29udGVudDogIltzdXBlcnZpc29yZF1cbm5vZGFlbW9uPXRydWVcbnBpZGZpbGU9L3RtcC9zdXBlcnZpc29yZC5waWRcbmxvZ2ZpbGU9L2Rldi9udWxsIDsgbm9kYWVtb24gd2lsbCBjYXVzZSBsb2dzIHRvIGdvIHRvIHN0ZG91dFxubG9nZmlsZV9tYXhieXRlcz0wXG5sb2dsZXZlbD1pbmZvXG5cbltwcm9ncmFtOnBocC1mcG1dXG5yZWRpcmVjdF9zdGRlcnI9dHJ1ZVxuc3Rkb3V0X2xvZ2ZpbGU9L2Rldi9zdGRvdXRcbnN0ZG91dF9sb2dmaWxlX21heGJ5dGVzPTBcbnN0ZGVycl9sb2dmaWxlPS9kZXYvc3RkZXJyXG5zdGRlcnJfbG9nZmlsZV9tYXhieXRlcz0wXG5jb21tYW5kPXBocCBhcnRpc2FuIHNlcnZlIC0taG9zdCAwLjAuMC4wIC0tcG9ydCA5MDAwXG5cbltwcm9ncmFtOnNjaGVkdWxlcl1cbmF1dG9yZXN0YXJ0PXRydWVcbnJlZGlyZWN0X3N0ZGVycj10cnVlXG5zdGRvdXRfbG9nZmlsZT0vZGV2L3N0ZG91dFxuc3Rkb3V0X2xvZ2ZpbGVfbWF4Ynl0ZXM9MFxuc3RkZXJyX2xvZ2ZpbGU9L2Rldi9zdGRlcnJcbnN0ZGVycl9sb2dmaWxlX21heGJ5dGVzPTBcbmNvbW1hbmQ9cGhwIGFydGlzYW4gc2NoZWR1bGU6d29ya1xuXG5bcHJvZ3JhbTpxdWV1ZS13b3JrZXJdXG5wcm9jZXNzX25hbWU9JShwcm9ncmFtX25hbWUpc18lKHByb2Nlc3NfbnVtKTAyZFxuYXV0b3Jlc3RhcnQ9dHJ1ZVxucmVkaXJlY3Rfc3RkZXJyPXRydWVcbnN0ZG91dF9sb2dmaWxlPS9kZXYvc3Rkb3V0XG5zdGRvdXRfbG9nZmlsZV9tYXhieXRlcz0wXG5zdGRlcnJfbG9nZmlsZT0vZGV2L3N0ZGVyclxuc3RkZXJyX2xvZ2ZpbGVfbWF4Ynl0ZXM9MFxubnVtcHJvY3M9MlxuY29tbWFuZD1waHAgYXJ0aXNhbiBxdWV1ZTp3b3JrIC0tc2xlZXA9MyAtLXRyaWVzPTEgLS1tZW1vcnk9MjU2IC0tdGltZW91dD0zNjAwXG5cbltldmVudGxpc3RlbmVyOnNodXRkb3duXVxuY29tbWFuZD1zaHV0ZG93bi5zaFxuZXZlbnRzPVBST0NFU1NfU1RBVEVfU1RPUFBFRCwgUFJPQ0VTU19TVEFURV9FWElURUQsIFBST0NFU1NfU1RBVEVfRkFUQUxcbnN0ZG91dF9sb2dmaWxlPS9kZXYvc3Rkb3V0XG5zdGRvdXRfbG9nZmlsZV9tYXhieXRlcz0wXG5zdGRlcnJfbG9nZmlsZT0vZGV2L3N0ZGVyclxuc3RkZXJyX2xvZ2ZpbGVfbWF4Ynl0ZXM9MFxuIgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi9waHAuaW5pCiAgICAgICAgdGFyZ2V0OiAvdXNyL2xvY2FsL2V0Yy9waHAvcGhwLmluaQogICAgICAgIGNvbnRlbnQ6ICJzZXNzaW9uLmF1dG9fc3RhcnQgPSBPZmZcbnNob3J0X29wZW5fdGFnID0gT2ZmXG5cbmVycm9yX3JlcG9ydGluZyA9IEVfQUxMICYgfkVfTk9USUNFICYgfkVfV0FSTklORyAmIH5FX1NUUklDVCAmIH5FX0RFUFJFQ0FURURcblxuOyBvcGNhY2hlLmVuYWJsZT0xXG47IG9wY2FjaGUucHJlbG9hZD0vc3J2L3d3dy9pbnZvaWNlbmluamEvY3VycmVudC9wcmVsb2FkLnBocFxuOyBvcGNhY2hlLnByZWxvYWRfdXNlcj13d3ctZGF0YVxuXG47IDsgVGhlIE9QY2FjaGUgc2hhcmVkIG1lbW9yeSBzdG9yYWdlIHNpemUuXG47IG9wY2FjaGUubWF4X2FjY2VsZXJhdGVkX2ZpbGVzPTMwMDAwMFxuOyBvcGNhY2hlLnZhbGlkYXRlX3RpbWVzdGFtcHM9MVxuOyBvcGNhY2hlLnJldmFsaWRhdGVfZnJlcT0zMFxuOyBvcGNhY2hlLmppdF9idWZmZXJfc2l6ZT0yNTZNXG47IG9wY2FjaGUuaml0PTEyMDVcbjsgb3BjYWNoZS5tZW1vcnlfY29uc3VtcHRpb249MTAyNE1cblxucG9zdF9tYXhfc2l6ZSA9IDYwTVxudXBsb2FkX21heF9maWxlc2l6ZSA9IDUwTVxubWVtb3J5X2xpbWl0PTUxMk1cbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vcGhwLWNsaS5pbmkKICAgICAgICB0YXJnZXQ6IC91c3IvbG9jYWwvZXRjL3BocC9waHAtY2xpLmluaQogICAgICAgIGNvbnRlbnQ6ICJzZXNzaW9uLmF1dG9fc3RhcnQgPSBPZmZcbnNob3J0X29wZW5fdGFnID0gT2ZmXG5cbmVycm9yX3JlcG9ydGluZyA9IEVfQUxMICYgfkVfTk9USUNFICYgfkVfV0FSTklORyAmIH5FX1NUUklDVCAmIH5FX0RFUFJFQ0FURURcblxuOyBvcGNhY2hlLmVuYWJsZV9jbGk9MVxuOyBvcGNhY2hlLmZhc3Rfc2h1dGRvd249MVxuOyBvcGNhY2hlLm1lbW9yeV9jb25zdW1wdGlvbj0yNTZcbjsgb3BjYWNoZS5pbnRlcm5lZF9zdHJpbmdzX2J1ZmZlcj04XG47IG9wY2FjaGUubWF4X2FjY2VsZXJhdGVkX2ZpbGVzPTQwMDBcbjsgb3BjYWNoZS5yZXZhbGlkYXRlX2ZyZXE9NjBcbjsgIyBodHRwOi8vc3ltZm9ueS5jb20vZG9jL2N1cnJlbnQvcGVyZm9ybWFuY2UuaHRtbFxuOyByZWFscGF0aF9jYWNoZV9zaXplID0gNDA5NktcbjsgcmVhbHBhdGhfY2FjaGVfdHRsID0gNjAwXG5cbm1lbW9yeV9saW1pdCA9IDJHXG5wb3N0X21heF9zaXplID0gNjBNXG51cGxvYWRfbWF4X2ZpbGVzaXplID0gNTBNIgogICAgZGVwZW5kc19vbjoKICAgICAgbWFyaWFkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogIG1hcmlhZGI6CiAgICBpbWFnZTogJ21hcmlhZGI6MTEnCiAgICB2b2x1bWVzOgogICAgICAtICdtYXJpYWRiLWRhdGE6L3Zhci9saWIvbXlzcWwnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBNWVNRTF9ST09UX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX01BUklBREJST09UCiAgICAgIC0gJ01ZU1FMX0RBVEFCQVNFPSR7REJfREFUQUJBU0U6LWludm9pY2VuaW5qYX0nCiAgICAgIC0gTVlTUUxfVVNFUj0kU0VSVklDRV9VU0VSX01BUklBREIKICAgICAgLSBNWVNRTF9QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9NQVJJQURCCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gaGVhbHRoY2hlY2suc2gKICAgICAgICAtICctLWNvbm5lY3QnCiAgICAgICAgLSAnLS1pbm5vZGJfaW5pdGlhbGl6ZWQnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAK", + "compose": "c2VydmljZXM6CiAgaW52b2ljZS1uaW5qYToKICAgIGltYWdlOiAnaW52b2ljZW5pbmphL2ludm9pY2VuaW5qYTo1JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0lOVk9JQ0VOSU5KQQogICAgICAtICdBUFBfTkFNRT0ke0FQUF9OQU1FOi0iSW52b2ljZSBOaW5qYSJ9JwogICAgICAtICdBUFBfRU5WPSR7QVBQX0VOVjotcHJvZHVjdGlvbn0nCiAgICAgIC0gJ0FQUF9VUkw9JHtTRVJWSUNFX0ZRRE5fSU5WT0lDRU5JTkpBfScKICAgICAgLSAnQVBQX0tFWT1iYXNlNjQ6JHtTRVJWSUNFX1JFQUxCQVNFNjRfSU5WT0lDRU5JTkpBfScKICAgICAgLSAnQVBQX0RFQlVHPSR7QVBQX0RFQlVHOi1mYWxzZX0nCiAgICAgIC0gJ1JFUVVJUkVfSFRUUFM9JHtSRVFVSVJFX0hUVFBTOi1mYWxzZX0nCiAgICAgIC0gJ1BIQU5UT01KU19QREZfR0VORVJBVElPTj0ke1BIQU5UT01KU19QREZfR0VORVJBVElPTjotZmFsc2V9JwogICAgICAtICdQREZfR0VORVJBVE9SPSR7UERGX0dFTkVSQVRPUjotaG9zdGVkX25pbmphfScKICAgICAgLSAnVFJVU1RFRF9QUk9YSUVTPSR7VFJVU1RFRF9QUk9YSUVTOi0qfScKICAgICAgLSBDQUNIRV9EUklWRVI9cmVkaXMKICAgICAgLSAnUVVFVUVfQ09OTkVDVElPTj0ke1FVRVVFX0NPTk5FQ1RJT046LXJlZGlzfScKICAgICAgLSBTRVNTSU9OX0RSSVZFUj1yZWRpcwogICAgICAtICdSRURJU19IT1NUPSR7UkVESVNfSE9TVDotcmVkaXN9JwogICAgICAtICdSRURJU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUkVESVN9JwogICAgICAtICdSRURJU19QT1JUPSR7UkVESVNfUE9SVDotNjM3OX0nCiAgICAgIC0gJ0RCX0hPU1Q9JHtEQl9IT1NUOi1tYXJpYWRifScKICAgICAgLSAnREJfUE9SVD0ke0RCX1BPUlQ6LTMzMDZ9JwogICAgICAtICdEQl9EQVRBQkFTRT0ke0RCX0RBVEFCQVNFOi1pbnZvaWNlbmluamF9JwogICAgICAtICdEQl9VU0VSTkFNRT0ke1NFUlZJQ0VfVVNFUl9NQVJJQURCfScKICAgICAgLSAnREJfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01BUklBREJ9JwogICAgICAtICdJTl9VU0VSX0VNQUlMPSR7SU5fVVNFUl9FTUFJTDotYWRtaW5AZXhhbXBsZS5jb219JwogICAgICAtICdJTl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfSU5WT0lDRU5JTkpBVVNFUn0nCiAgICAgIC0gJ01BSUxfTUFJTEVSPSR7TUFJTF9NQUlMRVI6LWxvZ30nCiAgICAgIC0gJ01BSUxfSE9TVD0ke01BSUxfSE9TVH0nCiAgICAgIC0gJ01BSUxfUE9SVD0ke01BSUxfUE9SVH0nCiAgICAgIC0gJ01BSUxfVVNFUk5BTUU9JHtNQUlMX1VTRVJOQU1FfScKICAgICAgLSAnTUFJTF9QQVNTV09SRD0ke01BSUxfUEFTU1dPUkR9JwogICAgICAtICdNQUlMX0VOQ1JZUFRJT049JHtNQUlMX0VOQ1JZUFRJT059JwogICAgICAtICdNQUlMX0ZST01fQUREUkVTUz0ke01BSUxfRlJPTV9BRERSRVNTfScKICAgICAgLSAnTUFJTF9GUk9NX05BTUU9JHtNQUlMX0ZST01fTkFNRX0nCiAgICAgIC0gJ0FXU19BQ0NFU1NfS0VZX0lEPSR7QVdTX0FDQ0VTU19LRVlfSUR9JwogICAgICAtICdBV1NfU0VDUkVUX0FDQ0VTU19LRVk9JHtBV1NfU0VDUkVUX0FDQ0VTU19LRVl9JwogICAgICAtICdBV1NfREVGQVVMVF9SRUdJT049JHtBV1NfREVGQVVMVF9SRUdJT059JwogICAgICAtICdBV1NfQlVDS0VUPSR7QVdTX0JVQ0tFVH0nCiAgICAgIC0gJ0FXU19VUkw9JHtBV1NfVVJMfScKICAgICAgLSAnQVdTX0VORFBPSU5UPSR7QVdTX0VORFBPSU5UfScKICAgICAgLSAnTk9SRElHRU5fU0VDUkVUX0lEPSR7Tk9SRElHRU5fU0VDUkVUX0lEfScKICAgICAgLSAnTk9SRElHRU5fU0VDUkVUX0tFWT0ke05PUkRJR0VOX1NFQ1JFVF9LRVl9JwogICAgICAtIElTX0RPQ0tFUj10cnVlCiAgICAgIC0gJ1NDT1VUX0RSSVZFUj0ke1NDT1VUX0RSSVZFUn0nCiAgICAgIC0gJ0xJQ0VOU0VfS0VZPSR7TElDRU5TRV9LRVl9JwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGVjaG8KICAgICAgICAtIG9rCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2ludm9pY2UtbmluamEtcHVibGljOi92YXIvd3d3L2FwcC9wdWJsaWMnCiAgICAgIC0gJ2ludm9pY2UtbmluamEtc3RvcmFnZTovdmFyL3d3dy9hcHAvc3RvcmFnZScKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vc3VwZXJ2aXNvcmQuY29uZgogICAgICAgIHRhcmdldDogL2V0Yy9zdXBlcnZpc29yZC5jb25mCiAgICAgICAgY29udGVudDogIltzdXBlcnZpc29yZF1cbm5vZGFlbW9uPXRydWVcbnBpZGZpbGU9L3RtcC9zdXBlcnZpc29yZC5waWRcbmxvZ2ZpbGU9L2Rldi9udWxsIDsgbm9kYWVtb24gd2lsbCBjYXVzZSBsb2dzIHRvIGdvIHRvIHN0ZG91dFxubG9nZmlsZV9tYXhieXRlcz0wXG5sb2dsZXZlbD1pbmZvXG5cbltwcm9ncmFtOnBocC1mcG1dXG5yZWRpcmVjdF9zdGRlcnI9dHJ1ZVxuc3Rkb3V0X2xvZ2ZpbGU9L2Rldi9zdGRvdXRcbnN0ZG91dF9sb2dmaWxlX21heGJ5dGVzPTBcbnN0ZGVycl9sb2dmaWxlPS9kZXYvc3RkZXJyXG5zdGRlcnJfbG9nZmlsZV9tYXhieXRlcz0wXG5jb21tYW5kPXBocCBhcnRpc2FuIHNlcnZlIC0taG9zdCAwLjAuMC4wIC0tcG9ydCA5MDAwXG5cbltwcm9ncmFtOnNjaGVkdWxlcl1cbmF1dG9yZXN0YXJ0PXRydWVcbnJlZGlyZWN0X3N0ZGVycj10cnVlXG5zdGRvdXRfbG9nZmlsZT0vZGV2L3N0ZG91dFxuc3Rkb3V0X2xvZ2ZpbGVfbWF4Ynl0ZXM9MFxuc3RkZXJyX2xvZ2ZpbGU9L2Rldi9zdGRlcnJcbnN0ZGVycl9sb2dmaWxlX21heGJ5dGVzPTBcbmNvbW1hbmQ9cGhwIGFydGlzYW4gc2NoZWR1bGU6d29ya1xuXG5bcHJvZ3JhbTpxdWV1ZS13b3JrZXJdXG5wcm9jZXNzX25hbWU9JShwcm9ncmFtX25hbWUpc18lKHByb2Nlc3NfbnVtKTAyZFxuYXV0b3Jlc3RhcnQ9dHJ1ZVxucmVkaXJlY3Rfc3RkZXJyPXRydWVcbnN0ZG91dF9sb2dmaWxlPS9kZXYvc3Rkb3V0XG5zdGRvdXRfbG9nZmlsZV9tYXhieXRlcz0wXG5zdGRlcnJfbG9nZmlsZT0vZGV2L3N0ZGVyclxuc3RkZXJyX2xvZ2ZpbGVfbWF4Ynl0ZXM9MFxubnVtcHJvY3M9MlxuY29tbWFuZD1waHAgYXJ0aXNhbiBxdWV1ZTp3b3JrIC0tc2xlZXA9MyAtLXRyaWVzPTEgLS1tZW1vcnk9MjU2IC0tdGltZW91dD0zNjAwXG5cbltldmVudGxpc3RlbmVyOnNodXRkb3duXVxuY29tbWFuZD1zaHV0ZG93bi5zaFxuZXZlbnRzPVBST0NFU1NfU1RBVEVfU1RPUFBFRCwgUFJPQ0VTU19TVEFURV9FWElURUQsIFBST0NFU1NfU1RBVEVfRkFUQUxcbnN0ZG91dF9sb2dmaWxlPS9kZXYvc3Rkb3V0XG5zdGRvdXRfbG9nZmlsZV9tYXhieXRlcz0wXG5zdGRlcnJfbG9nZmlsZT0vZGV2L3N0ZGVyclxuc3RkZXJyX2xvZ2ZpbGVfbWF4Ynl0ZXM9MFxuIgogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi9waHAuaW5pCiAgICAgICAgdGFyZ2V0OiAvdXNyL2xvY2FsL2V0Yy9waHAvcGhwLmluaQogICAgICAgIGNvbnRlbnQ6ICJzZXNzaW9uLmF1dG9fc3RhcnQgPSBPZmZcbnNob3J0X29wZW5fdGFnID0gT2ZmXG5cbmVycm9yX3JlcG9ydGluZyA9IEVfQUxMICYgfkVfTk9USUNFICYgfkVfV0FSTklORyAmIH5FX1NUUklDVCAmIH5FX0RFUFJFQ0FURURcblxuOyBvcGNhY2hlLmVuYWJsZT0xXG47IG9wY2FjaGUucHJlbG9hZD0vc3J2L3d3dy9pbnZvaWNlbmluamEvY3VycmVudC9wcmVsb2FkLnBocFxuOyBvcGNhY2hlLnByZWxvYWRfdXNlcj13d3ctZGF0YVxuXG47IDsgVGhlIE9QY2FjaGUgc2hhcmVkIG1lbW9yeSBzdG9yYWdlIHNpemUuXG47IG9wY2FjaGUubWF4X2FjY2VsZXJhdGVkX2ZpbGVzPTMwMDAwMFxuOyBvcGNhY2hlLnZhbGlkYXRlX3RpbWVzdGFtcHM9MVxuOyBvcGNhY2hlLnJldmFsaWRhdGVfZnJlcT0zMFxuOyBvcGNhY2hlLmppdF9idWZmZXJfc2l6ZT0yNTZNXG47IG9wY2FjaGUuaml0PTEyMDVcbjsgb3BjYWNoZS5tZW1vcnlfY29uc3VtcHRpb249MTAyNE1cblxucG9zdF9tYXhfc2l6ZSA9IDYwTVxudXBsb2FkX21heF9maWxlc2l6ZSA9IDUwTVxubWVtb3J5X2xpbWl0PTUxMk1cbiIKICAgICAgLQogICAgICAgIHR5cGU6IGJpbmQKICAgICAgICBzb3VyY2U6IC4vcGhwLWNsaS5pbmkKICAgICAgICB0YXJnZXQ6IC91c3IvbG9jYWwvZXRjL3BocC9waHAtY2xpLmluaQogICAgICAgIGNvbnRlbnQ6ICJzZXNzaW9uLmF1dG9fc3RhcnQgPSBPZmZcbnNob3J0X29wZW5fdGFnID0gT2ZmXG5cbmVycm9yX3JlcG9ydGluZyA9IEVfQUxMICYgfkVfTk9USUNFICYgfkVfV0FSTklORyAmIH5FX1NUUklDVCAmIH5FX0RFUFJFQ0FURURcblxuOyBvcGNhY2hlLmVuYWJsZV9jbGk9MVxuOyBvcGNhY2hlLmZhc3Rfc2h1dGRvd249MVxuOyBvcGNhY2hlLm1lbW9yeV9jb25zdW1wdGlvbj0yNTZcbjsgb3BjYWNoZS5pbnRlcm5lZF9zdHJpbmdzX2J1ZmZlcj04XG47IG9wY2FjaGUubWF4X2FjY2VsZXJhdGVkX2ZpbGVzPTQwMDBcbjsgb3BjYWNoZS5yZXZhbGlkYXRlX2ZyZXE9NjBcbjsgIyBodHRwOi8vc3ltZm9ueS5jb20vZG9jL2N1cnJlbnQvcGVyZm9ybWFuY2UuaHRtbFxuOyByZWFscGF0aF9jYWNoZV9zaXplID0gNDA5NktcbjsgcmVhbHBhdGhfY2FjaGVfdHRsID0gNjAwXG5cbm1lbW9yeV9saW1pdCA9IDJHXG5wb3N0X21heF9zaXplID0gNjBNXG51cGxvYWRfbWF4X2ZpbGVzaXplID0gNTBNXG4iCiAgICBkZXBlbmRzX29uOgogICAgICBtYXJpYWRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgbWFyaWFkYjoKICAgIGltYWdlOiAnbWFyaWFkYjoxMScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ21hcmlhZGItZGF0YTovdmFyL2xpYi9teXNxbCcKICAgIGVudmlyb25tZW50OgogICAgICAtICdNWVNRTF9ST09UX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NQVJJQURCUk9PVH0nCiAgICAgIC0gJ01ZU1FMX0RBVEFCQVNFPSR7REJfREFUQUJBU0U6LWludm9pY2VuaW5qYX0nCiAgICAgIC0gJ01ZU1FMX1VTRVI9JHtTRVJWSUNFX1VTRVJfTUFSSUFEQn0nCiAgICAgIC0gJ01ZU1FMX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NQVJJQURCfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBoZWFsdGhjaGVjay5zaAogICAgICAgIC0gJy0tY29ubmVjdCcKICAgICAgICAtICctLWlubm9kYl9pbml0aWFsaXplZCcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczo3LjQtYWxwaW5lJwogICAgY29tbWFuZDogJ3JlZGlzLXNlcnZlciAtLXJlcXVpcmVwYXNzICR7U0VSVklDRV9QQVNTV09SRF9SRURJU30nCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUkVESVNfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX1JFRElTfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2ludm9pY2UtbmluamEtcmVkaXMtZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtICctYScKICAgICAgICAtICcke1NFUlZJQ0VfUEFTU1dPUkRfUkVESVN9JwogICAgICAgIC0gcGluZwogICAgICBpbnRlcnZhbDogMTBzCiAgICAgIHRpbWVvdXQ6IDVzCiAgICAgIHJldHJpZXM6IDUK", "tags": [ "invoicing", "billing", @@ -2362,7 +2376,7 @@ "plunk": { "documentation": "https://docs.useplunk.com/getting-started/introduction?utm_source=coolify.io", "slogan": "Plunk, The Open-Source Email Platform for AWS", - "compose": "c2VydmljZXM6CiAgcGx1bms6CiAgICBpbWFnZTogJ2RyaWF1Zy9wbHVuazpsYXRlc3QnCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3Jlc3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9zdGFydGVkCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fUExVTktfMzAwMAogICAgICAtICdSRURJU19VUkw9cmVkaXM6Ly9yZWRpczo2Mzc5JwogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QHBvc3RncmVzcWwvcGx1bmstZGI/c2NoZW1hPXB1YmxpYycKICAgICAgLSAnSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUU0VDUkVUfScKICAgICAgLSAnQVdTX1JFR0lPTj0ke0FXU19SRUdJT046P30nCiAgICAgIC0gJ0FXU19BQ0NFU1NfS0VZX0lEPSR7QVdTX0FDQ0VTU19LRVlfSUQ6P30nCiAgICAgIC0gJ0FXU19TRUNSRVRfQUNDRVNTX0tFWT0ke0FXU19TRUNSRVRfQUNDRVNTX0tFWTo/fScKICAgICAgLSAnQVdTX1NFU19DT05GSUdVUkFUSU9OX1NFVD0ke0FXU19TRVNfQ09ORklHVVJBVElPTl9TRVQ6P30nCiAgICAgIC0gJ05FWFRfUFVCTElDX0FQSV9VUkk9JHtTRVJWSUNFX0ZRRE5fUExVTkt9L2FwaScKICAgICAgLSAnQVBQX1VSST0ke1NFUlZJQ0VfRlFETl9QTFVOS30nCiAgICAgIC0gJ0FQSV9VUkk9JHtTRVJWSUNFX0ZRRE5fUExVTkt9L2FwaScKICAgICAgLSAnRElTQUJMRV9TSUdOVVBTPSR7RElTQUJMRV9TSUdOVVBTOi1GYWxzZX0nCiAgICBlbnRyeXBvaW50OgogICAgICAtIC9hcHAvZW50cnkuc2gKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLXEnCiAgICAgICAgLSAnLS1zcGlkZXInCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTozMDAwJwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDE1CiAgcG9zdGdyZXNxbDoKICAgIGltYWdlOiAncG9zdGdyZXM6MTYtYWxwaW5lJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wbHVuay1kYn0nCiAgICB2b2x1bWVzOgogICAgICAtICdwbHVuay1wb3N0Z3Jlc3FsLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczo3LjQtYWxwaW5lJwogICAgdm9sdW1lczoKICAgICAgLSAncGx1bmstcmVkaXMtZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtIFBJTkcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAyMAo=", + "compose": "c2VydmljZXM6CiAgcGx1bms6CiAgICBpbWFnZTogJ2RyaWF1Zy9wbHVuazpsYXRlc3QnCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3Jlc3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9zdGFydGVkCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fUExVTktfMzAwMAogICAgICAtICdSRURJU19VUkw9cmVkaXM6Ly9yZWRpczo2Mzc5JwogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXNxbDovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QHBvc3RncmVzcWwvcGx1bmstZGI/c2NoZW1hPXB1YmxpYycKICAgICAgLSAnSldUX1NFQ1JFVD0ke1NFUlZJQ0VfUEFTU1dPUkRfSldUU0VDUkVUfScKICAgICAgLSAnQVdTX1JFR0lPTj0ke0FXU19SRUdJT046P30nCiAgICAgIC0gJ0FXU19BQ0NFU1NfS0VZX0lEPSR7QVdTX0FDQ0VTU19LRVlfSUQ6P30nCiAgICAgIC0gJ0FXU19TRUNSRVRfQUNDRVNTX0tFWT0ke0FXU19TRUNSRVRfQUNDRVNTX0tFWTo/fScKICAgICAgLSAnQVdTX1NFU19DT05GSUdVUkFUSU9OX1NFVD0ke0FXU19TRVNfQ09ORklHVVJBVElPTl9TRVQ6P30nCiAgICAgIC0gJ05FWFRfUFVCTElDX0FQSV9VUkk9JHtTRVJWSUNFX0ZRRE5fUExVTkt9L2FwaScKICAgICAgLSAnQVBQX1VSST0ke1NFUlZJQ0VfRlFETl9QTFVOS30nCiAgICAgIC0gJ0FQSV9VUkk9JHtTRVJWSUNFX0ZRRE5fUExVTkt9L2FwaScKICAgICAgLSAnRElTQUJMRV9TSUdOVVBTPSR7RElTQUJMRV9TSUdOVVBTOi1GYWxzZX0nCiAgICAgIC0gTk9ERV9PUFRJT05TPS0tbm8tbmV0d29yay1mYW1pbHktYXV0b3NlbGVjdGlvbgogICAgZW50cnlwb2ludDoKICAgICAgLSAvYXBwL2VudHJ5LnNoCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJyh3Z2V0IC1TIC0tc3BpZGVyIGh0dHA6Ly8xMjcuMC4wLjE6MzAwMC9hcGkvaGVhbHRoIDI+JjEgfCBncmVwIC1xICJIVFRQLzEuMSBbMS0zXSIpJwogICAgICBpbnRlcnZhbDogMnMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDE1CiAgcG9zdGdyZXNxbDoKICAgIGltYWdlOiAncG9zdGdyZXM6MTYtYWxwaW5lJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wbHVuay1kYn0nCiAgICB2b2x1bWVzOgogICAgICAtICdwbHVuay1wb3N0Z3Jlc3FsLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczo3LjQtYWxwaW5lJwogICAgdm9sdW1lczoKICAgICAgLSAncGx1bmstcmVkaXMtZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtIFBJTkcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAyMAo=", "tags": [ "plunk", "email", From 616076e083fca37da742b258708b91bb6386a4e9 Mon Sep 17 00:00:00 2001 From: Zakher Masri <46135573+zaaakher@users.noreply.github.com> Date: Wed, 22 Jan 2025 21:47:33 +0300 Subject: [PATCH 10/20] docs: add TECH_STACK.md (#4883) --- CONTRIBUTING.md | 2 ++ TECH_STACK.md | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 TECH_STACK.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 80ec0614e..dba3676cf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,6 +4,8 @@ You can ask for guidance anytime on our [Discord server](https://coollabs.io/discord) in the `#contribute` channel. +To understand the tech stack, please refer to the [Tech Stack](TECH_STACK.md) document. + ## Table of Contents 1. [Setup Development Environment](#1-setup-development-environment) diff --git a/TECH_STACK.md b/TECH_STACK.md new file mode 100644 index 000000000..8cd9a003e --- /dev/null +++ b/TECH_STACK.md @@ -0,0 +1,32 @@ +# Coolify Technology Stack + +## Frontend + +- Vue.js +- Tailwind CSS +- Monaco Editor (Code editor component) +- XTerm.js (Terminal component) +- Livewire (Reactive components) + +## Backend + +- Laravel (PHP Framework) +- PostgreSQL (Database) +- Redis (Caching & Real-time features) +- WebSocket (Real-time communication) + +## DevOps & Infrastructure + +- Docker +- Docker Compose +- Node.js (for some tooling) +- Vite (Build tool) + +## Languages + +- PHP +- JavaScript/TypeScript +- HTML/CSS +- Shell/Bash scripts +- YAML +- JSON From e155f3905bbf8312b7840af7c06c22d45026db6e Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Wed, 22 Jan 2025 19:57:30 +0100 Subject: [PATCH 11/20] feat(docs): update tech stack --- TECH_STACK.md | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/TECH_STACK.md b/TECH_STACK.md index 8cd9a003e..6a779eb29 100644 --- a/TECH_STACK.md +++ b/TECH_STACK.md @@ -2,31 +2,28 @@ ## Frontend -- Vue.js +- Livewire and Alpine.js +- Blade (PHP templating engine) - Tailwind CSS - Monaco Editor (Code editor component) - XTerm.js (Terminal component) -- Livewire (Reactive components) ## Backend -- Laravel (PHP Framework) -- PostgreSQL (Database) -- Redis (Caching & Real-time features) -- WebSocket (Real-time communication) +- Laravel 11 (PHP Framework) +- PostgreSQL 15 (Database) +- Redis 7 (Caching & Real-time features) +- Soketi (WebSocket Server) ## DevOps & Infrastructure -- Docker -- Docker Compose -- Node.js (for some tooling) -- Vite (Build tool) +- Docker & Docker Compose +- Nginx (Web Server) +- S6 Overlay (Process Supervisor) +- GitHub Actions (CI/CD) ## Languages -- PHP -- JavaScript/TypeScript -- HTML/CSS +- PHP 8.4 +- JavaScript - Shell/Bash scripts -- YAML -- JSON From 3f2f1cf966c01076a3c607102e4cae5473d5a112 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Wed, 22 Jan 2025 20:14:44 +0100 Subject: [PATCH 12/20] chore(core): EnvironmentVariable Model now extends BaseModel to remove duplicated code --- app/Models/EnvironmentVariable.php | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/app/Models/EnvironmentVariable.php b/app/Models/EnvironmentVariable.php index 507ff0d7e..5f686de60 100644 --- a/app/Models/EnvironmentVariable.php +++ b/app/Models/EnvironmentVariable.php @@ -4,9 +4,7 @@ namespace App\Models; use App\Models\EnvironmentVariable as ModelsEnvironmentVariable; use Illuminate\Database\Eloquent\Casts\Attribute; -use Illuminate\Database\Eloquent\Model; use OpenApi\Attributes as OA; -use Visus\Cuid2\Cuid2; #[OA\Schema( description: 'Environment Variable model', @@ -30,7 +28,7 @@ use Visus\Cuid2\Cuid2; 'updated_at' => ['type' => 'string'], ] )] -class EnvironmentVariable extends Model +class EnvironmentVariable extends BaseModel { protected $guarded = []; @@ -49,12 +47,6 @@ class EnvironmentVariable extends Model protected static function booted() { - static::creating(function (Model $model) { - if (! $model->uuid) { - $model->uuid = (string) new Cuid2; - } - }); - static::created(function (EnvironmentVariable $environment_variable) { if ($environment_variable->resourceable_type === Application::class && ! $environment_variable->is_preview) { $found = ModelsEnvironmentVariable::where('key', $environment_variable->key) From aeb57d279fbd0ddae50f27238c23050331ed99ca Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Wed, 22 Jan 2025 20:45:59 +0100 Subject: [PATCH 13/20] fix(workflows): `Waiting for changes` label should also be considered and improved messages --- .github/workflows/chore-manage-stale-issues-and-prs.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/chore-manage-stale-issues-and-prs.yml b/.github/workflows/chore-manage-stale-issues-and-prs.yml index 2afc996cb..58a2b7d7e 100644 --- a/.github/workflows/chore-manage-stale-issues-and-prs.yml +++ b/.github/workflows/chore-manage-stale-issues-and-prs.yml @@ -13,16 +13,16 @@ jobs: id: stale with: stale-issue-message: 'This issue will be automatically closed in a few days if no response is received. Please provide an update with the requested information.' - stale-pr-message: 'This pull request will be automatically closed in a few days if no response is received. Please update your PR or comment if you would like to continue working on it.' + stale-pr-message: 'This pull request requires attention. If no changes or response is received within the next few days, it will be automatically closed. Please update your PR or leave a comment with the requested information.' close-issue-message: 'This issue has been automatically closed due to inactivity.' - close-pr-message: 'This pull request has been automatically closed due to inactivity.' + close-pr-message: 'Thank you for your contribution. Due to inactivity, this PR was automatically closed. If you would like to continue working on this change in the future, feel free to reopen this PR or submit a new one.' days-before-stale: 14 days-before-close: 7 stale-issue-label: '⏱︎ Stale' stale-pr-label: '⏱︎ Stale' - only-labels: '💤 Waiting for feedback' + only-labels: '💤 Waiting for feedback, 💤 Waiting for changes' remove-stale-when-updated: true operations-per-run: 100 - labels-to-remove-when-unstale: '⏱︎ Stale, 💤 Waiting for feedback' + labels-to-remove-when-unstale: '⏱︎ Stale, 💤 Waiting for feedback, 💤 Waiting for changes' close-issue-reason: 'not_planned' exempt-all-milestones: false From 1b62e1f117861fbf0e7f52c5e6e323767007f5a1 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Wed, 22 Jan 2025 21:08:47 +0100 Subject: [PATCH 14/20] fix(workflows): remove tags only if the PR has been merged into the main branch --- ...hore-remove-labels-and-assignees-on-close.yml | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/.github/workflows/chore-remove-labels-and-assignees-on-close.yml b/.github/workflows/chore-remove-labels-and-assignees-on-close.yml index ea097e328..a3c299b5e 100644 --- a/.github/workflows/chore-remove-labels-and-assignees-on-close.yml +++ b/.github/workflows/chore-remove-labels-and-assignees-on-close.yml @@ -19,8 +19,12 @@ jobs: script: | const { owner, repo } = context.repo; - async function processIssue(issueNumber) { + async function processIssue(issueNumber, isFromPR = false, prBaseBranch = null) { try { + if (isFromPR && prBaseBranch !== 'main') { + return; + } + const { data: currentLabels } = await github.rest.issues.listLabelsOnIssue({ owner, repo, @@ -59,19 +63,19 @@ jobs: } } - if (context.eventName === 'issues' || context.eventName === 'pull_request' || context.eventName === 'pull_request_target') { - const issue = context.payload.issue || context.payload.pull_request; - await processIssue(issue.number); + if (context.eventName === 'issues') { + await processIssue(context.payload.issue.number); } if (context.eventName === 'pull_request' || context.eventName === 'pull_request_target') { const pr = context.payload.pull_request; - if (pr.body) { + await processIssue(pr.number); + if (pr.merged && pr.base.ref === 'main' && pr.body) { const issueReferences = pr.body.match(/#(\d+)/g); if (issueReferences) { for (const reference of issueReferences) { const issueNumber = parseInt(reference.substring(1)); - await processIssue(issueNumber); + await processIssue(issueNumber, true, pr.base.ref); } } } From 007e291befbf95eb9adc90a3e7195791adf47a31 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 23 Jan 2025 11:50:06 +0100 Subject: [PATCH 15/20] fix(terminal): terminal shows that it is not available, even though it is --- .../Project/Shared/ExecuteContainerCommand.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/Livewire/Project/Shared/ExecuteContainerCommand.php b/app/Livewire/Project/Shared/ExecuteContainerCommand.php index f993480c7..98289c536 100644 --- a/app/Livewire/Project/Shared/ExecuteContainerCommand.php +++ b/app/Livewire/Project/Shared/ExecuteContainerCommand.php @@ -146,11 +146,16 @@ class ExecuteContainerCommand extends Component private function checkShellAvailability(Server $server, string $container): bool { $escapedContainer = escapeshellarg($container); - $result = instant_remote_process([ - "docker exec {$escapedContainer} which bash || docker exec {$escapedContainer} which sh", - ], $server, false); + try { + instant_remote_process([ + "docker exec {$escapedContainer} bash -c 'exit 0' 2>/dev/null || ". + "docker exec {$escapedContainer} sh -c 'exit 0' 2>/dev/null", + ], $server); - return ! empty($result); + return true; + } catch (\Throwable) { + return false; + } } #[On('connectToServer')] From 09d64d4bf684da904891ee750ed1cb760c7b5181 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 23 Jan 2025 11:51:01 +0100 Subject: [PATCH 16/20] feat(terminal): show terminal unavailable if the container does not have a shell on the global terminal UI --- app/Livewire/Project/Shared/Terminal.php | 23 ++++++++ .../project/shared/terminal.blade.php | 54 ++++++++++++------- 2 files changed, 58 insertions(+), 19 deletions(-) diff --git a/app/Livewire/Project/Shared/Terminal.php b/app/Livewire/Project/Shared/Terminal.php index d8f101277..a3d1aa10f 100644 --- a/app/Livewire/Project/Shared/Terminal.php +++ b/app/Livewire/Project/Shared/Terminal.php @@ -9,6 +9,8 @@ use Livewire\Component; class Terminal extends Component { + public bool $hasShell = true; + public function getListeners() { $teamId = auth()->user()->currentTeam()->id; @@ -23,6 +25,21 @@ class Terminal extends Component $this->dispatch('reloadWindow'); } + private function checkShellAvailability(Server $server, string $container): bool + { + $escapedContainer = escapeshellarg($container); + try { + instant_remote_process([ + "docker exec {$escapedContainer} bash -c 'exit 0' 2>/dev/null || ". + "docker exec {$escapedContainer} sh -c 'exit 0' 2>/dev/null", + ], $server); + + return true; + } catch (\Throwable) { + return false; + } + } + #[On('send-terminal-command')] public function sendTerminalCommand($isContainer, $identifier, $serverUuid) { @@ -40,6 +57,12 @@ class Terminal extends Component return; } + // Check shell availability + $this->hasShell = $this->checkShellAvailability($server, $identifier); + if (! $this->hasShell) { + return; + } + // Escape the identifier for shell usage $escapedIdentifier = escapeshellarg($identifier); $command = SshMultiplexingHelper::generateSshCommand($server, "docker exec -it {$escapedIdentifier} sh -c 'PATH=\$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin && if [ -f ~/.profile ]; then . ~/.profile; fi && if [ -n \"\$SHELL\" ]; then exec \$SHELL; else sh; fi'"); diff --git a/resources/views/livewire/project/shared/terminal.blade.php b/resources/views/livewire/project/shared/terminal.blade.php index edf870ca7..f35624b60 100644 --- a/resources/views/livewire/project/shared/terminal.blade.php +++ b/resources/views/livewire/project/shared/terminal.blade.php @@ -1,23 +1,39 @@
-
-
- - -
+ @if(!$hasShell) +
+
+
+ + + +
+

Terminal Not Available

+

No shell (bash/sh) is available in this container. Please ensure either bash or sh is installed to use the terminal.

+
+
+
+
+ @else +
+
+ + +
+ @endif @script