From 4a66fdf75399a31930c96206b995cf9b52472c2d Mon Sep 17 00:00:00 2001 From: "sur.la.route" <17788706+christopherpickering@users.noreply.github.com> Date: Fri, 9 May 2025 07:07:02 -0500 Subject: [PATCH 01/53] fix(docker-compose build) added --no-cache flag added `--no-cache` flag when build is force. --- app/Jobs/ApplicationDeploymentJob.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index bebec64cf..e237bca0e 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -507,7 +507,11 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue if ($this->env_filename) { $command .= " --env-file {$this->workdir}/{$this->env_filename}"; } - $command .= " --project-name {$this->application->uuid} --project-directory {$this->workdir} -f {$this->workdir}{$this->docker_compose_location} build --pull"; + if ($this->force_rebuild) { + $command .= " --project-name {$this->application->uuid} --project-directory {$this->workdir} -f {$this->workdir}{$this->docker_compose_location} build --pull --no-cache"; + else + $command .= " --project-name {$this->application->uuid} --project-directory {$this->workdir} -f {$this->workdir}{$this->docker_compose_location} build --pull"; + } $this->execute_remote_command( [executeInDocker($this->deployment_uuid, $command), 'hidden' => true], ); From 525072c733868f0cc88195e7accaf890056fb9e6 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Fri, 16 May 2025 12:41:34 +0200 Subject: [PATCH 02/53] Enhance server patching UI in patches.blade.php - Update layout to improve user experience with a more structured design. - Add experimental label and helper text for clarity on package manager support. - Change button text to "Check Now" for better action indication. - Introduce automatic server update messaging. --- .../livewire/server/security/patches.blade.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/resources/views/livewire/server/security/patches.blade.php b/resources/views/livewire/server/security/patches.blade.php index d2059f14c..7dc2748fc 100644 --- a/resources/views/livewire/server/security/patches.blade.php +++ b/resources/views/livewire/server/security/patches.blade.php @@ -14,15 +14,16 @@
-
+

Server Patching

- Manually - Check -
-
Check if your server has updates available.
-
(only available for apt, dnf and zypper package managers atm, more coming - soon as well as more features...) + (experimental) + + + Check Now
+
Update your servers automatically.
From a5a7f8ae55b131557a019a4d5d06cc656f545725 Mon Sep 17 00:00:00 2001 From: ShadowArcanist <162910371+ShadowArcanist@users.noreply.github.com> Date: Mon, 19 May 2025 16:23:31 +0530 Subject: [PATCH 03/53] fix(service): Snapdrop no matching manifest error (#5849) --- templates/compose/snapdrop.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/snapdrop.yaml b/templates/compose/snapdrop.yaml index 336a75737..82ad5fecc 100644 --- a/templates/compose/snapdrop.yaml +++ b/templates/compose/snapdrop.yaml @@ -4,7 +4,7 @@ services: snapdrop: - image: lscr.io/linuxserver/snapdrop:latest + image: 'linuxserver/snapdrop:version-b8b78cc2' environment: - SERVICE_FQDN_SNAPDROP - PUID=1000 From f061147d43e93d500e28f81c1aee47ff27cc25b8 Mon Sep 17 00:00:00 2001 From: Datenschmutz <63157166+Datenschmutz@users.noreply.github.com> Date: Mon, 19 May 2025 13:00:22 +0200 Subject: [PATCH 04/53] chore(deps): update Authentik service to 2025.4.1 (#5830) --- templates/compose/authentik.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/compose/authentik.yaml b/templates/compose/authentik.yaml index 4947140b9..d6e2a9968 100644 --- a/templates/compose/authentik.yaml +++ b/templates/compose/authentik.yaml @@ -6,7 +6,7 @@ services: authentik-server: - image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2025.2.3} + image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2025.4.1} restart: unless-stopped command: server environment: @@ -35,7 +35,7 @@ services: redis: condition: service_healthy authentik-worker: - image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2025.2.3} + image: ghcr.io/goauthentik/server:${AUTHENTIK_TAG:-2025.4.1} restart: unless-stopped command: worker environment: From 42a7b13dbabc4464286bb3754cace7be26b85cda Mon Sep 17 00:00:00 2001 From: Almuzaini <62063512+YAlmuzaini@users.noreply.github.com> Date: Mon, 19 May 2025 14:02:50 +0300 Subject: [PATCH 05/53] fix(service): use the same volume between chatwoot and sidekiq (#5851) --- templates/compose/chatwoot.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/chatwoot.yaml b/templates/compose/chatwoot.yaml index b7eec88cc..900d3354b 100644 --- a/templates/compose/chatwoot.yaml +++ b/templates/compose/chatwoot.yaml @@ -80,7 +80,7 @@ services: - ACTIVE_STORAGE_SERVICE=${ACTIVE_STORAGE_SERVICE:-local} command: ['bundle', 'exec', 'sidekiq', '-C', 'config/sidekiq.yml'] volumes: - - sidekiq-data:/app/storage + - rails-data:/app/storage healthcheck: test: ["CMD-SHELL", "bundle exec rails runner 'puts Sidekiq.redis(&:info)' > /dev/null 2>&1"] interval: 30s From 38d9471de1404cc1cd88907e1bb12a9290bb6a1a Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 19 May 2025 13:29:23 +0200 Subject: [PATCH 06/53] fix(api): validate docker_compose_raw input in ApplicationsController - Ensure docker_compose_raw is provided and base64 encoded before processing. - Return appropriate validation error messages for missing or incorrectly formatted input. --- .../Api/ApplicationsController.php | 58 ++++++++++++++++++- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index 3e0627b21..7818c3df2 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -989,7 +989,34 @@ class ApplicationsController extends Controller $dockerComposeDomainsJson = collect(); if ($request->has('docker_compose_domains')) { - $yaml = Yaml::parse($application->docker_compose_raw); + if (! $request->has('docker_compose_raw')) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'docker_compose_raw' => 'The base64 encoded docker_compose_raw is required.', + ], + ], 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) { @@ -1918,7 +1945,34 @@ class ApplicationsController extends Controller $dockerComposeDomainsJson = collect(); if ($request->has('docker_compose_domains')) { - $yaml = Yaml::parse($application->docker_compose_raw); + if (! $request->has('docker_compose_raw')) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'docker_compose_raw' => 'The base64 encoded docker_compose_raw is required.', + ], + ], 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) { From cee9dfcf52d8af3b08ca1bc1bc92c4c59370f5f4 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 19 May 2025 13:30:31 +0200 Subject: [PATCH 07/53] fix(api): enhance validation for docker_compose_raw in ApplicationsController - Add checks to ensure docker_compose_raw is provided and correctly base64 encoded. - Implement detailed error responses for validation failures to improve user feedback. --- .../Api/ApplicationsController.php | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/app/Http/Controllers/Api/ApplicationsController.php b/app/Http/Controllers/Api/ApplicationsController.php index 7818c3df2..59e2692ba 100644 --- a/app/Http/Controllers/Api/ApplicationsController.php +++ b/app/Http/Controllers/Api/ApplicationsController.php @@ -1122,7 +1122,34 @@ class ApplicationsController extends Controller $dockerComposeDomainsJson = collect(); if ($request->has('docker_compose_domains')) { - $yaml = Yaml::parse($application->docker_compose_raw); + if (! $request->has('docker_compose_raw')) { + return response()->json([ + 'message' => 'Validation failed.', + 'errors' => [ + 'docker_compose_raw' => 'The base64 encoded docker_compose_raw is required.', + ], + ], 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) { From befc8a014276fb87f1c0855d9e34753809a62ba2 Mon Sep 17 00:00:00 2001 From: CrazyTim71 <118295691+CrazyTim71@users.noreply.github.com> Date: Mon, 19 May 2025 13:39:08 +0200 Subject: [PATCH 08/53] feat(service): add Yamtrack service (#5845) --- public/svgs/yamtrack.svg | 28 ++++++++ .../compose/yamtrack-with-postgresql.yaml | 70 +++++++++++++++++++ templates/compose/yamtrack.yaml | 45 ++++++++++++ 3 files changed, 143 insertions(+) create mode 100644 public/svgs/yamtrack.svg create mode 100644 templates/compose/yamtrack-with-postgresql.yaml create mode 100644 templates/compose/yamtrack.yaml diff --git a/public/svgs/yamtrack.svg b/public/svgs/yamtrack.svg new file mode 100644 index 000000000..8fd79ded2 --- /dev/null +++ b/public/svgs/yamtrack.svg @@ -0,0 +1,28 @@ + + + + +Created by potrace 1.14, written by Peter Selinger 2001-2017 + + + + + diff --git a/templates/compose/yamtrack-with-postgresql.yaml b/templates/compose/yamtrack-with-postgresql.yaml new file mode 100644 index 000000000..4dae2ae3d --- /dev/null +++ b/templates/compose/yamtrack-with-postgresql.yaml @@ -0,0 +1,70 @@ +# documentation: https://github.com/FuzzyGrim/Yamtrack/wiki +# slogan: Yamtrack is a self hosted media tracker for movies, tv shows, anime, manga, video games and books. +# tags: self-hosted, automation, tracker, media, movies, shows, anime, manga, games, books, comics +# logo: svgs/yamtrack.svg +# port: 8000 + +services: + yamtrack: + image: ghcr.io/fuzzygrim/yamtrack + depends_on: + - db + - redis + environment: + - SERVICE_FQDN_YAMTRACK_8000 + - TZ=${TZ:-Europe/Berlin} + - SECRET=$SERVICE_PASSWORD_SECRET + - REGISTRATION=${REGISTRATION_ENABLED:-true} + - URLS=$SERVICE_FQDN_YAMTRACK + - "REDIS_URL=redis://redis:6379" + + - DB_HOST=db + - DB_NAME=${POSTGRESQL_DATABASE:-yamtrack} + - DB_USER=${SERVICE_USER_POSTGRESQL} + - DB_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL} + - DB_PORT=5432 + healthcheck: + test: + [ + "CMD", + "wget", + "--no-verbose", + "--tries=1", + "--spider", + "http://127.0.0.1:8000/health/", + ] + interval: 5s + timeout: 20s + retries: 10 + + db: + image: postgres:16-alpine + container_name: yamtrack-db + environment: + - POSTGRES_USER=${SERVICE_USER_POSTGRESQL} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL} + - POSTGRES_DB=${POSTGRESQL_DATABASE:-yamtrack} + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 20s + retries: 10 + + redis: + image: "redis:7-alpine" + volumes: + - "redis_data:/data" + healthcheck: + test: + - CMD + - redis-cli + - ping + interval: 5s + timeout: 20s + retries: 10 + +volumes: + redis_data: null + postgres_data: null diff --git a/templates/compose/yamtrack.yaml b/templates/compose/yamtrack.yaml new file mode 100644 index 000000000..f20a0575f --- /dev/null +++ b/templates/compose/yamtrack.yaml @@ -0,0 +1,45 @@ +# documentation: https://github.com/FuzzyGrim/Yamtrack/wiki +# slogan: Yamtrack is a self hosted media tracker for movies, tv shows, anime, manga, video games and books. +# tags: self-hosted, automation, tracker, media, movies, shows, anime, manga, games, books, comics +# logo: svgs/yamtrack.svg +# port: 8000 + +services: + yamtrack: + image: ghcr.io/fuzzygrim/yamtrack + depends_on: + redis: + condition: service_healthy + environment: + - SERVICE_FQDN_YAMTRACK_8000 + - TZ=${TZ:-Europe/Berlin} + - SECRET=$SERVICE_PASSWORD_SECRET + - REGISTRATION=${REGISTRATION_ENABLED:-true} + - URLS=$SERVICE_FQDN_YAMTRACK + - "REDIS_URL=redis://redis:6379" + volumes: + - "yamtrack_data:/yamtrack/db" + healthcheck: + test: + - CMD-SHELL + - "wget --no-verbose --tries=1 --spider http://127.0.0.1:8000/health/ || exit 1" + interval: 5s + timeout: 20s + retries: 10 + + redis: + image: "redis:7-alpine" + volumes: + - "redis_data:/data" + healthcheck: + test: + - CMD + - redis-cli + - ping + interval: 5s + timeout: 20s + retries: 10 + +volumes: + redis_data: null + yamtrack_data: null From bd3f987fefbef7657d2085dfafb0dcba01a40589 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 19 May 2025 13:43:08 +0200 Subject: [PATCH 09/53] style(css): update padding utility for password input and add newline in app.css --- resources/css/app.css | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/resources/css/app.css b/resources/css/app.css index 1150917e7..79e5f0c13 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -38,6 +38,7 @@ color utility to any element that depends on these defaults. */ @layer base { + *, ::after, ::before, @@ -161,9 +162,9 @@ section { * Utility classes */ .input[type="password"] { - padding-right: var(--padding-10); + @apply pr-[2.4rem]; } .lds-heart { animation: lds-heart 1.2s infinite cubic-bezier(0.215, 0.61, 0.355, 1); -} +} \ No newline at end of file From a5ba61945f582b836c8f4cee79faa3c76e086de3 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 19 May 2025 13:43:22 +0200 Subject: [PATCH 10/53] fix(select): update PostgreSQL versions and titles in resource selection - Change default PostgreSQL version from 16 to 17. - Update Supabase PostgreSQL version to 17.4.1.032. - Modify PostGIS title to indicate AMD compatibility. - Update PGVector title to reflect version 17. --- .../views/livewire/project/new/select.blade.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/resources/views/livewire/project/new/select.blade.php b/resources/views/livewire/project/new/select.blade.php index c27163000..b0f324d4d 100644 --- a/resources/views/livewire/project/new/select.blade.php +++ b/resources/views/livewire/project/new/select.blade.php @@ -277,12 +277,12 @@ @if ($current_step === 'select-postgresql-type')

Select a Postgresql type

If you need extra extensions, you can select Supabase PostgreSQL (or others), otherwise select PostgreSQL - 16 (default).
+ 17 (default).
+ wire:click="setPostgresqlType('postgres:17-alpine')">
-
PostgreSQL 16 (default)
+
PostgreSQL 17 (default)
PostgreSQL is a powerful, open-source object-relational database system (no extensions).
@@ -297,7 +297,7 @@
+ wire:click="setPostgresqlType('supabase/postgres:17.4.1.032')">
Supabase PostgreSQL (with extensions)
@@ -314,9 +314,9 @@
+ wire:click="setPostgresqlType('postgis/postgis:17-3.5-alpine')">
-
PostGIS
+
PostGIS (AMD only)
PostGIS is a PostgreSQL extension for geographic objects.
@@ -331,9 +331,9 @@
+ wire:click="setPostgresqlType('pgvector/pgvector:pg17')">
-
PGVector (16)
+
PGVector (17)
PGVector is a PostgreSQL extension for vector data types.
From daefe28fd818c8e0aaed97f6440342303f13649d Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 19 May 2025 13:46:52 +0200 Subject: [PATCH 11/53] fix(database): include DatabaseStatusChanged event in activityMonitor dispatch --- app/Livewire/Project/Database/Heading.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/Livewire/Project/Database/Heading.php b/app/Livewire/Project/Database/Heading.php index 9ddb1909c..2f304c5e6 100644 --- a/app/Livewire/Project/Database/Heading.php +++ b/app/Livewire/Project/Database/Heading.php @@ -6,6 +6,7 @@ use App\Actions\Database\RestartDatabase; use App\Actions\Database\StartDatabase; use App\Actions\Database\StopDatabase; use App\Actions\Docker\GetContainersStatus; +use App\Events\DatabaseStatusChanged; use Illuminate\Support\Facades\Auth; use Livewire\Component; @@ -69,13 +70,13 @@ class Heading extends Component public function restart() { $activity = RestartDatabase::run($this->database); - $this->dispatch('activityMonitor', $activity->id); + $this->dispatch('activityMonitor', $activity->id, DatabaseStatusChanged::class); } public function start() { $activity = StartDatabase::run($this->database); - $this->dispatch('activityMonitor', $activity->id); + $this->dispatch('activityMonitor', $activity->id, DatabaseStatusChanged::class); } public function render() From c7f1e9444230303016a08e1c6d48a20b90860fd4 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 19 May 2025 13:51:31 +0200 Subject: [PATCH 12/53] refactore(services): improve yamtrack - make sure DBs are healty before starting yamtrack - formatting & naming improvements --- .../compose/yamtrack-with-postgresql.yaml | 34 ++++++++----------- templates/compose/yamtrack.yaml | 26 ++++++-------- 2 files changed, 26 insertions(+), 34 deletions(-) diff --git a/templates/compose/yamtrack-with-postgresql.yaml b/templates/compose/yamtrack-with-postgresql.yaml index 4dae2ae3d..470cabfbd 100644 --- a/templates/compose/yamtrack-with-postgresql.yaml +++ b/templates/compose/yamtrack-with-postgresql.yaml @@ -7,22 +7,23 @@ services: yamtrack: image: ghcr.io/fuzzygrim/yamtrack - depends_on: - - db - - redis environment: - SERVICE_FQDN_YAMTRACK_8000 + - URLS=${SERVICE_FQDN_YAMTRACK} - TZ=${TZ:-Europe/Berlin} - - SECRET=$SERVICE_PASSWORD_SECRET + - SECRET=${SERVICE_PASSWORD_SECRET} - REGISTRATION=${REGISTRATION_ENABLED:-true} - - URLS=$SERVICE_FQDN_YAMTRACK - - "REDIS_URL=redis://redis:6379" - - - DB_HOST=db - - DB_NAME=${POSTGRESQL_DATABASE:-yamtrack} + - REDIS_URL=redis://redis:6379 + - DB_HOST=postgres + - DB_NAME=${POSTGRESQL_DATABASE:-yamtrack-db} - DB_USER=${SERVICE_USER_POSTGRESQL} - DB_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL} - DB_PORT=5432 + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy healthcheck: test: [ @@ -37,15 +38,14 @@ services: timeout: 20s retries: 10 - db: + postgres: image: postgres:16-alpine - container_name: yamtrack-db environment: - POSTGRES_USER=${SERVICE_USER_POSTGRESQL} - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRESQL} - - POSTGRES_DB=${POSTGRESQL_DATABASE:-yamtrack} + - POSTGRES_DB=${POSTGRESQL_DATABASE:-yamtrack-db} volumes: - - postgres_data:/var/lib/postgresql/data + - yamtrack_postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s @@ -53,9 +53,9 @@ services: retries: 10 redis: - image: "redis:7-alpine" + image: redis:7-alpine volumes: - - "redis_data:/data" + - yamtrack_redis_data:/data healthcheck: test: - CMD @@ -64,7 +64,3 @@ services: interval: 5s timeout: 20s retries: 10 - -volumes: - redis_data: null - postgres_data: null diff --git a/templates/compose/yamtrack.yaml b/templates/compose/yamtrack.yaml index f20a0575f..7b626e737 100644 --- a/templates/compose/yamtrack.yaml +++ b/templates/compose/yamtrack.yaml @@ -7,18 +7,18 @@ services: yamtrack: image: ghcr.io/fuzzygrim/yamtrack + environment: + - SERVICE_FQDN_YAMTRACK_8000 + - URLS=${SERVICE_FQDN_YAMTRACK} + - TZ=${TZ:-Europe/Berlin} + - SECRET=${SERVICE_PASSWORD_SECRET} + - REGISTRATION=${REGISTRATION_ENABLED:-true} + - REDIS_URL=redis://redis:6379 + volumes: + - yamtrack_data:/yamtrack/db depends_on: redis: condition: service_healthy - environment: - - SERVICE_FQDN_YAMTRACK_8000 - - TZ=${TZ:-Europe/Berlin} - - SECRET=$SERVICE_PASSWORD_SECRET - - REGISTRATION=${REGISTRATION_ENABLED:-true} - - URLS=$SERVICE_FQDN_YAMTRACK - - "REDIS_URL=redis://redis:6379" - volumes: - - "yamtrack_data:/yamtrack/db" healthcheck: test: - CMD-SHELL @@ -28,9 +28,9 @@ services: retries: 10 redis: - image: "redis:7-alpine" + image: redis:7-alpine volumes: - - "redis_data:/data" + - yamtrack_redis_data:/data healthcheck: test: - CMD @@ -39,7 +39,3 @@ services: interval: 5s timeout: 20s retries: 10 - -volumes: - redis_data: null - yamtrack_data: null From fe69a70d19a4dec4d397bab2f7edc866e4738aa7 Mon Sep 17 00:00:00 2001 From: Eugene Scheepers <52255287+ejscheepers@users.noreply.github.com> Date: Mon, 19 May 2025 15:00:56 +0200 Subject: [PATCH 13/53] feat(service): add PG Back Web service (#5079) --- public/svgs/pgbackweb.png | Bin 0 -> 23304 bytes templates/compose/pgbackweb.yaml | 36 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 public/svgs/pgbackweb.png create mode 100644 templates/compose/pgbackweb.yaml diff --git a/public/svgs/pgbackweb.png b/public/svgs/pgbackweb.png new file mode 100644 index 0000000000000000000000000000000000000000..6c76c8075400408413050e590ef5f626b46bc340 GIT binary patch literal 23304 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 Date: Mon, 19 May 2025 15:03:27 +0200 Subject: [PATCH 14/53] chore(service): pgbackweb formatting and naming update --- templates/compose/pgbackweb.yaml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/templates/compose/pgbackweb.yaml b/templates/compose/pgbackweb.yaml index 67701814a..4c006a6ce 100644 --- a/templates/compose/pgbackweb.yaml +++ b/templates/compose/pgbackweb.yaml @@ -3,6 +3,7 @@ # tags: backup, postgresql, web-interface # logo: svgs/pgbackweb.svg # port: 8085 + services: pgbackweb: image: eduardolat/pgbackweb:latest @@ -11,26 +12,23 @@ services: environment: - SERVICE_FQDN_PGBACKWEB_8085 - PBW_ENCRYPTION_KEY=${SERVICE_PASSWORD_64_PGBACKWEB} - - PBW_POSTGRES_CONN_STRING=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/pgbackweb?sslmode=disable + - PBW_POSTGRES_CONN_STRING=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres:5432/${POSTGRES_DB:-pgbackweb-db}?sslmode=disable - TZ=${TIME_ZONE:-UTC} depends_on: postgres: condition: service_healthy exclude_from_hc: true + postgres: image: postgres:17 environment: - POSTGRES_USER=${SERVICE_USER_POSTGRES} - - POSTGRES_DB=pgbackweb - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB:-pgbackweb-db} volumes: - - postgres_data:/var/lib/postgresql/data + - pgbackweb_postgres_data:/var/lib/postgresql/data healthcheck: test: ["CMD-SHELL", "pg_isready -U ${SERVICE_USER_POSTGRES} -d pgbackweb"] interval: 5s timeout: 5s retries: 5 - -volumes: - postgres_data: - pgbackweb_backups: From ebe269324c151348bbd9bf1dad5cd063d8734727 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 19 May 2025 15:29:48 +0200 Subject: [PATCH 15/53] style(css): refine badge utility styles in utilities.css --- resources/css/utilities.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/css/utilities.css b/resources/css/utilities.css index 44d9c60df..7a149a95b 100644 --- a/resources/css/utilities.css +++ b/resources/css/utilities.css @@ -70,11 +70,11 @@ } @utility badge { - @apply inline-block w-3 h-3 text-xs font-bold leading-none rounded-full border border-neutral-200 dark:border-black; + @apply inline-block w-3 h-3 text-xs font-bold leading-none border border-neutral-200 dark:border-black; } @utility badge-absolute { - @apply absolute top-0 right-0 w-2 h-2 rounded-t-none rounded-r-none border-none; + @apply absolute top-0 right-0 w-2 h-2 rounded-bl-full; } @utility badge-success { From 61e45fbf3d7ffcdecd34471dfff0df29181a8d2e Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 19 May 2025 15:31:35 +0200 Subject: [PATCH 16/53] style(css): enhance badge utility styles in utilities.css --- resources/css/utilities.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/resources/css/utilities.css b/resources/css/utilities.css index 7a149a95b..8504ed3d9 100644 --- a/resources/css/utilities.css +++ b/resources/css/utilities.css @@ -70,11 +70,11 @@ } @utility badge { - @apply inline-block w-3 h-3 text-xs font-bold leading-none border border-neutral-200 dark:border-black; + @apply inline-block w-3 h-3 text-xs font-bold rounded-full leading-none border border-neutral-200 dark:border-black; } -@utility badge-absolute { - @apply absolute top-0 right-0 w-2 h-2 rounded-bl-full; +@utility badge-dashboard { + @apply absolute top-0 right-0 w-2.5 h-2.5 rounded-bl-full text-xs font-bold leading-none border border-neutral-200 dark:border-black; } @utility badge-success { From 786bfa960f656ff8308ebe74acb3eadc142ceeff Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Mon, 19 May 2025 21:50:32 +0200 Subject: [PATCH 17/53] improvement(core): simplify events for app/db/service status changes --- app/Actions/Application/StopApplication.php | 4 ++ app/Actions/Database/StopDatabase.php | 36 ++++++---- app/Actions/Docker/GetContainersStatus.php | 2 + app/Actions/Service/StartService.php | 2 +- app/Actions/Service/StopService.php | 3 + app/Events/ServiceChecked.php | 35 ++++++++++ app/Events/ServiceStatusChanged.php | 17 +++-- app/Jobs/ApplicationDeploymentJob.php | 4 +- .../Project/Application/Configuration.php | 10 ++- .../Project/Application/Deployment/Index.php | 9 +++ .../Project/Application/Deployment/Show.php | 10 ++- app/Livewire/Project/Application/Heading.php | 20 ++---- .../Project/Database/Configuration.php | 10 +++ app/Livewire/Project/Database/Heading.php | 57 ++++++++-------- .../Project/Service/Configuration.php | 14 +--- app/Livewire/Project/Service/EditDomain.php | 1 - .../Service/{Navbar.php => Heading.php} | 66 ++++++++++--------- app/Livewire/Project/Shared/Destination.php | 3 - .../Shared/ExecuteContainerCommand.php | 9 +++ app/Livewire/Project/Shared/Logs.php | 9 +++ .../Project/Shared/ScheduledTask/Show.php | 9 +++ .../components/modal-confirmation.blade.php | 1 - .../views/components/status/index.blade.php | 3 +- .../components/status/services.blade.php | 3 +- .../project/application/heading.blade.php | 5 +- .../project/database/heading.blade.php | 6 +- .../livewire/project/resource/index.blade.php | 24 +++---- .../project/service/configuration.blade.php | 4 +- .../{navbar.blade.php => heading.blade.php} | 11 ++-- .../livewire/project/service/index.blade.php | 2 +- .../execute-container-command.blade.php | 13 ++-- .../shared/scheduled-task/show.blade.php | 2 +- 32 files changed, 251 insertions(+), 153 deletions(-) create mode 100644 app/Events/ServiceChecked.php rename app/Livewire/Project/Service/{Navbar.php => Heading.php} (65%) rename resources/views/livewire/project/service/{navbar.blade.php => heading.blade.php} (97%) diff --git a/app/Actions/Application/StopApplication.php b/app/Actions/Application/StopApplication.php index f5f16f3fe..01c258b65 100644 --- a/app/Actions/Application/StopApplication.php +++ b/app/Actions/Application/StopApplication.php @@ -3,6 +3,7 @@ namespace App\Actions\Application; use App\Actions\Server\CleanupDocker; +use App\Events\ServiceStatusChanged; use App\Models\Application; use Lorisleiva\Actions\Concerns\AsAction; @@ -14,6 +15,7 @@ class StopApplication public function handle(Application $application, bool $previewDeployments = false, bool $dockerCleanup = true) { + ray('StopApplication'); try { $server = $application->destination->server; if (! $server->isFunctional()) { @@ -38,6 +40,8 @@ class StopApplication } } catch (\Exception $e) { return $e->getMessage(); + } finally { + ServiceStatusChanged::dispatch($application->environment->project->team->id); } } } diff --git a/app/Actions/Database/StopDatabase.php b/app/Actions/Database/StopDatabase.php index 161e7dad7..5c0cadd55 100644 --- a/app/Actions/Database/StopDatabase.php +++ b/app/Actions/Database/StopDatabase.php @@ -3,6 +3,7 @@ namespace App\Actions\Database; use App\Actions\Server\CleanupDocker; +use App\Events\ServiceStatusChanged; use App\Models\StandaloneClickhouse; use App\Models\StandaloneDragonfly; use App\Models\StandaloneKeydb; @@ -19,23 +20,30 @@ class StopDatabase public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse $database, bool $isDeleteOperation = false, bool $dockerCleanup = true) { - $server = $database->destination->server; - if (! $server->isFunctional()) { - return 'Server is not functional'; - } - - $this->stopContainer($database, $database->uuid, 30); - if ($isDeleteOperation) { - if ($dockerCleanup) { - CleanupDocker::dispatch($server, true); + try { + $server = $database->destination->server; + if (! $server->isFunctional()) { + return 'Server is not functional'; } + + $this->stopContainer($database, $database->uuid, 30); + if ($isDeleteOperation) { + if ($dockerCleanup) { + CleanupDocker::dispatch($server, true); + } + } + + if ($database->is_public) { + StopDatabaseProxy::run($database); + } + + return 'Database stopped successfully'; + } catch (\Exception $e) { + return 'Database stop failed: '.$e->getMessage(); + } finally { + ServiceStatusChanged::dispatch($database->environment->project->team->id); } - if ($database->is_public) { - StopDatabaseProxy::run($database); - } - - return 'Database stopped successfully'; } private function stopContainer($database, string $containerName, int $timeout = 30): void diff --git a/app/Actions/Docker/GetContainersStatus.php b/app/Actions/Docker/GetContainersStatus.php index 091268043..d7275ca90 100644 --- a/app/Actions/Docker/GetContainersStatus.php +++ b/app/Actions/Docker/GetContainersStatus.php @@ -4,6 +4,7 @@ namespace App\Actions\Docker; use App\Actions\Database\StartDatabaseProxy; use App\Actions\Shared\ComplexStatusCheck; +use App\Events\ServiceChecked; use App\Models\ApplicationPreview; use App\Models\Server; use App\Models\ServiceDatabase; @@ -341,5 +342,6 @@ class GetContainersStatus } // $this->server->team?->notify(new ContainerStopped($containerName, $this->server, $url)); } + ServiceChecked::dispatch($this->server->team->id); } } diff --git a/app/Actions/Service/StartService.php b/app/Actions/Service/StartService.php index d48594e62..1e7779a75 100644 --- a/app/Actions/Service/StartService.php +++ b/app/Actions/Service/StartService.php @@ -41,6 +41,6 @@ class StartService } } - return remote_process($commands, $service->server, type_uuid: $service->uuid, callEventOnFinish: 'ServiceStatusChanged'); + return remote_process($commands, $service->server, type_uuid: $service->uuid); } } diff --git a/app/Actions/Service/StopService.php b/app/Actions/Service/StopService.php index 4bc2ecf03..9638db57f 100644 --- a/app/Actions/Service/StopService.php +++ b/app/Actions/Service/StopService.php @@ -3,6 +3,7 @@ namespace App\Actions\Service; use App\Actions\Server\CleanupDocker; +use App\Events\ServiceStatusChanged; use App\Models\Service; use Lorisleiva\Actions\Concerns\AsAction; @@ -31,6 +32,8 @@ class StopService } } catch (\Exception $e) { return $e->getMessage(); + } finally { + ServiceStatusChanged::dispatch($service->environment->project->team->id); } } } diff --git a/app/Events/ServiceChecked.php b/app/Events/ServiceChecked.php new file mode 100644 index 000000000..3f130a0fb --- /dev/null +++ b/app/Events/ServiceChecked.php @@ -0,0 +1,35 @@ +check() && auth()->user()->currentTeam()) { + $teamId = auth()->user()->currentTeam()->id; + } + $this->teamId = $teamId; + } + + public function broadcastOn(): array + { + if (is_null($this->teamId)) { + return []; + } + + return [ + new PrivateChannel("team.{$this->teamId}"), + ]; + } +} diff --git a/app/Events/ServiceStatusChanged.php b/app/Events/ServiceStatusChanged.php index f5a30e874..506f77881 100644 --- a/app/Events/ServiceStatusChanged.php +++ b/app/Events/ServiceStatusChanged.php @@ -7,30 +7,29 @@ use Illuminate\Broadcasting\PrivateChannel; use Illuminate\Contracts\Broadcasting\ShouldBroadcast; use Illuminate\Foundation\Events\Dispatchable; use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Facades\Auth; class ServiceStatusChanged implements ShouldBroadcast { use Dispatchable, InteractsWithSockets, SerializesModels; - public int|string|null $userId = null; + public ?int $teamId = null; - public function __construct($userId = null) + public function __construct($teamId = null) { - if (is_null($userId)) { - $userId = Auth::id() ?? null; + if (is_null($teamId) && auth()->check() && auth()->user()->currentTeam()) { + $teamId = auth()->user()->currentTeam()->id; } - $this->userId = $userId; + $this->teamId = $teamId; } - public function broadcastOn(): ?array + public function broadcastOn(): array { - if (is_null($this->userId)) { + if (is_null($this->teamId)) { return []; } return [ - new PrivateChannel("user.{$this->userId}"), + new PrivateChannel("team.{$this->teamId}"), ]; } } diff --git a/app/Jobs/ApplicationDeploymentJob.php b/app/Jobs/ApplicationDeploymentJob.php index bebec64cf..c58b075f4 100644 --- a/app/Jobs/ApplicationDeploymentJob.php +++ b/app/Jobs/ApplicationDeploymentJob.php @@ -5,7 +5,7 @@ namespace App\Jobs; use App\Actions\Docker\GetContainersStatus; use App\Enums\ApplicationDeploymentStatus; use App\Enums\ProcessStatus; -use App\Events\ApplicationStatusChanged; +use App\Events\ServiceStatusChanged; use App\Models\Application; use App\Models\ApplicationDeploymentQueue; use App\Models\ApplicationPreview; @@ -331,7 +331,7 @@ class ApplicationDeploymentJob implements ShouldBeEncrypted, ShouldQueue $this->application_deployment_queue->addLogEntry("Gracefully shutting down build container: {$this->deployment_uuid}"); $this->graceful_shutdown_container($this->deployment_uuid); - ApplicationStatusChanged::dispatch(data_get($this->application, 'environment.project.team.id')); + ServiceStatusChanged::dispatch(data_get($this->application, 'environment.project.team.id')); } } diff --git a/app/Livewire/Project/Application/Configuration.php b/app/Livewire/Project/Application/Configuration.php index 267ca72ad..f0b95a9c8 100644 --- a/app/Livewire/Project/Application/Configuration.php +++ b/app/Livewire/Project/Application/Configuration.php @@ -17,7 +17,15 @@ class Configuration extends Component public $servers; - protected $listeners = ['buildPackUpdated' => '$refresh']; + public function getListeners() + { + $teamId = auth()->user()->currentTeam()->id; + + return [ + "echo-private:team.{$teamId},ServiceChecked" => '$refresh', + 'buildPackUpdated' => '$refresh', + ]; + } public function mount() { diff --git a/app/Livewire/Project/Application/Deployment/Index.php b/app/Livewire/Project/Application/Deployment/Index.php index 0567a6e8a..c957615ac 100644 --- a/app/Livewire/Project/Application/Deployment/Index.php +++ b/app/Livewire/Project/Application/Deployment/Index.php @@ -28,6 +28,15 @@ class Index extends Component protected $queryString = ['pull_request_id']; + public function getListeners() + { + $teamId = auth()->user()->currentTeam()->id; + + return [ + "echo-private:team.{$teamId},ServiceChecked" => '$refresh', + ]; + } + public function mount() { $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); diff --git a/app/Livewire/Project/Application/Deployment/Show.php b/app/Livewire/Project/Application/Deployment/Show.php index 7b2ac09d3..cdac47d3d 100644 --- a/app/Livewire/Project/Application/Deployment/Show.php +++ b/app/Livewire/Project/Application/Deployment/Show.php @@ -18,7 +18,15 @@ class Show extends Component public $isKeepAliveOn = true; - protected $listeners = ['refreshQueue']; + public function getListeners() + { + $teamId = auth()->user()->currentTeam()->id; + + return [ + "echo-private:team.{$teamId},ServiceChecked" => '$refresh', + 'refreshQueue', + ]; + } public function mount() { diff --git a/app/Livewire/Project/Application/Heading.php b/app/Livewire/Project/Application/Heading.php index 5b0ae12ef..1bacc920f 100644 --- a/app/Livewire/Project/Application/Heading.php +++ b/app/Livewire/Project/Application/Heading.php @@ -4,7 +4,6 @@ namespace App\Livewire\Project\Application; use App\Actions\Application\StopApplication; use App\Actions\Docker\GetContainersStatus; -use App\Events\ApplicationStatusChanged; use App\Models\Application; use Livewire\Component; use Visus\Cuid2\Cuid2; @@ -28,7 +27,8 @@ class Heading extends Component $teamId = auth()->user()->currentTeam()->id; return [ - "echo-private:team.{$teamId},ApplicationStatusChanged" => 'check_status', + "echo-private:team.{$teamId},ServiceStatusChanged" => 'checkStatus', + "echo-private:team.{$teamId},ServiceChecked" => '$refresh', 'compose_loaded' => '$refresh', 'update_links' => '$refresh', ]; @@ -46,14 +46,11 @@ class Heading extends Component $this->lastDeploymentLink = $this->application->gitCommitLink(data_get($lastDeployment, 'commit')); } - public function check_status($showNotification = false) + public function checkStatus() { if ($this->application->destination->server->isFunctional()) { GetContainersStatus::dispatch($this->application->destination->server); } - if ($showNotification) { - $this->dispatch('success', 'Success', 'Application status updated.'); - } } public function force_deploy_without_cache() @@ -111,16 +108,7 @@ class Heading extends Component public function stop() { - StopApplication::run($this->application, false, $this->docker_cleanup); - $this->application->status = 'exited'; - $this->application->save(); - if ($this->application->additional_servers->count() > 0) { - $this->application->additional_servers->each(function ($server) { - $server->pivot->status = 'exited:unhealthy'; - $server->pivot->save(); - }); - } - ApplicationStatusChanged::dispatch(data_get($this->application, 'environment.project.team.id')); + StopApplication::dispatch($this->application, false, $this->docker_cleanup); } public function restart() diff --git a/app/Livewire/Project/Database/Configuration.php b/app/Livewire/Project/Database/Configuration.php index 938abba54..6c4d0867e 100644 --- a/app/Livewire/Project/Database/Configuration.php +++ b/app/Livewire/Project/Database/Configuration.php @@ -2,6 +2,7 @@ namespace App\Livewire\Project\Database; +use Auth; use Livewire\Component; class Configuration extends Component @@ -14,6 +15,15 @@ class Configuration extends Component public $environment; + public function getListeners() + { + $teamId = Auth::user()->currentTeam()->id; + + return [ + "echo-private:team.{$teamId},ServiceChecked" => '$refresh', + ]; + } + public function mount() { $this->currentRoute = request()->route()->getName(); diff --git a/app/Livewire/Project/Database/Heading.php b/app/Livewire/Project/Database/Heading.php index 2f304c5e6..177bb549c 100644 --- a/app/Livewire/Project/Database/Heading.php +++ b/app/Livewire/Project/Database/Heading.php @@ -6,8 +6,7 @@ use App\Actions\Database\RestartDatabase; use App\Actions\Database\StartDatabase; use App\Actions\Database\StopDatabase; use App\Actions\Docker\GetContainersStatus; -use App\Events\DatabaseStatusChanged; -use Illuminate\Support\Facades\Auth; +use App\Events\ServiceStatusChanged; use Livewire\Component; class Heading extends Component @@ -20,36 +19,41 @@ class Heading extends Component public function getListeners() { - $userId = Auth::id(); + $teamId = auth()->user()->currentTeam()->id; return [ - "echo-private:user.{$userId},DatabaseStatusChanged" => 'activityFinished', + "echo-private:team.{$teamId},ServiceStatusChanged" => 'checkStatus', + "echo-private:team.{$teamId},ServiceChecked" => 'activityFinished', + 'refresh' => '$refresh', + 'compose_loaded' => '$refresh', + 'update_links' => '$refresh', ]; } public function activityFinished() { - $this->database->update([ - 'started_at' => now(), - ]); - $this->check_status(); + try { + $this->database->update([ + 'started_at' => now(), + ]); - if (is_null($this->database->config_hash) || $this->database->isConfigurationChanged()) { - $this->database->isConfigurationChanged(true); - $this->dispatch('configurationChanged'); - } else { - $this->dispatch('configurationChanged'); + if (is_null($this->database->config_hash) || $this->database->isConfigurationChanged()) { + $this->database->isConfigurationChanged(true); + $this->dispatch('configurationChanged'); + } else { + $this->dispatch('configurationChanged'); + } + } catch (\Exception $e) { + return handleError($e, $this); + } finally { + $this->dispatch('refresh'); } } - public function check_status($showNotification = false) + public function checkStatus() { if ($this->database->destination->server->isFunctional()) { - GetContainersStatus::run($this->database->destination->server); - } - - if ($showNotification) { - $this->dispatch('success', 'Database status updated.'); + GetContainersStatus::dispatch($this->database->destination->server); } } @@ -60,23 +64,24 @@ class Heading extends Component public function stop() { - StopDatabase::run($this->database, false, $this->docker_cleanup); - $this->database->status = 'exited'; - $this->database->save(); - $this->check_status(); - $this->dispatch('refresh'); + try { + $this->dispatch('info', 'Stopping database.'); + StopDatabase::dispatch($this->database, false, $this->docker_cleanup); + } catch (\Exception $e) { + $this->dispatch('error', $e->getMessage()); + } } public function restart() { $activity = RestartDatabase::run($this->database); - $this->dispatch('activityMonitor', $activity->id, DatabaseStatusChanged::class); + $this->dispatch('activityMonitor', $activity->id, ServiceStatusChanged::class); } public function start() { $activity = StartDatabase::run($this->database); - $this->dispatch('activityMonitor', $activity->id, DatabaseStatusChanged::class); + $this->dispatch('activityMonitor', $activity->id, ServiceStatusChanged::class); } public function render() diff --git a/app/Livewire/Project/Service/Configuration.php b/app/Livewire/Project/Service/Configuration.php index 20067b1f9..8ac74e7de 100644 --- a/app/Livewire/Project/Service/Configuration.php +++ b/app/Livewire/Project/Service/Configuration.php @@ -2,7 +2,6 @@ namespace App\Livewire\Project\Service; -use App\Actions\Docker\GetContainersStatus; use App\Models\Service; use Illuminate\Support\Facades\Auth; use Livewire\Component; @@ -27,13 +26,10 @@ class Configuration extends Component public function getListeners() { - $userId = Auth::id(); + $teamId = Auth::user()->currentTeam()->id; return [ - "echo-private:user.{$userId},ServiceStatusChanged" => 'check_status', - 'refreshStatus' => '$refresh', - 'check_status', - 'refreshServices', + "echo-private:team.{$teamId},ServiceChecked" => 'serviceChecked', ]; } @@ -97,19 +93,15 @@ class Configuration extends Component } } - public function check_status() + public function serviceChecked() { try { - if ($this->service->server->isFunctional()) { - GetContainersStatus::dispatch($this->service->server); - } $this->service->applications->each(function ($application) { $application->refresh(); }); $this->service->databases->each(function ($database) { $database->refresh(); }); - $this->dispatch('refreshStatus'); } catch (\Exception $e) { return handleError($e, $this); } diff --git a/app/Livewire/Project/Service/EditDomain.php b/app/Livewire/Project/Service/EditDomain.php index fb1c05255..b7f73159e 100644 --- a/app/Livewire/Project/Service/EditDomain.php +++ b/app/Livewire/Project/Service/EditDomain.php @@ -47,7 +47,6 @@ class EditDomain extends Component $this->application->service->parse(); $this->dispatch('refresh'); $this->dispatch('configurationChanged'); - $this->dispatch('refreshStatus'); } catch (\Throwable $e) { $originalFqdn = $this->application->getOriginal('fqdn'); if ($originalFqdn !== $this->application->fqdn) { diff --git a/app/Livewire/Project/Service/Navbar.php b/app/Livewire/Project/Service/Heading.php similarity index 65% rename from app/Livewire/Project/Service/Navbar.php rename to app/Livewire/Project/Service/Heading.php index 5da425cbd..96e94ce92 100644 --- a/app/Livewire/Project/Service/Navbar.php +++ b/app/Livewire/Project/Service/Heading.php @@ -2,6 +2,7 @@ namespace App\Livewire\Project\Service; +use App\Actions\Docker\GetContainersStatus; use App\Actions\Service\StartService; use App\Actions\Service\StopService; use App\Enums\ProcessStatus; @@ -11,7 +12,7 @@ use Illuminate\Support\Facades\Auth; use Livewire\Component; use Spatie\Activitylog\Models\Activity; -class Navbar extends Component +class Heading extends Component { public Service $service; @@ -35,35 +36,44 @@ class Navbar extends Component public function getListeners() { - $userId = Auth::id(); + $teamId = Auth::user()->currentTeam()->id; return [ - "echo-private:user.{$userId},ServiceStatusChanged" => 'serviceStarted', + "echo-private:team.{$teamId},ServiceStatusChanged" => 'checkStatus', + "echo-private:team.{$teamId},ServiceChecked" => 'serviceChecked', + 'refresh' => '$refresh', 'envsUpdated' => '$refresh', - 'refreshStatus' => '$refresh', ]; } - public function serviceStarted() + public function checkStatus() { - // $this->dispatch('success', 'Service status changed.'); - if (is_null($this->service->config_hash) || $this->service->isConfigurationChanged()) { - $this->service->isConfigurationChanged(true); - $this->dispatch('configurationChanged'); - } else { - $this->dispatch('configurationChanged'); + if ($this->service->server->isFunctional()) { + GetContainersStatus::dispatch($this->service->server); } } - public function check_status_without_notification() + public function serviceChecked() { - $this->dispatch('check_status'); - } + try { + $this->service->applications->each(function ($application) { + $application->refresh(); + }); + $this->service->databases->each(function ($database) { + $database->refresh(); + }); + if (is_null($this->service->config_hash) || $this->service->isConfigurationChanged()) { + $this->service->isConfigurationChanged(true); + $this->dispatch('configurationChanged'); + } else { + $this->dispatch('configurationChanged'); + } + } catch (\Exception $e) { + return handleError($e, $this); + } finally { + $this->dispatch('refresh')->self(); + } - public function check_status() - { - $this->dispatch('check_status'); - $this->dispatch('success', 'Service status updated.'); } public function checkDeployments() @@ -86,7 +96,7 @@ class Navbar extends Component public function start() { $activity = StartService::run($this->service, pullLatestImages: true); - $this->dispatch('activityMonitor', $activity->id); + $this->dispatch('activityMonitor', $activity->id, ServiceStatusChanged::class); } public function forceDeploy() @@ -98,22 +108,16 @@ class Navbar extends Component $activity->save(); } $activity = StartService::run($this->service, pullLatestImages: true, stopBeforeStart: true); - $this->dispatch('activityMonitor', $activity->id); + $this->dispatch('activityMonitor', $activity->id, ServiceStatusChanged::class); } catch (\Exception $e) { $this->dispatch('error', $e->getMessage()); } } - public function stop($cleanupContainers = false) + public function stop() { try { - StopService::run($this->service, false, $this->docker_cleanup); - ServiceStatusChanged::dispatch(); - if ($cleanupContainers) { - $this->dispatch('success', 'Containers cleaned up.'); - } else { - $this->dispatch('success', 'Service stopped.'); - } + StopService::dispatch($this->service, false, $this->docker_cleanup); } catch (\Exception $e) { $this->dispatch('error', $e->getMessage()); } @@ -128,7 +132,7 @@ class Navbar extends Component return; } $activity = StartService::run($this->service, stopBeforeStart: true); - $this->dispatch('activityMonitor', $activity->id); + $this->dispatch('activityMonitor', $activity->id, ServiceStatusChanged::class); } public function pullAndRestartEvent() @@ -140,12 +144,12 @@ class Navbar extends Component return; } $activity = StartService::run($this->service, pullLatestImages: true, stopBeforeStart: true); - $this->dispatch('activityMonitor', $activity->id); + $this->dispatch('activityMonitor', $activity->id, ServiceStatusChanged::class); } public function render() { - return view('livewire.project.service.navbar', [ + return view('livewire.project.service.heading', [ 'checkboxes' => [ ['id' => 'docker_cleanup', 'label' => __('resource.docker_cleanup')], ], diff --git a/app/Livewire/Project/Shared/Destination.php b/app/Livewire/Project/Shared/Destination.php index 71a913add..9d5331ff6 100644 --- a/app/Livewire/Project/Shared/Destination.php +++ b/app/Livewire/Project/Shared/Destination.php @@ -119,17 +119,14 @@ class Destination extends Component public function refreshServers() { GetContainersStatus::run($this->resource->destination->server); - // ContainerStatusJob::dispatchSync($this->resource->destination->server); $this->loadData(); $this->dispatch('refresh'); - ApplicationStatusChanged::dispatch(data_get($this->resource, 'environment.project.team.id')); } public function addServer(int $network_id, int $server_id) { $this->resource->additional_networks()->attach($network_id, ['server_id' => $server_id]); $this->loadData(); - ApplicationStatusChanged::dispatch(data_get($this->resource, 'environment.project.team.id')); } public function removeServer(int $network_id, int $server_id, $password) diff --git a/app/Livewire/Project/Shared/ExecuteContainerCommand.php b/app/Livewire/Project/Shared/ExecuteContainerCommand.php index 98289c536..df69a2250 100644 --- a/app/Livewire/Project/Shared/ExecuteContainerCommand.php +++ b/app/Livewire/Project/Shared/ExecuteContainerCommand.php @@ -35,6 +35,15 @@ class ExecuteContainerCommand extends Component 'command' => 'required', ]; + public function getListeners() + { + $teamId = auth()->user()->currentTeam()->id; + + return [ + "echo-private:team.{$teamId},ServiceChecked" => '$refresh', + ]; + } + public function mount() { if (! auth()->user()->isAdmin()) { diff --git a/app/Livewire/Project/Shared/Logs.php b/app/Livewire/Project/Shared/Logs.php index 12022b1ee..2d760fae2 100644 --- a/app/Livewire/Project/Shared/Logs.php +++ b/app/Livewire/Project/Shared/Logs.php @@ -37,6 +37,15 @@ class Logs extends Component public $cpu; + public function getListeners() + { + $teamId = auth()->user()->currentTeam()->id; + + return [ + "echo-private:team.{$teamId},ServiceChecked" => '$refresh', + ]; + } + public function loadContainers($server_id) { try { diff --git a/app/Livewire/Project/Shared/ScheduledTask/Show.php b/app/Livewire/Project/Shared/ScheduledTask/Show.php index 6d9c6982a..fe6e36d5c 100644 --- a/app/Livewire/Project/Shared/ScheduledTask/Show.php +++ b/app/Livewire/Project/Shared/ScheduledTask/Show.php @@ -46,6 +46,15 @@ class Show extends Component #[Locked] public string $task_uuid; + public function getListeners() + { + $teamId = auth()->user()->currentTeam()->id; + + return [ + "echo-private:team.{$teamId},ServiceChecked" => '$refresh', + ]; + } + public function mount(string $task_uuid, string $project_uuid, string $environment_uuid, ?string $application_uuid = null, ?string $service_uuid = null) { try { diff --git a/resources/views/components/modal-confirmation.blade.php b/resources/views/components/modal-confirmation.blade.php index 626d55329..3d7bf83dd 100644 --- a/resources/views/components/modal-confirmation.blade.php +++ b/resources/views/components/modal-confirmation.blade.php @@ -87,7 +87,6 @@ params.push(this.password); } params.push(this.selectedActions); - return $wire[methodName](...params) .then(result => { if (result === true) { diff --git a/resources/views/components/status/index.blade.php b/resources/views/components/status/index.blade.php index fcc2688e1..fe9569c8a 100644 --- a/resources/views/components/status/index.blade.php +++ b/resources/views/components/status/index.blade.php @@ -13,7 +13,8 @@ @endif @if (!str($resource->status)->contains('exited') && $showRefreshButton) -
@@ -159,16 +159,16 @@
diff --git a/resources/views/livewire/project/service/configuration.blade.php b/resources/views/livewire/project/service/configuration.blade.php index a849dd1d7..abb7229c6 100644 --- a/resources/views/livewire/project/service/configuration.blade.php +++ b/resources/views/livewire/project/service/configuration.blade.php @@ -2,7 +2,7 @@ {{ data_get_str($service, 'name')->limit(10) }} > Configuration | Coolify - +
@@ -36,7 +36,7 @@ @if ($currentRoute === 'project.service.configuration')

Services

-
+
@foreach ($applications as $application)
str( diff --git a/resources/views/livewire/project/service/navbar.blade.php b/resources/views/livewire/project/service/heading.blade.php similarity index 97% rename from resources/views/livewire/project/service/navbar.blade.php rename to resources/views/livewire/project/service/heading.blade.php index cf5a8177e..b461933a4 100644 --- a/resources/views/livewire/project/service/navbar.blade.php +++ b/resources/views/livewire/project/service/heading.blade.php @@ -1,4 +1,4 @@ -
+
Service Startup @@ -40,8 +40,7 @@ + step1ButtonText="Continue" step2ButtonText="Stop Service"> + step1ButtonText="Continue" step2ButtonText="Stop Service"> + step1ButtonText="Continue" step2ButtonText="Stop Service"> - +
@elseif ($type === 'service') - + @elseif ($type === 'server') @endif - @if(!$hasShell) + @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.

+

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

@else @if ($type === 'server') - + Reconnect
diff --git a/resources/views/livewire/project/shared/scheduled-task/show.blade.php b/resources/views/livewire/project/shared/scheduled-task/show.blade.php index d3f6cb5dc..c32659ad8 100644 --- a/resources/views/livewire/project/shared/scheduled-task/show.blade.php +++ b/resources/views/livewire/project/shared/scheduled-task/show.blade.php @@ -6,7 +6,7 @@

Scheduled Task

@elseif ($type === 'service') - + @endif
From ca77dc8eb9d482ccdc9069498ee5ebc5a7d56d7d Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 19 May 2025 22:27:04 +0200 Subject: [PATCH 18/53] fix(css): tailwind v5 things --- resources/css/app.css | 2 +- resources/css/utilities.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/css/app.css b/resources/css/app.css index 79e5f0c13..77fa2d66b 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -44,7 +44,7 @@ ::before, ::backdrop, ::file-selector-button { - border-color: var(--color-gray-200, currentcolor); + border-color: var(--color-coolgray-200, currentcolor); } } diff --git a/resources/css/utilities.css b/resources/css/utilities.css index 8504ed3d9..0735e35e2 100644 --- a/resources/css/utilities.css +++ b/resources/css/utilities.css @@ -194,7 +194,7 @@ } @utility fullscreen { - @apply overflow-y-auto fixed top-0 left-0 w-full h-full bg-white z-9999 dark:bg-coolgray-100 scrollbar; + @apply overflow-y-auto fixed top-0 left-0 w-full h-full bg-white z-[9999] dark:bg-coolgray-100 scrollbar; } @utility toast { From 107143390251f794975939f95605bc4736b09c43 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 19 May 2025 22:27:39 +0200 Subject: [PATCH 19/53] fix(service): Diun ENV for consistency --- templates/compose/diun.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/diun.yaml b/templates/compose/diun.yaml index 2894917e5..266bd44ba 100644 --- a/templates/compose/diun.yaml +++ b/templates/compose/diun.yaml @@ -15,7 +15,7 @@ services: - LOG_LEVEL=${LOG_LEVEL:-info} - LOG_JSON=${LOG_JSON:-false} - DIUN_WATCH_WORKERS=${DIUN_WATCH_WORKERS:-20} - - DIUN_WATCH_SCHEDULE=${CRON_WATCH_SCHEDULE:- * */6 * * *} + - DIUN_WATCH_SCHEDULE=${DIUN_WATCH_SCHEDULE:- * */6 * * *} - DIUN_WATCH_JITTER=${DIUN_WATCH_JITTER:-30s} - DIUN_PROVIDERS_DOCKER=${DIUN_PROVIDERS_DOCKER:-true} - DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT=${DIUN_PROVIDERS_DOCKER_WATCHBYDEFAULT:-true} From 8aca7561d9b53a1e40c9296ccd4071b9b287a78d Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 19 May 2025 22:27:55 +0200 Subject: [PATCH 20/53] fix(service): memos service name --- templates/compose/memos.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/memos.yaml b/templates/compose/memos.yaml index 753630060..32bc2f297 100644 --- a/templates/compose/memos.yaml +++ b/templates/compose/memos.yaml @@ -5,7 +5,7 @@ # port: 5230 services: - wg-easy: + memos: image: neosmemo/memos:stable volumes: - memos/:/var/opt/memos From 71b272f06ae17e1c774544049e384b8875d41bd4 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 19 May 2025 22:28:48 +0200 Subject: [PATCH 21/53] refactor(service): improve paymenter - formatting - ENV style - add depends_on --- templates/compose/paymenter.yaml | 33 ++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/templates/compose/paymenter.yaml b/templates/compose/paymenter.yaml index c05c93d7c..9854581f9 100644 --- a/templates/compose/paymenter.yaml +++ b/templates/compose/paymenter.yaml @@ -10,27 +10,32 @@ services: volumes: - app_logs:/app/storage/logs - app_public:/app/storage/public - healthcheck: - test: ["CMD-SHELL", "curl -sf http://localhost:80 || exit 1"] - interval: 10s - timeout: 1s - retries: 3 environment: SERVICE_FQDN_PAYMENTER: ${SERVICE_FQDN_PAYMENTER_80} DB_DATABASE: ${MYSQL_DATABASE:-paymenter-db} DB_PASSWORD: ${SERVICE_PASSWORD_MYSQL} DB_USERNAME: ${SERVICE_USER_MYSQL} - APP_ENV: "production" - CACHE_STORE: "redis" - SESSION_DRIVER: "redis" - QUEUE_CONNECTION: "redis" - REDIS_HOST: "redis" + APP_ENV: production + CACHE_STORE: redis + SESSION_DRIVER: redis + QUEUE_CONNECTION: redis + REDIS_HOST: redis REDIS_USERNAME: default - REDIS_PASSWORD: "${SERVICE_PASSWORD_64_REDIS}" - DB_CONNECTION: "mariadb" - DB_HOST: "mariadb" - DB_PORT: "3306" + REDIS_PASSWORD: ${SERVICE_PASSWORD_64_REDIS} + DB_CONNECTION: mariadb + DB_HOST: mariadb + DB_PORT: 3306 APP_KEY: ${SERVICE_BASE64_KEY} + depends_on: + mariadb: + condition: service_healthy + redis: + condition: service_started + healthcheck: + test: ["CMD-SHELL", "curl -sf http://localhost:80 || exit 1"] + interval: 10s + timeout: 1s + retries: 3 mariadb: image: mariadb:11 From 65d64dcbadd25916da3a8b3de389c3e01f3ff42f Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 19 May 2025 22:29:16 +0200 Subject: [PATCH 22/53] chore(service): remove typesense default API key --- templates/compose/typesense.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/compose/typesense.yaml b/templates/compose/typesense.yaml index 443d00df2..d6c383b90 100644 --- a/templates/compose/typesense.yaml +++ b/templates/compose/typesense.yaml @@ -11,7 +11,7 @@ services: - SERVICE_FQDN_TYPESENSE_8108 - TYPESENSE_ENABLE_CORS=${TYPESENSE_ENABLE_CORS:-true} - TYPESENSE_DATA_DIR=/data - - TYPESENSE_API_KEY=${TYPESENSE_API_KEY:-xyz} + - TYPESENSE_API_KEY=${TYPESENSE_API_KEY} volumes: - typesense_data:/data healthcheck: From a337d4b4f8210860f1ae0952f238963e5f8c5d36 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 19 May 2025 22:30:01 +0200 Subject: [PATCH 23/53] chore(service): format yamtrack healthcheck --- templates/compose/yamtrack.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/templates/compose/yamtrack.yaml b/templates/compose/yamtrack.yaml index 7b626e737..49e760e8f 100644 --- a/templates/compose/yamtrack.yaml +++ b/templates/compose/yamtrack.yaml @@ -21,8 +21,10 @@ services: condition: service_healthy healthcheck: test: - - CMD-SHELL - - "wget --no-verbose --tries=1 --spider http://127.0.0.1:8000/health/ || exit 1" + [ + "CMD-SHELL", + "wget --quiet --tries=1 --spider http://127.0.0.1:8000/health/ || exit 1", + ] interval: 5s timeout: 20s retries: 10 From 69c01b650a6b9fe233759233456fa1bcb8fbcebb Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 19 May 2025 22:30:15 +0200 Subject: [PATCH 24/53] Update service-templates.json --- templates/service-templates.json | 69 ++++++++++++++++++++++++++++---- 1 file changed, 62 insertions(+), 7 deletions(-) diff --git a/templates/service-templates.json b/templates/service-templates.json index 6d1c85451..73faee6e7 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -144,7 +144,7 @@ "authentik": { "documentation": "https://docs.goauthentik.io/docs/installation/docker-compose?utm_source=coolify.io", "slogan": "An open-source Identity Provider, focused on flexibility and versatility.", - "compose": "c2VydmljZXM6CiAgYXV0aGVudGlrLXNlcnZlcjoKICAgIGltYWdlOiAnZ2hjci5pby9nb2F1dGhlbnRpay9zZXJ2ZXI6JHtBVVRIRU5USUtfVEFHOi0yMDI1LjIuM30nCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgY29tbWFuZDogc2VydmVyCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fQVVUSEVOVElLU0VSVkVSXzkwMDAKICAgICAgLSAnQVVUSEVOVElLX1JFRElTX19IT1NUPSR7UkVESVNfSE9TVDotcmVkaXN9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fSE9TVD0ke1BPU1RHUkVTX0hPU1Q6LXBvc3RncmVzcWx9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX05BTUU9JHtQT1NUR1JFU19EQjotYXV0aGVudGlrfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1NFQ1JFVF9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X0FVVEhFTlRJS1NFUlZFUn0nCiAgICAgIC0gJ0FVVEhFTlRJS19FUlJPUl9SRVBPUlRJTkdfX0VOQUJMRUQ9JHtBVVRIRU5USUtfRVJST1JfUkVQT1JUSU5HX19FTkFCTEVEOi10cnVlfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19IT1NUPSR7QVVUSEVOVElLX0VNQUlMX19IT1NUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19QT1JUPSR7QVVUSEVOVElLX0VNQUlMX19QT1JUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19VU0VSTkFNRT0ke0FVVEhFTlRJS19FTUFJTF9fVVNFUk5BTUV9JwogICAgICAtICdBVVRIRU5USUtfRU1BSUxfX1BBU1NXT1JEPSR7QVVUSEVOVElLX0VNQUlMX19QQVNTV09SRH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMUz0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMU30nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTD0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVD0ke0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fRlJPTT0ke0FVVEhFTlRJS19FTUFJTF9fRlJPTX0nCiAgICB2b2x1bWVzOgogICAgICAtICcuL21lZGlhOi9tZWRpYScKICAgICAgLSAnLi9jdXN0b20tdGVtcGxhdGVzOi90ZW1wbGF0ZXMnCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3Jlc3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgYXV0aGVudGlrLXdvcmtlcjoKICAgIGltYWdlOiAnZ2hjci5pby9nb2F1dGhlbnRpay9zZXJ2ZXI6JHtBVVRIRU5USUtfVEFHOi0yMDI1LjIuM30nCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgY29tbWFuZDogd29ya2VyCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnQVVUSEVOVElLX1JFRElTX19IT1NUPSR7UkVESVNfSE9TVDotcmVkaXN9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fSE9TVD0ke1BPU1RHUkVTX0hPU1Q6LXBvc3RncmVzcWx9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX05BTUU9JHtQT1NUR1JFU19EQjotYXV0aGVudGlrfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1NFQ1JFVF9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X0FVVEhFTlRJS1NFUlZFUn0nCiAgICAgIC0gJ0FVVEhFTlRJS19FUlJPUl9SRVBPUlRJTkdfX0VOQUJMRUQ9JHtBVVRIRU5USUtfRVJST1JfUkVQT1JUSU5HX19FTkFCTEVEfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19IT1NUPSR7QVVUSEVOVElLX0VNQUlMX19IT1NUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19QT1JUPSR7QVVUSEVOVElLX0VNQUlMX19QT1JUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19VU0VSTkFNRT0ke0FVVEhFTlRJS19FTUFJTF9fVVNFUk5BTUV9JwogICAgICAtICdBVVRIRU5USUtfRU1BSUxfX1BBU1NXT1JEPSR7QVVUSEVOVElLX0VNQUlMX19QQVNTV09SRH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMUz0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMU30nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTD0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVD0ke0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fRlJPTT0ke0FVVEhFTlRJS19FTUFJTF9fRlJPTX0nCiAgICB1c2VyOiByb290CiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgICAgLSAnLi9tZWRpYTovbWVkaWEnCiAgICAgIC0gJy4vY2VydHM6L2NlcnRzJwogICAgICAtICcuL2N1c3RvbS10ZW1wbGF0ZXM6L3RlbXBsYXRlcycKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzcWw6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICBwb3N0Z3Jlc3FsOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNi1hbHBpbmUnCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1kICQke1BPU1RHUkVTX0RCfSAtVSAkJHtQT1NUR1JFU19VU0VSfScKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogICAgdm9sdW1lczoKICAgICAgLSAnYXV0aGVudGlrLWRiOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNRTH0nCiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVNRTH0nCiAgICAgIC0gUE9TVEdSRVNfREI9YXV0aGVudGlrCiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOmFscGluZScKICAgIGNvbW1hbmQ6ICctLXNhdmUgNjAgMSAtLWxvZ2xldmVsIHdhcm5pbmcnCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdyZWRpcy1jbGkgcGluZyB8IGdyZXAgUE9ORycKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogICAgdm9sdW1lczoKICAgICAgLSAncmVkaXM6L2RhdGEnCg==", + "compose": "c2VydmljZXM6CiAgYXV0aGVudGlrLXNlcnZlcjoKICAgIGltYWdlOiAnZ2hjci5pby9nb2F1dGhlbnRpay9zZXJ2ZXI6JHtBVVRIRU5USUtfVEFHOi0yMDI1LjQuMX0nCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgY29tbWFuZDogc2VydmVyCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fQVVUSEVOVElLU0VSVkVSXzkwMDAKICAgICAgLSAnQVVUSEVOVElLX1JFRElTX19IT1NUPSR7UkVESVNfSE9TVDotcmVkaXN9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fSE9TVD0ke1BPU1RHUkVTX0hPU1Q6LXBvc3RncmVzcWx9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX05BTUU9JHtQT1NUR1JFU19EQjotYXV0aGVudGlrfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1NFQ1JFVF9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X0FVVEhFTlRJS1NFUlZFUn0nCiAgICAgIC0gJ0FVVEhFTlRJS19FUlJPUl9SRVBPUlRJTkdfX0VOQUJMRUQ9JHtBVVRIRU5USUtfRVJST1JfUkVQT1JUSU5HX19FTkFCTEVEOi10cnVlfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19IT1NUPSR7QVVUSEVOVElLX0VNQUlMX19IT1NUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19QT1JUPSR7QVVUSEVOVElLX0VNQUlMX19QT1JUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19VU0VSTkFNRT0ke0FVVEhFTlRJS19FTUFJTF9fVVNFUk5BTUV9JwogICAgICAtICdBVVRIRU5USUtfRU1BSUxfX1BBU1NXT1JEPSR7QVVUSEVOVElLX0VNQUlMX19QQVNTV09SRH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMUz0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMU30nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTD0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVD0ke0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fRlJPTT0ke0FVVEhFTlRJS19FTUFJTF9fRlJPTX0nCiAgICB2b2x1bWVzOgogICAgICAtICcuL21lZGlhOi9tZWRpYScKICAgICAgLSAnLi9jdXN0b20tdGVtcGxhdGVzOi90ZW1wbGF0ZXMnCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3Jlc3FsOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgYXV0aGVudGlrLXdvcmtlcjoKICAgIGltYWdlOiAnZ2hjci5pby9nb2F1dGhlbnRpay9zZXJ2ZXI6JHtBVVRIRU5USUtfVEFHOi0yMDI1LjQuMX0nCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgY29tbWFuZDogd29ya2VyCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnQVVUSEVOVElLX1JFRElTX19IT1NUPSR7UkVESVNfSE9TVDotcmVkaXN9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fSE9TVD0ke1BPU1RHUkVTX0hPU1Q6LXBvc3RncmVzcWx9JwogICAgICAtICdBVVRIRU5USUtfUE9TVEdSRVNRTF9fVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX05BTUU9JHtQT1NUR1JFU19EQjotYXV0aGVudGlrfScKICAgICAgLSAnQVVUSEVOVElLX1BPU1RHUkVTUUxfX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU1FMfScKICAgICAgLSAnQVVUSEVOVElLX1NFQ1JFVF9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X0FVVEhFTlRJS1NFUlZFUn0nCiAgICAgIC0gJ0FVVEhFTlRJS19FUlJPUl9SRVBPUlRJTkdfX0VOQUJMRUQ9JHtBVVRIRU5USUtfRVJST1JfUkVQT1JUSU5HX19FTkFCTEVEfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19IT1NUPSR7QVVUSEVOVElLX0VNQUlMX19IT1NUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19QT1JUPSR7QVVUSEVOVElLX0VNQUlMX19QT1JUfScKICAgICAgLSAnQVVUSEVOVElLX0VNQUlMX19VU0VSTkFNRT0ke0FVVEhFTlRJS19FTUFJTF9fVVNFUk5BTUV9JwogICAgICAtICdBVVRIRU5USUtfRU1BSUxfX1BBU1NXT1JEPSR7QVVUSEVOVElLX0VNQUlMX19QQVNTV09SRH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMUz0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1RMU30nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTD0ke0FVVEhFTlRJS19FTUFJTF9fVVNFX1NTTH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVD0ke0FVVEhFTlRJS19FTUFJTF9fVElNRU9VVH0nCiAgICAgIC0gJ0FVVEhFTlRJS19FTUFJTF9fRlJPTT0ke0FVVEhFTlRJS19FTUFJTF9fRlJPTX0nCiAgICB1c2VyOiByb290CiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgICAgLSAnLi9tZWRpYTovbWVkaWEnCiAgICAgIC0gJy4vY2VydHM6L2NlcnRzJwogICAgICAtICcuL2N1c3RvbS10ZW1wbGF0ZXM6L3RlbXBsYXRlcycKICAgIGRlcGVuZHNfb246CiAgICAgIHBvc3RncmVzcWw6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgICAgcmVkaXM6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICBwb3N0Z3Jlc3FsOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNi1hbHBpbmUnCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1kICQke1BPU1RHUkVTX0RCfSAtVSAkJHtQT1NUR1JFU19VU0VSfScKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogICAgdm9sdW1lczoKICAgICAgLSAnYXV0aGVudGlrLWRiOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNRTH0nCiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVNRTH0nCiAgICAgIC0gUE9TVEdSRVNfREI9YXV0aGVudGlrCiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOmFscGluZScKICAgIGNvbW1hbmQ6ICctLXNhdmUgNjAgMSAtLWxvZ2xldmVsIHdhcm5pbmcnCiAgICByZXN0YXJ0OiB1bmxlc3Mtc3RvcHBlZAogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdyZWRpcy1jbGkgcGluZyB8IGdyZXAgUE9ORycKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQogICAgdm9sdW1lczoKICAgICAgLSAncmVkaXM6L2RhdGEnCg==", "tags": [ "identity", "login", @@ -372,7 +372,7 @@ "chatwoot": { "documentation": "https://www.chatwoot.com/docs/self-hosted/?utm_source=coolify.io", "slogan": "Delightful customer relationships at scale.", - "compose": "c2VydmljZXM6CiAgY2hhdHdvb3Q6CiAgICBpbWFnZTogJ2NoYXR3b290L2NoYXR3b290OmxhdGVzdCcKICAgIGRlcGVuZHNfb246CiAgICAgIC0gcG9zdGdyZXMKICAgICAgLSByZWRpcwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0NIQVRXT09UXzMwMDAKICAgICAgLSBTRUNSRVRfS0VZX0JBU0U9JFNFUlZJQ0VfUEFTU1dPUkRfQ0hBVFdPT1QKICAgICAgLSAnRlJPTlRFTkRfVVJMPSR7U0VSVklDRV9GUUROX0NIQVRXT09UfScKICAgICAgLSAnREVGQVVMVF9MT0NBTEU9JHtDSEFUV09PVF9ERUZBVUxUX0xPQ0FMRX0nCiAgICAgIC0gJ0ZPUkNFX1NTTD0ke0ZPUkNFX1NTTDotZmFsc2V9JwogICAgICAtICdFTkFCTEVfQUNDT1VOVF9TSUdOVVA9JHtFTkFCTEVfQUNDT1VOVF9TSUdOVVA6LWZhbHNlfScKICAgICAgLSAnUkVESVNfVVJMPXJlZGlzOi8vZGVmYXVsdEByZWRpczo2Mzc5JwogICAgICAtIFJFRElTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1JFRElTCiAgICAgIC0gJ1JFRElTX09QRU5TU0xfVkVSSUZZX01PREU9JHtSRURJU19PUEVOU1NMX1ZFUklGWV9NT0RFOi1ub25lfScKICAgICAgLSAnUE9TVEdSRVNfREFUQUJBU0U9JHtQT1NUR1JFU19EQjotY2hhdHdvb3R9JwogICAgICAtICdQT1NUR1JFU19IT1NUPSR7UE9TVEdSRVNfSE9TVDotcG9zdGdyZXN9JwogICAgICAtIFBPU1RHUkVTX1VTRVJOQU1FPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtICdSQUlMU19NQVhfVEhSRUFEUz0ke1JBSUxTX01BWF9USFJFQURTOi01fScKICAgICAgLSAnTk9ERV9FTlY9JHtOT0RFX0VOVjotcHJvZHVjdGlvbn0nCiAgICAgIC0gJ1JBSUxTX0VOVj0ke1JBSUxTX0VOVjotcHJvZHVjdGlvbn0nCiAgICAgIC0gJ0lOU1RBTExBVElPTl9FTlY9JHtJTlNUQUxMQVRJT05fRU5WOi1kb2NrZXJ9JwogICAgICAtICdNQUlMRVJfU0VOREVSX0VNQUlMPSR7Q0hBVFdPT1RfTUFJTEVSX1NFTkRFUl9FTUFJTH0nCiAgICAgIC0gJ1NNVFBfQUREUkVTUz0ke0NIQVRXT09UX1NNVFBfQUREUkVTU30nCiAgICAgIC0gJ1NNVFBfQVVUSEVOVElDQVRJT049JHtDSEFUV09PVF9TTVRQX0FVVEhFTlRJQ0FUSU9OfScKICAgICAgLSAnU01UUF9ET01BSU49JHtDSEFUV09PVF9TTVRQX0RPTUFJTn0nCiAgICAgIC0gJ1NNVFBfRU5BQkxFX1NUQVJUVExTX0FVVE89JHtDSEFUV09PVF9TTVRQX0VOQUJMRV9TVEFSVFRMU19BVVRPfScKICAgICAgLSAnU01UUF9QT1JUPSR7Q0hBVFdPT1RfU01UUF9QT1JUfScKICAgICAgLSAnU01UUF9VU0VSTkFNRT0ke0NIQVRXT09UX1NNVFBfVVNFUk5BTUV9JwogICAgICAtICdTTVRQX1BBU1NXT1JEPSR7Q0hBVFdPT1RfU01UUF9QQVNTV09SRH0nCiAgICAgIC0gJ0FDVElWRV9TVE9SQUdFX1NFUlZJQ0U9JHtBQ1RJVkVfU1RPUkFHRV9TRVJWSUNFOi1sb2NhbH0nCiAgICBlbnRyeXBvaW50OiBkb2NrZXIvZW50cnlwb2ludHMvcmFpbHMuc2gKICAgIGNvbW1hbmQ6ICdzaCAtYyAiYnVuZGxlIGV4ZWMgcmFpbHMgZGI6Y2hhdHdvb3RfcHJlcGFyZSAmJiBidW5kbGUgZXhlYyByYWlscyBzIC1wIDMwMDAgLWIgMC4wLjAuMCInCiAgICB2b2x1bWVzOgogICAgICAtICdyYWlscy1kYXRhOi9hcHAvc3RvcmFnZScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLS1zcGlkZXInCiAgICAgICAgLSAnLXEnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTozMDAwJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgc2lkZWtpcToKICAgIGltYWdlOiAnY2hhdHdvb3QvY2hhdHdvb3Q6bGF0ZXN0JwogICAgZGVwZW5kc19vbjoKICAgICAgLSBwb3N0Z3JlcwogICAgICAtIHJlZGlzCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRUNSRVRfS0VZX0JBU0U9JFNFUlZJQ0VfUEFTU1dPUkRfQ0hBVFdPT1QKICAgICAgLSAnRlJPTlRFTkRfVVJMPSR7U0VSVklDRV9GUUROX0NIQVRXT09UfScKICAgICAgLSAnREVGQVVMVF9MT0NBTEU9JHtDSEFUV09PVF9ERUZBVUxUX0xPQ0FMRX0nCiAgICAgIC0gJ0ZPUkNFX1NTTD0ke0ZPUkNFX1NTTDotZmFsc2V9JwogICAgICAtICdFTkFCTEVfQUNDT1VOVF9TSUdOVVA9JHtFTkFCTEVfQUNDT1VOVF9TSUdOVVA6LWZhbHNlfScKICAgICAgLSAnUkVESVNfVVJMPXJlZGlzOi8vZGVmYXVsdEByZWRpczo2Mzc5JwogICAgICAtIFJFRElTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1JFRElTCiAgICAgIC0gJ1JFRElTX09QRU5TU0xfVkVSSUZZX01PREU9JHtSRURJU19PUEVOU1NMX1ZFUklGWV9NT0RFOi1ub25lfScKICAgICAgLSAnUE9TVEdSRVNfREFUQUJBU0U9JHtQT1NUR1JFU19EQjotY2hhdHdvb3R9JwogICAgICAtICdQT1NUR1JFU19IT1NUPSR7UE9TVEdSRVNfSE9TVDotcG9zdGdyZXN9JwogICAgICAtIFBPU1RHUkVTX1VTRVJOQU1FPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtICdSQUlMU19NQVhfVEhSRUFEUz0ke1JBSUxTX01BWF9USFJFQURTOi01fScKICAgICAgLSAnTk9ERV9FTlY9JHtOT0RFX0VOVjotcHJvZHVjdGlvbn0nCiAgICAgIC0gJ1JBSUxTX0VOVj0ke1JBSUxTX0VOVjotcHJvZHVjdGlvbn0nCiAgICAgIC0gJ0lOU1RBTExBVElPTl9FTlY9JHtJTlNUQUxMQVRJT05fRU5WOi1kb2NrZXJ9JwogICAgICAtICdNQUlMRVJfU0VOREVSX0VNQUlMPSR7Q0hBVFdPT1RfTUFJTEVSX1NFTkRFUl9FTUFJTH0nCiAgICAgIC0gJ1NNVFBfQUREUkVTUz0ke0NIQVRXT09UX1NNVFBfQUREUkVTU30nCiAgICAgIC0gJ1NNVFBfQVVUSEVOVElDQVRJT049JHtDSEFUV09PVF9TTVRQX0FVVEhFTlRJQ0FUSU9OfScKICAgICAgLSAnU01UUF9ET01BSU49JHtDSEFUV09PVF9TTVRQX0RPTUFJTn0nCiAgICAgIC0gJ1NNVFBfRU5BQkxFX1NUQVJUVExTX0FVVE89JHtDSEFUV09PVF9TTVRQX0VOQUJMRV9TVEFSVFRMU19BVVRPfScKICAgICAgLSAnU01UUF9QT1JUPSR7Q0hBVFdPT1RfU01UUF9QT1JUfScKICAgICAgLSAnU01UUF9VU0VSTkFNRT0ke0NIQVRXT09UX1NNVFBfVVNFUk5BTUV9JwogICAgICAtICdTTVRQX1BBU1NXT1JEPSR7Q0hBVFdPT1RfU01UUF9QQVNTV09SRH0nCiAgICAgIC0gJ0FDVElWRV9TVE9SQUdFX1NFUlZJQ0U9JHtBQ1RJVkVfU1RPUkFHRV9TRVJWSUNFOi1sb2NhbH0nCiAgICBjb21tYW5kOgogICAgICAtIGJ1bmRsZQogICAgICAtIGV4ZWMKICAgICAgLSBzaWRla2lxCiAgICAgIC0gJy1DJwogICAgICAtIGNvbmZpZy9zaWRla2lxLnltbAogICAgdm9sdW1lczoKICAgICAgLSAnc2lkZWtpcS1kYXRhOi9hcHAvc3RvcmFnZScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAiYnVuZGxlIGV4ZWMgcmFpbHMgcnVubmVyICdwdXRzIFNpZGVraXEucmVkaXMoJjppbmZvKScgPiAvZGV2L251bGwgMj4mMSIKICAgICAgaW50ZXJ2YWw6IDMwcwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMwogIHBvc3RncmVzOgogICAgaW1hZ2U6ICdwZ3ZlY3Rvci9wZ3ZlY3RvcjpwZzEyJwogICAgcmVzdGFydDogYWx3YXlzCiAgICB2b2x1bWVzOgogICAgICAtICdwb3N0Z3Jlcy1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1jaGF0d29vdH0nCiAgICAgIC0gUE9TVEdSRVNfVVNFUj0kU0VSVklDRV9VU0VSX1BPU1RHUkVTCiAgICAgIC0gUE9TVEdSRVNfUEFTU1dPUkQ9JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVMKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSAkU0VSVklDRV9VU0VSX1BPU1RHUkVTIC1kIGNoYXR3b290IC1oIDEyNy4wLjAuMScKICAgICAgaW50ZXJ2YWw6IDMwcwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogNQogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczphbHBpbmUnCiAgICByZXN0YXJ0OiBhbHdheXMKICAgIGNvbW1hbmQ6CiAgICAgIC0gc2gKICAgICAgLSAnLWMnCiAgICAgIC0gJ3JlZGlzLXNlcnZlciAtLXJlcXVpcmVwYXNzICIkU0VSVklDRV9QQVNTV09SRF9SRURJUyInCiAgICB2b2x1bWVzOgogICAgICAtICdyZWRpcy1kYXRhOi9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHJlZGlzLWNsaQogICAgICAgIC0gJy1hJwogICAgICAgIC0gJFNFUlZJQ0VfUEFTU1dPUkRfUkVESVMKICAgICAgICAtIFBJTkcKICAgICAgaW50ZXJ2YWw6IDMwcwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogNQo=", + "compose": "c2VydmljZXM6CiAgY2hhdHdvb3Q6CiAgICBpbWFnZTogJ2NoYXR3b290L2NoYXR3b290OmxhdGVzdCcKICAgIGRlcGVuZHNfb246CiAgICAgIC0gcG9zdGdyZXMKICAgICAgLSByZWRpcwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0NIQVRXT09UXzMwMDAKICAgICAgLSBTRUNSRVRfS0VZX0JBU0U9JFNFUlZJQ0VfUEFTU1dPUkRfQ0hBVFdPT1QKICAgICAgLSAnRlJPTlRFTkRfVVJMPSR7U0VSVklDRV9GUUROX0NIQVRXT09UfScKICAgICAgLSAnREVGQVVMVF9MT0NBTEU9JHtDSEFUV09PVF9ERUZBVUxUX0xPQ0FMRX0nCiAgICAgIC0gJ0ZPUkNFX1NTTD0ke0ZPUkNFX1NTTDotZmFsc2V9JwogICAgICAtICdFTkFCTEVfQUNDT1VOVF9TSUdOVVA9JHtFTkFCTEVfQUNDT1VOVF9TSUdOVVA6LWZhbHNlfScKICAgICAgLSAnUkVESVNfVVJMPXJlZGlzOi8vZGVmYXVsdEByZWRpczo2Mzc5JwogICAgICAtIFJFRElTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1JFRElTCiAgICAgIC0gJ1JFRElTX09QRU5TU0xfVkVSSUZZX01PREU9JHtSRURJU19PUEVOU1NMX1ZFUklGWV9NT0RFOi1ub25lfScKICAgICAgLSAnUE9TVEdSRVNfREFUQUJBU0U9JHtQT1NUR1JFU19EQjotY2hhdHdvb3R9JwogICAgICAtICdQT1NUR1JFU19IT1NUPSR7UE9TVEdSRVNfSE9TVDotcG9zdGdyZXN9JwogICAgICAtIFBPU1RHUkVTX1VTRVJOQU1FPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtICdSQUlMU19NQVhfVEhSRUFEUz0ke1JBSUxTX01BWF9USFJFQURTOi01fScKICAgICAgLSAnTk9ERV9FTlY9JHtOT0RFX0VOVjotcHJvZHVjdGlvbn0nCiAgICAgIC0gJ1JBSUxTX0VOVj0ke1JBSUxTX0VOVjotcHJvZHVjdGlvbn0nCiAgICAgIC0gJ0lOU1RBTExBVElPTl9FTlY9JHtJTlNUQUxMQVRJT05fRU5WOi1kb2NrZXJ9JwogICAgICAtICdNQUlMRVJfU0VOREVSX0VNQUlMPSR7Q0hBVFdPT1RfTUFJTEVSX1NFTkRFUl9FTUFJTH0nCiAgICAgIC0gJ1NNVFBfQUREUkVTUz0ke0NIQVRXT09UX1NNVFBfQUREUkVTU30nCiAgICAgIC0gJ1NNVFBfQVVUSEVOVElDQVRJT049JHtDSEFUV09PVF9TTVRQX0FVVEhFTlRJQ0FUSU9OfScKICAgICAgLSAnU01UUF9ET01BSU49JHtDSEFUV09PVF9TTVRQX0RPTUFJTn0nCiAgICAgIC0gJ1NNVFBfRU5BQkxFX1NUQVJUVExTX0FVVE89JHtDSEFUV09PVF9TTVRQX0VOQUJMRV9TVEFSVFRMU19BVVRPfScKICAgICAgLSAnU01UUF9QT1JUPSR7Q0hBVFdPT1RfU01UUF9QT1JUfScKICAgICAgLSAnU01UUF9VU0VSTkFNRT0ke0NIQVRXT09UX1NNVFBfVVNFUk5BTUV9JwogICAgICAtICdTTVRQX1BBU1NXT1JEPSR7Q0hBVFdPT1RfU01UUF9QQVNTV09SRH0nCiAgICAgIC0gJ0FDVElWRV9TVE9SQUdFX1NFUlZJQ0U9JHtBQ1RJVkVfU1RPUkFHRV9TRVJWSUNFOi1sb2NhbH0nCiAgICBlbnRyeXBvaW50OiBkb2NrZXIvZW50cnlwb2ludHMvcmFpbHMuc2gKICAgIGNvbW1hbmQ6ICdzaCAtYyAiYnVuZGxlIGV4ZWMgcmFpbHMgZGI6Y2hhdHdvb3RfcHJlcGFyZSAmJiBidW5kbGUgZXhlYyByYWlscyBzIC1wIDMwMDAgLWIgMC4wLjAuMCInCiAgICB2b2x1bWVzOgogICAgICAtICdyYWlscy1kYXRhOi9hcHAvc3RvcmFnZScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSB3Z2V0CiAgICAgICAgLSAnLS1zcGlkZXInCiAgICAgICAgLSAnLXEnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTozMDAwJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgc2lkZWtpcToKICAgIGltYWdlOiAnY2hhdHdvb3QvY2hhdHdvb3Q6bGF0ZXN0JwogICAgZGVwZW5kc19vbjoKICAgICAgLSBwb3N0Z3JlcwogICAgICAtIHJlZGlzCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRUNSRVRfS0VZX0JBU0U9JFNFUlZJQ0VfUEFTU1dPUkRfQ0hBVFdPT1QKICAgICAgLSAnRlJPTlRFTkRfVVJMPSR7U0VSVklDRV9GUUROX0NIQVRXT09UfScKICAgICAgLSAnREVGQVVMVF9MT0NBTEU9JHtDSEFUV09PVF9ERUZBVUxUX0xPQ0FMRX0nCiAgICAgIC0gJ0ZPUkNFX1NTTD0ke0ZPUkNFX1NTTDotZmFsc2V9JwogICAgICAtICdFTkFCTEVfQUNDT1VOVF9TSUdOVVA9JHtFTkFCTEVfQUNDT1VOVF9TSUdOVVA6LWZhbHNlfScKICAgICAgLSAnUkVESVNfVVJMPXJlZGlzOi8vZGVmYXVsdEByZWRpczo2Mzc5JwogICAgICAtIFJFRElTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1JFRElTCiAgICAgIC0gJ1JFRElTX09QRU5TU0xfVkVSSUZZX01PREU9JHtSRURJU19PUEVOU1NMX1ZFUklGWV9NT0RFOi1ub25lfScKICAgICAgLSAnUE9TVEdSRVNfREFUQUJBU0U9JHtQT1NUR1JFU19EQjotY2hhdHdvb3R9JwogICAgICAtICdQT1NUR1JFU19IT1NUPSR7UE9TVEdSRVNfSE9TVDotcG9zdGdyZXN9JwogICAgICAtIFBPU1RHUkVTX1VTRVJOQU1FPSRTRVJWSUNFX1VTRVJfUE9TVEdSRVMKICAgICAgLSBQT1NUR1JFU19QQVNTV09SRD0kU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFUwogICAgICAtICdSQUlMU19NQVhfVEhSRUFEUz0ke1JBSUxTX01BWF9USFJFQURTOi01fScKICAgICAgLSAnTk9ERV9FTlY9JHtOT0RFX0VOVjotcHJvZHVjdGlvbn0nCiAgICAgIC0gJ1JBSUxTX0VOVj0ke1JBSUxTX0VOVjotcHJvZHVjdGlvbn0nCiAgICAgIC0gJ0lOU1RBTExBVElPTl9FTlY9JHtJTlNUQUxMQVRJT05fRU5WOi1kb2NrZXJ9JwogICAgICAtICdNQUlMRVJfU0VOREVSX0VNQUlMPSR7Q0hBVFdPT1RfTUFJTEVSX1NFTkRFUl9FTUFJTH0nCiAgICAgIC0gJ1NNVFBfQUREUkVTUz0ke0NIQVRXT09UX1NNVFBfQUREUkVTU30nCiAgICAgIC0gJ1NNVFBfQVVUSEVOVElDQVRJT049JHtDSEFUV09PVF9TTVRQX0FVVEhFTlRJQ0FUSU9OfScKICAgICAgLSAnU01UUF9ET01BSU49JHtDSEFUV09PVF9TTVRQX0RPTUFJTn0nCiAgICAgIC0gJ1NNVFBfRU5BQkxFX1NUQVJUVExTX0FVVE89JHtDSEFUV09PVF9TTVRQX0VOQUJMRV9TVEFSVFRMU19BVVRPfScKICAgICAgLSAnU01UUF9QT1JUPSR7Q0hBVFdPT1RfU01UUF9QT1JUfScKICAgICAgLSAnU01UUF9VU0VSTkFNRT0ke0NIQVRXT09UX1NNVFBfVVNFUk5BTUV9JwogICAgICAtICdTTVRQX1BBU1NXT1JEPSR7Q0hBVFdPT1RfU01UUF9QQVNTV09SRH0nCiAgICAgIC0gJ0FDVElWRV9TVE9SQUdFX1NFUlZJQ0U9JHtBQ1RJVkVfU1RPUkFHRV9TRVJWSUNFOi1sb2NhbH0nCiAgICBjb21tYW5kOgogICAgICAtIGJ1bmRsZQogICAgICAtIGV4ZWMKICAgICAgLSBzaWRla2lxCiAgICAgIC0gJy1DJwogICAgICAtIGNvbmZpZy9zaWRla2lxLnltbAogICAgdm9sdW1lczoKICAgICAgLSAncmFpbHMtZGF0YTovYXBwL3N0b3JhZ2UnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gImJ1bmRsZSBleGVjIHJhaWxzIHJ1bm5lciAncHV0cyBTaWRla2lxLnJlZGlzKCY6aW5mbyknID4gL2Rldi9udWxsIDI+JjEiCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDMKICBwb3N0Z3JlczoKICAgIGltYWdlOiAncGd2ZWN0b3IvcGd2ZWN0b3I6cGcxMicKICAgIHJlc3RhcnQ6IGFsd2F5cwogICAgdm9sdW1lczoKICAgICAgLSAncG9zdGdyZXMtZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfREI9JHtQT1NUR1JFU19EQjotY2hhdHdvb3R9JwogICAgICAtIFBPU1RHUkVTX1VTRVI9JFNFUlZJQ0VfVVNFUl9QT1NUR1JFUwogICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLVUgJFNFUlZJQ0VfVVNFUl9QT1NUR1JFUyAtZCBjaGF0d29vdCAtaCAxMjcuMC4wLjEnCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDUKICByZWRpczoKICAgIGltYWdlOiAncmVkaXM6YWxwaW5lJwogICAgcmVzdGFydDogYWx3YXlzCiAgICBjb21tYW5kOgogICAgICAtIHNoCiAgICAgIC0gJy1jJwogICAgICAtICdyZWRpcy1zZXJ2ZXIgLS1yZXF1aXJlcGFzcyAiJFNFUlZJQ0VfUEFTU1dPUkRfUkVESVMiJwogICAgdm9sdW1lczoKICAgICAgLSAncmVkaXMtZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtICctYScKICAgICAgICAtICRTRVJWSUNFX1BBU1NXT1JEX1JFRElTCiAgICAgICAgLSBQSU5HCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDUK", "tags": [ "chatwoot", "chat", @@ -625,7 +625,7 @@ "diun": { "documentation": "https://crazymax.dev/diun/?utm_source=coolify.io", "slogan": "Docker Image Update Notifier is a CLI application to receive notifications when a Docker image is updated on a Docker registry.", - "compose": "c2VydmljZXM6CiAgZGl1bjoKICAgIGltYWdlOiAnY3JhenltYXgvZGl1bjpsYXRlc3QnCiAgICBjb21tYW5kOiBzZXJ2ZQogICAgdm9sdW1lczoKICAgICAgLSAnZGl1bl9kYXRhOi9kYXRhJwogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgIGVudmlyb25tZW50OgogICAgICAtICdUWj0ke1RJTUVfWk9ORTotRXVyb3BlL1ZpZW5uYX0nCiAgICAgIC0gJ0xPR19MRVZFTD0ke0xPR19MRVZFTDotaW5mb30nCiAgICAgIC0gJ0xPR19KU09OPSR7TE9HX0pTT046LWZhbHNlfScKICAgICAgLSAnRElVTl9XQVRDSF9XT1JLRVJTPSR7RElVTl9XQVRDSF9XT1JLRVJTOi0yMH0nCiAgICAgIC0gJ0RJVU5fV0FUQ0hfU0NIRURVTEU9JHtDUk9OX1dBVENIX1NDSEVEVUxFOi0gKiAqLzYgKiAqICp9JwogICAgICAtICdESVVOX1dBVENIX0pJVFRFUj0ke0RJVU5fV0FUQ0hfSklUVEVSOi0zMHN9JwogICAgICAtICdESVVOX1BST1ZJREVSU19ET0NLRVI9JHtESVVOX1BST1ZJREVSU19ET0NLRVI6LXRydWV9JwogICAgICAtICdESVVOX1BST1ZJREVSU19ET0NLRVJfV0FUQ0hCWURFRkFVTFQ9JHtESVVOX1BST1ZJREVSU19ET0NLRVJfV0FUQ0hCWURFRkFVTFQ6LXRydWV9JwogICAgICAtICdESVVOX05PVElGX1NMQUNLX1dFQkhPT0tVUkw9JHtTRVJWSUNFX1dFQkhPT0tfVVJMX1NMQUNLfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBkaXVuCiAgICAgICAgLSAnLS12ZXJzaW9uJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDMK", + "compose": "c2VydmljZXM6CiAgZGl1bjoKICAgIGltYWdlOiAnY3JhenltYXgvZGl1bjpsYXRlc3QnCiAgICBjb21tYW5kOiBzZXJ2ZQogICAgdm9sdW1lczoKICAgICAgLSAnZGl1bl9kYXRhOi9kYXRhJwogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgIGVudmlyb25tZW50OgogICAgICAtICdUWj0ke1RJTUVfWk9ORTotRXVyb3BlL1ZpZW5uYX0nCiAgICAgIC0gJ0xPR19MRVZFTD0ke0xPR19MRVZFTDotaW5mb30nCiAgICAgIC0gJ0xPR19KU09OPSR7TE9HX0pTT046LWZhbHNlfScKICAgICAgLSAnRElVTl9XQVRDSF9XT1JLRVJTPSR7RElVTl9XQVRDSF9XT1JLRVJTOi0yMH0nCiAgICAgIC0gJ0RJVU5fV0FUQ0hfU0NIRURVTEU9JHtESVVOX1dBVENIX1NDSEVEVUxFOi0gKiAqLzYgKiAqICp9JwogICAgICAtICdESVVOX1dBVENIX0pJVFRFUj0ke0RJVU5fV0FUQ0hfSklUVEVSOi0zMHN9JwogICAgICAtICdESVVOX1BST1ZJREVSU19ET0NLRVI9JHtESVVOX1BST1ZJREVSU19ET0NLRVI6LXRydWV9JwogICAgICAtICdESVVOX1BST1ZJREVSU19ET0NLRVJfV0FUQ0hCWURFRkFVTFQ9JHtESVVOX1BST1ZJREVSU19ET0NLRVJfV0FUQ0hCWURFRkFVTFQ6LXRydWV9JwogICAgICAtICdESVVOX05PVElGX1NMQUNLX1dFQkhPT0tVUkw9JHtTRVJWSUNFX1dFQkhPT0tfVVJMX1NMQUNLfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBkaXVuCiAgICAgICAgLSAnLS12ZXJzaW9uJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDMK", "tags": [ "docker", "notifier", @@ -1984,7 +1984,7 @@ "memos": { "documentation": "https://github.com/usememos/memos?utm_source=coolify.io", "slogan": "An open-source, lightweight note-taking solution. The pain-less way to create your meaningful notes. Your Notes, Your Way.", - "compose": "c2VydmljZXM6CiAgd2ctZWFzeToKICAgIGltYWdlOiAnbmVvc21lbW8vbWVtb3M6c3RhYmxlJwogICAgdm9sdW1lczoKICAgICAgLSAnbWVtb3MvOi92YXIvb3B0L21lbW9zJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX01FTU9TXzUyMzAK", + "compose": "c2VydmljZXM6CiAgbWVtb3M6CiAgICBpbWFnZTogJ25lb3NtZW1vL21lbW9zOnN0YWJsZScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ21lbW9zLzovdmFyL29wdC9tZW1vcycKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9NRU1PU181MjMwCg==", "tags": [ "note-taking", "microblog", @@ -2535,7 +2535,7 @@ "paymenter": { "documentation": "https://paymenter.org/docs/guides/docker?utm_source=coolify.io", "slogan": "Open-Source Billing, Built for Hosting", - "compose": "c2VydmljZXM6CiAgcGF5bWVudGVyOgogICAgaW1hZ2U6ICdnaGNyLmlvL3BheW1lbnRlci9wYXltZW50ZXI6bGF0ZXN0JwogICAgdm9sdW1lczoKICAgICAgLSAnYXBwX2xvZ3M6L2FwcC9zdG9yYWdlL2xvZ3MnCiAgICAgIC0gJ2FwcF9wdWJsaWM6L2FwcC9zdG9yYWdlL3B1YmxpYycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnY3VybCAtc2YgaHR0cDovL2xvY2FsaG9zdDo4MCB8fCBleGl0IDEnCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogMXMKICAgICAgcmV0cmllczogMwogICAgZW52aXJvbm1lbnQ6CiAgICAgIFNFUlZJQ0VfRlFETl9QQVlNRU5URVI6ICcke1NFUlZJQ0VfRlFETl9QQVlNRU5URVJfODB9JwogICAgICBEQl9EQVRBQkFTRTogJyR7TVlTUUxfREFUQUJBU0U6LXBheW1lbnRlci1kYn0nCiAgICAgIERCX1BBU1NXT1JEOiAnJHtTRVJWSUNFX1BBU1NXT1JEX01ZU1FMfScKICAgICAgREJfVVNFUk5BTUU6ICcke1NFUlZJQ0VfVVNFUl9NWVNRTH0nCiAgICAgIEFQUF9FTlY6IHByb2R1Y3Rpb24KICAgICAgQ0FDSEVfU1RPUkU6IHJlZGlzCiAgICAgIFNFU1NJT05fRFJJVkVSOiByZWRpcwogICAgICBRVUVVRV9DT05ORUNUSU9OOiByZWRpcwogICAgICBSRURJU19IT1NUOiByZWRpcwogICAgICBSRURJU19VU0VSTkFNRTogZGVmYXVsdAogICAgICBSRURJU19QQVNTV09SRDogJyR7U0VSVklDRV9QQVNTV09SRF82NF9SRURJU30nCiAgICAgIERCX0NPTk5FQ1RJT046IG1hcmlhZGIKICAgICAgREJfSE9TVDogbWFyaWFkYgogICAgICBEQl9QT1JUOiAnMzMwNicKICAgICAgQVBQX0tFWTogJyR7U0VSVklDRV9CQVNFNjRfS0VZfScKICBtYXJpYWRiOgogICAgaW1hZ2U6ICdtYXJpYWRiOjExJwogICAgdm9sdW1lczoKICAgICAgLSAncGF5bWVudGVyX21hcmlhZGJfZGF0YTovdmFyL2xpYi9teXNxbCcKICAgIGVudmlyb25tZW50OgogICAgICAtICdNWVNRTF9ST09UX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NWVNRTFJPT1R9JwogICAgICAtICdNWVNRTF9EQVRBQkFTRT0ke01ZU1FMX0RBVEFCQVNFOi1wYXltZW50ZXItZGJ9JwogICAgICAtICdNWVNRTF9VU0VSPSR7U0VSVklDRV9VU0VSX01ZU1FMfScKICAgICAgLSAnTVlTUUxfUEFTU1dPUkQ9JHtTRVJWSUNFX1BBU1NXT1JEX01ZU1FMfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBoZWFsdGhjaGVjay5zaAogICAgICAgIC0gJy0tY29ubmVjdCcKICAgICAgICAtICctLWlubm9kYl9pbml0aWFsaXplZCcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAogIHJlZGlzOgogICAgaW1hZ2U6ICdyZWRpczphbHBpbmUnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3JlZGlzLWNsaSBwaW5nIHx8IGV4aXQgMScKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiAxcwogICAgICByZXRyaWVzOiAzCg==", + "compose": "c2VydmljZXM6CiAgcGF5bWVudGVyOgogICAgaW1hZ2U6ICdnaGNyLmlvL3BheW1lbnRlci9wYXltZW50ZXI6bGF0ZXN0JwogICAgdm9sdW1lczoKICAgICAgLSAnYXBwX2xvZ3M6L2FwcC9zdG9yYWdlL2xvZ3MnCiAgICAgIC0gJ2FwcF9wdWJsaWM6L2FwcC9zdG9yYWdlL3B1YmxpYycKICAgIGVudmlyb25tZW50OgogICAgICBTRVJWSUNFX0ZRRE5fUEFZTUVOVEVSOiAnJHtTRVJWSUNFX0ZRRE5fUEFZTUVOVEVSXzgwfScKICAgICAgREJfREFUQUJBU0U6ICcke01ZU1FMX0RBVEFCQVNFOi1wYXltZW50ZXItZGJ9JwogICAgICBEQl9QQVNTV09SRDogJyR7U0VSVklDRV9QQVNTV09SRF9NWVNRTH0nCiAgICAgIERCX1VTRVJOQU1FOiAnJHtTRVJWSUNFX1VTRVJfTVlTUUx9JwogICAgICBBUFBfRU5WOiBwcm9kdWN0aW9uCiAgICAgIENBQ0hFX1NUT1JFOiByZWRpcwogICAgICBTRVNTSU9OX0RSSVZFUjogcmVkaXMKICAgICAgUVVFVUVfQ09OTkVDVElPTjogcmVkaXMKICAgICAgUkVESVNfSE9TVDogcmVkaXMKICAgICAgUkVESVNfVVNFUk5BTUU6IGRlZmF1bHQKICAgICAgUkVESVNfUEFTU1dPUkQ6ICcke1NFUlZJQ0VfUEFTU1dPUkRfNjRfUkVESVN9JwogICAgICBEQl9DT05ORUNUSU9OOiBtYXJpYWRiCiAgICAgIERCX0hPU1Q6IG1hcmlhZGIKICAgICAgREJfUE9SVDogMzMwNgogICAgICBBUFBfS0VZOiAnJHtTRVJWSUNFX0JBU0U2NF9LRVl9JwogICAgZGVwZW5kc19vbjoKICAgICAgbWFyaWFkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICByZWRpczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2Vfc3RhcnRlZAogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdjdXJsIC1zZiBodHRwOi8vbG9jYWxob3N0OjgwIHx8IGV4aXQgMScKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiAxcwogICAgICByZXRyaWVzOiAzCiAgbWFyaWFkYjoKICAgIGltYWdlOiAnbWFyaWFkYjoxMScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3BheW1lbnRlcl9tYXJpYWRiX2RhdGE6L3Zhci9saWIvbXlzcWwnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnTVlTUUxfUk9PVF9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfTVlTUUxST09UfScKICAgICAgLSAnTVlTUUxfREFUQUJBU0U9JHtNWVNRTF9EQVRBQkFTRTotcGF5bWVudGVyLWRifScKICAgICAgLSAnTVlTUUxfVVNFUj0ke1NFUlZJQ0VfVVNFUl9NWVNRTH0nCiAgICAgIC0gJ01ZU1FMX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9NWVNRTH0nCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gaGVhbHRoY2hlY2suc2gKICAgICAgICAtICctLWNvbm5lY3QnCiAgICAgICAgLSAnLS1pbm5vZGJfaW5pdGlhbGl6ZWQnCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiAyMHMKICAgICAgcmV0cmllczogMTAKICByZWRpczoKICAgIGltYWdlOiAncmVkaXM6YWxwaW5lJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdyZWRpcy1jbGkgcGluZyB8fCBleGl0IDEnCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogMXMKICAgICAgcmV0cmllczogMwo=", "tags": [ "automation", "billing", @@ -2561,6 +2561,19 @@ "minversion": "0.0.0", "port": "8080" }, + "pgbackweb": { + "documentation": "https://github.com/eduardolat/pgbackweb?utm_source=coolify.io", + "slogan": "Effortless PostgreSQL backups with a user-friendly web interface!", + "compose": "c2VydmljZXM6CiAgcGdiYWNrd2ViOgogICAgaW1hZ2U6ICdlZHVhcmRvbGF0L3BnYmFja3dlYjpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtICdwZ2JhY2t3ZWJfYmFja3VwczovYmFja3VwcycKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9QR0JBQ0tXRUJfODA4NQogICAgICAtICdQQldfRU5DUllQVElPTl9LRVk9JHtTRVJWSUNFX1BBU1NXT1JEXzY0X1BHQkFDS1dFQn0nCiAgICAgIC0gJ1BCV19QT1NUR1JFU19DT05OX1NUUklORz1wb3N0Z3Jlc3FsOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AcG9zdGdyZXM6NTQzMi8ke1BPU1RHUkVTX0RCOi1wZ2JhY2t3ZWItZGJ9P3NzbG1vZGU9ZGlzYWJsZScKICAgICAgLSAnVFo9JHtUSU1FX1pPTkU6LVVUQ30nCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3JlczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgZXhjbHVkZV9mcm9tX2hjOiB0cnVlCiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE3JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1wZ2JhY2t3ZWItZGJ9JwogICAgdm9sdW1lczoKICAgICAgLSAncGdiYWNrd2ViX3Bvc3RncmVzX2RhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfSAtZCBwZ2JhY2t3ZWInCiAgICAgIGludGVydmFsOiA1cwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1Cg==", + "tags": [ + "backup", + "postgresql", + "web-interface" + ], + "logo": "svgs/pgbackweb.svg", + "minversion": "0.0.0", + "port": "8085" + }, "phpmyadmin": { "documentation": "https://phpmyadmin.net?utm_source=coolify.io", "slogan": "phpMyAdmin is a web-based database management tool for administering your MySQL and MariaDB databases through a user-friendly interface.", @@ -2931,7 +2944,7 @@ "snapdrop": { "documentation": "https://github.com/RobinLinus/snapdrop?utm_source=coolify.io", "slogan": "A self-hosted file-sharing service for secure and convenient file transfers, whether on a local network or the internet.", - "compose": "c2VydmljZXM6CiAgc25hcGRyb3A6CiAgICBpbWFnZTogJ2xzY3IuaW8vbGludXhzZXJ2ZXIvc25hcGRyb3A6bGF0ZXN0JwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX1NOQVBEUk9QCiAgICAgIC0gUFVJRD0xMDAwCiAgICAgIC0gUEdJRD0xMDAwCiAgICAgIC0gVFo9RXVyb3BlL01hZHJpZAogICAgdm9sdW1lczoKICAgICAgLSAnc25hcGRyb3AtY29uZmlnOi9jb25maWcnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRAogICAgICAgIC0gY3VybAogICAgICAgIC0gJy1mJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6ODAnCiAgICAgIGludGVydmFsOiAycwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMTUK", + "compose": "c2VydmljZXM6CiAgc25hcGRyb3A6CiAgICBpbWFnZTogJ2xpbnV4c2VydmVyL3NuYXBkcm9wOnZlcnNpb24tYjhiNzhjYzInCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fU05BUERST1AKICAgICAgLSBQVUlEPTEwMDAKICAgICAgLSBQR0lEPTEwMDAKICAgICAgLSBUWj1FdXJvcGUvTWFkcmlkCiAgICB2b2x1bWVzOgogICAgICAtICdzbmFwZHJvcC1jb25maWc6L2NvbmZpZycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovLzEyNy4wLjAuMTo4MCcKICAgICAgaW50ZXJ2YWw6IDJzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAxNQo=", "tags": [ "file", "sharing", @@ -3183,7 +3196,7 @@ "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.", - "compose": "c2VydmljZXM6CiAgdHlwZXNlbnNlOgogICAgaW1hZ2U6ICd0eXBlc2Vuc2UvdHlwZXNlbnNlOjI4LjAnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fVFlQRVNFTlNFXzgxMDgKICAgICAgLSAnVFlQRVNFTlNFX0VOQUJMRV9DT1JTPSR7VFlQRVNFTlNFX0VOQUJMRV9DT1JTOi10cnVlfScKICAgICAgLSBUWVBFU0VOU0VfREFUQV9ESVI9L2RhdGEKICAgICAgLSAnVFlQRVNFTlNFX0FQSV9LRVk9JHtUWVBFU0VOU0VfQVBJX0tFWToteHl6fScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3R5cGVzZW5zZV9kYXRhOi9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGJhc2gKICAgICAgICAtICctYycKICAgICAgICAtICdleGVjIDM8Pi9kZXYvdGNwL2xvY2FsaG9zdC84MTA4ICYmIHByaW50ZiAnJ0dFVCAvaGVhbHRoIEhUVFAvMS4xXHJcbkNvbm5lY3Rpb246IGNsb3NlXHJcblxyXG4nJyA+JjMgJiYgaGVhZCAtbjEgPCYzIHwgZ3JlcCAnJzIwMCcnICYmIGV4ZWMgMz4mLScKICAgICAgcmV0cmllczogNQogICAgICB0aW1lb3V0OiA3cwo=", + "compose": "c2VydmljZXM6CiAgdHlwZXNlbnNlOgogICAgaW1hZ2U6ICd0eXBlc2Vuc2UvdHlwZXNlbnNlOjI4LjAnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSBTRVJWSUNFX0ZRRE5fVFlQRVNFTlNFXzgxMDgKICAgICAgLSAnVFlQRVNFTlNFX0VOQUJMRV9DT1JTPSR7VFlQRVNFTlNFX0VOQUJMRV9DT1JTOi10cnVlfScKICAgICAgLSBUWVBFU0VOU0VfREFUQV9ESVI9L2RhdGEKICAgICAgLSAnVFlQRVNFTlNFX0FQSV9LRVk9JHtUWVBFU0VOU0VfQVBJX0tFWX0nCiAgICB2b2x1bWVzOgogICAgICAtICd0eXBlc2Vuc2VfZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBiYXNoCiAgICAgICAgLSAnLWMnCiAgICAgICAgLSAnZXhlYyAzPD4vZGV2L3RjcC9sb2NhbGhvc3QvODEwOCAmJiBwcmludGYgJydHRVQgL2hlYWx0aCBIVFRQLzEuMVxyXG5Db25uZWN0aW9uOiBjbG9zZVxyXG5cclxuJycgPiYzICYmIGhlYWQgLW4xIDwmMyB8IGdyZXAgJycyMDAnJyAmJiBleGVjIDM+Ji0nCiAgICAgIHJldHJpZXM6IDUKICAgICAgdGltZW91dDogN3MK", "tags": [ "search", "search-engine", @@ -3565,6 +3578,48 @@ "logo": "svgs/wordpress.svg", "minversion": "0.0.0" }, + "yamtrack-with-postgresql": { + "documentation": "https://github.com/FuzzyGrim/Yamtrack/wiki?utm_source=coolify.io", + "slogan": "Yamtrack is a self hosted media tracker for movies, tv shows, anime, manga, video games and books.", + "compose": "c2VydmljZXM6CiAgeWFtdHJhY2s6CiAgICBpbWFnZTogZ2hjci5pby9mdXp6eWdyaW0veWFtdHJhY2sKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9ZQU1UUkFDS184MDAwCiAgICAgIC0gJ1VSTFM9JHtTRVJWSUNFX0ZRRE5fWUFNVFJBQ0t9JwogICAgICAtICdUWj0ke1RaOi1FdXJvcGUvQmVybGlufScKICAgICAgLSAnU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9TRUNSRVR9JwogICAgICAtICdSRUdJU1RSQVRJT049JHtSRUdJU1RSQVRJT05fRU5BQkxFRDotdHJ1ZX0nCiAgICAgIC0gJ1JFRElTX1VSTD1yZWRpczovL3JlZGlzOjYzNzknCiAgICAgIC0gREJfSE9TVD1wb3N0Z3JlcwogICAgICAtICdEQl9OQU1FPSR7UE9TVEdSRVNRTF9EQVRBQkFTRToteWFtdHJhY2stZGJ9JwogICAgICAtICdEQl9VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTUUx9JwogICAgICAtICdEQl9QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNRTH0nCiAgICAgIC0gREJfUE9SVD01NDMyCiAgICBkZXBlbmRzX29uOgogICAgICBwb3N0Z3JlczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgICByZWRpczoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIHdnZXQKICAgICAgICAtICctLW5vLXZlcmJvc2UnCiAgICAgICAgLSAnLS10cmllcz0xJwogICAgICAgIC0gJy0tc3BpZGVyJwogICAgICAgIC0gJ2h0dHA6Ly8xMjcuMC4wLjE6ODAwMC9oZWFsdGgvJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcG9zdGdyZXM6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2LWFscGluZScKICAgIGVudmlyb25tZW50OgogICAgICAtICdQT1NUR1JFU19VU0VSPSR7U0VSVklDRV9VU0VSX1BPU1RHUkVTUUx9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNRTH0nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNRTF9EQVRBQkFTRToteWFtdHJhY2stZGJ9JwogICAgdm9sdW1lczoKICAgICAgLSAneWFtdHJhY2tfcG9zdGdyZXNfZGF0YTovdmFyL2xpYi9wb3N0Z3Jlc3FsL2RhdGEnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3BnX2lzcmVhZHkgLVUgJCR7UE9TVEdSRVNfVVNFUn0gLWQgJCR7UE9TVEdSRVNfREJ9JwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOjctYWxwaW5lJwogICAgdm9sdW1lczoKICAgICAgLSAneWFtdHJhY2tfcmVkaXNfZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAo=", + "tags": [ + "self-hosted", + "automation", + "tracker", + "media", + "movies", + "shows", + "anime", + "manga", + "games", + "books", + "comics" + ], + "logo": "svgs/yamtrack.svg", + "minversion": "0.0.0", + "port": "8000" + }, + "yamtrack": { + "documentation": "https://github.com/FuzzyGrim/Yamtrack/wiki?utm_source=coolify.io", + "slogan": "Yamtrack is a self hosted media tracker for movies, tv shows, anime, manga, video games and books.", + "compose": "c2VydmljZXM6CiAgeWFtdHJhY2s6CiAgICBpbWFnZTogZ2hjci5pby9mdXp6eWdyaW0veWFtdHJhY2sKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9ZQU1UUkFDS184MDAwCiAgICAgIC0gJ1VSTFM9JHtTRVJWSUNFX0ZRRE5fWUFNVFJBQ0t9JwogICAgICAtICdUWj0ke1RaOi1FdXJvcGUvQmVybGlufScKICAgICAgLSAnU0VDUkVUPSR7U0VSVklDRV9QQVNTV09SRF9TRUNSRVR9JwogICAgICAtICdSRUdJU1RSQVRJT049JHtSRUdJU1RSQVRJT05fRU5BQkxFRDotdHJ1ZX0nCiAgICAgIC0gJ1JFRElTX1VSTD1yZWRpczovL3JlZGlzOjYzNzknCiAgICB2b2x1bWVzOgogICAgICAtICd5YW10cmFja19kYXRhOi95YW10cmFjay9kYicKICAgIGRlcGVuZHNfb246CiAgICAgIHJlZGlzOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ3dnZXQgLS1xdWlldCAtLXRyaWVzPTEgLS1zcGlkZXIgaHR0cDovLzEyNy4wLjAuMTo4MDAwL2hlYWx0aC8gfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogNXMKICAgICAgdGltZW91dDogMjBzCiAgICAgIHJldHJpZXM6IDEwCiAgcmVkaXM6CiAgICBpbWFnZTogJ3JlZGlzOjctYWxwaW5lJwogICAgdm9sdW1lczoKICAgICAgLSAneWFtdHJhY2tfcmVkaXNfZGF0YTovZGF0YScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSByZWRpcy1jbGkKICAgICAgICAtIHBpbmcKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAo=", + "tags": [ + "self-hosted", + "automation", + "tracker", + "media", + "movies", + "shows", + "anime", + "manga", + "games", + "books", + "comics" + ], + "logo": "svgs/yamtrack.svg", + "minversion": "0.0.0", + "port": "8000" + }, "zipline": { "documentation": "https://github.com/diced/zipline?utm_source=coolify.io", "slogan": "A ShareX/file upload server that is easy to use, packed with features, and with an easy setup!", From 2ef71d91147dafe9a03d2eacb9ca938612f99386 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 19 May 2025 22:47:33 +0200 Subject: [PATCH 25/53] fix(css): 8+ issue with new tailwind v4 --- resources/css/utilities.css | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/resources/css/utilities.css b/resources/css/utilities.css index 0735e35e2..edfe98c76 100644 --- a/resources/css/utilities.css +++ b/resources/css/utilities.css @@ -11,7 +11,7 @@ } @utility input-sticky { - @apply block py-1.5 w-full text-sm text-black rounded-sm border-0 ring-1 ring-inset dark:bg-coolgray-100 dark:text-white ring-neutral-200 dark:ring-coolgray-300 focus:ring-2 dark:focus:ring-coolgray-300 focus:ring-neutral-400; + @apply block py-1.5 w-full text-sm text-black rounded-sm border-0 ring-1 ring-inset dark:bg-coolgray-100 dark:text-white ring-neutral-200 dark:ring-coolgray-300 focus:ring-2 focus:ring-neutral-400 dark:focus:ring-coolgray-300; } @utility input-sticky-active { @@ -20,12 +20,12 @@ /* Focus */ @utility input-focus { - @apply focus:ring-2 dark:focus:ring-coolgray-300 focus:ring-neutral-400; + @apply focus:ring-2 focus:ring-neutral-400 dark:focus:ring-coolgray-300; } /* input, select before */ @utility input-select { - @apply block py-1.5 w-full text-sm text-black rounded-sm border-0 ring-1 ring-inset dark:bg-coolgray-100 dark:text-white ring-neutral-200 dark:ring-coolgray-300 dark:disabled:bg-coolgray-100/40 dark:disabled:ring-transparent disabled:bg-neutral-200 disabled:text-neutral-500; + @apply block py-1.5 w-full text-sm text-black rounded-sm border-0 ring-1 ring-inset dark:bg-coolgray-100 dark:text-white ring-neutral-200 dark:ring-coolgray-300 disabled:bg-neutral-200 disabled:text-neutral-500 dark:disabled:bg-coolgray-100/40 dark:disabled:ring-transparent; } /* Readonly */ @@ -62,11 +62,11 @@ } @utility dropdown-item { - @apply flex relative gap-2 justify-start items-center py-1 pr-4 pl-2 w-full text-xs transition-colors cursor-pointer select-none dark:text-white hover:bg-neutral-100 dark:hover:bg-coollabs outline-hidden data-disabled:pointer-events-none data-disabled:opacity-50; + @apply flex relative gap-2 justify-start items-center py-1 pr-4 pl-2 w-full text-xs transition-colors cursor-pointer select-none dark:text-white hover:bg-neutral-100 dark:hover:bg-coollabs outline-none data-disabled:pointer-events-none data-disabled:opacity-50; } @utility dropdown-item-no-padding { - @apply flex relative gap-2 justify-start items-center py-1 w-full text-xs transition-colors cursor-pointer select-none dark:text-white hover:bg-neutral-100 dark:hover:bg-coollabs outline-hidden data-disabled:pointer-events-none data-disabled:opacity-50; + @apply flex relative gap-2 justify-start items-center py-1 w-full text-xs transition-colors cursor-pointer select-none dark:text-white hover:bg-neutral-100 dark:hover:bg-coollabs outline-none data-disabled:pointer-events-none data-disabled:opacity-50; } @utility badge { @@ -110,7 +110,7 @@ } @utility scrollbar { - @apply scrollbar-thumb-coollabs-100 dark:scrollbar-track-coolgray-200 scrollbar-track-neutral-200 scrollbar-thin; + @apply scrollbar-thumb-coollabs-100 scrollbar-track-neutral-200 dark:scrollbar-track-coolgray-200 scrollbar-thin; } @utility main { @@ -166,7 +166,7 @@ } @utility bg-coollabs-gradient { - @apply text-transparent text-white from-purple-500 via-pink-500 to-red-500 bg-linear-to-r; + @apply bg-gradient-to-r from-purple-500 via-pink-500 to-red-500 bg-clip-text text-transparent; } @utility text-helper { @@ -198,7 +198,7 @@ } @utility toast { - @apply z-1; + @apply z-[1]; } @utility dz-button { From 9331ccaf3eafc3c53b6ab6ab59a14bac0b6c1173 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 19 May 2025 23:01:28 +0200 Subject: [PATCH 26/53] fix(css): `bg-coollabs-gradient` not working anymore --- resources/css/utilities.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/css/utilities.css b/resources/css/utilities.css index edfe98c76..4993b2302 100644 --- a/resources/css/utilities.css +++ b/resources/css/utilities.css @@ -166,7 +166,7 @@ } @utility bg-coollabs-gradient { - @apply bg-gradient-to-r from-purple-500 via-pink-500 to-red-500 bg-clip-text text-transparent; + @apply from-purple-500 via-pink-500 to-red-500 bg-linear-to-r; } @utility text-helper { From 79e620eac5ec9b7ca2684490946b64e08cdb7b09 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 19 May 2025 23:35:17 +0200 Subject: [PATCH 27/53] fix(ui): add back missing service navbar components --- app/Livewire/Project/Service/Navbar.php | 154 +++++++++++++++ .../livewire/project/service/navbar.blade.php | 182 ++++++++++++++++++ 2 files changed, 336 insertions(+) create mode 100644 app/Livewire/Project/Service/Navbar.php create mode 100644 resources/views/livewire/project/service/navbar.blade.php diff --git a/app/Livewire/Project/Service/Navbar.php b/app/Livewire/Project/Service/Navbar.php new file mode 100644 index 000000000..5da425cbd --- /dev/null +++ b/app/Livewire/Project/Service/Navbar.php @@ -0,0 +1,154 @@ +service->status)->contains('running') && is_null($this->service->config_hash)) { + $this->service->isConfigurationChanged(true); + $this->dispatch('configurationChanged'); + } + } + + public function getListeners() + { + $userId = Auth::id(); + + return [ + "echo-private:user.{$userId},ServiceStatusChanged" => 'serviceStarted', + 'envsUpdated' => '$refresh', + 'refreshStatus' => '$refresh', + ]; + } + + public function serviceStarted() + { + // $this->dispatch('success', 'Service status changed.'); + if (is_null($this->service->config_hash) || $this->service->isConfigurationChanged()) { + $this->service->isConfigurationChanged(true); + $this->dispatch('configurationChanged'); + } else { + $this->dispatch('configurationChanged'); + } + } + + public function check_status_without_notification() + { + $this->dispatch('check_status'); + } + + public function check_status() + { + $this->dispatch('check_status'); + $this->dispatch('success', 'Service status updated.'); + } + + public function checkDeployments() + { + try { + $activity = Activity::where('properties->type_uuid', $this->service->uuid)->latest()->first(); + $status = data_get($activity, 'properties.status'); + if ($status === ProcessStatus::QUEUED->value || $status === ProcessStatus::IN_PROGRESS->value) { + $this->isDeploymentProgress = true; + } else { + $this->isDeploymentProgress = false; + } + } catch (\Throwable) { + $this->isDeploymentProgress = false; + } + + return $this->isDeploymentProgress; + } + + public function start() + { + $activity = StartService::run($this->service, pullLatestImages: true); + $this->dispatch('activityMonitor', $activity->id); + } + + public function forceDeploy() + { + try { + $activities = Activity::where('properties->type_uuid', $this->service->uuid)->where('properties->status', ProcessStatus::IN_PROGRESS->value)->orWhere('properties->status', ProcessStatus::QUEUED->value)->get(); + foreach ($activities as $activity) { + $activity->properties->status = ProcessStatus::ERROR->value; + $activity->save(); + } + $activity = StartService::run($this->service, pullLatestImages: true, stopBeforeStart: true); + $this->dispatch('activityMonitor', $activity->id); + } catch (\Exception $e) { + $this->dispatch('error', $e->getMessage()); + } + } + + public function stop($cleanupContainers = false) + { + try { + StopService::run($this->service, false, $this->docker_cleanup); + ServiceStatusChanged::dispatch(); + if ($cleanupContainers) { + $this->dispatch('success', 'Containers cleaned up.'); + } else { + $this->dispatch('success', 'Service stopped.'); + } + } catch (\Exception $e) { + $this->dispatch('error', $e->getMessage()); + } + } + + public function restart() + { + $this->checkDeployments(); + if ($this->isDeploymentProgress) { + $this->dispatch('error', 'There is a deployment in progress.'); + + return; + } + $activity = StartService::run($this->service, stopBeforeStart: true); + $this->dispatch('activityMonitor', $activity->id); + } + + public function pullAndRestartEvent() + { + $this->checkDeployments(); + if ($this->isDeploymentProgress) { + $this->dispatch('error', 'There is a deployment in progress.'); + + return; + } + $activity = StartService::run($this->service, pullLatestImages: true, stopBeforeStart: true); + $this->dispatch('activityMonitor', $activity->id); + } + + public function render() + { + return view('livewire.project.service.navbar', [ + 'checkboxes' => [ + ['id' => 'docker_cleanup', 'label' => __('resource.docker_cleanup')], + ], + ]); + } +} diff --git a/resources/views/livewire/project/service/navbar.blade.php b/resources/views/livewire/project/service/navbar.blade.php new file mode 100644 index 000000000..dd2ce4142 --- /dev/null +++ b/resources/views/livewire/project/service/navbar.blade.php @@ -0,0 +1,182 @@ +
+ + + Service Startup + + + + +

{{ $title }}

+ +
+ @script + + @endscript +
From 9651195318ffbfefebb4a07dfdaf53b1a19dd0ad Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 20 May 2025 11:07:55 +0200 Subject: [PATCH 28/53] Update app/Livewire/Server/Security/Patches.php Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- app/Livewire/Server/Security/Patches.php | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/Livewire/Server/Security/Patches.php b/app/Livewire/Server/Security/Patches.php index 183055813..9392fc351 100644 --- a/app/Livewire/Server/Security/Patches.php +++ b/app/Livewire/Server/Security/Patches.php @@ -67,8 +67,18 @@ class Patches extends Component public function updateAllPackages() { + if (! $this->packageManager || ! $this->osId) { + $this->dispatch('error', message: 'Run “Check for updates” first.'); + return; + } + try { - $activity = UpdatePackage::run(server: $this->server, packageManager: $this->packageManager, osId: $this->osId, all: true); + $activity = UpdatePackage::run( + server: $this->server, + packageManager: $this->packageManager, + osId: $this->osId, + all: true + ); $this->dispatch('activityMonitor', $activity->id, ServerPackageUpdated::class); } catch (\Exception $e) { $this->dispatch('error', message: $e->getMessage()); From 2424bd408b7c58a6f5599fe8ab1ca9e5fac3627e Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 20 May 2025 11:15:07 +0200 Subject: [PATCH 29/53] Update app/Livewire/Project/Service/Heading.php Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- app/Livewire/Project/Service/Heading.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/Livewire/Project/Service/Heading.php b/app/Livewire/Project/Service/Heading.php index 96e94ce92..f88f62e9c 100644 --- a/app/Livewire/Project/Service/Heading.php +++ b/app/Livewire/Project/Service/Heading.php @@ -102,7 +102,11 @@ class Heading extends Component public function forceDeploy() { try { - $activities = Activity::where('properties->type_uuid', $this->service->uuid)->where('properties->status', ProcessStatus::IN_PROGRESS->value)->orWhere('properties->status', ProcessStatus::QUEUED->value)->get(); + $activities = Activity::where('properties->type_uuid', $this->service->uuid) + ->where(function ($q) { + $q->where('properties->status', ProcessStatus::IN_PROGRESS->value) + ->orWhere('properties->status', ProcessStatus::QUEUED->value); + })->get(); foreach ($activities as $activity) { $activity->properties->status = ProcessStatus::ERROR->value; $activity->save(); From 35b08453e1e8393eafdff881f4ff4ad1946ab6ee Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 20 May 2025 10:30:31 +0200 Subject: [PATCH 30/53] refactor(service): consolidate configuration change dispatch logic and remove unused navbar component --- app/Livewire/Project/Service/Heading.php | 4 +- app/Livewire/Project/Service/Navbar.php | 154 --------------- .../livewire/project/service/navbar.blade.php | 182 ------------------ .../livewire/project/shared/logs.blade.php | 2 +- 4 files changed, 2 insertions(+), 340 deletions(-) delete mode 100644 app/Livewire/Project/Service/Navbar.php delete mode 100644 resources/views/livewire/project/service/navbar.blade.php diff --git a/app/Livewire/Project/Service/Heading.php b/app/Livewire/Project/Service/Heading.php index f88f62e9c..0587a1ebc 100644 --- a/app/Livewire/Project/Service/Heading.php +++ b/app/Livewire/Project/Service/Heading.php @@ -64,10 +64,8 @@ class Heading extends Component }); if (is_null($this->service->config_hash) || $this->service->isConfigurationChanged()) { $this->service->isConfigurationChanged(true); - $this->dispatch('configurationChanged'); - } else { - $this->dispatch('configurationChanged'); } + $this->dispatch('configurationChanged'); } catch (\Exception $e) { return handleError($e, $this); } finally { diff --git a/app/Livewire/Project/Service/Navbar.php b/app/Livewire/Project/Service/Navbar.php deleted file mode 100644 index 5da425cbd..000000000 --- a/app/Livewire/Project/Service/Navbar.php +++ /dev/null @@ -1,154 +0,0 @@ -service->status)->contains('running') && is_null($this->service->config_hash)) { - $this->service->isConfigurationChanged(true); - $this->dispatch('configurationChanged'); - } - } - - public function getListeners() - { - $userId = Auth::id(); - - return [ - "echo-private:user.{$userId},ServiceStatusChanged" => 'serviceStarted', - 'envsUpdated' => '$refresh', - 'refreshStatus' => '$refresh', - ]; - } - - public function serviceStarted() - { - // $this->dispatch('success', 'Service status changed.'); - if (is_null($this->service->config_hash) || $this->service->isConfigurationChanged()) { - $this->service->isConfigurationChanged(true); - $this->dispatch('configurationChanged'); - } else { - $this->dispatch('configurationChanged'); - } - } - - public function check_status_without_notification() - { - $this->dispatch('check_status'); - } - - public function check_status() - { - $this->dispatch('check_status'); - $this->dispatch('success', 'Service status updated.'); - } - - public function checkDeployments() - { - try { - $activity = Activity::where('properties->type_uuid', $this->service->uuid)->latest()->first(); - $status = data_get($activity, 'properties.status'); - if ($status === ProcessStatus::QUEUED->value || $status === ProcessStatus::IN_PROGRESS->value) { - $this->isDeploymentProgress = true; - } else { - $this->isDeploymentProgress = false; - } - } catch (\Throwable) { - $this->isDeploymentProgress = false; - } - - return $this->isDeploymentProgress; - } - - public function start() - { - $activity = StartService::run($this->service, pullLatestImages: true); - $this->dispatch('activityMonitor', $activity->id); - } - - public function forceDeploy() - { - try { - $activities = Activity::where('properties->type_uuid', $this->service->uuid)->where('properties->status', ProcessStatus::IN_PROGRESS->value)->orWhere('properties->status', ProcessStatus::QUEUED->value)->get(); - foreach ($activities as $activity) { - $activity->properties->status = ProcessStatus::ERROR->value; - $activity->save(); - } - $activity = StartService::run($this->service, pullLatestImages: true, stopBeforeStart: true); - $this->dispatch('activityMonitor', $activity->id); - } catch (\Exception $e) { - $this->dispatch('error', $e->getMessage()); - } - } - - public function stop($cleanupContainers = false) - { - try { - StopService::run($this->service, false, $this->docker_cleanup); - ServiceStatusChanged::dispatch(); - if ($cleanupContainers) { - $this->dispatch('success', 'Containers cleaned up.'); - } else { - $this->dispatch('success', 'Service stopped.'); - } - } catch (\Exception $e) { - $this->dispatch('error', $e->getMessage()); - } - } - - public function restart() - { - $this->checkDeployments(); - if ($this->isDeploymentProgress) { - $this->dispatch('error', 'There is a deployment in progress.'); - - return; - } - $activity = StartService::run($this->service, stopBeforeStart: true); - $this->dispatch('activityMonitor', $activity->id); - } - - public function pullAndRestartEvent() - { - $this->checkDeployments(); - if ($this->isDeploymentProgress) { - $this->dispatch('error', 'There is a deployment in progress.'); - - return; - } - $activity = StartService::run($this->service, pullLatestImages: true, stopBeforeStart: true); - $this->dispatch('activityMonitor', $activity->id); - } - - public function render() - { - return view('livewire.project.service.navbar', [ - 'checkboxes' => [ - ['id' => 'docker_cleanup', 'label' => __('resource.docker_cleanup')], - ], - ]); - } -} diff --git a/resources/views/livewire/project/service/navbar.blade.php b/resources/views/livewire/project/service/navbar.blade.php deleted file mode 100644 index dd2ce4142..000000000 --- a/resources/views/livewire/project/service/navbar.blade.php +++ /dev/null @@ -1,182 +0,0 @@ -
- - - Service Startup - - - - -

{{ $title }}

- - - @script - - @endscript -
diff --git a/resources/views/livewire/project/shared/logs.blade.php b/resources/views/livewire/project/shared/logs.blade.php index 199f755da..622269344 100644 --- a/resources/views/livewire/project/shared/logs.blade.php +++ b/resources/views/livewire/project/shared/logs.blade.php @@ -42,7 +42,7 @@ @endforelse
@elseif ($type === 'service') - +
Here you can see the logs of the service.
@forelse ($containers as $container) From 9c3817ee14f3bc33b163fe18c5626d091a4a7ac7 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 20 May 2025 10:33:55 +0200 Subject: [PATCH 31/53] fix(deploy): update resource timestamp handling in deploy_resource method --- app/Http/Controllers/Api/DeployController.php | 7 ++++--- app/Livewire/Project/Database/Heading.php | 9 +++------ 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/app/Http/Controllers/Api/DeployController.php b/app/Http/Controllers/Api/DeployController.php index 46606e24a..5c7f20902 100644 --- a/app/Http/Controllers/Api/DeployController.php +++ b/app/Http/Controllers/Api/DeployController.php @@ -319,9 +319,10 @@ class DeployController extends Controller default: // Database resource StartDatabase::dispatch($resource); - $resource->update([ - 'started_at' => now(), - ]); + + $resource->started_at ??= now(); + $resource->save(); + $message = "Database {$resource->name} started."; break; } diff --git a/app/Livewire/Project/Database/Heading.php b/app/Livewire/Project/Database/Heading.php index 177bb549c..d5b65bf63 100644 --- a/app/Livewire/Project/Database/Heading.php +++ b/app/Livewire/Project/Database/Heading.php @@ -33,16 +33,13 @@ class Heading extends Component public function activityFinished() { try { - $this->database->update([ - 'started_at' => now(), - ]); + $this->database->started_at ??= now(); + $this->database->save(); if (is_null($this->database->config_hash) || $this->database->isConfigurationChanged()) { $this->database->isConfigurationChanged(true); - $this->dispatch('configurationChanged'); - } else { - $this->dispatch('configurationChanged'); } + $this->dispatch('configurationChanged'); } catch (\Exception $e) { return handleError($e, $this); } finally { From 64305b79921d3f875cb3111e2c6a3bb68369e258 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 20 May 2025 10:54:15 +0200 Subject: [PATCH 32/53] refactor(sidebar): simplify server patching link by removing button element --- resources/views/components/server/sidebar-security.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/components/server/sidebar-security.blade.php b/resources/views/components/server/sidebar-security.blade.php index e89092179..6f6d9d8a0 100644 --- a/resources/views/components/server/sidebar-security.blade.php +++ b/resources/views/components/server/sidebar-security.blade.php @@ -1,6 +1,6 @@ From 0cd8f5628c53cfd13269d28ca10a820c45f57e33 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Tue, 20 May 2025 10:54:51 +0200 Subject: [PATCH 33/53] refactor(slide-over): streamline button element and improve code readability --- resources/views/components/slide-over.blade.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/resources/views/components/slide-over.blade.php b/resources/views/components/slide-over.blade.php index 74ce135b5..642598b5b 100644 --- a/resources/views/components/slide-over.blade.php +++ b/resources/views/components/slide-over.blade.php @@ -1,8 +1,7 @@ @props(['closeWithX' => false, 'fullScreen' => false])
+}" class="relative w-auto h-auto" {{ $attributes }}> {{ $slot }}