From 7caf70941381ffe6320875c7c9d147eb08254a37 Mon Sep 17 00:00:00 2001 From: Jere Salonen Date: Tue, 23 Apr 2024 19:59:16 +0200 Subject: [PATCH 01/56] feat: Add EdgeDB edgedb.svg includes EdgeDB logo and add edgedb.yaml the configuration for edgedb and postgres services. Commit includes setting environment variables, volumes, health checks, and ports. --- public/svgs/edgedb.svg | 3 +++ templates/compose/edgedb.yaml | 43 +++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 public/svgs/edgedb.svg create mode 100644 templates/compose/edgedb.yaml diff --git a/public/svgs/edgedb.svg b/public/svgs/edgedb.svg new file mode 100644 index 000000000..a906f7f7e --- /dev/null +++ b/public/svgs/edgedb.svg @@ -0,0 +1,3 @@ + + + diff --git a/templates/compose/edgedb.yaml b/templates/compose/edgedb.yaml new file mode 100644 index 000000000..62c6e8000 --- /dev/null +++ b/templates/compose/edgedb.yaml @@ -0,0 +1,43 @@ +# documentation: https://www.edgedb.com +# slogan: An open-source database designed as a spiritual successor to SQL and the relational paradigm. Powered by the Postgres query engine under the hood. +# tags: db database sql +# logo: svgs/edgedb.svg + +services: + edgedb: + image: edgedb/edgedb + environment: + - EDGEDB_SERVER_ADMIN_UI=${EDGEDB_SERVER_ADMIN_UI:-enabled} + - EDGEDB_SERVER_BACKEND_DSN=postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB + - EDGEDB_SERVER_SECURITY=strict + - EDGEDB_SERVER_PASSWORD=$SERVICE_EDGEDB_SERVER_PASSWORD + - EDGEDB_SERVER_TLS_CERT_MODE=generate_self_signed + # - EDGEDB_SERVER_TLS_CERT_FILE= # Ideally Coolify should generate its own certificates + # - EDGEDB_SERVER_TLS_KEY_FILE= # -- || -- + - POSTGRES_DB=${POSTGRES_DB:-edgedb} + + depends_on: + postgresql: + condition: service_healthy + volumes: + - "./dbschema:/dbschema" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:5656/server/status/alive"] + interval: 5s + timeout: 20s + retries: 10 + ports: + - "5656:5656" + postgresql: + image: postgres:16-alpine + volumes: + - postgresql-data:/var/lib/postgresql/data + environment: + - POSTGRES_USER=$SERVICE_USER_POSTGRES + - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES + - POSTGRES_DB=${POSTGRES_DB:-edgedb} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 20s + retries: 10 \ No newline at end of file From 03d347f082b86a4b8c980186884bc83b415d5c7e Mon Sep 17 00:00:00 2001 From: Jere Salonen Date: Tue, 23 Apr 2024 20:08:08 +0200 Subject: [PATCH 02/56] fix: Add port metadata and Coolify magic to generate the domain --- templates/compose/edgedb.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/compose/edgedb.yaml b/templates/compose/edgedb.yaml index 62c6e8000..a4e127fa5 100644 --- a/templates/compose/edgedb.yaml +++ b/templates/compose/edgedb.yaml @@ -2,11 +2,13 @@ # slogan: An open-source database designed as a spiritual successor to SQL and the relational paradigm. Powered by the Postgres query engine under the hood. # tags: db database sql # logo: svgs/edgedb.svg +# port: 5656 services: edgedb: image: edgedb/edgedb environment: + - SERVICE_FQDN_EDGEDB - EDGEDB_SERVER_ADMIN_UI=${EDGEDB_SERVER_ADMIN_UI:-enabled} - EDGEDB_SERVER_BACKEND_DSN=postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB - EDGEDB_SERVER_SECURITY=strict From a094eceb624b024ef46efd1e98a6769003555c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Smitka?= Date: Wed, 9 Oct 2024 18:34:17 +0200 Subject: [PATCH 03/56] Expose port 443/udp with Caddy proxy --- bootstrap/helpers/proxy.php | 1 + 1 file changed, 1 insertion(+) diff --git a/bootstrap/helpers/proxy.php b/bootstrap/helpers/proxy.php index 5d1ad5390..9fa93e2e9 100644 --- a/bootstrap/helpers/proxy.php +++ b/bootstrap/helpers/proxy.php @@ -239,6 +239,7 @@ function generate_default_proxy_configuration(Server $server) 'ports' => [ '80:80', '443:443', + '443:443/udp', ], 'labels' => [ 'coolify.managed=true', From f95f44f4ccee167a1cfa491d6e5824ab44dd9955 Mon Sep 17 00:00:00 2001 From: MarioCake Date: Wed, 9 Oct 2024 23:45:57 +0200 Subject: [PATCH 04/56] Add settings button to projects page. --- app/Livewire/Project/Index.php | 6 +++++- resources/views/livewire/project/index.blade.php | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/Livewire/Project/Index.php b/app/Livewire/Project/Index.php index 0e4f15a5c..9ba082a8c 100644 --- a/app/Livewire/Project/Index.php +++ b/app/Livewire/Project/Index.php @@ -18,7 +18,11 @@ class Index extends Component public function mount() { $this->private_keys = PrivateKey::ownedByCurrentTeam()->get(); - $this->projects = Project::ownedByCurrentTeam()->get(); + $this->projects = Project::ownedByCurrentTeam()->get()->map(function ($project) { + $project->route = route('project.edit', ['project_uuid' => $project->uuid]); + + return $project; + }); $this->servers = Server::ownedByCurrentTeam()->count(); } diff --git a/resources/views/livewire/project/index.blade.php b/resources/views/livewire/project/index.blade.php index 10719456e..bebe15258 100644 --- a/resources/views/livewire/project/index.blade.php +++ b/resources/views/livewire/project/index.blade.php @@ -24,6 +24,12 @@
+ From 62e67eff8931bd0c136235831f3e77218e786980 Mon Sep 17 00:00:00 2001 From: MarioCake Date: Wed, 9 Oct 2024 23:49:54 +0200 Subject: [PATCH 05/56] Remove click handler for settings div. --- resources/views/livewire/project/index.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/views/livewire/project/index.blade.php b/resources/views/livewire/project/index.blade.php index bebe15258..d53535582 100644 --- a/resources/views/livewire/project/index.blade.php +++ b/resources/views/livewire/project/index.blade.php @@ -24,7 +24,7 @@
-
+
Settings From 0155af211653270247149447e99e9b87b926d760 Mon Sep 17 00:00:00 2001 From: loudar Date: Thu, 10 Oct 2024 01:01:11 +0200 Subject: [PATCH 06/56] limit randomly generated github app name length --- app/Livewire/Source/Github/Create.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Livewire/Source/Github/Create.php b/app/Livewire/Source/Github/Create.php index f85e8646e..103c5c9fb 100644 --- a/app/Livewire/Source/Github/Create.php +++ b/app/Livewire/Source/Github/Create.php @@ -23,7 +23,7 @@ class Create extends Component public function mount() { - $this->name = generate_random_name(); + $this->name = substr(generate_random_name(), 0, 34); // GitHub Apps names can only be 34 characters long } public function createGitHubApp() From 76d631d7ba7699d07ec53168a0c12718f842d2ed Mon Sep 17 00:00:00 2001 From: MarioCake Date: Thu, 10 Oct 2024 09:45:13 +0200 Subject: [PATCH 07/56] Rename route attribute to settingsRoute attribute. --- app/Livewire/Project/Index.php | 2 +- resources/views/livewire/project/index.blade.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/Livewire/Project/Index.php b/app/Livewire/Project/Index.php index 9ba082a8c..f8eb838be 100644 --- a/app/Livewire/Project/Index.php +++ b/app/Livewire/Project/Index.php @@ -19,7 +19,7 @@ class Index extends Component { $this->private_keys = PrivateKey::ownedByCurrentTeam()->get(); $this->projects = Project::ownedByCurrentTeam()->get()->map(function ($project) { - $project->route = route('project.edit', ['project_uuid' => $project->uuid]); + $project->settingsRoute = route('project.edit', ['project_uuid' => $project->uuid]); return $project; }); diff --git a/resources/views/livewire/project/index.blade.php b/resources/views/livewire/project/index.blade.php index d53535582..cb8e1bbed 100644 --- a/resources/views/livewire/project/index.blade.php +++ b/resources/views/livewire/project/index.blade.php @@ -26,7 +26,7 @@
From 031ffbeb2909248992753680562164ff39d17ca0 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 11 Oct 2024 17:40:39 +0200 Subject: [PATCH 08/56] chore: Update livewire/livewire dependency to version 3.4.9 --- composer.json | 2 +- composer.lock | 21 ++++++++++----------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/composer.json b/composer.json index 7bb2b761a..fbd77d0cf 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "lcobucci/jwt": "^5.0.0", "league/flysystem-aws-s3-v3": "^3.0", "league/flysystem-sftp-v3": "^3.0", - "livewire/livewire": "3.5.2", + "livewire/livewire": "3.4.9", "log1x/laravel-webfonts": "^1.0", "lorisleiva/laravel-actions": "^2.7", "nubs/random-name-generator": "^2.2", diff --git a/composer.lock b/composer.lock index e0456481c..0b8da82d0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e6b8a44dc3fbcd52d0d5b17628efac99", + "content-hash": "c47adf3684eb727e22503937435c0914", "packages": [ { "name": "amphp/amp", @@ -4402,16 +4402,16 @@ }, { "name": "livewire/livewire", - "version": "v3.5.2", + "version": "v3.4.9", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "636725c1f87bc7844dd80277488268db27eec1aa" + "reference": "c65b3f0798ab2c9338213ede3588c3cdf4e6fcc0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/636725c1f87bc7844dd80277488268db27eec1aa", - "reference": "636725c1f87bc7844dd80277488268db27eec1aa", + "url": "https://api.github.com/repos/livewire/livewire/zipball/c65b3f0798ab2c9338213ede3588c3cdf4e6fcc0", + "reference": "c65b3f0798ab2c9338213ede3588c3cdf4e6fcc0", "shasum": "" }, "require": { @@ -4421,16 +4421,15 @@ "illuminate/validation": "^10.0|^11.0", "league/mime-type-detection": "^1.9", "php": "^8.1", - "symfony/console": "^6.0|^7.0", "symfony/http-kernel": "^6.2|^7.0" }, "require-dev": { "calebporzio/sushi": "^2.1", - "laravel/framework": "^10.15.0|^11.0", + "laravel/framework": "^10.0|^11.0", "laravel/prompts": "^0.1.6", "mockery/mockery": "^1.3.1", - "orchestra/testbench": "^8.21.0|^9.0", - "orchestra/testbench-dusk": "^8.24|^9.1", + "orchestra/testbench": "8.20.0|^9.0", + "orchestra/testbench-dusk": "8.20.0|^9.0", "phpunit/phpunit": "^10.4", "psy/psysh": "^0.11.22|^0.12" }, @@ -4466,7 +4465,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v3.5.2" + "source": "https://github.com/livewire/livewire/tree/v3.4.9" }, "funding": [ { @@ -4474,7 +4473,7 @@ "type": "github" } ], - "time": "2024-07-03T17:22:45+00:00" + "time": "2024-03-14T14:03:32+00:00" }, { "name": "log1x/laravel-webfonts", From efd5cf6eadafe56bb1bcc20802e01f5573bf1129 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 11 Oct 2024 17:41:56 +0200 Subject: [PATCH 09/56] chore: Update livewire/livewire dependency to version 3.4.9 --- composer.json | 2 +- composer.lock | 21 ++++++++++----------- config/sentry.php | 2 +- config/version.php | 3 +-- versions.json | 4 ++-- 5 files changed, 15 insertions(+), 17 deletions(-) diff --git a/composer.json b/composer.json index 7bb2b761a..fbd77d0cf 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "lcobucci/jwt": "^5.0.0", "league/flysystem-aws-s3-v3": "^3.0", "league/flysystem-sftp-v3": "^3.0", - "livewire/livewire": "3.5.2", + "livewire/livewire": "3.4.9", "log1x/laravel-webfonts": "^1.0", "lorisleiva/laravel-actions": "^2.7", "nubs/random-name-generator": "^2.2", diff --git a/composer.lock b/composer.lock index e0456481c..0b8da82d0 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e6b8a44dc3fbcd52d0d5b17628efac99", + "content-hash": "c47adf3684eb727e22503937435c0914", "packages": [ { "name": "amphp/amp", @@ -4402,16 +4402,16 @@ }, { "name": "livewire/livewire", - "version": "v3.5.2", + "version": "v3.4.9", "source": { "type": "git", "url": "https://github.com/livewire/livewire.git", - "reference": "636725c1f87bc7844dd80277488268db27eec1aa" + "reference": "c65b3f0798ab2c9338213ede3588c3cdf4e6fcc0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/livewire/livewire/zipball/636725c1f87bc7844dd80277488268db27eec1aa", - "reference": "636725c1f87bc7844dd80277488268db27eec1aa", + "url": "https://api.github.com/repos/livewire/livewire/zipball/c65b3f0798ab2c9338213ede3588c3cdf4e6fcc0", + "reference": "c65b3f0798ab2c9338213ede3588c3cdf4e6fcc0", "shasum": "" }, "require": { @@ -4421,16 +4421,15 @@ "illuminate/validation": "^10.0|^11.0", "league/mime-type-detection": "^1.9", "php": "^8.1", - "symfony/console": "^6.0|^7.0", "symfony/http-kernel": "^6.2|^7.0" }, "require-dev": { "calebporzio/sushi": "^2.1", - "laravel/framework": "^10.15.0|^11.0", + "laravel/framework": "^10.0|^11.0", "laravel/prompts": "^0.1.6", "mockery/mockery": "^1.3.1", - "orchestra/testbench": "^8.21.0|^9.0", - "orchestra/testbench-dusk": "^8.24|^9.1", + "orchestra/testbench": "8.20.0|^9.0", + "orchestra/testbench-dusk": "8.20.0|^9.0", "phpunit/phpunit": "^10.4", "psy/psysh": "^0.11.22|^0.12" }, @@ -4466,7 +4465,7 @@ "description": "A front-end framework for Laravel.", "support": { "issues": "https://github.com/livewire/livewire/issues", - "source": "https://github.com/livewire/livewire/tree/v3.5.2" + "source": "https://github.com/livewire/livewire/tree/v3.4.9" }, "funding": [ { @@ -4474,7 +4473,7 @@ "type": "github" } ], - "time": "2024-07-03T17:22:45+00:00" + "time": "2024-03-14T14:03:32+00:00" }, { "name": "log1x/laravel-webfonts", diff --git a/config/sentry.php b/config/sentry.php index 03d36280c..ade6923ac 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.359', + 'release' => '4.0.0-beta.360', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index 6d3ef4243..5639fc8a8 100644 --- a/config/version.php +++ b/config/version.php @@ -1,4 +1,3 @@ Date: Fri, 11 Oct 2024 17:48:03 +0200 Subject: [PATCH 10/56] chore: Update version to 4.0.0-beta.361 --- config/sentry.php | 2 +- config/version.php | 2 +- versions.json | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/config/sentry.php b/config/sentry.php index cf1271119..a56ee680c 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.360', + 'release' => '4.0.0-beta.361', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index 305c873ce..0e83ff40e 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ Date: Fri, 11 Oct 2024 18:09:46 +0200 Subject: [PATCH 11/56] Romanian translation --- lang/ro.json | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 lang/ro.json diff --git a/lang/ro.json b/lang/ro.json new file mode 100644 index 000000000..8d147a5c5 --- /dev/null +++ b/lang/ro.json @@ -0,0 +1,37 @@ +{ + "auth.login": "Autentificare", + "auth.login.azure": "Autentificare cu Microsoft", + "auth.login.bitbucket": "Autentificare cu Bitbucket", + "auth.login.github": "Autentificare cu GitHub", + "auth.login.gitlab": "Autentificare cu Gitlab", + "auth.login.google": "Autentificare cu Google", + "auth.already_registered": "Sunteți deja înregistrat?", + "auth.confirm_password": "Confirmați parola", + "auth.forgot_password": "Ați uitat parola", + "auth.forgot_password_send_email": "Trimiteți e-mail pentru resetarea parolei", + "auth.register_now": "Înregistrare", + "auth.logout": "Deconectare", + "auth.register": "Înregistrare", + "auth.registration_disabled": "Înregistrarea este dezactivată. Vă rugăm să contactați administratorul site-ului.", + "auth.reset_password": "Resetare parolă", + "auth.failed": "Autentificare nereușită. Vă rugăm să verificați datele introduse.", + "auth.failed.callback": "A apărut o eroare în timpul autentificării cu furnizorul extern.", + "auth.failed.password": "Parola furnizată este incorectă.", + "auth.failed.email": "Nu putem găsi un utilizator cu această adresă de e-mail.", + "auth.throttle": "Prea multe încercări de autentificare. Vă rugăm să încercați din nou în :seconds secunde.", + "input.name": "Nume", + "input.email": "E-mail", + "input.password": "Parolă", + "input.password.again": "Repetați parola", + "input.code": "Cod de unică folosință", + "input.recovery_code": "Cod de recuperare", + "button.save": "Salvare", + "repository.url": "Exemple
Pentru depozite publice, utilizați https://....
Pentru depozite private, utilizați git@....

https://github.com/coollabsio/coolify-examples va fi selectată ramura main
https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify va fi selectată ramura nodejs-fastify.
https://gitea.com/sedlav/expressjs.git va fi selectată ramura main.
https://gitlab.com/andrasbacsai/nodejs-example.git va fi selectată ramura main.", + "service.stop": "Acest serviciu va fi oprit.", + "resource.docker_cleanup": "Executați curățarea Docker (eliminați imaginile neutilizate și memoria cache a constructorului).", + "resource.non_persistent": "Toate datele nepersistente vor fi șterse.", + "resource.delete_volumes": "Ștergeți definitiv toate volumele asociate cu această resursă.", + "resource.delete_connected_networks": "Ștergeți definitiv toate rețelele non-predefinite asociate cu această resursă.", + "resource.delete_configurations": "Ștergeți definitiv toate fișierele de configurare de pe server.", + "database.delete_backups_locally": "Toate copiile de rezervă vor fi șterse definitiv din stocarea locală." +} From 69d9e028f75f558ce08f26dbe173a401ffe4ee0d Mon Sep 17 00:00:00 2001 From: Stefan Date: Fri, 11 Oct 2024 18:15:32 +0200 Subject: [PATCH 12/56] Wif wording --- lang/ro.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lang/ro.json b/lang/ro.json index 8d147a5c5..db1aa85db 100644 --- a/lang/ro.json +++ b/lang/ro.json @@ -1,14 +1,14 @@ { "auth.login": "Autentificare", - "auth.login.azure": "Autentificare cu Microsoft", - "auth.login.bitbucket": "Autentificare cu Bitbucket", - "auth.login.github": "Autentificare cu GitHub", - "auth.login.gitlab": "Autentificare cu Gitlab", - "auth.login.google": "Autentificare cu Google", + "auth.login.azure": "Autentificare prin Microsoft", + "auth.login.bitbucket": "Autentificare prin Bitbucket", + "auth.login.github": "Autentificare prin GitHub", + "auth.login.gitlab": "Autentificare prin Gitlab", + "auth.login.google": "Autentificare prin Google", "auth.already_registered": "Sunteți deja înregistrat?", "auth.confirm_password": "Confirmați parola", "auth.forgot_password": "Ați uitat parola", - "auth.forgot_password_send_email": "Trimiteți e-mail pentru resetarea parolei", + "auth.forgot_password_send_email": "Trimiteți e-mail-ul pentru resetarea parolei", "auth.register_now": "Înregistrare", "auth.logout": "Deconectare", "auth.register": "Înregistrare", From 98c18311d3a90475109de7f35cf82486e5fa8229 Mon Sep 17 00:00:00 2001 From: tarik <77856978+ItsTarikBTW@users.noreply.github.com> Date: Fri, 11 Oct 2024 18:22:02 +0100 Subject: [PATCH 13/56] Add missing Arabic translations --- lang/ar.json | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lang/ar.json b/lang/ar.json index c5ec96c8d..4b9afbe99 100644 --- a/lang/ar.json +++ b/lang/ar.json @@ -26,5 +26,12 @@ "input.code": "الرمز لمرة واحدة", "input.recovery_code": "رمز الاسترداد", "button.save": "حفظ", - "repository.url": "أمثلة
للمستودعات العامة، استخدم https://....
للمستودعات الخاصة، استخدم git@....

سيتم تحديد الفرع main لـ https://github.com/coollabsio/coolify-examples
سيتم تحديد الفرع nodejs-fastify لـ https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify
سيتم تحديد الفرع main لـ https://gitea.com/sedlav/expressjs.git
سيتم تحديد الفرع main لـ https://gitlab.com/andrasbacsai/nodejs-example.git." + "repository.url": "أمثلة
للمستودعات العامة، استخدم https://....
للمستودعات الخاصة، استخدم git@....

سيتم تحديد الفرع main لـ https://github.com/coollabsio/coolify-examples
سيتم تحديد الفرع nodejs-fastify لـ https://github.com/coollabsio/coolify-examples/tree/nodejs-fastify
سيتم تحديد الفرع main لـ https://gitea.com/sedlav/expressjs.git
سيتم تحديد الفرع main لـ https://gitlab.com/andrasbacsai/nodejs-example.git.", + "service.stop": "سيتم إيقاف هذه الخدمة.", + "resource.docker_cleanup": "قم بتشغيل Docker Cleanup (قم بإزالة الصور غير المستخدمة وذاكرة التخزين المؤقت للمنشئ).", + "resource.non_persistent": "سيتم حذف جميع البيانات غير الدائمة.", + "resource.delete_volumes": "حذف جميع المجلدات والملفات المرتبطة بهذا المورد بشكل دائم.", + "resource.delete_connected_networks": "حذف جميع الشبكات غير المحددة مسبقًا والمرتبطة بهذا المورد بشكل دائم.", + "resource.delete_configurations": "حذف جميع ملفات التعريف من الخادم بشكل دائم.", + "database.delete_backups_locally": "حذف كافة النسخ الاحتياطية نهائيًا من التخزين المحلي." } From de75ae2eb4a1a610729be1864b1004653e20a315 Mon Sep 17 00:00:00 2001 From: Franck Kerbiriou Date: Thu, 29 Aug 2024 15:20:06 +0200 Subject: [PATCH 14/56] Add Calcom template --- public/svgs/calcom.svg | 9 ++++++ templates/compose/calcom.yaml | 59 +++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 public/svgs/calcom.svg create mode 100644 templates/compose/calcom.yaml diff --git a/public/svgs/calcom.svg b/public/svgs/calcom.svg new file mode 100644 index 000000000..446b16655 --- /dev/null +++ b/public/svgs/calcom.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/templates/compose/calcom.yaml b/templates/compose/calcom.yaml new file mode 100644 index 000000000..ac737f8aa --- /dev/null +++ b/templates/compose/calcom.yaml @@ -0,0 +1,59 @@ +# documentation: https://cal.com/docs +# slogan: Scheduling infrastructure for everyone. +# tags: calcom,calendso,scheduling,open,source +# logo: svgs/calcom.svg +# port: 3000 + +services: + postgresql: + image: postgres:16-alpine + volumes: + - postgresql-data:/var/lib/postgresql/data + environment: + - POSTGRES_USER=$SERVICE_USER_POSTGRES + - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES + - POSTGRES_DB=${POSTGRES_DB:-calendso} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 20s + retries: 10 + calcom: + image: calcom.docker.scarf.sh/calcom/cal.com + environment: + # Some variables still uses Calcom previous name, Calendso + # Full list https://github.com/calcom/cal.com/blob/main/.env.example + - SERVICE_FQDN_CALCOM_3000 + - NEXT_PUBLIC_LICENSE_CONSENT=agree + - NODE_ENV=production + - NEXT_PUBLIC_WEBAPP_URL=$SERVICE_FQDN_CALCOM + - NEXT_PUBLIC_API_V2_URL=${SERVICE_FQDN_CALCOM}/api/v2 + # NEXTAUTH_URL=http://localhost:3000/api/auth + # It is highly recommended that the NEXTAUTH_SECRET must be overridden and very unique + # Use `openssl rand -base64 32` to generate a key + - NEXTAUTH_SECRET=$SERVICE_BASE64_CALCOM_SECRET + # Encryption key that will be used to encrypt CalDAV credentials, choose a random string, for example with `dd if=/dev/urandom bs=1K count=1 | md5sum` + - CALENDSO_ENCRYPTION_KEY=$SERVICE_BASE64_CALCOM_KEY + - POSTGRES_USER=$SERVICE_USER_POSTGRES + - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES + - POSTGRES_DB=${POSTGRES_DB:-calendso} + - DATABASE_HOST=postgresql + - DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@${DATABASE_HOST}/${POSTGRES_DB:-calendso} + # Needed to run migrations while using a connection pooler like PgBouncer + # Use the same one as DATABASE_URL if you're not using a connection pooler + - DATABASE_DIRECT_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@${DATABASE_HOST}/${POSTGRES_DB:-calendso} + # GOOGLE_API_CREDENTIALS={} + # Set this to '1' if you don't want Cal to collect anonymous usage + - CALCOM_TELEMETRY_DISABLED=1 + # E-mail settings + # Configures the global From: header whilst sending emails. + - EMAIL_FROM=$EMAIL_FROM + - EMAIL_FROM_NAME=$EMAIL_FROM_NAME + # Configure SMTP settings (@see https://nodemailer.com/smtp/). + - EMAIL_SERVER_HOST=$EMAIL_SERVER_HOST + - EMAIL_SERVER_PORT=$EMAIL_SERVER_PORT + - EMAIL_SERVER_USER=$EMAIL_SERVER_USER + - EMAIL_SERVER_PASSWORD=$EMAIL_SERVER_PASSWORD + - NEXT_PUBLIC_APP_NAME="Cal.com" + depends_on: + - postgresql From 4f76dc835b6b577d03363a1961a6381750c78110 Mon Sep 17 00:00:00 2001 From: Franck Kerbiriou Date: Sat, 12 Oct 2024 14:04:57 -0500 Subject: [PATCH 15/56] Refactor service --- templates/compose/calcom.yaml | 66 ++++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 29 deletions(-) diff --git a/templates/compose/calcom.yaml b/templates/compose/calcom.yaml index ac737f8aa..c7ea7744c 100644 --- a/templates/compose/calcom.yaml +++ b/templates/compose/calcom.yaml @@ -5,55 +5,63 @@ # port: 3000 services: - postgresql: - image: postgres:16-alpine - volumes: - - postgresql-data:/var/lib/postgresql/data - environment: - - POSTGRES_USER=$SERVICE_USER_POSTGRES - - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES - - POSTGRES_DB=${POSTGRES_DB:-calendso} - healthcheck: - test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] - interval: 5s - timeout: 20s - retries: 10 calcom: image: calcom.docker.scarf.sh/calcom/cal.com environment: # Some variables still uses Calcom previous name, Calendso + # # Full list https://github.com/calcom/cal.com/blob/main/.env.example - SERVICE_FQDN_CALCOM_3000 - NEXT_PUBLIC_LICENSE_CONSENT=agree - NODE_ENV=production - - NEXT_PUBLIC_WEBAPP_URL=$SERVICE_FQDN_CALCOM + - NEXT_PUBLIC_WEBAPP_URL=${SERVICE_FQDN_CALCOM} - NEXT_PUBLIC_API_V2_URL=${SERVICE_FQDN_CALCOM}/api/v2 - # NEXTAUTH_URL=http://localhost:3000/api/auth + # https://next-auth.js.org/configuration/options#nextauth_url + # From https://github.com/calcom/docker?tab=readme-ov-file#important-run-time-variables, it should be ${NEXT_PUBLIC_WEBAPP_URL}/api/auth + - NEXTAUTH_URL=${SERVICE_FQDN_CALCOM}/api/auth # It is highly recommended that the NEXTAUTH_SECRET must be overridden and very unique # Use `openssl rand -base64 32` to generate a key - - NEXTAUTH_SECRET=$SERVICE_BASE64_CALCOM_SECRET + - NEXTAUTH_SECRET=${NEXTAUTH_SECRET:-$SERVICE_BASE64_CALCOM_SECRET} # Encryption key that will be used to encrypt CalDAV credentials, choose a random string, for example with `dd if=/dev/urandom bs=1K count=1 | md5sum` - - CALENDSO_ENCRYPTION_KEY=$SERVICE_BASE64_CALCOM_KEY - - POSTGRES_USER=$SERVICE_USER_POSTGRES - - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES + - CALENDSO_ENCRYPTION_KEY=${CALENDSO_ENCRYPTION_KEY:-$SERVICE_BASE64_CALCOM_KEY} + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} - POSTGRES_DB=${POSTGRES_DB:-calendso} - DATABASE_HOST=postgresql - - DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@${DATABASE_HOST}/${POSTGRES_DB:-calendso} + - DATABASE_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@${DATABASE_HOST:-postgresql}/${POSTGRES_DB:-calendso} # Needed to run migrations while using a connection pooler like PgBouncer - # Use the same one as DATABASE_URL if you're not using a connection pooler - - DATABASE_DIRECT_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@${DATABASE_HOST}/${POSTGRES_DB:-calendso} + # Use the same one as DATABASE_URL if you are not using a connection pooler + - DATABASE_DIRECT_URL=postgresql://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@${DATABASE_HOST:-postgresql}/${POSTGRES_DB:-calendso} # GOOGLE_API_CREDENTIALS={} - # Set this to '1' if you don't want Cal to collect anonymous usage + # Set this to 1 if you don't want Cal to collect anonymous usage - CALCOM_TELEMETRY_DISABLED=1 # E-mail settings # Configures the global From: header whilst sending emails. - - EMAIL_FROM=$EMAIL_FROM - - EMAIL_FROM_NAME=$EMAIL_FROM_NAME + - EMAIL_FROM=${EMAIL_FROM} + - EMAIL_FROM_NAME=${EMAIL_FROM_NAME} # Configure SMTP settings (@see https://nodemailer.com/smtp/). - - EMAIL_SERVER_HOST=$EMAIL_SERVER_HOST - - EMAIL_SERVER_PORT=$EMAIL_SERVER_PORT - - EMAIL_SERVER_USER=$EMAIL_SERVER_USER - - EMAIL_SERVER_PASSWORD=$EMAIL_SERVER_PASSWORD + - EMAIL_SERVER_HOST=${EMAIL_SERVER_HOST} + - EMAIL_SERVER_PORT=${EMAIL_SERVER_PORT} + - EMAIL_SERVER_USER=${EMAIL_SERVER_USER} + - EMAIL_SERVER_PASSWORD=${EMAIL_SERVER_PASSWORD} - NEXT_PUBLIC_APP_NAME="Cal.com" + # More info on ALLOWED_HOSTNAMES https://github.com/calcom/cal.com/issues/12201 + - ALLOWED_HOSTNAMES=["${SERVICE_FQDN_CALCOM}"] depends_on: - postgresql + postgresql: + image: postgres:16-alpine + environment: + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_DB=${POSTGRES_DATABASE:-calcom} + volumes: + - calcom-postgresql-data:/var/lib/postgresql/data + healthcheck: + test: + - CMD-SHELL + - pg_isready -U ${SERVICE_USER_POSTGRES} -d ${POSTGRES_DATABASE:-calcom} + interval: 10s + timeout: 5s + retries: 5 + restart: unless-stopped From eb8dfecfd49d9d3d444a8cb1843ea4b4d00345f1 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 08:22:44 +0200 Subject: [PATCH 16/56] push helper to dockerhub --- .github/workflows/coolify-helper-next.yml | 33 ++++++++++++++++++----- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/.github/workflows/coolify-helper-next.yml b/.github/workflows/coolify-helper-next.yml index 4add8516e..f46c67375 100644 --- a/.github/workflows/coolify-helper-next.yml +++ b/.github/workflows/coolify-helper-next.yml @@ -8,7 +8,8 @@ on: - docker/coolify-helper/Dockerfile env: - REGISTRY: ghcr.io + GITHUB_REGISTRY: ghcr.io + DOCKER_REGISTRY: docker.io IMAGE_NAME: "coollabsio/coolify-helper" jobs: @@ -19,12 +20,18 @@ jobs: packages: write steps: - uses: actions/checkout@v4 - - name: Login to ghcr.io + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} - name: Get Version id: version run: | @@ -47,12 +54,18 @@ jobs: packages: write steps: - uses: actions/checkout@v4 - - name: Login to ghcr.io + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} - name: Get Version id: version run: | @@ -81,12 +94,18 @@ jobs: uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Login to ghcr.io + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} - name: Get Version id: version run: | From 4873779973594407e210f973553fc05b8788c935 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 08:38:03 +0200 Subject: [PATCH 17/56] chore: Update Docker build and push actions to v6 --- .github/workflows/coolify-helper-next.yml | 34 ++++++++++++++++------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/.github/workflows/coolify-helper-next.yml b/.github/workflows/coolify-helper-next.yml index f46c67375..d8d230af5 100644 --- a/.github/workflows/coolify-helper-next.yml +++ b/.github/workflows/coolify-helper-next.yml @@ -20,33 +20,39 @@ jobs: packages: write steps: - uses: actions/checkout@v4 + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Login to ${{ env.DOCKER_REGISTRY }} uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} + - name: Get Version id: version run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Build image and push to registry - uses: docker/build-push-action@v5 + + - name: Build and Push Image + uses: docker/build-push-action@v6 with: - no-cache: true context: . file: docker/coolify-helper/Dockerfile platforms: linux/amd64 push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next labels: | coolify.managed=true + aarch64: runs-on: [ self-hosted, arm64 ] permissions: @@ -54,31 +60,36 @@ jobs: packages: write steps: - uses: actions/checkout@v4 + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Login to ${{ env.DOCKER_REGISTRY }} uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} + - name: Get Version id: version run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Build image and push to registry - uses: docker/build-push-action@v5 + + - name: Build and Push Image + uses: docker/build-push-action@v6 with: - no-cache: true context: . file: docker/coolify-helper/Dockerfile platforms: linux/aarch64 push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 labels: | coolify.managed=true merge-manifest: @@ -110,9 +121,12 @@ jobs: id: version run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Create & publish manifest + - name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }} run: | - docker buildx imagetools create --append ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:next + docker buildx imagetools create --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:next + - name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }} + run: | + docker buildx imagetools create --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:next - uses: sarisia/actions-status-discord@v1 if: always() with: From 3383285415683291d6a3d42e331de5be4c11e6cc Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 08:39:09 +0200 Subject: [PATCH 18/56] chore: Update Docker build and push actions to v6 --- .github/workflows/coolify-helper-next.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/coolify-helper-next.yml b/.github/workflows/coolify-helper-next.yml index d8d230af5..d03c42cd7 100644 --- a/.github/workflows/coolify-helper-next.yml +++ b/.github/workflows/coolify-helper-next.yml @@ -52,7 +52,6 @@ jobs: ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next labels: | coolify.managed=true - aarch64: runs-on: [ self-hosted, arm64 ] permissions: From de572762ec144344497684c25d75d145e44a9f99 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 08:41:21 +0200 Subject: [PATCH 19/56] chore: Update Docker build and push actions to v6 --- .github/workflows/coolify-helper-next.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coolify-helper-next.yml b/.github/workflows/coolify-helper-next.yml index d03c42cd7..10602aa6f 100644 --- a/.github/workflows/coolify-helper-next.yml +++ b/.github/workflows/coolify-helper-next.yml @@ -79,7 +79,7 @@ jobs: run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Build and Push Image + - name: Build and Push Image uses: docker/build-push-action@v6 with: context: . From bd4f47494c85d29568d855a7cad5b549728116b9 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 08:48:20 +0200 Subject: [PATCH 20/56] chore: sync coolify-helper to dockerhub as well --- .github/workflows/coolify-helper.yml | 72 ++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 20 deletions(-) diff --git a/.github/workflows/coolify-helper.yml b/.github/workflows/coolify-helper.yml index a9e8a5dd0..6e5680879 100644 --- a/.github/workflows/coolify-helper.yml +++ b/.github/workflows/coolify-helper.yml @@ -1,4 +1,4 @@ -name: Coolify Helper Image (v4) +name: Coolify Helper Image on: push: @@ -8,7 +8,8 @@ on: - docker/coolify-helper/Dockerfile env: - REGISTRY: ghcr.io + GITHUB_REGISTRY: ghcr.io + DOCKER_REGISTRY: docker.io IMAGE_NAME: "coollabsio/coolify-helper" jobs: @@ -19,25 +20,36 @@ jobs: packages: write steps: - uses: actions/checkout@v4 - - name: Login to ghcr.io + + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + - name: Get Version id: version run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Build image and push to registry - uses: docker/build-push-action@v5 + + - name: Build and Push Image + uses: docker/build-push-action@v6 with: - no-cache: true context: . file: docker/coolify-helper/Dockerfile platforms: linux/amd64 push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} labels: | coolify.managed=true aarch64: @@ -47,25 +59,36 @@ jobs: packages: write steps: - uses: actions/checkout@v4 - - name: Login to ghcr.io + + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + - name: Get Version id: version run: | - echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Build image and push to registry - uses: docker/build-push-action@v5 + echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT + + - name: Build and Push Image + uses: docker/build-push-action@v6 with: - no-cache: true context: . file: docker/coolify-helper/Dockerfile platforms: linux/aarch64 push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 labels: | coolify.managed=true merge-manifest: @@ -81,19 +104,28 @@ jobs: uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Login to ghcr.io + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} - name: Get Version id: version run: | - echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Create & publish manifest + echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT + - name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }} run: | - docker buildx imagetools create --append ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + docker buildx imagetools create --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest + - name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }} + run: | + docker buildx imagetools create --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest - uses: sarisia/actions-status-discord@v1 if: always() with: From 104aa447cc304072eb0d63f37f4001dbd0cc64ae Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 08:52:53 +0200 Subject: [PATCH 21/56] chore: push realtime to dockerhub --- .github/workflows/coolify-realtime-next.yml | 82 ++++++++++++++++----- 1 file changed, 62 insertions(+), 20 deletions(-) diff --git a/.github/workflows/coolify-realtime-next.yml b/.github/workflows/coolify-realtime-next.yml index 33e048627..19f4c690f 100644 --- a/.github/workflows/coolify-realtime-next.yml +++ b/.github/workflows/coolify-realtime-next.yml @@ -1,17 +1,18 @@ -name: Coolify Realtime Development (v4) +name: Coolify Realtime Development on: push: branches: [ "next" ] paths: - - .github/workflows/coolify-realtime.yml + - .github/workflows/coolify-realtime-next.yml - docker/coolify-realtime/Dockerfile - docker/coolify-realtime/terminal-server.js - docker/coolify-realtime/package.json - docker/coolify-realtime/soketi-entrypoint.sh env: - REGISTRY: ghcr.io + GITHUB_REGISTRY: ghcr.io + DOCKER_REGISTRY: docker.io IMAGE_NAME: "coollabsio/coolify-realtime" jobs: @@ -22,27 +23,39 @@ jobs: packages: write steps: - uses: actions/checkout@v4 - - name: Login to ghcr.io + + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + - name: Get Version id: version run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Build image and push to registry - uses: docker/build-push-action@v5 + + - name: Build and Push Image + uses: docker/build-push-action@v6 with: - no-cache: true context: . file: docker/coolify-realtime/Dockerfile platforms: linux/amd64 push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next labels: | coolify.managed=true + aarch64: runs-on: [ self-hosted, arm64 ] permissions: @@ -50,27 +63,39 @@ jobs: packages: write steps: - uses: actions/checkout@v4 - - name: Login to ghcr.io + + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + - name: Get Version id: version run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Build image and push to registry - uses: docker/build-push-action@v5 + + - name: Build and Push Image + uses: docker/build-push-action@v6 with: - no-cache: true context: . file: docker/coolify-realtime/Dockerfile platforms: linux/aarch64 push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 labels: | coolify.managed=true + merge-manifest: runs-on: ubuntu-latest permissions: @@ -80,24 +105,41 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Set up QEMU uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Login to ghcr.io + + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + - name: Get Version id: version run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Create & publish manifest + + - name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }} run: | - docker buildx imagetools create --append ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next + docker buildx imagetools create --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:next + + - name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }} + run: | + docker buildx imagetools create --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:next + - uses: sarisia/actions-status-discord@v1 if: always() with: - webhook: ${{ secrets.DISCORD_WEBHOOK_PROD_RELEASE_CHANNEL }} + webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL }} From 953a7d3f1ee8ce39cf5bc8ad32f6f65e73eaa1bc Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 08:53:51 +0200 Subject: [PATCH 22/56] fix --- .github/workflows/coolify-realtime-next.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coolify-realtime-next.yml b/.github/workflows/coolify-realtime-next.yml index 19f4c690f..ba3e7cdf5 100644 --- a/.github/workflows/coolify-realtime-next.yml +++ b/.github/workflows/coolify-realtime-next.yml @@ -83,7 +83,7 @@ jobs: run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Build and Push Image + - name: Build and Push Image uses: docker/build-push-action@v6 with: context: . From ca454b297b066e81e1f807a4902c4ebf0296375c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 08:56:45 +0200 Subject: [PATCH 23/56] fix --- .github/workflows/coolify-realtime-next.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/coolify-realtime-next.yml b/.github/workflows/coolify-realtime-next.yml index ba3e7cdf5..c4ed4707f 100644 --- a/.github/workflows/coolify-realtime-next.yml +++ b/.github/workflows/coolify-realtime-next.yml @@ -143,3 +143,13 @@ jobs: if: always() with: webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL }} + + - name: Remote -next and -next-aarch64 images from ${{ env.GITHUB_REGISTRY }} + run: | + docker buildx imagetools rmi ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next + docker buildx imagetools rmi ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 + + - name: Remote -next and -next-aarch64 images from ${{ env.DOCKER_REGISTRY }} + run: | + docker buildx imagetools rmi ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next + docker buildx imagetools rmi ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 From afe94b9059cb484a406c905fa34d38d3d3d4c9a5 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 09:00:50 +0200 Subject: [PATCH 24/56] fix --- .github/workflows/coolify-realtime-next.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/coolify-realtime-next.yml b/.github/workflows/coolify-realtime-next.yml index c4ed4707f..6a5650508 100644 --- a/.github/workflows/coolify-realtime-next.yml +++ b/.github/workflows/coolify-realtime-next.yml @@ -144,12 +144,12 @@ jobs: with: webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL }} - - name: Remote -next and -next-aarch64 images from ${{ env.GITHUB_REGISTRY }} + - name: Remove -next and -next-aarch64 images from ${{ env.GITHUB_REGISTRY }} run: | - docker buildx imagetools rmi ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next - docker buildx imagetools rmi ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 + docker manifest rm ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next || true + docker manifest rm ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 || true - - name: Remote -next and -next-aarch64 images from ${{ env.DOCKER_REGISTRY }} + - name: Remove -next and -next-aarch64 images from ${{ env.DOCKER_REGISTRY }} run: | - docker buildx imagetools rmi ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next - docker buildx imagetools rmi ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 + docker manifest rm ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next || true + docker manifest rm ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 || true From a3934750b3f42e26ebcb2fbad059847ee4e7acd5 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 09:08:31 +0200 Subject: [PATCH 25/56] fix realtime-next --- .github/workflows/coolify-realtime-next.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.github/workflows/coolify-realtime-next.yml b/.github/workflows/coolify-realtime-next.yml index 6a5650508..ba3e7cdf5 100644 --- a/.github/workflows/coolify-realtime-next.yml +++ b/.github/workflows/coolify-realtime-next.yml @@ -143,13 +143,3 @@ jobs: if: always() with: webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL }} - - - name: Remove -next and -next-aarch64 images from ${{ env.GITHUB_REGISTRY }} - run: | - docker manifest rm ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next || true - docker manifest rm ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 || true - - - name: Remove -next and -next-aarch64 images from ${{ env.DOCKER_REGISTRY }} - run: | - docker manifest rm ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next || true - docker manifest rm ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 || true From 16b33df2e18a8fc6284b82ea04b769902e3262ea Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 09:08:41 +0200 Subject: [PATCH 26/56] fix: helper push --- .github/workflows/coolify-helper.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/coolify-helper.yml b/.github/workflows/coolify-helper.yml index 6e5680879..664e502b0 100644 --- a/.github/workflows/coolify-helper.yml +++ b/.github/workflows/coolify-helper.yml @@ -104,6 +104,7 @@ jobs: uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: @@ -116,16 +117,20 @@ jobs: registry: ${{ env.DOCKER_REGISTRY }} username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} + - name: Get Version id: version run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT + - name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }} run: | docker buildx imagetools create --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest + - name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }} run: | docker buildx imagetools create --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest + - uses: sarisia/actions-status-discord@v1 if: always() with: From 6e5df991226f41a6726d32b477fba2b6e5dca4cd Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 09:08:51 +0200 Subject: [PATCH 27/56] chore: sync coolify-realtime to dockerhub --- .github/workflows/coolify-realtime.yml | 78 ++++++++++++++++++++------ 1 file changed, 60 insertions(+), 18 deletions(-) diff --git a/.github/workflows/coolify-realtime.yml b/.github/workflows/coolify-realtime.yml index 30910ae0b..89ce0f0e8 100644 --- a/.github/workflows/coolify-realtime.yml +++ b/.github/workflows/coolify-realtime.yml @@ -1,4 +1,4 @@ -name: Coolify Realtime (v4) +name: Coolify Realtime on: push: @@ -11,7 +11,8 @@ on: - docker/coolify-realtime/soketi-entrypoint.sh env: - REGISTRY: ghcr.io + GITHUB_REGISTRY: ghcr.io + DOCKER_REGISTRY: docker.io IMAGE_NAME: "coollabsio/coolify-realtime" jobs: @@ -22,27 +23,39 @@ jobs: packages: write steps: - uses: actions/checkout@v4 - - name: Login to ghcr.io + + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + - name: Get Version id: version run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Build image and push to registry - uses: docker/build-push-action@v5 + + - name: Build and Push Image + uses: docker/build-push-action@v6 with: - no-cache: true context: . file: docker/coolify-realtime/Dockerfile platforms: linux/amd64 push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} labels: | coolify.managed=true + aarch64: runs-on: [ self-hosted, arm64 ] permissions: @@ -50,27 +63,39 @@ jobs: packages: write steps: - uses: actions/checkout@v4 - - name: Login to ghcr.io + + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + - name: Get Version id: version run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Build image and push to registry - uses: docker/build-push-action@v5 + + - name: Build and Push Image + uses: docker/build-push-action@v6 with: - no-cache: true context: . file: docker/coolify-realtime/Dockerfile platforms: linux/aarch64 push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 labels: | coolify.managed=true + merge-manifest: runs-on: ubuntu-latest permissions: @@ -80,23 +105,40 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Set up QEMU uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Login to ghcr.io + + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + - name: Get Version id: version run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Create & publish manifest + + - name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }} run: | - docker buildx imagetools create --append ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + docker buildx imagetools create --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest + + - name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }} + run: | + docker buildx imagetools create --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest + - uses: sarisia/actions-status-discord@v1 if: always() with: From da3ef6a7df50831475a5db967ff5eedb9d679ec1 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 09:18:17 +0200 Subject: [PATCH 28/56] chore: rename workflows --- ...d-prs.yml => chore-lock-closed-issues-discussions-and-prs.yml} | 0 ...e-issues-and-prs.yml => chore-manage-stale-issues-and-prs.yml} | 0 ...n-close.yml => chore-remove-labels-and-assignees-on-close.yml} | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename .github/workflows/{lock-closed-issues-discussions-and-prs.yml => chore-lock-closed-issues-discussions-and-prs.yml} (100%) rename .github/workflows/{manage-stale-issues-and-prs.yml => chore-manage-stale-issues-and-prs.yml} (100%) rename .github/workflows/{remove-labels-and-assignees-on-close.yml => chore-remove-labels-and-assignees-on-close.yml} (100%) diff --git a/.github/workflows/lock-closed-issues-discussions-and-prs.yml b/.github/workflows/chore-lock-closed-issues-discussions-and-prs.yml similarity index 100% rename from .github/workflows/lock-closed-issues-discussions-and-prs.yml rename to .github/workflows/chore-lock-closed-issues-discussions-and-prs.yml diff --git a/.github/workflows/manage-stale-issues-and-prs.yml b/.github/workflows/chore-manage-stale-issues-and-prs.yml similarity index 100% rename from .github/workflows/manage-stale-issues-and-prs.yml rename to .github/workflows/chore-manage-stale-issues-and-prs.yml diff --git a/.github/workflows/remove-labels-and-assignees-on-close.yml b/.github/workflows/chore-remove-labels-and-assignees-on-close.yml similarity index 100% rename from .github/workflows/remove-labels-and-assignees-on-close.yml rename to .github/workflows/chore-remove-labels-and-assignees-on-close.yml From b72505127c94a99903e5a89efa396c4b56948367 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 09:18:25 +0200 Subject: [PATCH 29/56] fix --- .github/workflows/coolify-helper-next.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coolify-helper-next.yml b/.github/workflows/coolify-helper-next.yml index 10602aa6f..835d15b9e 100644 --- a/.github/workflows/coolify-helper-next.yml +++ b/.github/workflows/coolify-helper-next.yml @@ -1,4 +1,4 @@ -name: Coolify Helper Image Development (v4) +name: Coolify Helper Image Development on: push: From 765cb7360c3c6b2544ffd82615e93ff0df8b052f Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 09:19:26 +0200 Subject: [PATCH 30/56] chore: rename development to staging build --- .github/workflows/coolify-staging-build.yml | 133 ++++++++++++++++++++ .github/workflows/development-build.yml | 79 ------------ 2 files changed, 133 insertions(+), 79 deletions(-) create mode 100644 .github/workflows/coolify-staging-build.yml delete mode 100644 .github/workflows/development-build.yml diff --git a/.github/workflows/coolify-staging-build.yml b/.github/workflows/coolify-staging-build.yml new file mode 100644 index 000000000..baffe53d6 --- /dev/null +++ b/.github/workflows/coolify-staging-build.yml @@ -0,0 +1,133 @@ +name: Staging Build + +on: + push: + branches-ignore: ["main", "v3"] + paths-ignore: + - .github/workflows/coolify-helper.yml + - .github/workflows/coolify-helper-next.yml + - .github/workflows/coolify-realtime.yml + - .github/workflows/coolify-realtime-next.yml + - docker/coolify-helper/Dockerfile + - docker/coolify-realtime/Dockerfile + - templates/service-templates.json + +env: + GITHUB_REGISTRY: ghcr.io + DOCKER_REGISTRY: docker.io + IMAGE_NAME: "coollabsio/coolify" + +jobs: + amd64: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Login to ${{ env.GITHUB_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.GITHUB_REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Build and Push Image + uses: docker/build-push-action@v6 + with: + context: . + file: docker/prod/Dockerfile + platforms: linux/amd64 + push: true + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }} + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }} + labels: | + coolify.managed=true + + aarch64: + runs-on: [self-hosted, arm64] + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + + - name: Login to ${{ env.GITHUB_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.GITHUB_REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Build and Push Image + uses: docker/build-push-action@v6 + with: + context: . + file: docker/prod/Dockerfile + platforms: linux/aarch64 + push: true + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-aarch64 + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-aarch64 + labels: | + coolify.managed=true + + merge-manifest: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + needs: [amd64, aarch64] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to ${{ env.GITHUB_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.GITHUB_REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }} + run: | + docker buildx imagetools create \ + --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-aarch64 \ + --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }} + + - name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }} + run: | + docker buildx imagetools create \ + --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-aarch64 \ + --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }} + + - uses: sarisia/actions-status-discord@v1 + if: always() + with: + webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL }} diff --git a/.github/workflows/development-build.yml b/.github/workflows/development-build.yml deleted file mode 100644 index 268b885ac..000000000 --- a/.github/workflows/development-build.yml +++ /dev/null @@ -1,79 +0,0 @@ -name: Development Build (v4) - -on: - push: - branches-ignore: ["main", "v3"] - paths-ignore: - - .github/workflows/coolify-helper.yml - - docker/coolify-helper/Dockerfile - -env: - REGISTRY: ghcr.io - IMAGE_NAME: "coollabsio/coolify" - -jobs: - amd64: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Login to ghcr.io - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Build image and push to registry - uses: docker/build-push-action@v5 - with: - context: . - file: docker/prod/Dockerfile - platforms: linux/amd64 - push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }} - aarch64: - runs-on: [self-hosted, arm64] - permissions: - contents: read - packages: write - steps: - - uses: actions/checkout@v4 - - name: Login to ghcr.io - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Build image and push to registry - uses: docker/build-push-action@v5 - with: - context: . - file: docker/prod/Dockerfile - platforms: linux/aarch64 - push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-aarch64 - merge-manifest: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - needs: [amd64, aarch64] - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Login to ghcr.io - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Create & publish manifest - run: | - docker buildx imagetools create --append ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}-aarch64 --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }} - - uses: sarisia/actions-status-discord@v1 - if: always() - with: - webhook: ${{ secrets.DISCORD_WEBHOOK_DEV_RELEASE_CHANNEL }} From 3459e0b0d19d86989d365e29bda293d472b7351a Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 09:22:33 +0200 Subject: [PATCH 31/56] chore: sync coolify-testing-host to dockerhbu --- .github/workflows/coolify-testing-host.yml | 85 +++++++++++++++++----- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/.github/workflows/coolify-testing-host.yml b/.github/workflows/coolify-testing-host.yml index 5fdc32991..cd3c72cd9 100644 --- a/.github/workflows/coolify-testing-host.yml +++ b/.github/workflows/coolify-testing-host.yml @@ -1,14 +1,15 @@ -name: Coolify Testing Host (v4-non-prod) +name: Coolify Testing Host on: push: - branches: [ "main", "next" ] + branches: [ "next" ] paths: - .github/workflows/coolify-testing-host.yml - docker/testing-host/Dockerfile env: - REGISTRY: ghcr.io + GITHUB_REGISTRY: ghcr.io + DOCKER_REGISTRY: docker.io IMAGE_NAME: "coollabsio/coolify-testing-host" jobs: @@ -19,21 +20,34 @@ jobs: packages: write steps: - uses: actions/checkout@v4 - - name: Login to ghcr.io + + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build image and push to registry - uses: docker/build-push-action@v5 + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Build and Push Image + uses: docker/build-push-action@v6 with: - no-cache: true context: . file: docker/testing-host/Dockerfile platforms: linux/amd64 push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}:latest + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}:latest + labels: | + coolify.managed=true + aarch64: runs-on: [ self-hosted, arm64 ] permissions: @@ -41,21 +55,34 @@ jobs: packages: write steps: - uses: actions/checkout@v4 - - name: Login to ghcr.io + + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Build image and push to registry - uses: docker/build-push-action@v5 + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Build and Push Image + uses: docker/build-push-action@v6 with: - no-cache: true context: . file: docker/testing-host/Dockerfile platforms: linux/aarch64 push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}:latest-aarch64 + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}:latest-aarch64 + labels: | + coolify.managed=true + merge-manifest: runs-on: ubuntu-latest permissions: @@ -65,19 +92,39 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Set up QEMU uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Login to ghcr.io + + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: - registry: ${{ env.REGISTRY }} + registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Create & publish manifest + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }} run: | - docker buildx imagetools create --append ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + docker buildx imagetools create \ + --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 \ + --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest + + - name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }} + run: | + docker buildx imagetools create \ + --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 \ + --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest + - uses: sarisia/actions-status-discord@v1 if: always() with: From 6c2c2ee3478ff3618b4699bf54d84b1a28e385ee Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 09:27:23 +0200 Subject: [PATCH 32/56] fix: format --- .github/workflows/coolify-helper-next.yml | 19 +++++++++++++++++-- .github/workflows/coolify-helper.yml | 13 +++++++++++-- .github/workflows/coolify-realtime-next.yml | 10 ++++++++-- .github/workflows/coolify-realtime.yml | 10 ++++++++-- .github/workflows/coolify-staging-build.yml | 15 ++++++++------- 5 files changed, 52 insertions(+), 15 deletions(-) diff --git a/.github/workflows/coolify-helper-next.yml b/.github/workflows/coolify-helper-next.yml index 835d15b9e..50186b95a 100644 --- a/.github/workflows/coolify-helper-next.yml +++ b/.github/workflows/coolify-helper-next.yml @@ -91,6 +91,7 @@ jobs: ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 labels: | coolify.managed=true + merge-manifest: runs-on: ubuntu-latest permissions: @@ -100,32 +101,46 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Set up QEMU uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Login to ${{ env.DOCKER_REGISTRY }} uses: docker/login-action@v3 with: registry: ${{ env.DOCKER_REGISTRY }} username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }} + - name: Get Version id: version run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.helper.version' versions.json)"|xargs >> $GITHUB_OUTPUT + - name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }} run: | - docker buildx imagetools create --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:next + docker buildx imagetools create \ + --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \ + --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next \ + --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:next + - name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }} run: | - docker buildx imagetools create --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:next + docker buildx imagetools create \ + --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \ + --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next \ + --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:next + - uses: sarisia/actions-status-discord@v1 if: always() with: diff --git a/.github/workflows/coolify-helper.yml b/.github/workflows/coolify-helper.yml index 664e502b0..2de4c85ba 100644 --- a/.github/workflows/coolify-helper.yml +++ b/.github/workflows/coolify-helper.yml @@ -100,8 +100,10 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Set up QEMU uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 @@ -111,6 +113,7 @@ jobs: registry: ${{ env.GITHUB_REGISTRY }} username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Login to ${{ env.DOCKER_REGISTRY }} uses: docker/login-action@v3 with: @@ -125,11 +128,17 @@ jobs: - name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }} run: | - docker buildx imagetools create --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest + docker buildx imagetools create \ + --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \ + --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \ + --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest - name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }} run: | - docker buildx imagetools create --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest + docker buildx imagetools create \ + --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \ + --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \ + --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest - uses: sarisia/actions-status-discord@v1 if: always() diff --git a/.github/workflows/coolify-realtime-next.yml b/.github/workflows/coolify-realtime-next.yml index ba3e7cdf5..d8c6e0aad 100644 --- a/.github/workflows/coolify-realtime-next.yml +++ b/.github/workflows/coolify-realtime-next.yml @@ -133,11 +133,17 @@ jobs: - name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }} run: | - docker buildx imagetools create --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:next + docker buildx imagetools create \ + --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \ + --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next \ + --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:next - name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }} run: | - docker buildx imagetools create --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:next + docker buildx imagetools create \ + --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next-aarch64 \ + --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-next \ + --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:next - uses: sarisia/actions-status-discord@v1 if: always() diff --git a/.github/workflows/coolify-realtime.yml b/.github/workflows/coolify-realtime.yml index 89ce0f0e8..6551bdb0a 100644 --- a/.github/workflows/coolify-realtime.yml +++ b/.github/workflows/coolify-realtime.yml @@ -133,11 +133,17 @@ jobs: - name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }} run: | - docker buildx imagetools create --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest + docker buildx imagetools create \ + --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \ + --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \ + --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest - name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }} run: | - docker buildx imagetools create --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest + docker buildx imagetools create \ + --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \ + --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \ + --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest - uses: sarisia/actions-status-discord@v1 if: always() diff --git a/.github/workflows/coolify-staging-build.yml b/.github/workflows/coolify-staging-build.yml index baffe53d6..0bab2f3ec 100644 --- a/.github/workflows/coolify-staging-build.yml +++ b/.github/workflows/coolify-staging-build.yml @@ -4,13 +4,14 @@ on: push: branches-ignore: ["main", "v3"] paths-ignore: - - .github/workflows/coolify-helper.yml - - .github/workflows/coolify-helper-next.yml - - .github/workflows/coolify-realtime.yml - - .github/workflows/coolify-realtime-next.yml - - docker/coolify-helper/Dockerfile - - docker/coolify-realtime/Dockerfile - - templates/service-templates.json + - .github/workflows/coolify-helper.yml + - .github/workflows/coolify-helper-next.yml + - .github/workflows/coolify-realtime.yml + - .github/workflows/coolify-realtime-next.yml + - docker/coolify-helper/Dockerfile + - docker/coolify-realtime/Dockerfile + - docker/testing-host/Dockerfile + - templates/service-templates.json env: GITHUB_REGISTRY: ghcr.io From bb168086531737404fa17b7dc3240124de1a2c82 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 09:28:34 +0200 Subject: [PATCH 33/56] fix --- .github/workflows/coolify-realtime.yml | 2 +- .github/workflows/coolify-staging-build.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coolify-realtime.yml b/.github/workflows/coolify-realtime.yml index 6551bdb0a..7bf406ae6 100644 --- a/.github/workflows/coolify-realtime.yml +++ b/.github/workflows/coolify-realtime.yml @@ -83,7 +83,7 @@ jobs: run: | echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app ghcr.io/jqlang/jq:latest '.coolify.realtime.version' versions.json)"|xargs >> $GITHUB_OUTPUT - - name: Build and Push Image + - name: Build and Push Image uses: docker/build-push-action@v6 with: context: . diff --git a/.github/workflows/coolify-staging-build.yml b/.github/workflows/coolify-staging-build.yml index 0bab2f3ec..2d2da6e75 100644 --- a/.github/workflows/coolify-staging-build.yml +++ b/.github/workflows/coolify-staging-build.yml @@ -102,7 +102,7 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - - name: Login to ${{ env.GITHUB_REGISTRY }} + - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 with: registry: ${{ env.GITHUB_REGISTRY }} From fb80924a51f85ef3539a4dfaa7619c22bbb74cd7 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 09:31:32 +0200 Subject: [PATCH 34/56] fix --- .github/workflows/coolify-testing-host.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coolify-testing-host.yml b/.github/workflows/coolify-testing-host.yml index cd3c72cd9..27c836730 100644 --- a/.github/workflows/coolify-testing-host.yml +++ b/.github/workflows/coolify-testing-host.yml @@ -43,8 +43,8 @@ jobs: platforms: linux/amd64 push: true tags: | - ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}:latest - ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}:latest + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest labels: | coolify.managed=true @@ -78,8 +78,8 @@ jobs: platforms: linux/aarch64 push: true tags: | - ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}:latest-aarch64 - ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}:latest-aarch64 + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest-aarch64 labels: | coolify.managed=true From 0a3e1ffbe480dad82ad39c3b12cc0c2a6c0dfbc9 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 09:37:17 +0200 Subject: [PATCH 35/56] chore: sync coolify prod image to dockerhub as well --- .../workflows/coolify-production-build.yml | 148 ++++++++++++++++++ .github/workflows/production-build.yml | 89 ----------- 2 files changed, 148 insertions(+), 89 deletions(-) create mode 100644 .github/workflows/coolify-production-build.yml delete mode 100644 .github/workflows/production-build.yml diff --git a/.github/workflows/coolify-production-build.yml b/.github/workflows/coolify-production-build.yml new file mode 100644 index 000000000..9a63fbb27 --- /dev/null +++ b/.github/workflows/coolify-production-build.yml @@ -0,0 +1,148 @@ +name: Production Build (v4) + +on: + push: + branches: ["main"] + paths-ignore: + - .github/workflows/coolify-helper.yml + - .github/workflows/coolify-helper-next.yml + - .github/workflows/coolify-realtime.yml + - .github/workflows/coolify-realtime-next.yml + - docker/coolify-helper/Dockerfile + - docker/coolify-realtime/Dockerfile + - docker/testing-host/Dockerfile + - templates/service-templates.json + +env: + GITHUB_REGISTRY: ghcr.io + DOCKER_REGISTRY: docker.io + IMAGE_NAME: "coollabsio/coolify" + +jobs: + amd64: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Login to ${{ env.GITHUB_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.GITHUB_REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Get Version + id: version + run: | + echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getVersion.php)"|xargs >> $GITHUB_OUTPUT] + + - name: Build and Push Image + uses: docker/build-push-action@v6 + with: + context: . + file: docker/prod/Dockerfile + platforms: linux/amd64 + push: true + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} + labels: | + coolify.managed=true + + aarch64: + runs-on: [self-hosted, arm64] + steps: + - uses: actions/checkout@v4 + + - name: Login to ${{ env.GITHUB_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.GITHUB_REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Get Version + id: version + run: | + echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getVersion.php)"|xargs >> $GITHUB_OUTPUT] + + - name: Build and Push Image + uses: docker/build-push-action@v6 + with: + context: . + file: docker/prod/Dockerfile + platforms: linux/aarch64 + push: true + tags: | + ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 + ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 + labels: | + coolify.managed=true + + merge-manifest: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + needs: [amd64, aarch64] + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to ${{ env.GITHUB_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.GITHUB_REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to ${{ env.DOCKER_REGISTRY }} + uses: docker/login-action@v3 + with: + registry: ${{ env.DOCKER_REGISTRY }} + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_TOKEN }} + + - name: Get Version + id: version + run: | + echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getVersion.php)"|xargs >> $GITHUB_OUTPUT + + - name: Create & publish manifest on ${{ env.GITHUB_REGISTRY }} + run: | + docker buildx imagetools create \ + --append ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \ + --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \ + --tag ${{ env.GITHUB_REGISTRY }}/${{ env.IMAGE_NAME }}:latest + + - name: Create & publish manifest on ${{ env.DOCKER_REGISTRY }} + run: | + docker buildx imagetools create \ + --append ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 \ + --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} \ + --tag ${{ env.DOCKER_REGISTRY }}/${{ env.IMAGE_NAME }}:latest + + - uses: sarisia/actions-status-discord@v1 + if: always() + with: + webhook: ${{ secrets.DISCORD_WEBHOOK_PROD_RELEASE_CHANNEL }} diff --git a/.github/workflows/production-build.yml b/.github/workflows/production-build.yml deleted file mode 100644 index c78c865bf..000000000 --- a/.github/workflows/production-build.yml +++ /dev/null @@ -1,89 +0,0 @@ -name: Production Build (v4) - -on: - push: - branches: ["main"] - paths-ignore: - - .github/workflows/coolify-helper.yml - - docker/coolify-helper/Dockerfile - - templates/service-templates.json - -env: - REGISTRY: ghcr.io - IMAGE_NAME: "coollabsio/coolify" - -jobs: - amd64: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Login to ghcr.io - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Get Version - id: version - run: | - echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getVersion.php)"|xargs >> $GITHUB_OUTPUT - - name: Build image and push to registry - uses: docker/build-push-action@v5 - with: - context: . - file: docker/prod/Dockerfile - platforms: linux/amd64 - push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} - aarch64: - runs-on: [self-hosted, arm64] - steps: - - uses: actions/checkout@v4 - - name: Login to ghcr.io - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Get Version - id: version - run: | - echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getVersion.php)"|xargs >> $GITHUB_OUTPUT - - name: Build image and push to registry - uses: docker/build-push-action@v5 - with: - context: . - file: docker/prod/Dockerfile - platforms: linux/aarch64 - push: true - tags: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 - merge-manifest: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - needs: [amd64, aarch64] - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - name: Login to ghcr.io - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - name: Get Version - id: version - run: | - echo "VERSION=$(docker run --rm -v "$(pwd):/app" -w /app php:8.2-alpine3.16 php bootstrap/getVersion.php)"|xargs >> $GITHUB_OUTPUT - - name: Create & publish manifest - run: | - docker buildx imagetools create --append ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }}-aarch64 --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.VERSION }} --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - - uses: sarisia/actions-status-discord@v1 - if: always() - with: - webhook: ${{ secrets.DISCORD_WEBHOOK_PROD_RELEASE_CHANNEL }} From d11a363a204463892a9f68451773f97f28299b66 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 09:39:16 +0200 Subject: [PATCH 36/56] do we need qemu? nah --- .github/workflows/coolify-helper-next.yml | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/workflows/coolify-helper-next.yml b/.github/workflows/coolify-helper-next.yml index 50186b95a..4354294b1 100644 --- a/.github/workflows/coolify-helper-next.yml +++ b/.github/workflows/coolify-helper-next.yml @@ -99,14 +99,8 @@ jobs: packages: write needs: [ amd64, aarch64 ] steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - uses: actions/checkout@v4 + - uses: docker/setup-buildx-action@v3 - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 From e99b39d584d53479b154bb5e3c506a9513b16c65 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 09:44:22 +0200 Subject: [PATCH 37/56] remove unnecessary things --- .github/workflows/coolify-helper.yml | 9 ++------- .github/workflows/coolify-production-build.yml | 9 ++------- .github/workflows/coolify-realtime-next.yml | 9 ++------- .github/workflows/coolify-realtime.yml | 9 ++------- .github/workflows/coolify-staging-build.yml | 9 ++------- .github/workflows/coolify-testing-host.yml | 9 ++------- 6 files changed, 12 insertions(+), 42 deletions(-) diff --git a/.github/workflows/coolify-helper.yml b/.github/workflows/coolify-helper.yml index 2de4c85ba..6d852a2b3 100644 --- a/.github/workflows/coolify-helper.yml +++ b/.github/workflows/coolify-helper.yml @@ -98,14 +98,9 @@ jobs: packages: write needs: [ amd64, aarch64 ] steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - uses: docker/setup-buildx-action@v3 - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 diff --git a/.github/workflows/coolify-production-build.yml b/.github/workflows/coolify-production-build.yml index 9a63fbb27..771687d4b 100644 --- a/.github/workflows/coolify-production-build.yml +++ b/.github/workflows/coolify-production-build.yml @@ -100,14 +100,9 @@ jobs: packages: write needs: [amd64, aarch64] steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - uses: docker/setup-buildx-action@v3 - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 diff --git a/.github/workflows/coolify-realtime-next.yml b/.github/workflows/coolify-realtime-next.yml index d8c6e0aad..7e937d17a 100644 --- a/.github/workflows/coolify-realtime-next.yml +++ b/.github/workflows/coolify-realtime-next.yml @@ -103,14 +103,9 @@ jobs: packages: write needs: [ amd64, aarch64 ] steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - uses: docker/setup-buildx-action@v3 - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 diff --git a/.github/workflows/coolify-realtime.yml b/.github/workflows/coolify-realtime.yml index 7bf406ae6..97bfd52eb 100644 --- a/.github/workflows/coolify-realtime.yml +++ b/.github/workflows/coolify-realtime.yml @@ -103,14 +103,9 @@ jobs: packages: write needs: [ amd64, aarch64 ] steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - uses: docker/setup-buildx-action@v3 - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 diff --git a/.github/workflows/coolify-staging-build.yml b/.github/workflows/coolify-staging-build.yml index 2d2da6e75..dd5e6ebd6 100644 --- a/.github/workflows/coolify-staging-build.yml +++ b/.github/workflows/coolify-staging-build.yml @@ -93,14 +93,9 @@ jobs: packages: write needs: [amd64, aarch64] steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - uses: docker/setup-buildx-action@v3 - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 diff --git a/.github/workflows/coolify-testing-host.yml b/.github/workflows/coolify-testing-host.yml index 27c836730..95a228114 100644 --- a/.github/workflows/coolify-testing-host.yml +++ b/.github/workflows/coolify-testing-host.yml @@ -90,14 +90,9 @@ jobs: packages: write needs: [ amd64, aarch64 ] steps: - - name: Checkout - uses: actions/checkout@v4 + - uses: actions/checkout@v4 - - name: Set up QEMU - uses: docker/setup-qemu-action@v3 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + - uses: docker/setup-buildx-action@v3 - name: Login to ${{ env.GITHUB_REGISTRY }} uses: docker/login-action@v3 From c137620b81096fe4afa37a318ff4924a6c6ae335 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 10:29:45 +0200 Subject: [PATCH 38/56] chore: update Docker version to 26.0 --- app/Actions/Server/InstallDocker.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Actions/Server/InstallDocker.php b/app/Actions/Server/InstallDocker.php index f671f2d2a..2e1df8185 100644 --- a/app/Actions/Server/InstallDocker.php +++ b/app/Actions/Server/InstallDocker.php @@ -17,7 +17,7 @@ class InstallDocker throw new \Exception('Server OS type is not supported for automated installation. Please install Docker manually before continuing: documentation.'); } ray('Installing Docker on server: '.$server->name.' ('.$server->ip.')'.' with OS type: '.$supported_os_type); - $dockerVersion = '24.0'; + $dockerVersion = '26.0'; $config = base64_encode('{ "log-driver": "json-file", "log-opts": { From 1f193d465d79af918d20a4ac01a1033096347dc2 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 12:07:37 +0200 Subject: [PATCH 39/56] sentinel updates --- app/Actions/Server/StartSentinel.php | 27 +++- .../Controllers/Api/ServersController.php | 2 +- app/Jobs/PushServerUpdateJob.php | 53 ++++++++ app/Livewire/Server/Form.php | 45 ++++++- app/Models/Application.php | 2 +- app/Models/InstanceSettings.php | 1 + app/Models/Server.php | 42 +++--- app/Models/ServerSetting.php | 7 +- app/Models/StandaloneClickhouse.php | 2 +- app/Models/StandaloneDragonfly.php | 2 +- app/Models/StandaloneKeydb.php | 2 +- app/Models/StandaloneMariadb.php | 2 +- app/Models/StandaloneMongodb.php | 2 +- app/Models/StandaloneMysql.php | 2 +- app/Models/StandalonePostgresql.php | 2 +- app/Models/StandaloneRedis.php | 2 +- bootstrap/helpers/shared.php | 7 - .../2024_06_18_105948_move_server_metrics.php | 2 +- ...pdate_metrics_token_in_server_settings.php | 38 ++++++ openapi.yaml | 6 +- .../views/livewire/server/form.blade.php | 121 ++++++++++-------- routes/api.php | 25 ++++ scripts/install.sh | 2 +- 23 files changed, 293 insertions(+), 103 deletions(-) create mode 100644 app/Jobs/PushServerUpdateJob.php create mode 100644 database/migrations/2024_10_14_090416_update_metrics_token_in_server_settings.php diff --git a/app/Actions/Server/StartSentinel.php b/app/Actions/Server/StartSentinel.php index b79bc8f67..4b45d0738 100644 --- a/app/Actions/Server/StartSentinel.php +++ b/app/Actions/Server/StartSentinel.php @@ -2,6 +2,7 @@ namespace App\Actions\Server; +use App\Models\InstanceSettings; use App\Models\Server; use Lorisleiva\Actions\Concerns\AsAction; @@ -16,11 +17,25 @@ class StartSentinel } $metrics_history = $server->settings->metrics_history_days; $refresh_rate = $server->settings->metrics_refresh_rate_seconds; - $token = $server->settings->metrics_token; - instant_remote_process([ - "docker run --rm --pull always -d -e \"TOKEN={$token}\" -e \"SCHEDULER=true\" -e \"METRICS_HISTORY={$metrics_history}\" -e \"REFRESH_RATE={$refresh_rate}\" --name coolify-sentinel -v /var/run/docker.sock:/var/run/docker.sock -v /data/coolify/metrics:/app/metrics -v /data/coolify/logs:/app/logs --pid host --health-cmd \"curl --fail http://127.0.0.1:8888/api/health || exit 1\" --health-interval 10s --health-retries 3 ghcr.io/coollabsio/sentinel:$version", - 'chown -R 9999:root /data/coolify/metrics /data/coolify/logs', - 'chmod -R 700 /data/coolify/metrics /data/coolify/logs', - ], $server, true); + $token = $server->settings->sentinel_token; + $fqdn = InstanceSettings::get()->fqdn; + if (str($fqdn)->startsWith('http')) { + throw new \Exception('You should use https to run Sentinel.'); + } + $environments = [ + 'TOKEN' => $token, + 'ENDPOINT' => InstanceSettings::get()->fqdn, + 'COLLECTOR_ENABLED' => 'true', + 'COLLECTOR_REFRESH_RATE_SECONDS' => $refresh_rate, + 'COLLECTOR_RETENTION_PERIOD_DAYS' => $metrics_history + ]; + $docker_environments = "-e \"" . implode("\" -e \"", array_map(fn($key, $value) => "$key=$value", array_keys($environments), $environments)) . "\""; + ray($docker_environments); + return true; + // instant_remote_process([ + // "docker run --rm --pull always -d $docker_environments --name coolify-sentinel -v /var/run/docker.sock:/var/run/docker.sock -v /data/coolify/sentinel:/app/sentinel --pid host --health-cmd \"curl --fail http://127.0.0.1:8888/api/health || exit 1\" --health-interval 10s --health-retries 3 ghcr.io/coollabsio/sentinel:$version", + // 'chown -R 9999:root /data/coolify/sentinel', + // 'chmod -R 700 /data/coolify/sentinel', + // ], $server, true); } } diff --git a/app/Http/Controllers/Api/ServersController.php b/app/Http/Controllers/Api/ServersController.php index a49515579..6d512e578 100644 --- a/app/Http/Controllers/Api/ServersController.php +++ b/app/Http/Controllers/Api/ServersController.php @@ -23,7 +23,7 @@ class ServersController extends Controller return serializeApiResponse($settings); } $settings = $settings->makeHidden([ - 'metrics_token', + 'sentinel_token', ]); return serializeApiResponse($settings); diff --git a/app/Jobs/PushServerUpdateJob.php b/app/Jobs/PushServerUpdateJob.php new file mode 100644 index 000000000..27aa58201 --- /dev/null +++ b/app/Jobs/PushServerUpdateJob.php @@ -0,0 +1,53 @@ +data) { + throw new \Exception('No data provided'); + } + $data = collect($this->data); + $containers = collect(data_get($data, 'containers')); + if ($containers->isEmpty()) { + return; + } + foreach ($containers as $container) { + $containerStatus = data_get($container, 'status', 'exited'); + $containerHealth = data_get($container, 'health', 'unhealthy'); + $containerStatus = "$containerStatus ($containerHealth)"; + $labels = collect(data_get($container, 'labels')); + if ($labels->has('coolify.applicationId')) { + $applicationId = $labels->get('coolify.applicationId'); + } + Log::info("$applicationId, $containerStatus"); + } + } + + +} diff --git a/app/Livewire/Server/Form.php b/app/Livewire/Server/Form.php index fe7fc6020..6efff504b 100644 --- a/app/Livewire/Server/Form.php +++ b/app/Livewire/Server/Form.php @@ -7,6 +7,7 @@ use App\Actions\Server\StopSentinel; use App\Jobs\DockerCleanupJob; use App\Jobs\PullSentinelImageJob; use App\Models\Server; +use Illuminate\Support\Facades\Http; use Livewire\Component; class Form extends Component @@ -54,9 +55,9 @@ class Form extends Component 'server.settings.concurrent_builds' => 'required|integer|min:1', 'server.settings.dynamic_timeout' => 'required|integer|min:1', 'server.settings.is_metrics_enabled' => 'required|boolean', - 'server.settings.metrics_token' => 'required', - 'server.settings.metrics_refresh_rate_seconds' => 'required|integer|min:1', - 'server.settings.metrics_history_days' => 'required|integer|min:1', + 'server.settings.sentinel_token' => 'required', + 'server.settings.sentinel_metrics_refresh_rate_seconds' => 'required|integer|min:1', + 'server.settings.sentinel_metrics_history_days' => 'required|integer|min:1', 'wildcard_domain' => 'nullable|url', 'server.settings.is_server_api_enabled' => 'required|boolean', 'server.settings.server_timezone' => 'required|string|timezone', @@ -81,9 +82,9 @@ class Form extends Component 'server.settings.concurrent_builds' => 'Concurrent Builds', 'server.settings.dynamic_timeout' => 'Dynamic Timeout', 'server.settings.is_metrics_enabled' => 'Metrics', - 'server.settings.metrics_token' => 'Metrics Token', - 'server.settings.metrics_refresh_rate_seconds' => 'Metrics Interval', - 'server.settings.metrics_history_days' => 'Metrics History', + 'server.settings.sentinel_token' => 'Metrics Token', + 'server.settings.sentinel_metrics_refresh_rate_seconds' => 'Metrics Interval', + 'server.settings.sentinel_metrics_history_days' => 'Metrics History', 'server.settings.is_server_api_enabled' => 'Server API', 'server.settings.server_timezone' => 'Server Timezone', 'server.settings.delete_unused_volumes' => 'Delete Unused Volumes', @@ -100,7 +101,15 @@ class Form extends Component $this->server->settings->delete_unused_volumes = $server->settings->delete_unused_volumes; $this->server->settings->delete_unused_networks = $server->settings->delete_unused_networks; } - + public function regenerateSentinelToken() { + try { + $this->server->generateSentinelToken(); + $this->server->settings->refresh(); + $this->dispatch('success', 'Metrics token regenerated.'); + } catch (\Throwable $e) { + return handleError($e, $this); + } + } public function updated($field) { if ($field === 'server.settings.docker_cleanup_frequency') { @@ -174,6 +183,28 @@ class Form extends Component } } + public function getPushData() + { + try { + if (!isDev()) { + throw new \Exception('This feature is only available in dev mode.'); + } + $response = Http::withHeaders([ + 'Authorization' => 'Bearer ' . $this->server->settings->sentinel_token, + ])->post('http://host.docker.internal:8888/api/push', [ + 'data' => 'test', + ]); + if ($response->successful()) { + $this->dispatch('success', 'Push data sent.'); + return; + } + $error = data_get($response->json(), 'error'); + throw new \Exception($error); + + } catch(\Throwable $e) { + return handleError($e, $this); + } + } public function restartSentinel() { try { diff --git a/app/Models/Application.php b/app/Models/Application.php index 07aeb4c5b..10ef8079c 100644 --- a/app/Models/Application.php +++ b/app/Models/Application.php @@ -1406,7 +1406,7 @@ class Application extends BaseModel $container_name = $this->uuid; if ($server->isMetricsEnabled()) { $from = now()->subMinutes($mins)->toIso8601ZuluString(); - $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); + $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); if (str($metrics)->contains('error')) { $error = json_decode($metrics, true); $error = data_get($error, 'error', 'Something is not okay, are you okay?'); diff --git a/app/Models/InstanceSettings.php b/app/Models/InstanceSettings.php index bb3d1478b..3ee142050 100644 --- a/app/Models/InstanceSettings.php +++ b/app/Models/InstanceSettings.php @@ -21,6 +21,7 @@ class InstanceSettings extends Model implements SendsEmail 'is_auto_update_enabled' => 'boolean', 'auto_update_frequency' => 'string', 'update_check_frequency' => 'string', + 'sentinel_token' => 'encrypted', ]; public function fqdn(): Attribute diff --git a/app/Models/Server.php b/app/Models/Server.php index 0eca3c168..cd7667c70 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -17,6 +17,8 @@ use Spatie\SchemalessAttributes\Casts\SchemalessAttributes; use Spatie\SchemalessAttributes\SchemalessAttributesTrait; use Spatie\Url\Url; use Symfony\Component\Yaml\Yaml; +use Illuminate\Support\Str; + #[OA\Schema( description: 'Server model', @@ -166,7 +168,7 @@ class Server extends BaseModel public function setupDefault404Redirect() { - $dynamic_conf_path = $this->proxyPath().'/dynamic'; + $dynamic_conf_path = $this->proxyPath() . '/dynamic'; $proxy_type = $this->proxyType(); $redirect_url = $this->proxy->redirect_url; if ($proxy_type === ProxyTypes::TRAEFIK->value) { @@ -180,8 +182,8 @@ class Server extends BaseModel respond 404 }'; $conf = - "# This file is automatically generated by Coolify.\n". - "# Do not edit it manually (only if you know what are you doing).\n\n". + "# This file is automatically generated by Coolify.\n" . + "# Do not edit it manually (only if you know what are you doing).\n\n" . $conf; $base64 = base64_encode($conf); instant_remote_process([ @@ -243,8 +245,8 @@ respond 404 ]; $conf = Yaml::dump($dynamic_conf, 12, 2); $conf = - "# This file is automatically generated by Coolify.\n". - "# Do not edit it manually (only if you know what are you doing).\n\n". + "# This file is automatically generated by Coolify.\n" . + "# Do not edit it manually (only if you know what are you doing).\n\n" . $conf; $base64 = base64_encode($conf); @@ -253,8 +255,8 @@ respond 404 redir $redirect_url }"; $conf = - "# This file is automatically generated by Coolify.\n". - "# Do not edit it manually (only if you know what are you doing).\n\n". + "# This file is automatically generated by Coolify.\n" . + "# Do not edit it manually (only if you know what are you doing).\n\n" . $conf; $base64 = base64_encode($conf); } @@ -272,7 +274,7 @@ respond 404 public function setupDynamicProxyConfiguration() { $settings = instanceSettings(); - $dynamic_config_path = $this->proxyPath().'/dynamic'; + $dynamic_config_path = $this->proxyPath() . '/dynamic'; if ($this->proxyType() === ProxyTypes::TRAEFIK->value) { $file = "$dynamic_config_path/coolify.yaml"; if (empty($settings->fqdn) || (isCloud() && $this->id !== 0) || ! $this->isLocalhost()) { @@ -391,8 +393,8 @@ respond 404 } $yaml = Yaml::dump($traefik_dynamic_conf, 12, 2); $yaml = - "# This file is automatically generated by Coolify.\n". - "# Do not edit it manually (only if you know what are you doing).\n\n". + "# This file is automatically generated by Coolify.\n" . + "# Do not edit it manually (only if you know what are you doing).\n\n" . $yaml; $base64 = base64_encode($yaml); @@ -456,13 +458,13 @@ $schema://$host { if (isDev()) { $proxy_path = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/proxy/caddy'; } else { - $proxy_path = $proxy_path.'/caddy'; + $proxy_path = $proxy_path . '/caddy'; } } elseif ($proxyType === ProxyTypes::NGINX->value) { if (isDev()) { $proxy_path = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/proxy/nginx'; } else { - $proxy_path = $proxy_path.'/nginx'; + $proxy_path = $proxy_path . '/nginx'; } } @@ -525,6 +527,17 @@ $schema://$host { Storage::disk('ssh-mux')->delete($this->muxFilename()); } + public function generateSentinelToken() + { + $data = [ + 'server_uuid' => $this->uuid, + ]; + $token = json_encode($data); + $encrypted = encrypt($token); + $this->settings->sentinel_token = $encrypted; + $this->settings->save(); + return $encrypted; + } public function isSentinelEnabled() { return $this->isMetricsEnabled() || $this->isServerApiEnabled(); @@ -555,7 +568,6 @@ $schema://$host { ray($process->exitCode(), $process->output(), $process->errorOutput()); throw new \Exception("Server API is not reachable on http://{$server_ip}:12172"); } - } } @@ -579,7 +591,7 @@ $schema://$host { { if ($this->isMetricsEnabled()) { $from = now()->subMinutes($mins)->toIso8601ZuluString(); - $cpu = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$this->settings->metrics_token}\" http://localhost:8888/api/cpu/history?from=$from'"], $this, false); + $cpu = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$this->settings->sentinel_token}\" http://localhost:8888/api/cpu/history?from=$from'"], $this, false); if (str($cpu)->contains('error')) { $error = json_decode($cpu, true); $error = data_get($error, 'error', 'Something is not okay, are you okay?'); @@ -606,7 +618,7 @@ $schema://$host { { if ($this->isMetricsEnabled()) { $from = now()->subMinutes($mins)->toIso8601ZuluString(); - $memory = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$this->settings->metrics_token}\" http://localhost:8888/api/memory/history?from=$from'"], $this, false); + $memory = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$this->settings->sentinel_token}\" http://localhost:8888/api/memory/history?from=$from'"], $this, false); if (str($memory)->contains('error')) { $error = json_decode($memory, true); $error = data_get($error, 'error', 'Something is not okay, are you okay?'); diff --git a/app/Models/ServerSetting.php b/app/Models/ServerSetting.php index c44a393b4..f5e0f7b0b 100644 --- a/app/Models/ServerSetting.php +++ b/app/Models/ServerSetting.php @@ -35,9 +35,9 @@ use OpenApi\Attributes as OA; 'logdrain_highlight_project_id' => ['type' => 'string'], 'logdrain_newrelic_base_uri' => ['type' => 'string'], 'logdrain_newrelic_license_key' => ['type' => 'string'], - 'metrics_history_days' => ['type' => 'integer'], - 'metrics_refresh_rate_seconds' => ['type' => 'integer'], - 'metrics_token' => ['type' => 'string'], + 'sentinel_metrics_history_days' => ['type' => 'integer'], + 'sentinel_metrics_refresh_rate_seconds' => ['type' => 'integer'], + 'sentinel_token' => ['type' => 'string'], 'docker_cleanup_frequency' => ['type' => 'string'], 'docker_cleanup_threshold' => ['type' => 'integer'], 'server_id' => ['type' => 'integer'], @@ -53,6 +53,7 @@ class ServerSetting extends Model protected $casts = [ 'force_docker_cleanup' => 'boolean', 'docker_cleanup_threshold' => 'integer', + 'sentinel_token' => 'encrypted', ]; public function server() diff --git a/app/Models/StandaloneClickhouse.php b/app/Models/StandaloneClickhouse.php index e4341b1b9..6274f51b2 100644 --- a/app/Models/StandaloneClickhouse.php +++ b/app/Models/StandaloneClickhouse.php @@ -272,7 +272,7 @@ class StandaloneClickhouse extends BaseModel $container_name = $this->uuid; if ($server->isMetricsEnabled()) { $from = now()->subMinutes($mins)->toIso8601ZuluString(); - $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); + $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); if (str($metrics)->contains('error')) { $error = json_decode($metrics, true); $error = data_get($error, 'error', 'Something is not okay, are you okay?'); diff --git a/app/Models/StandaloneDragonfly.php b/app/Models/StandaloneDragonfly.php index 94ab2d745..3555e7afd 100644 --- a/app/Models/StandaloneDragonfly.php +++ b/app/Models/StandaloneDragonfly.php @@ -272,7 +272,7 @@ class StandaloneDragonfly extends BaseModel $container_name = $this->uuid; if ($server->isMetricsEnabled()) { $from = now()->subMinutes($mins)->toIso8601ZuluString(); - $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); + $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); if (str($metrics)->contains('error')) { $error = json_decode($metrics, true); $error = data_get($error, 'error', 'Something is not okay, are you okay?'); diff --git a/app/Models/StandaloneKeydb.php b/app/Models/StandaloneKeydb.php index 335c8931c..4725ca533 100644 --- a/app/Models/StandaloneKeydb.php +++ b/app/Models/StandaloneKeydb.php @@ -272,7 +272,7 @@ class StandaloneKeydb extends BaseModel $container_name = $this->uuid; if ($server->isMetricsEnabled()) { $from = now()->subMinutes($mins)->toIso8601ZuluString(); - $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); + $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); if (str($metrics)->contains('error')) { $error = json_decode($metrics, true); $error = data_get($error, 'error', 'Something is not okay, are you okay?'); diff --git a/app/Models/StandaloneMariadb.php b/app/Models/StandaloneMariadb.php index c6c08dee5..8f1a2c1ee 100644 --- a/app/Models/StandaloneMariadb.php +++ b/app/Models/StandaloneMariadb.php @@ -272,7 +272,7 @@ class StandaloneMariadb extends BaseModel $container_name = $this->uuid; if ($server->isMetricsEnabled()) { $from = now()->subMinutes($mins)->toIso8601ZuluString(); - $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); + $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); if (str($metrics)->contains('error')) { $error = json_decode($metrics, true); $error = data_get($error, 'error', 'Something is not okay, are you okay?'); diff --git a/app/Models/StandaloneMongodb.php b/app/Models/StandaloneMongodb.php index 99893b1d1..41b2ce9eb 100644 --- a/app/Models/StandaloneMongodb.php +++ b/app/Models/StandaloneMongodb.php @@ -292,7 +292,7 @@ class StandaloneMongodb extends BaseModel $container_name = $this->uuid; if ($server->isMetricsEnabled()) { $from = now()->subMinutes($mins)->toIso8601ZuluString(); - $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); + $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); if (str($metrics)->contains('error')) { $error = json_decode($metrics, true); $error = data_get($error, 'error', 'Something is not okay, are you okay?'); diff --git a/app/Models/StandaloneMysql.php b/app/Models/StandaloneMysql.php index f2a5b5c14..da2ac070f 100644 --- a/app/Models/StandaloneMysql.php +++ b/app/Models/StandaloneMysql.php @@ -273,7 +273,7 @@ class StandaloneMysql extends BaseModel $container_name = $this->uuid; if ($server->isMetricsEnabled()) { $from = now()->subMinutes($mins)->toIso8601ZuluString(); - $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); + $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); if (str($metrics)->contains('error')) { $error = json_decode($metrics, true); $error = data_get($error, 'error', 'Something is not okay, are you okay?'); diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php index 1b18a5ca7..e0f42269d 100644 --- a/app/Models/StandalonePostgresql.php +++ b/app/Models/StandalonePostgresql.php @@ -274,7 +274,7 @@ class StandalonePostgresql extends BaseModel $container_name = $this->uuid; if ($server->isMetricsEnabled()) { $from = now()->subMinutes($mins)->toIso8601ZuluString(); - $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); + $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); if (str($metrics)->contains('error')) { $error = json_decode($metrics, true); $error = data_get($error, 'error', 'Something is not okay, are you okay?'); diff --git a/app/Models/StandaloneRedis.php b/app/Models/StandaloneRedis.php index a5868e243..fe9f6dfc7 100644 --- a/app/Models/StandaloneRedis.php +++ b/app/Models/StandaloneRedis.php @@ -268,7 +268,7 @@ class StandaloneRedis extends BaseModel $container_name = $this->uuid; if ($server->isMetricsEnabled()) { $from = now()->subMinutes($mins)->toIso8601ZuluString(); - $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->metrics_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); + $metrics = instant_remote_process(["docker exec coolify-sentinel sh -c 'curl -H \"Authorization: Bearer {$server->settings->sentinel_token}\" http://localhost:8888/api/container/{$container_name}/metrics/history?from=$from'"], $server, false); if (str($metrics)->contains('error')) { $error = json_decode($metrics, true); $error = data_get($error, 'error', 'Something is not okay, are you okay?'); diff --git a/bootstrap/helpers/shared.php b/bootstrap/helpers/shared.php index ea9d6ff3c..86c6def76 100644 --- a/bootstrap/helpers/shared.php +++ b/bootstrap/helpers/shared.php @@ -1338,13 +1338,6 @@ function isAnyDeploymentInprogress() exit(0); } -function generateSentinelToken() -{ - $token = Str::random(64); - - return $token; -} - function isBase64Encoded($strValue) { return base64_encode(base64_decode($strValue, true)) === $strValue; diff --git a/database/migrations/2024_06_18_105948_move_server_metrics.php b/database/migrations/2024_06_18_105948_move_server_metrics.php index 26a1d1684..a6bccd16a 100644 --- a/database/migrations/2024_06_18_105948_move_server_metrics.php +++ b/database/migrations/2024_06_18_105948_move_server_metrics.php @@ -18,7 +18,7 @@ return new class extends Migration $table->boolean('is_metrics_enabled')->default(false); $table->integer('metrics_refresh_rate_seconds')->default(5); $table->integer('metrics_history_days')->default(30); - $table->string('metrics_token')->default(generateSentinelToken()); + $table->string('metrics_token')->nullable(); }); } diff --git a/database/migrations/2024_10_14_090416_update_metrics_token_in_server_settings.php b/database/migrations/2024_10_14_090416_update_metrics_token_in_server_settings.php new file mode 100644 index 000000000..32b1e5349 --- /dev/null +++ b/database/migrations/2024_10_14_090416_update_metrics_token_in_server_settings.php @@ -0,0 +1,38 @@ +dropColumn('metrics_token'); + $table->dropColumn('metrics_refresh_rate_seconds'); + $table->dropColumn('metrics_history_days'); + $table->text('sentinel_token')->nullable(); + $table->integer('sentinel_metrics_refresh_rate_seconds')->default(5); + $table->integer('sentinel_metrics_history_days')->default(30); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('server_settings', function (Blueprint $table) { + $table->string('metrics_token')->nullable(); + $table->integer('metrics_refresh_rate_seconds')->default(5); + $table->integer('metrics_history_days')->default(30); + $table->dropColumn('sentinel_token'); + $table->dropColumn('sentinel_metrics_refresh_rate_seconds'); + $table->dropColumn('sentinel_metrics_history_days'); + }); + } +}; diff --git a/openapi.yaml b/openapi.yaml index 91d5c1443..3521b7de4 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -4981,11 +4981,11 @@ components: type: string logdrain_newrelic_license_key: type: string - metrics_history_days: + sentinel_metrics_refresh_rate_seconds: type: integer - metrics_refresh_rate_seconds: + sentinel_metrics_history_days: type: integer - metrics_token: + sentinel_token: type: string docker_cleanup_frequency: type: string diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index 48c16051e..d3f51625a 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -68,7 +68,8 @@
+ helper="An IP Address (127.0.0.1) or domain (example.com). Make sure there is no protocol like http(s):// so you provide a FQDN not a URL." + required />
@@ -94,7 +95,8 @@
- @@ -129,23 +131,32 @@
@if ($server->settings->is_cloudflare_tunnel)
- +
@elseif (!$server->isFunctional()) -
- To automatically configure Cloudflare Tunnels, please validate your server first. Then you will need a Cloudflare token and an SSH domain configured. -
- To manually configure Cloudflare Tunnels, please click here, then you should validate the server. -

- For more information, please read our documentation. +
+ To automatically configure Cloudflare Tunnels, please + validate your server first. Then you will need a Cloudflare token and an SSH + domain configured. +
+ To manually configure Cloudflare Tunnels, please + click here, then you should validate the server. +

+ For more information, please read our documentation.
@endif @if (!$server->settings->is_cloudflare_tunnel && $server->isFunctional()) - + @endif - @if ($server->isFunctional() &&!$server->settings->is_cloudflare_tunnel) + @if ($server->isFunctional() && !$server->settings->is_cloudflare_tunnel)
I have configured Cloudflare Tunnels manually
@@ -201,57 +212,58 @@ " instantSave id="server.settings.force_docker_cleanup" label="Force Docker Cleanup" />
- + 'Optionally permanently deletes all unused networks (if enabled in advanced options).', + ]" :confirmWithText="false" :confirmWithPassword="false" + step2ButtonText="Trigger Docker Cleanup" />
@if ($server->settings->force_docker_cleanup) - @else - + @endif
-
-

Warning: Enable these options only if you fully understand their implications and consequences!
Improper use will result in data loss and could cause functional issues.

- Warning: Enable these + options only if you fully understand their implications and + consequences!
Improper use will result in data loss and could cause + functional issues.

+ - " /> + + " />
@@ -269,21 +281,30 @@ {{-- Restart --}} {{-- @endif --}} -
Metrics are disabled until a few bugs are fixed.
- {{--
+ @if (isDev()) + Get Push Data + {{--
-
-
-
- - - + Start Sentinel +
--}} +
+
+ + Regenerate +
+
+ + +
-
--}} + @else +
Metrics are disabled until a few bugs are fixed.
+ @endif @endif
diff --git a/routes/api.php b/routes/api.php index 57f45be5d..76fd93141 100644 --- a/routes/api.php +++ b/routes/api.php @@ -13,6 +13,9 @@ use App\Http\Controllers\Api\TeamController; use App\Http\Middleware\ApiAllowed; use App\Http\Middleware\IgnoreReadOnlyApiToken; use App\Http\Middleware\OnlyRootApiToken; +use App\Jobs\PushServerUpdateJob; +use App\Models\Server; +use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Route; Route::get('/health', [OtherController::class, 'healthcheck']); @@ -129,6 +132,28 @@ Route::group([ }); +Route::group([ + 'prefix' => 'v1', +], function () { + Route::post('/sentinel/push', function () { + $token = request()->header('Authorization'); + if (!$token) { + return response()->json(['message' => 'Unauthorized'], 401); + } + $naked_token = str_replace('Bearer ', '', $token); + $decrypted = decrypt($naked_token); + $decrypted_token = json_decode($decrypted, true); + $server_uuid = data_get($decrypted_token, 'server_uuid'); + $server = Server::where('uuid', $server_uuid)->first(); + if (!$server) { + return response()->json(['message' => 'Server not found'], 404); + } + $data = request()->all(); + PushServerUpdateJob::dispatch($server, $data); + return response()->json(['message' => 'ok'], 200); + }); +}); + Route::any('/{any}', function () { return response()->json(['message' => 'Not found.', 'docs' => 'https://coolify.io/docs'], 404); })->where('any', '.*'); diff --git a/scripts/install.sh b/scripts/install.sh index 76a369e62..af3b4d464 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -13,7 +13,7 @@ DOCKER_VERSION="26.0" # TODO: Ask for a user CURRENT_USER=$USER -mkdir -p /data/coolify/{source,ssh,applications,databases,backups,services,proxy,webhooks-during-maintenance,metrics,logs} +mkdir -p /data/coolify/{source,ssh,applications,databases,backups,services,proxy,webhooks-during-maintenance,sentinel} mkdir -p /data/coolify/ssh/{keys,mux} mkdir -p /data/coolify/proxy/dynamic From b2e515f770553bd18e1972c5906073331766a14b Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 13:32:36 +0200 Subject: [PATCH 40/56] sentinel --- app/Console/Kernel.php | 2 +- app/Jobs/PushServerUpdateJob.php | 101 ++++++++++++++++-- app/Models/Server.php | 31 +++--- ...pdate_metrics_token_in_server_settings.php | 6 ++ .../views/livewire/server/form.blade.php | 2 +- routes/api.php | 7 +- 6 files changed, 120 insertions(+), 29 deletions(-) diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 1430fcdd1..6da32b461 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -38,7 +38,7 @@ class Kernel extends ConsoleKernel $schedule->job(new CleanupInstanceStuffsJob)->everyMinute()->onOneServer(); // Server Jobs $this->check_scheduled_backups($schedule); - $this->check_resources($schedule); + // $this->check_resources($schedule); $this->check_scheduled_tasks($schedule); $schedule->command('uploads:clear')->everyTwoMinutes(); diff --git a/app/Jobs/PushServerUpdateJob.php b/app/Jobs/PushServerUpdateJob.php index 27aa58201..226cf9392 100644 --- a/app/Jobs/PushServerUpdateJob.php +++ b/app/Jobs/PushServerUpdateJob.php @@ -2,14 +2,16 @@ namespace App\Jobs; +use App\Actions\Proxy\StartProxy; +use App\Models\Application; +use App\Models\ApplicationPreview; use App\Models\Server; use Illuminate\Bus\Queueable; -use Illuminate\Contracts\Queue\ShouldBeEncrypted; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -use Illuminate\Support\Arr; +use Illuminate\Support\Collection; use Illuminate\Support\Facades\Log; class PushServerUpdateJob implements ShouldQueue @@ -25,11 +27,19 @@ class PushServerUpdateJob implements ShouldQueue return isDev() ? 1 : 3; } - public function __construct(public Server $server, public $data) {} + public function __construct(public Server $server, public $data) + { + // TODO: Handle multiple servers + // TODO: Handle Preview deployments + // TODO: Handle DB TCP proxies + // TODO: Handle DBs + // TODO: Handle services + // TODO: Handle proxies + } public function handle() { - if (!$this->data) { + if (! $this->data) { throw new \Exception('No data provided'); } $data = collect($this->data); @@ -37,17 +47,90 @@ class PushServerUpdateJob implements ShouldQueue if ($containers->isEmpty()) { return; } + $foundApplicationIds = collect(); + $foundServiceIds = collect(); + $foundProxy = false; foreach ($containers as $container) { - $containerStatus = data_get($container, 'status', 'exited'); - $containerHealth = data_get($container, 'health', 'unhealthy'); + $containerStatus = data_get($container, 'state', 'exited'); + $containerHealth = data_get($container, 'health_status', 'unhealthy'); $containerStatus = "$containerStatus ($containerHealth)"; $labels = collect(data_get($container, 'labels')); - if ($labels->has('coolify.applicationId')) { - $applicationId = $labels->get('coolify.applicationId'); + $coolify_managed = $labels->has('coolify.managed'); + if ($coolify_managed) { + if ($labels->has('coolify.applicationId')) { + $applicationId = $labels->get('coolify.applicationId'); + $pullRequestId = data_get($labels, 'coolify.pullRequestId', '0'); + $foundApplicationIds->push($applicationId); + try { + $this->updateApplicationStatus($applicationId, $pullRequestId, $containerStatus); + } catch (\Exception $e) { + Log::error($e); + } + } elseif ($labels->has('coolify.serviceId')) { + $serviceId = $labels->get('coolify.serviceId'); + $foundServiceIds->push($serviceId); + Log::info("Service: $serviceId, $containerStatus"); + } else { + $name = data_get($container, 'name'); + $uuid = $labels->get('com.docker.compose.service'); + $type = $labels->get('coolify.type'); + if ($name === 'coolify-proxy') { + $foundProxy = true; + Log::info("Proxy: $uuid, $containerStatus"); + } elseif ($type === 'service') { + Log::info("Service: $uuid, $containerStatus"); + } else { + Log::info("Database: $uuid, $containerStatus"); + } + } } - Log::info("$applicationId, $containerStatus"); + } + + // If proxy is not found, start it + if (! $foundProxy && $this->server->isProxyShouldRun()) { + Log::info('Proxy not found, starting it'); + StartProxy::dispatch($this->server); + } + + // Update not found applications + $allApplicationIds = $this->server->applications()->pluck('id'); + $notFoundApplicationIds = $allApplicationIds->diff($foundApplicationIds); + if ($notFoundApplicationIds->isNotEmpty()) { + Log::info('Not found application ids', ['application_ids' => $notFoundApplicationIds]); + $this->updateNotFoundApplications($notFoundApplicationIds); } } + private function updateApplicationStatus(string $applicationId, string $pullRequestId, string $containerStatus) + { + if ($pullRequestId === '0') { + $application = Application::find($applicationId); + if (! $application) { + return; + } + $application->status = $containerStatus; + $application->save(); + Log::info('Application updated', ['application_id' => $applicationId, 'status' => $containerStatus]); + } else { + $application = ApplicationPreview::where('application_id', $applicationId)->where('pull_request_id', $pullRequestId)->first(); + if (! $application) { + return; + } + $application->status = $containerStatus; + $application->save(); + } + } + private function updateNotFoundApplications(Collection $applicationIds) + { + $applicationIds->each(function ($applicationId) { + Log::info('Updating application status', ['application_id' => $applicationId, 'status' => 'exited']); + $application = Application::find($applicationId); + if ($application) { + $application->status = 'exited'; + $application->save(); + Log::info('Application status updated', ['application_id' => $applicationId, 'status' => 'exited']); + } + }); + } } diff --git a/app/Models/Server.php b/app/Models/Server.php index cd7667c70..9e947c20b 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -17,8 +17,6 @@ use Spatie\SchemalessAttributes\Casts\SchemalessAttributes; use Spatie\SchemalessAttributes\SchemalessAttributesTrait; use Spatie\Url\Url; use Symfony\Component\Yaml\Yaml; -use Illuminate\Support\Str; - #[OA\Schema( description: 'Server model', @@ -168,7 +166,7 @@ class Server extends BaseModel public function setupDefault404Redirect() { - $dynamic_conf_path = $this->proxyPath() . '/dynamic'; + $dynamic_conf_path = $this->proxyPath().'/dynamic'; $proxy_type = $this->proxyType(); $redirect_url = $this->proxy->redirect_url; if ($proxy_type === ProxyTypes::TRAEFIK->value) { @@ -182,8 +180,8 @@ class Server extends BaseModel respond 404 }'; $conf = - "# This file is automatically generated by Coolify.\n" . - "# Do not edit it manually (only if you know what are you doing).\n\n" . + "# This file is automatically generated by Coolify.\n". + "# Do not edit it manually (only if you know what are you doing).\n\n". $conf; $base64 = base64_encode($conf); instant_remote_process([ @@ -245,8 +243,8 @@ respond 404 ]; $conf = Yaml::dump($dynamic_conf, 12, 2); $conf = - "# This file is automatically generated by Coolify.\n" . - "# Do not edit it manually (only if you know what are you doing).\n\n" . + "# This file is automatically generated by Coolify.\n". + "# Do not edit it manually (only if you know what are you doing).\n\n". $conf; $base64 = base64_encode($conf); @@ -255,8 +253,8 @@ respond 404 redir $redirect_url }"; $conf = - "# This file is automatically generated by Coolify.\n" . - "# Do not edit it manually (only if you know what are you doing).\n\n" . + "# This file is automatically generated by Coolify.\n". + "# Do not edit it manually (only if you know what are you doing).\n\n". $conf; $base64 = base64_encode($conf); } @@ -274,7 +272,7 @@ respond 404 public function setupDynamicProxyConfiguration() { $settings = instanceSettings(); - $dynamic_config_path = $this->proxyPath() . '/dynamic'; + $dynamic_config_path = $this->proxyPath().'/dynamic'; if ($this->proxyType() === ProxyTypes::TRAEFIK->value) { $file = "$dynamic_config_path/coolify.yaml"; if (empty($settings->fqdn) || (isCloud() && $this->id !== 0) || ! $this->isLocalhost()) { @@ -393,8 +391,8 @@ respond 404 } $yaml = Yaml::dump($traefik_dynamic_conf, 12, 2); $yaml = - "# This file is automatically generated by Coolify.\n" . - "# Do not edit it manually (only if you know what are you doing).\n\n" . + "# This file is automatically generated by Coolify.\n". + "# Do not edit it manually (only if you know what are you doing).\n\n". $yaml; $base64 = base64_encode($yaml); @@ -458,13 +456,13 @@ $schema://$host { if (isDev()) { $proxy_path = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/proxy/caddy'; } else { - $proxy_path = $proxy_path . '/caddy'; + $proxy_path = $proxy_path.'/caddy'; } } elseif ($proxyType === ProxyTypes::NGINX->value) { if (isDev()) { $proxy_path = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/proxy/nginx'; } else { - $proxy_path = $proxy_path . '/nginx'; + $proxy_path = $proxy_path.'/nginx'; } } @@ -536,8 +534,10 @@ $schema://$host { $encrypted = encrypt($token); $this->settings->sentinel_token = $encrypted; $this->settings->save(); + return $encrypted; } + public function isSentinelEnabled() { return $this->isMetricsEnabled() || $this->isServerApiEnabled(); @@ -989,7 +989,8 @@ $schema://$host { public function isProxyShouldRun() { - if ($this->proxyType() === ProxyTypes::NONE->value || $this->settings->is_build_server) { + // TODO: Do we need "|| $this->proxy->force_stop" here? + if ($this->proxyType() === ProxyTypes::NONE->value || $this->isBuildServer()) { return false; } diff --git a/database/migrations/2024_10_14_090416_update_metrics_token_in_server_settings.php b/database/migrations/2024_10_14_090416_update_metrics_token_in_server_settings.php index 32b1e5349..21c871cf4 100644 --- a/database/migrations/2024_10_14_090416_update_metrics_token_in_server_settings.php +++ b/database/migrations/2024_10_14_090416_update_metrics_token_in_server_settings.php @@ -19,6 +19,9 @@ return new class extends Migration $table->integer('sentinel_metrics_refresh_rate_seconds')->default(5); $table->integer('sentinel_metrics_history_days')->default(30); }); + Schema::table('servers', function (Blueprint $table) { + $table->dateTime('sentinel_update_at')->default(now()); + }); } /** @@ -34,5 +37,8 @@ return new class extends Migration $table->dropColumn('sentinel_metrics_refresh_rate_seconds'); $table->dropColumn('sentinel_metrics_history_days'); }); + Schema::table('servers', function (Blueprint $table) { + $table->dropColumn('sentinel_update_at'); + }); } }; diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index d3f51625a..ace297712 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -282,7 +282,7 @@ {{-- @endif --}} @if (isDev()) - Get Push Data + Push Test {{--
Start Sentinel diff --git a/routes/api.php b/routes/api.php index 76fd93141..db07921a4 100644 --- a/routes/api.php +++ b/routes/api.php @@ -15,7 +15,6 @@ use App\Http\Middleware\IgnoreReadOnlyApiToken; use App\Http\Middleware\OnlyRootApiToken; use App\Jobs\PushServerUpdateJob; use App\Models\Server; -use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Route; Route::get('/health', [OtherController::class, 'healthcheck']); @@ -137,7 +136,7 @@ Route::group([ ], function () { Route::post('/sentinel/push', function () { $token = request()->header('Authorization'); - if (!$token) { + if (! $token) { return response()->json(['message' => 'Unauthorized'], 401); } $naked_token = str_replace('Bearer ', '', $token); @@ -145,11 +144,13 @@ Route::group([ $decrypted_token = json_decode($decrypted, true); $server_uuid = data_get($decrypted_token, 'server_uuid'); $server = Server::where('uuid', $server_uuid)->first(); - if (!$server) { + if (! $server) { return response()->json(['message' => 'Server not found'], 404); } $data = request()->all(); + $server->update(['sentinel_update_at' => now()]); PushServerUpdateJob::dispatch($server, $data); + return response()->json(['message' => 'ok'], 200); }); }); From c54b865beea1fe21e967204a2d3e33e49cf5fb16 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:40:16 +0200 Subject: [PATCH 41/56] fix cal.com --- templates/compose/calcom.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/templates/compose/calcom.yaml b/templates/compose/calcom.yaml index c7ea7744c..2e7bca8ae 100644 --- a/templates/compose/calcom.yaml +++ b/templates/compose/calcom.yaml @@ -7,6 +7,7 @@ services: calcom: image: calcom.docker.scarf.sh/calcom/cal.com + platform: linux/amd64 environment: # Some variables still uses Calcom previous name, Calendso # @@ -21,9 +22,9 @@ services: - NEXTAUTH_URL=${SERVICE_FQDN_CALCOM}/api/auth # It is highly recommended that the NEXTAUTH_SECRET must be overridden and very unique # Use `openssl rand -base64 32` to generate a key - - NEXTAUTH_SECRET=${NEXTAUTH_SECRET:-$SERVICE_BASE64_CALCOM_SECRET} + - NEXTAUTH_SECRET=${SERVICE_BASE64_CALCOMSECRET} # Encryption key that will be used to encrypt CalDAV credentials, choose a random string, for example with `dd if=/dev/urandom bs=1K count=1 | md5sum` - - CALENDSO_ENCRYPTION_KEY=${CALENDSO_ENCRYPTION_KEY:-$SERVICE_BASE64_CALCOM_KEY} + - CALENDSO_ENCRYPTION_KEY=${SERVICE_BASE64_CALCOMKEY} - POSTGRES_USER=${SERVICE_USER_POSTGRES} - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} - POSTGRES_DB=${POSTGRES_DB:-calendso} @@ -54,13 +55,13 @@ services: environment: - POSTGRES_USER=${SERVICE_USER_POSTGRES} - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} - - POSTGRES_DB=${POSTGRES_DATABASE:-calcom} + - POSTGRES_DB=${POSTGRES_DB:-calendso} volumes: - calcom-postgresql-data:/var/lib/postgresql/data healthcheck: test: - CMD-SHELL - - pg_isready -U ${SERVICE_USER_POSTGRES} -d ${POSTGRES_DATABASE:-calcom} + - pg_isready -U ${SERVICE_USER_POSTGRES} -d ${POSTGRES_DB:-calendso} interval: 10s timeout: 5s retries: 5 From d34c4dd1e82582bcde73f7f4c6ba2a068a941e00 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:40:27 +0200 Subject: [PATCH 42/56] Update service-templates.json --- templates/service-templates.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/templates/service-templates.json b/templates/service-templates.json index 664eb1ade..074a2cebd 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -224,6 +224,21 @@ "minversion": "0.0.0", "port": "10000" }, + "calcom": { + "documentation": "https://cal.com/docs?utm_source=coolify.io", + "slogan": "Scheduling infrastructure for everyone.", + "compose": "c2VydmljZXM6CiAgY2FsY29tOgogICAgaW1hZ2U6IGNhbGNvbS5kb2NrZXIuc2NhcmYuc2gvY2FsY29tL2NhbC5jb20KICAgIHBsYXRmb3JtOiBsaW51eC9hbWQ2NAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0NBTENPTV8zMDAwCiAgICAgIC0gTkVYVF9QVUJMSUNfTElDRU5TRV9DT05TRU5UPWFncmVlCiAgICAgIC0gTk9ERV9FTlY9cHJvZHVjdGlvbgogICAgICAtICdORVhUX1BVQkxJQ19XRUJBUFBfVVJMPSR7U0VSVklDRV9GUUROX0NBTENPTX0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0FQSV9WMl9VUkw9JHtTRVJWSUNFX0ZRRE5fQ0FMQ09NfS9hcGkvdjInCiAgICAgIC0gJ05FWFRBVVRIX1VSTD0ke1NFUlZJQ0VfRlFETl9DQUxDT019L2FwaS9hdXRoJwogICAgICAtICdORVhUQVVUSF9TRUNSRVQ9JHtTRVJWSUNFX0JBU0U2NF9DQUxDT01TRUNSRVR9JwogICAgICAtICdDQUxFTkRTT19FTkNSWVBUSU9OX0tFWT0ke1NFUlZJQ0VfQkFTRTY0X0NBTENPTUtFWX0nCiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1jYWxlbmRzb30nCiAgICAgIC0gREFUQUJBU0VfSE9TVD1wb3N0Z3Jlc3FsCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AJHtEQVRBQkFTRV9IT1NUOi1wb3N0Z3Jlc3FsfS8ke1BPU1RHUkVTX0RCOi1jYWxlbmRzb30nCiAgICAgIC0gJ0RBVEFCQVNFX0RJUkVDVF9VUkw9cG9zdGdyZXNxbDovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7REFUQUJBU0VfSE9TVDotcG9zdGdyZXNxbH0vJHtQT1NUR1JFU19EQjotY2FsZW5kc299JwogICAgICAtIENBTENPTV9URUxFTUVUUllfRElTQUJMRUQ9MQogICAgICAtICdFTUFJTF9GUk9NPSR7RU1BSUxfRlJPTX0nCiAgICAgIC0gJ0VNQUlMX0ZST01fTkFNRT0ke0VNQUlMX0ZST01fTkFNRX0nCiAgICAgIC0gJ0VNQUlMX1NFUlZFUl9IT1NUPSR7RU1BSUxfU0VSVkVSX0hPU1R9JwogICAgICAtICdFTUFJTF9TRVJWRVJfUE9SVD0ke0VNQUlMX1NFUlZFUl9QT1JUfScKICAgICAgLSAnRU1BSUxfU0VSVkVSX1VTRVI9JHtFTUFJTF9TRVJWRVJfVVNFUn0nCiAgICAgIC0gJ0VNQUlMX1NFUlZFUl9QQVNTV09SRD0ke0VNQUlMX1NFUlZFUl9QQVNTV09SRH0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0FQUF9OQU1FPSJDYWwuY29tIicKICAgICAgLSAnQUxMT1dFRF9IT1NUTkFNRVM9WyIke1NFUlZJQ0VfRlFETl9DQUxDT019Il0nCiAgICBkZXBlbmRzX29uOgogICAgICAtIHBvc3RncmVzcWwKICBwb3N0Z3Jlc3FsOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNi1hbHBpbmUnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LWNhbGVuZHNvfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2NhbGNvbS1wb3N0Z3Jlc3FsLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfSAtZCAke1BPU1RHUkVTX0RCOi1jYWxlbmRzb30nCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogNQogICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWQK", + "tags": [ + "calcom", + "calendso", + "scheduling", + "open", + "source" + ], + "logo": "svgs/calcom.svg", + "minversion": "0.0.0", + "port": "3000" + }, "castopod": { "documentation": "https://docs.castopod.org/main/en/?utm_source=coolify.io", "slogan": "Castopod is a free & open-source hosting platform made for podcasters who want engage and interact with their audience.", From abaccdf03dc753f9a8ffb3d7c6286a6dfd5d7a66 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 14 Oct 2024 15:05:05 +0200 Subject: [PATCH 43/56] fix calcom postgres healthcheck --- templates/compose/calcom.yaml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/templates/compose/calcom.yaml b/templates/compose/calcom.yaml index 2e7bca8ae..89f3376ee 100644 --- a/templates/compose/calcom.yaml +++ b/templates/compose/calcom.yaml @@ -59,10 +59,7 @@ services: volumes: - calcom-postgresql-data:/var/lib/postgresql/data healthcheck: - test: - - CMD-SHELL - - pg_isready -U ${SERVICE_USER_POSTGRES} -d ${POSTGRES_DB:-calendso} - interval: 10s - timeout: 5s - retries: 5 - restart: unless-stopped + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 20s + retries: 10 From b6cd54ccbc70af5502c4cbce674cc6223703fde9 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 14 Oct 2024 15:21:41 +0200 Subject: [PATCH 44/56] fix edgedb --- templates/compose/edgedb.yaml | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/templates/compose/edgedb.yaml b/templates/compose/edgedb.yaml index a4e127fa5..c305895ee 100644 --- a/templates/compose/edgedb.yaml +++ b/templates/compose/edgedb.yaml @@ -1,3 +1,4 @@ +# ignore: true # documentation: https://www.edgedb.com # slogan: An open-source database designed as a spiritual successor to SQL and the relational paradigm. Powered by the Postgres query engine under the hood. # tags: db database sql @@ -8,38 +9,33 @@ services: edgedb: image: edgedb/edgedb environment: - - SERVICE_FQDN_EDGEDB + - SERVICE_FQDN_EDGEDB_5656 - EDGEDB_SERVER_ADMIN_UI=${EDGEDB_SERVER_ADMIN_UI:-enabled} - - EDGEDB_SERVER_BACKEND_DSN=postgres://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgresql:5432/$POSTGRES_DB - - EDGEDB_SERVER_SECURITY=strict - - EDGEDB_SERVER_PASSWORD=$SERVICE_EDGEDB_SERVER_PASSWORD - - EDGEDB_SERVER_TLS_CERT_MODE=generate_self_signed - # - EDGEDB_SERVER_TLS_CERT_FILE= # Ideally Coolify should generate its own certificates - # - EDGEDB_SERVER_TLS_KEY_FILE= # -- || -- + - EDGEDB_SERVER_BACKEND_DSN=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgresql:5432/${POSTGRES_DB:-edgedb} + - EDGEDB_SERVER_SECURITY=${EDGEDB_SERVER_SECURITY:-strict} + - EDGEDB_SERVER_PASSWORD=${SERVICE_PASSWORD_EDGEDB} - POSTGRES_DB=${POSTGRES_DB:-edgedb} - depends_on: postgresql: condition: service_healthy volumes: - - "./dbschema:/dbschema" + - edgedb-data:/dbschema healthcheck: test: ["CMD", "curl", "-f", "http://localhost:5656/server/status/alive"] interval: 5s timeout: 20s retries: 10 - ports: - - "5656:5656" + postgresql: image: postgres:16-alpine volumes: - - postgresql-data:/var/lib/postgresql/data + - edgedb-postgresql-data:/var/lib/postgresql/data environment: - - POSTGRES_USER=$SERVICE_USER_POSTGRES - - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} - POSTGRES_DB=${POSTGRES_DB:-edgedb} healthcheck: test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] interval: 5s timeout: 20s - retries: 10 \ No newline at end of file + retries: 10 From bd18ca5817c455ef2dfc4ce684e7ec2eaa26608f Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 14 Oct 2024 15:22:32 +0200 Subject: [PATCH 45/56] Update service-templates.json --- templates/service-templates.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/service-templates.json b/templates/service-templates.json index 074a2cebd..ebfca7623 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -227,7 +227,7 @@ "calcom": { "documentation": "https://cal.com/docs?utm_source=coolify.io", "slogan": "Scheduling infrastructure for everyone.", - "compose": "c2VydmljZXM6CiAgY2FsY29tOgogICAgaW1hZ2U6IGNhbGNvbS5kb2NrZXIuc2NhcmYuc2gvY2FsY29tL2NhbC5jb20KICAgIHBsYXRmb3JtOiBsaW51eC9hbWQ2NAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0NBTENPTV8zMDAwCiAgICAgIC0gTkVYVF9QVUJMSUNfTElDRU5TRV9DT05TRU5UPWFncmVlCiAgICAgIC0gTk9ERV9FTlY9cHJvZHVjdGlvbgogICAgICAtICdORVhUX1BVQkxJQ19XRUJBUFBfVVJMPSR7U0VSVklDRV9GUUROX0NBTENPTX0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0FQSV9WMl9VUkw9JHtTRVJWSUNFX0ZRRE5fQ0FMQ09NfS9hcGkvdjInCiAgICAgIC0gJ05FWFRBVVRIX1VSTD0ke1NFUlZJQ0VfRlFETl9DQUxDT019L2FwaS9hdXRoJwogICAgICAtICdORVhUQVVUSF9TRUNSRVQ9JHtTRVJWSUNFX0JBU0U2NF9DQUxDT01TRUNSRVR9JwogICAgICAtICdDQUxFTkRTT19FTkNSWVBUSU9OX0tFWT0ke1NFUlZJQ0VfQkFTRTY0X0NBTENPTUtFWX0nCiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1jYWxlbmRzb30nCiAgICAgIC0gREFUQUJBU0VfSE9TVD1wb3N0Z3Jlc3FsCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AJHtEQVRBQkFTRV9IT1NUOi1wb3N0Z3Jlc3FsfS8ke1BPU1RHUkVTX0RCOi1jYWxlbmRzb30nCiAgICAgIC0gJ0RBVEFCQVNFX0RJUkVDVF9VUkw9cG9zdGdyZXNxbDovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7REFUQUJBU0VfSE9TVDotcG9zdGdyZXNxbH0vJHtQT1NUR1JFU19EQjotY2FsZW5kc299JwogICAgICAtIENBTENPTV9URUxFTUVUUllfRElTQUJMRUQ9MQogICAgICAtICdFTUFJTF9GUk9NPSR7RU1BSUxfRlJPTX0nCiAgICAgIC0gJ0VNQUlMX0ZST01fTkFNRT0ke0VNQUlMX0ZST01fTkFNRX0nCiAgICAgIC0gJ0VNQUlMX1NFUlZFUl9IT1NUPSR7RU1BSUxfU0VSVkVSX0hPU1R9JwogICAgICAtICdFTUFJTF9TRVJWRVJfUE9SVD0ke0VNQUlMX1NFUlZFUl9QT1JUfScKICAgICAgLSAnRU1BSUxfU0VSVkVSX1VTRVI9JHtFTUFJTF9TRVJWRVJfVVNFUn0nCiAgICAgIC0gJ0VNQUlMX1NFUlZFUl9QQVNTV09SRD0ke0VNQUlMX1NFUlZFUl9QQVNTV09SRH0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0FQUF9OQU1FPSJDYWwuY29tIicKICAgICAgLSAnQUxMT1dFRF9IT1NUTkFNRVM9WyIke1NFUlZJQ0VfRlFETl9DQUxDT019Il0nCiAgICBkZXBlbmRzX29uOgogICAgICAtIHBvc3RncmVzcWwKICBwb3N0Z3Jlc3FsOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNi1hbHBpbmUnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LWNhbGVuZHNvfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2NhbGNvbS1wb3N0Z3Jlc3FsLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfSAtZCAke1BPU1RHUkVTX0RCOi1jYWxlbmRzb30nCiAgICAgIGludGVydmFsOiAxMHMKICAgICAgdGltZW91dDogNXMKICAgICAgcmV0cmllczogNQogICAgcmVzdGFydDogdW5sZXNzLXN0b3BwZWQK", + "compose": "c2VydmljZXM6CiAgY2FsY29tOgogICAgaW1hZ2U6IGNhbGNvbS5kb2NrZXIuc2NhcmYuc2gvY2FsY29tL2NhbC5jb20KICAgIHBsYXRmb3JtOiBsaW51eC9hbWQ2NAogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gU0VSVklDRV9GUUROX0NBTENPTV8zMDAwCiAgICAgIC0gTkVYVF9QVUJMSUNfTElDRU5TRV9DT05TRU5UPWFncmVlCiAgICAgIC0gTk9ERV9FTlY9cHJvZHVjdGlvbgogICAgICAtICdORVhUX1BVQkxJQ19XRUJBUFBfVVJMPSR7U0VSVklDRV9GUUROX0NBTENPTX0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0FQSV9WMl9VUkw9JHtTRVJWSUNFX0ZRRE5fQ0FMQ09NfS9hcGkvdjInCiAgICAgIC0gJ05FWFRBVVRIX1VSTD0ke1NFUlZJQ0VfRlFETl9DQUxDT019L2FwaS9hdXRoJwogICAgICAtICdORVhUQVVUSF9TRUNSRVQ9JHtTRVJWSUNFX0JBU0U2NF9DQUxDT01TRUNSRVR9JwogICAgICAtICdDQUxFTkRTT19FTkNSWVBUSU9OX0tFWT0ke1NFUlZJQ0VfQkFTRTY0X0NBTENPTUtFWX0nCiAgICAgIC0gJ1BPU1RHUkVTX1VTRVI9JHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19QQVNTV09SRD0ke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9JwogICAgICAtICdQT1NUR1JFU19EQj0ke1BPU1RHUkVTX0RCOi1jYWxlbmRzb30nCiAgICAgIC0gREFUQUJBU0VfSE9TVD1wb3N0Z3Jlc3FsCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3Jlc3FsOi8vJHtTRVJWSUNFX1VTRVJfUE9TVEdSRVN9OiR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU31AJHtEQVRBQkFTRV9IT1NUOi1wb3N0Z3Jlc3FsfS8ke1BPU1RHUkVTX0RCOi1jYWxlbmRzb30nCiAgICAgIC0gJ0RBVEFCQVNFX0RJUkVDVF9VUkw9cG9zdGdyZXNxbDovLyR7U0VSVklDRV9VU0VSX1BPU1RHUkVTfToke1NFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVN9QCR7REFUQUJBU0VfSE9TVDotcG9zdGdyZXNxbH0vJHtQT1NUR1JFU19EQjotY2FsZW5kc299JwogICAgICAtIENBTENPTV9URUxFTUVUUllfRElTQUJMRUQ9MQogICAgICAtICdFTUFJTF9GUk9NPSR7RU1BSUxfRlJPTX0nCiAgICAgIC0gJ0VNQUlMX0ZST01fTkFNRT0ke0VNQUlMX0ZST01fTkFNRX0nCiAgICAgIC0gJ0VNQUlMX1NFUlZFUl9IT1NUPSR7RU1BSUxfU0VSVkVSX0hPU1R9JwogICAgICAtICdFTUFJTF9TRVJWRVJfUE9SVD0ke0VNQUlMX1NFUlZFUl9QT1JUfScKICAgICAgLSAnRU1BSUxfU0VSVkVSX1VTRVI9JHtFTUFJTF9TRVJWRVJfVVNFUn0nCiAgICAgIC0gJ0VNQUlMX1NFUlZFUl9QQVNTV09SRD0ke0VNQUlMX1NFUlZFUl9QQVNTV09SRH0nCiAgICAgIC0gJ05FWFRfUFVCTElDX0FQUF9OQU1FPSJDYWwuY29tIicKICAgICAgLSAnQUxMT1dFRF9IT1NUTkFNRVM9WyIke1NFUlZJQ0VfRlFETl9DQUxDT019Il0nCiAgICBkZXBlbmRzX29uOgogICAgICAtIHBvc3RncmVzcWwKICBwb3N0Z3Jlc3FsOgogICAgaW1hZ2U6ICdwb3N0Z3JlczoxNi1hbHBpbmUnCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnUE9TVEdSRVNfVVNFUj0ke1NFUlZJQ0VfVVNFUl9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX1BBU1NXT1JEPSR7U0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU30nCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LWNhbGVuZHNvfScKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2NhbGNvbS1wb3N0Z3Jlc3FsLWRhdGE6L3Zhci9saWIvcG9zdGdyZXNxbC9kYXRhJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdwZ19pc3JlYWR5IC1VICQke1BPU1RHUkVTX1VTRVJ9IC1kICQke1BPU1RHUkVTX0RCfScKICAgICAgaW50ZXJ2YWw6IDVzCiAgICAgIHRpbWVvdXQ6IDIwcwogICAgICByZXRyaWVzOiAxMAo=", "tags": [ "calcom", "calendso", From c0c77d711af4c1b38f5ab91650dacdc9032a148a Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 14 Oct 2024 15:46:58 +0200 Subject: [PATCH 46/56] Update azimutt.yaml --- templates/compose/azimutt.yaml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/templates/compose/azimutt.yaml b/templates/compose/azimutt.yaml index 314d4479a..4b498e423 100644 --- a/templates/compose/azimutt.yaml +++ b/templates/compose/azimutt.yaml @@ -9,9 +9,9 @@ services: postgres: image: postgres:15 environment: - - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES - - POSTGRES_USER=$SERVICE_USER_POSTGRES - - POSTGRES_DB=azimutt + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_DB=${POSTGRES_DB:-azimutt} volumes: - azimutt-postgres-data:/var/lib/postgresql/data healthcheck: @@ -80,8 +80,8 @@ services: - PHX_SERVER=true - PHX_HOST=$SERVICE_URL_AZIMUTT - PORT=${PORT:-4000} - - DATABASE_URL=ecto://$SERVICE_USER_POSTGRES:$SERVICE_PASSWORD_POSTGRES@postgres/azimutt - - SECRET_KEY_BASE=$SERVICE_BASE64_64_AZIMUTT + - DATABASE_URL=ecto://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@postgres/${POSTGRES_DB:-azimutt} + - SECRET_KEY_BASE=${SERVICE_BASE64_64_AZIMUTT} - FILE_STORAGE_ADAPTER=${FILE_STORAGE_ADAPTER:-s3} - AUTH_PASSWORD=${AUTH_PASSWORD:-true} - SKIP_ONBOARDING_FUNNEL=${SKIP_ONBOARDING_FUNNEL:-true} From 4caca0dfe59593e5d61327da0cd79ea2c6191268 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:57:09 +0200 Subject: [PATCH 47/56] fix plausible --- templates/compose/plausible.yaml | 53 ++++++++++++++++++++++++-------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/templates/compose/plausible.yaml b/templates/compose/plausible.yaml index e02e92d38..25b5c6938 100644 --- a/templates/compose/plausible.yaml +++ b/templates/compose/plausible.yaml @@ -10,31 +10,53 @@ services: command: 'sh -c "sleep 10 && /entrypoint.sh db createdb && /entrypoint.sh db migrate && /entrypoint.sh run"' environment: - SERVICE_FQDN_PLAUSIBLE - - "DATABASE_URL=postgres://postgres:$SERVICE_PASSWORD_POSTGRES@plausible_db/plausible" + - DATABASE_URL=postgres://${SERVICE_USER_POSTGRES}:${SERVICE_PASSWORD_POSTGRES}@plausible-db:5432/${POSTGRES_DB:-plausible-db} + - CLICKHOUSE_DATABASE_URL=http://plausible-events-db:8123/plausible_events_db - BASE_URL=$SERVICE_FQDN_PLAUSIBLE - SECRET_KEY_BASE=$SERVICE_BASE64_64_PLAUSIBLE - TOTP_VAULT_KEY=$SERVICE_REALBASE64_32_TOTP depends_on: - - plausible_db - - plausible_events_db - - mail + plausible-db: + condition: service_healthy + plausible-events-db: + condition: service_healthy + mail: + condition: service_healthy + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:8000/ping"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 45s + + mail: image: bytemark/smtp + platform: linux/amd64 + healthcheck: + test: ["CMD-SHELL", "bash -c ':> /dev/tcp/127.0.0.1/25' || exit 1"] + interval: 5s + timeout: 10s + retries: 20 - plausible_db: + plausible-db: image: "postgres:16-alpine" volumes: - - "db-data:/var/lib/postgresql/data" + - plausible-postgres-data:/var/lib/postgresql/data environment: - - POSTGRES_DB=plausible - - POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES + - POSTGRES_DB=${POSTGRES_DB:-plausible-db} + - POSTGRES_USER=${SERVICE_USER_POSTGRES} + - POSTGRES_PASSWORD=${SERVICE_PASSWORD_POSTGRES} + healthcheck: + test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"] + interval: 5s + timeout: 20s + retries: 10 - plausible_events_db: + plausible-events-db: image: "clickhouse/clickhouse-server:24.3.3.102-alpine" volumes: - - type: volume - source: event-data - target: /var/lib/clickhouse + - plausible-events-data:/var/lib/clickhouse - type: bind source: ./clickhouse/clickhouse-config.xml target: /etc/clickhouse-server/config.d/logging.xml @@ -49,3 +71,10 @@ services: nofile: soft: 262144 hard: 262144 + healthcheck: + test: + [ + "CMD-SHELL", + "wget --no-verbose --tries=1 -O - http://127.0.0.1:8123/ping || exit 1", + ] + start_period: 30s From a7dc8fa2ccc7cabd4f50ffc98e1c46d510574749 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:57:45 +0200 Subject: [PATCH 48/56] format --- templates/compose/plausible.yaml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/templates/compose/plausible.yaml b/templates/compose/plausible.yaml index 25b5c6938..d932316d8 100644 --- a/templates/compose/plausible.yaml +++ b/templates/compose/plausible.yaml @@ -23,13 +23,20 @@ services: mail: condition: service_healthy healthcheck: - test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://127.0.0.1:8000/ping"] + test: + [ + "CMD", + "wget", + "--no-verbose", + "--tries=1", + "--spider", + "http://127.0.0.1:8000/ping", + ] interval: 10s timeout: 5s retries: 5 start_period: 45s - mail: image: bytemark/smtp platform: linux/amd64 From c3311133c200e9577c698de0a978468dbe445928 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Mon, 14 Oct 2024 17:43:47 +0200 Subject: [PATCH 49/56] fix windmill healthchecks --- templates/compose/windmill.yaml | 10 +++++----- templates/service-templates.json | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/templates/compose/windmill.yaml b/templates/compose/windmill.yaml index a14854ba0..1326870c2 100644 --- a/templates/compose/windmill.yaml +++ b/templates/compose/windmill.yaml @@ -32,7 +32,7 @@ services: volumes: - worker-logs:/tmp/windmill/logs healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8000/api/version || exit 1"] + test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 @@ -51,7 +51,7 @@ services: - worker-dependency-cache:/tmp/windmill/cache - worker-logs:/tmp/windmill/logs healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8000/api/version || exit 1"] + test: ["CMD-SHELL", "exit 0"] interval: 30s timeout: 10s retries: 3 @@ -70,7 +70,7 @@ services: - worker-dependency-cache:/tmp/windmill/cache - worker-logs:/tmp/windmill/logs healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8000/api/version || exit 1"] + test: ["CMD-SHELL", "exit 0"] interval: 30s timeout: 10s retries: 3 @@ -89,7 +89,7 @@ services: - worker-dependency-cache:/tmp/windmill/cache - worker-logs:/tmp/windmill/logs healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8000/api/version || exit 1"] + test: ["CMD-SHELL", "exit 0"] interval: 30s timeout: 10s retries: 3 @@ -108,7 +108,7 @@ services: volumes: - worker-logs:/tmp/windmill/logs healthcheck: - test: ["CMD", "curl", "-f", "http://localhost:8000/api/version || exit 1"] + test: ["CMD-SHELL", "exit 0"] interval: 30s timeout: 10s retries: 3 diff --git a/templates/service-templates.json b/templates/service-templates.json index ebfca7623..7ebdfe604 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -2639,7 +2639,7 @@ "windmill": { "documentation": "https://www.windmill.dev/docs/?utm_source=coolify.io", "slogan": "Windmill is a developer platform to build production-grade multi-steps automations and internal apps.", - "compose": "c2VydmljZXM6CiAgZGI6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2JwogICAgc2htX3NpemU6IDFnCiAgICB2b2x1bWVzOgogICAgICAtICdkYi1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LXdpbmRtaWxsfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSBwb3N0Z3JlcycKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgd2luZG1pbGwtc2VydmVyOgogICAgaW1hZ2U6ICdnaGNyLmlvL3dpbmRtaWxsLWxhYnMvd2luZG1pbGw6bWFpbicKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9XSU5ETUlMTF84MDAwCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovL3Bvc3RncmVzOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQGRiL3dpbmRtaWxsJwogICAgICAtICdNT0RFPSR7TU9ERTotc2VydmVyfScKICAgICAgLSBCQVNFX1VSTD0kU0VSVklDRV9GUUROX1dJTkRNSUxMCiAgICBkZXBlbmRzX29uOgogICAgICBkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgdm9sdW1lczoKICAgICAgLSAnd29ya2VyLWxvZ3M6L3RtcC93aW5kbWlsbC9sb2dzJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwMDAvYXBpL3ZlcnNpb24gfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgd2luZG1pbGwtd29ya2VyLTE6CiAgICBpbWFnZTogJ2doY3IuaW8vd2luZG1pbGwtbGFicy93aW5kbWlsbDptYWluJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovL3Bvc3RncmVzOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQGRiL3dpbmRtaWxsJwogICAgICAtICdNT0RFPSR7TU9ERTotd29ya2VyfScKICAgICAgLSAnV09SS0VSX0dST1VQPSR7V09SS0VSX0dST1VQOi1kZWZhdWx0fScKICAgIGRlcGVuZHNfb246CiAgICAgIGRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgICAgLSAnd29ya2VyLWRlcGVuZGVuY3ktY2FjaGU6L3RtcC93aW5kbWlsbC9jYWNoZScKICAgICAgLSAnd29ya2VyLWxvZ3M6L3RtcC93aW5kbWlsbC9sb2dzJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwMDAvYXBpL3ZlcnNpb24gfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgd2luZG1pbGwtd29ya2VyLTI6CiAgICBpbWFnZTogJ2doY3IuaW8vd2luZG1pbGwtbGFicy93aW5kbWlsbDptYWluJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovL3Bvc3RncmVzOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQGRiL3dpbmRtaWxsJwogICAgICAtICdNT0RFPSR7TU9ERTotd29ya2VyfScKICAgICAgLSAnV09SS0VSX0dST1VQPSR7V09SS0VSX0dST1VQOi1kZWZhdWx0fScKICAgIGRlcGVuZHNfb246CiAgICAgIGRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgICAgLSAnd29ya2VyLWRlcGVuZGVuY3ktY2FjaGU6L3RtcC93aW5kbWlsbC9jYWNoZScKICAgICAgLSAnd29ya2VyLWxvZ3M6L3RtcC93aW5kbWlsbC9sb2dzJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwMDAvYXBpL3ZlcnNpb24gfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgd2luZG1pbGwtd29ya2VyLTM6CiAgICBpbWFnZTogJ2doY3IuaW8vd2luZG1pbGwtbGFicy93aW5kbWlsbDptYWluJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovL3Bvc3RncmVzOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQGRiL3dpbmRtaWxsJwogICAgICAtICdNT0RFPSR7TU9ERTotd29ya2VyfScKICAgICAgLSAnV09SS0VSX0dST1VQPSR7V09SS0VSX0dST1VQOi1kZWZhdWx0fScKICAgIGRlcGVuZHNfb246CiAgICAgIGRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgICAgLSAnd29ya2VyLWRlcGVuZGVuY3ktY2FjaGU6L3RtcC93aW5kbWlsbC9jYWNoZScKICAgICAgLSAnd29ya2VyLWxvZ3M6L3RtcC93aW5kbWlsbC9sb2dzJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwMDAvYXBpL3ZlcnNpb24gfHwgZXhpdCAxJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgd2luZG1pbGwtd29ya2VyLW5hdGl2ZToKICAgIGltYWdlOiAnZ2hjci5pby93aW5kbWlsbC1sYWJzL3dpbmRtaWxsOm1haW4nCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vcG9zdGdyZXM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAZGIvd2luZG1pbGwnCiAgICAgIC0gJ01PREU9JHtNT0RFOi13b3JrZXJ9JwogICAgICAtICdXT1JLRVJfR1JPVVA9JHtXT1JLRVJfR1JPVVA6LW5hdGl2ZX0nCiAgICAgIC0gJ05VTV9XT1JLRVJTPSR7TlVNX1dPUktFUlM6LTh9JwogICAgICAtICdTTEVFUF9RVUVVRT0ke1NMRUVQX1FVRVVFOi0yMDB9JwogICAgZGVwZW5kc19vbjoKICAgICAgZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3dvcmtlci1sb2dzOi90bXAvd2luZG1pbGwvbG9ncycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ECiAgICAgICAgLSBjdXJsCiAgICAgICAgLSAnLWYnCiAgICAgICAgLSAnaHR0cDovL2xvY2FsaG9zdDo4MDAwL2FwaS92ZXJzaW9uIHx8IGV4aXQgMScKICAgICAgaW50ZXJ2YWw6IDMwcwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMwogIGxzcDoKICAgIGltYWdlOiAnZ2hjci5pby93aW5kbWlsbC1sYWJzL3dpbmRtaWxsLWxzcDpsYXRlc3QnCiAgICB2b2x1bWVzOgogICAgICAtICdsc3AtY2FjaGU6L3Jvb3QvLmNhY2hlJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdleGl0IDAnCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDMK", + "compose": "c2VydmljZXM6CiAgZGI6CiAgICBpbWFnZTogJ3Bvc3RncmVzOjE2JwogICAgc2htX3NpemU6IDFnCiAgICB2b2x1bWVzOgogICAgICAtICdkYi1kYXRhOi92YXIvbGliL3Bvc3RncmVzcWwvZGF0YScKICAgIGVudmlyb25tZW50OgogICAgICAtIFBPU1RHUkVTX1BBU1NXT1JEPSRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTCiAgICAgIC0gJ1BPU1RHUkVTX0RCPSR7UE9TVEdSRVNfREI6LXdpbmRtaWxsfScKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAncGdfaXNyZWFkeSAtVSBwb3N0Z3JlcycKICAgICAgaW50ZXJ2YWw6IDEwcwogICAgICB0aW1lb3V0OiA1cwogICAgICByZXRyaWVzOiA1CiAgd2luZG1pbGwtc2VydmVyOgogICAgaW1hZ2U6ICdnaGNyLmlvL3dpbmRtaWxsLWxhYnMvd2luZG1pbGw6bWFpbicKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9XSU5ETUlMTF84MDAwCiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovL3Bvc3RncmVzOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQGRiL3dpbmRtaWxsJwogICAgICAtICdNT0RFPSR7TU9ERTotc2VydmVyfScKICAgICAgLSBCQVNFX1VSTD0kU0VSVklDRV9GUUROX1dJTkRNSUxMCiAgICBkZXBlbmRzX29uOgogICAgICBkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgdm9sdW1lczoKICAgICAgLSAnd29ya2VyLWxvZ3M6L3RtcC93aW5kbWlsbC9sb2dzJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQKICAgICAgICAtIGN1cmwKICAgICAgICAtICctZicKICAgICAgICAtICdodHRwOi8vbG9jYWxob3N0OjgwMDAvaGVhbHRoJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgd2luZG1pbGwtd29ya2VyLTE6CiAgICBpbWFnZTogJ2doY3IuaW8vd2luZG1pbGwtbGFicy93aW5kbWlsbDptYWluJwogICAgZW52aXJvbm1lbnQ6CiAgICAgIC0gJ0RBVEFCQVNFX1VSTD1wb3N0Z3JlczovL3Bvc3RncmVzOiRTRVJWSUNFX1BBU1NXT1JEX1BPU1RHUkVTQGRiL3dpbmRtaWxsJwogICAgICAtICdNT0RFPSR7TU9ERTotd29ya2VyfScKICAgICAgLSAnV09SS0VSX0dST1VQPSR7V09SS0VSX0dST1VQOi1kZWZhdWx0fScKICAgIGRlcGVuZHNfb246CiAgICAgIGRiOgogICAgICAgIGNvbmRpdGlvbjogc2VydmljZV9oZWFsdGh5CiAgICB2b2x1bWVzOgogICAgICAtICcvdmFyL3J1bi9kb2NrZXIuc29jazovdmFyL3J1bi9kb2NrZXIuc29jaycKICAgICAgLSAnd29ya2VyLWRlcGVuZGVuY3ktY2FjaGU6L3RtcC93aW5kbWlsbC9jYWNoZScKICAgICAgLSAnd29ya2VyLWxvZ3M6L3RtcC93aW5kbWlsbC9sb2dzJwogICAgaGVhbHRoY2hlY2s6CiAgICAgIHRlc3Q6CiAgICAgICAgLSBDTUQtU0hFTEwKICAgICAgICAtICdleGl0IDAnCiAgICAgIGludGVydmFsOiAzMHMKICAgICAgdGltZW91dDogMTBzCiAgICAgIHJldHJpZXM6IDMKICB3aW5kbWlsbC13b3JrZXItMjoKICAgIGltYWdlOiAnZ2hjci5pby93aW5kbWlsbC1sYWJzL3dpbmRtaWxsOm1haW4nCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vcG9zdGdyZXM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAZGIvd2luZG1pbGwnCiAgICAgIC0gJ01PREU9JHtNT0RFOi13b3JrZXJ9JwogICAgICAtICdXT1JLRVJfR1JPVVA9JHtXT1JLRVJfR1JPVVA6LWRlZmF1bHR9JwogICAgZGVwZW5kc19vbjoKICAgICAgZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIHZvbHVtZXM6CiAgICAgIC0gJy92YXIvcnVuL2RvY2tlci5zb2NrOi92YXIvcnVuL2RvY2tlci5zb2NrJwogICAgICAtICd3b3JrZXItZGVwZW5kZW5jeS1jYWNoZTovdG1wL3dpbmRtaWxsL2NhY2hlJwogICAgICAtICd3b3JrZXItbG9nczovdG1wL3dpbmRtaWxsL2xvZ3MnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ2V4aXQgMCcKICAgICAgaW50ZXJ2YWw6IDMwcwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMwogIHdpbmRtaWxsLXdvcmtlci0zOgogICAgaW1hZ2U6ICdnaGNyLmlvL3dpbmRtaWxsLWxhYnMvd2luZG1pbGw6bWFpbicKICAgIGVudmlyb25tZW50OgogICAgICAtICdEQVRBQkFTRV9VUkw9cG9zdGdyZXM6Ly9wb3N0Z3JlczokU0VSVklDRV9QQVNTV09SRF9QT1NUR1JFU0BkYi93aW5kbWlsbCcKICAgICAgLSAnTU9ERT0ke01PREU6LXdvcmtlcn0nCiAgICAgIC0gJ1dPUktFUl9HUk9VUD0ke1dPUktFUl9HUk9VUDotZGVmYXVsdH0nCiAgICBkZXBlbmRzX29uOgogICAgICBkYjoKICAgICAgICBjb25kaXRpb246IHNlcnZpY2VfaGVhbHRoeQogICAgdm9sdW1lczoKICAgICAgLSAnL3Zhci9ydW4vZG9ja2VyLnNvY2s6L3Zhci9ydW4vZG9ja2VyLnNvY2snCiAgICAgIC0gJ3dvcmtlci1kZXBlbmRlbmN5LWNhY2hlOi90bXAvd2luZG1pbGwvY2FjaGUnCiAgICAgIC0gJ3dvcmtlci1sb2dzOi90bXAvd2luZG1pbGwvbG9ncycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnZXhpdCAwJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgd2luZG1pbGwtd29ya2VyLW5hdGl2ZToKICAgIGltYWdlOiAnZ2hjci5pby93aW5kbWlsbC1sYWJzL3dpbmRtaWxsOm1haW4nCiAgICBlbnZpcm9ubWVudDoKICAgICAgLSAnREFUQUJBU0VfVVJMPXBvc3RncmVzOi8vcG9zdGdyZXM6JFNFUlZJQ0VfUEFTU1dPUkRfUE9TVEdSRVNAZGIvd2luZG1pbGwnCiAgICAgIC0gJ01PREU9JHtNT0RFOi13b3JrZXJ9JwogICAgICAtICdXT1JLRVJfR1JPVVA9JHtXT1JLRVJfR1JPVVA6LW5hdGl2ZX0nCiAgICAgIC0gJ05VTV9XT1JLRVJTPSR7TlVNX1dPUktFUlM6LTh9JwogICAgICAtICdTTEVFUF9RVUVVRT0ke1NMRUVQX1FVRVVFOi0yMDB9JwogICAgZGVwZW5kc19vbjoKICAgICAgZGI6CiAgICAgICAgY29uZGl0aW9uOiBzZXJ2aWNlX2hlYWx0aHkKICAgIHZvbHVtZXM6CiAgICAgIC0gJ3dvcmtlci1sb2dzOi90bXAvd2luZG1pbGwvbG9ncycKICAgIGhlYWx0aGNoZWNrOgogICAgICB0ZXN0OgogICAgICAgIC0gQ01ELVNIRUxMCiAgICAgICAgLSAnZXhpdCAwJwogICAgICBpbnRlcnZhbDogMzBzCiAgICAgIHRpbWVvdXQ6IDEwcwogICAgICByZXRyaWVzOiAzCiAgbHNwOgogICAgaW1hZ2U6ICdnaGNyLmlvL3dpbmRtaWxsLWxhYnMvd2luZG1pbGwtbHNwOmxhdGVzdCcKICAgIHZvbHVtZXM6CiAgICAgIC0gJ2xzcC1jYWNoZTovcm9vdC8uY2FjaGUnCiAgICBoZWFsdGhjaGVjazoKICAgICAgdGVzdDoKICAgICAgICAtIENNRC1TSEVMTAogICAgICAgIC0gJ2V4aXQgMCcKICAgICAgaW50ZXJ2YWw6IDMwcwogICAgICB0aW1lb3V0OiAxMHMKICAgICAgcmV0cmllczogMwo=", "tags": [ "windmill", "workflow", From 8a2c9f3d443820541fbf14682efa0dd5b2fc319c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 17:54:29 +0200 Subject: [PATCH 50/56] updates sentinel --- app/Jobs/PushServerUpdateJob.php | 312 +++++++++++++++++++++++++------ 1 file changed, 259 insertions(+), 53 deletions(-) diff --git a/app/Jobs/PushServerUpdateJob.php b/app/Jobs/PushServerUpdateJob.php index 226cf9392..a426e8532 100644 --- a/app/Jobs/PushServerUpdateJob.php +++ b/app/Jobs/PushServerUpdateJob.php @@ -2,17 +2,20 @@ namespace App\Jobs; +use App\Actions\Database\StartDatabaseProxy; use App\Actions\Proxy\StartProxy; +use App\Actions\Shared\ComplexStatusCheck; use App\Models\Application; use App\Models\ApplicationPreview; use App\Models\Server; +use App\Models\ServiceApplication; +use App\Models\ServiceDatabase; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; use Illuminate\Support\Collection; -use Illuminate\Support\Facades\Log; class PushServerUpdateJob implements ShouldQueue { @@ -20,7 +23,33 @@ class PushServerUpdateJob implements ShouldQueue public $tries = 1; - public $timeout = 60; + public $timeout = 30; + + public Collection $containers; + + public Collection $allApplicationIds; + + public Collection $allDatabaseUuids; + + public Collection $allServiceApplicationIds; + + public Collection $allApplicationPreviewsIds; + + public Collection $allServiceDatabaseIds; + + public Collection $allApplicationsWithAdditionalServers; + + public Collection $foundApplicationIds; + + public Collection $foundDatabaseUuids; + + public Collection $foundServiceApplicationIds; + + public Collection $foundServiceDatabaseIds; + + public Collection $foundApplicationPreviewsIds; + + public bool $foundProxy = false; public function backoff(): int { @@ -29,12 +58,19 @@ class PushServerUpdateJob implements ShouldQueue public function __construct(public Server $server, public $data) { - // TODO: Handle multiple servers - // TODO: Handle Preview deployments - // TODO: Handle DB TCP proxies - // TODO: Handle DBs - // TODO: Handle services - // TODO: Handle proxies + // TODO: Handle multiple servers - done - NOT TESTED + // TODO: Handle Preview deployments - done - NOT TESTED + $this->containers = collect(); + $this->foundApplicationIds = collect(); + $this->foundDatabaseUuids = collect(); + $this->foundServiceApplicationIds = collect(); + $this->foundApplicationPreviewsIds = collect(); + $this->foundServiceDatabaseIds = collect(); + $this->allApplicationIds = collect(); + $this->allDatabaseUuids = collect(); + $this->allTcpProxyUuids = collect(); + $this->allServiceApplicationIds = collect(); + $this->allServiceDatabaseIds = collect(); } public function handle() @@ -43,14 +79,34 @@ class PushServerUpdateJob implements ShouldQueue throw new \Exception('No data provided'); } $data = collect($this->data); - $containers = collect(data_get($data, 'containers')); - if ($containers->isEmpty()) { + $this->containers = collect(data_get($data, 'containers')); + if ($this->containers->isEmpty()) { return; } - $foundApplicationIds = collect(); - $foundServiceIds = collect(); - $foundProxy = false; - foreach ($containers as $container) { + $this->allApplicationIds = $this->server->applications() + ->filter(function ($application) { + return $application->additional_servers->count() === 0; + }) + ->pluck('id'); + $this->allApplicationsWithAdditionalServers = $this->server->applications() + ->filter(function ($application) { + return $application->additional_servers->count() > 0; + }); + $this->allApplicationPreviewsIds = $this->server->previews()->pluck('id'); + $this->allDatabaseUuids = $this->server->databases()->pluck('uuid'); + $this->allTcpProxyUuids = $this->server->databases()->where('is_public', true)->pluck('uuid'); + $this->server->services()->each(function ($service) { + $service->applications()->pluck('id')->each(function ($applicationId) { + $this->allServiceApplicationIds->push($applicationId); + }); + $service->databases()->pluck('id')->each(function ($databaseId) { + $this->allServiceDatabaseIds->push($databaseId); + }); + }); + + logger('allServiceApplicationIds', ['allServiceApplicationIds' => $this->allServiceApplicationIds]); + + foreach ($this->containers as $container) { $containerStatus = data_get($container, 'state', 'exited'); $containerHealth = data_get($container, 'health_status', 'unhealthy'); $containerStatus = "$containerStatus ($containerHealth)"; @@ -60,77 +116,227 @@ class PushServerUpdateJob implements ShouldQueue if ($labels->has('coolify.applicationId')) { $applicationId = $labels->get('coolify.applicationId'); $pullRequestId = data_get($labels, 'coolify.pullRequestId', '0'); - $foundApplicationIds->push($applicationId); try { - $this->updateApplicationStatus($applicationId, $pullRequestId, $containerStatus); + if ($pullRequestId === '0') { + if ($this->allApplicationIds->contains($applicationId)) { + $this->foundApplicationIds->push($applicationId); + } + $this->updateApplicationStatus($applicationId, $containerStatus); + } else { + if ($this->allApplicationPreviewsIds->contains($applicationId)) { + $this->foundApplicationPreviewsIds->push($applicationId); + } + $this->updateApplicationPreviewStatus($applicationId, $containerStatus); + } } catch (\Exception $e) { - Log::error($e); + logger()->error($e); } } elseif ($labels->has('coolify.serviceId')) { $serviceId = $labels->get('coolify.serviceId'); - $foundServiceIds->push($serviceId); - Log::info("Service: $serviceId, $containerStatus"); + $subType = $labels->get('coolify.service.subType'); + $subId = $labels->get('coolify.service.subId'); + if ($subType === 'application') { + $this->foundServiceApplicationIds->push($subId); + $this->updateServiceSubStatus($serviceId, $subType, $subId, $containerStatus); + } elseif ($subType === 'database') { + $this->foundServiceDatabaseIds->push($subId); + $this->updateServiceSubStatus($serviceId, $subType, $subId, $containerStatus); + } + } else { $name = data_get($container, 'name'); $uuid = $labels->get('com.docker.compose.service'); $type = $labels->get('coolify.type'); if ($name === 'coolify-proxy') { - $foundProxy = true; - Log::info("Proxy: $uuid, $containerStatus"); + $this->foundProxy = true; } elseif ($type === 'service') { - Log::info("Service: $uuid, $containerStatus"); + logger("Service: $uuid, $containerStatus"); } else { - Log::info("Database: $uuid, $containerStatus"); + if ($this->allDatabaseUuids->contains($uuid)) { + $this->foundDatabaseUuids->push($uuid); + if ($this->allTcpProxyUuids->contains($uuid)) { + $this->updateDatabaseStatus($uuid, $containerStatus, tcpProxy: true); + } else { + $this->updateDatabaseStatus($uuid, $containerStatus, tcpProxy: false); + } + } } } } } + $this->updateProxyStatus(); + + $this->updateNotFoundApplicationStatus(); + $this->updateNotFoundApplicationPreviewStatus(); + $this->updateNotFoundDatabaseStatus(); + $this->updateNotFoundServiceStatus(); + + $this->updateAdditionalServersStatus(); + } + + private function updateApplicationStatus(string $applicationId, string $containerStatus) + { + $application = $this->server->applications()->where('id', $applicationId)->first(); + if (! $application) { + return; + } + $application->status = $containerStatus; + $application->save(); + logger('Application updated', ['application_id' => $applicationId, 'status' => $containerStatus]); + } + + private function updateApplicationPreviewStatus(string $applicationId, string $containerStatus) + { + $application = $this->server->previews()->where('id', $applicationId)->first(); + if (! $application) { + return; + } + $application->status = $containerStatus; + $application->save(); + logger('Application preview updated', ['application_id' => $applicationId, 'status' => $containerStatus]); + } + + private function updateNotFoundApplicationStatus() + { + $notFoundApplicationIds = $this->allApplicationIds->diff($this->foundApplicationIds); + if ($notFoundApplicationIds->isNotEmpty()) { + logger('Not found application ids', ['application_ids' => $notFoundApplicationIds]); + $notFoundApplicationIds->each(function ($applicationId) { + logger('Updating application status', ['application_id' => $applicationId, 'status' => 'exited']); + $application = Application::find($applicationId); + if ($application) { + $application->status = 'exited'; + $application->save(); + logger('Application status updated', ['application_id' => $applicationId, 'status' => 'exited']); + } + }); + } + } + + private function updateNotFoundApplicationPreviewStatus() + { + $notFoundApplicationPreviewsIds = $this->allApplicationPreviewsIds->diff($this->foundApplicationPreviewsIds); + if ($notFoundApplicationPreviewsIds->isNotEmpty()) { + logger('Not found application previews ids', ['application_previews_ids' => $notFoundApplicationPreviewsIds]); + $notFoundApplicationPreviewsIds->each(function ($applicationPreviewId) { + logger('Updating application preview status', ['application_preview_id' => $applicationPreviewId, 'status' => 'exited']); + $applicationPreview = ApplicationPreview::find($applicationPreviewId); + if ($applicationPreview) { + $applicationPreview->status = 'exited'; + $applicationPreview->save(); + logger('Application preview status updated', ['application_preview_id' => $applicationPreviewId, 'status' => 'exited']); + } + }); + } + } + + private function updateProxyStatus() + { // If proxy is not found, start it - if (! $foundProxy && $this->server->isProxyShouldRun()) { - Log::info('Proxy not found, starting it'); + if (! $this->foundProxy && $this->server->isProxyShouldRun()) { + logger('Proxy not found, starting it.'); StartProxy::dispatch($this->server); } - // Update not found applications - $allApplicationIds = $this->server->applications()->pluck('id'); - $notFoundApplicationIds = $allApplicationIds->diff($foundApplicationIds); - if ($notFoundApplicationIds->isNotEmpty()) { - Log::info('Not found application ids', ['application_ids' => $notFoundApplicationIds]); - $this->updateNotFoundApplications($notFoundApplicationIds); + } + + private function updateDatabaseStatus(string $databaseUuid, string $containerStatus, bool $tcpProxy = false) + { + $database = $this->server->databases()->where('uuid', $databaseUuid)->first(); + if (! $database) { + return; + } + $database->status = $containerStatus; + $database->save(); + + if (str($containerStatus)->contains('running') && $tcpProxy) { + $tcpProxyContainerFound = $this->containers->filter(function ($value, $key) use ($databaseUuid) { + return data_get($value, 'name') === "$databaseUuid-proxy"; + })->first(); + + if (! $tcpProxyContainerFound) { + logger('Starting TCP proxy for database', ['database_uuid' => $databaseUuid]); + StartDatabaseProxy::dispatch($database); + } else { + logger('TCP proxy for database found in containers', ['database_uuid' => $databaseUuid]); + } } } - private function updateApplicationStatus(string $applicationId, string $pullRequestId, string $containerStatus) + private function updateNotFoundDatabaseStatus() { - if ($pullRequestId === '0') { - $application = Application::find($applicationId); - if (! $application) { - return; - } + $notFoundDatabaseUuids = $this->allDatabaseUuids->diff($this->foundDatabaseUuids); + if ($notFoundDatabaseUuids->isNotEmpty()) { + logger('Not found database uuids', ['database_uuids' => $notFoundDatabaseUuids]); + $notFoundDatabaseUuids->each(function ($databaseUuid) { + logger('Updating database status', ['database_uuid' => $databaseUuid, 'status' => 'exited']); + $database = $this->server->databases()->where('uuid', $databaseUuid)->first(); + if ($database) { + $database->status = 'exited'; + $database->save(); + logger('Database status updated', ['database_uuid' => $databaseUuid, 'status' => 'exited']); + } + }); + } + } + + private function updateServiceSubStatus(string $serviceId, string $subType, string $subId, string $containerStatus) + { + $service = $this->server->services()->where('id', $serviceId)->first(); + if (! $service) { + return; + } + if ($subType === 'application') { + $application = $service->applications()->where('id', $subId)->first(); $application->status = $containerStatus; $application->save(); - Log::info('Application updated', ['application_id' => $applicationId, 'status' => $containerStatus]); + logger('Service application updated', ['service_id' => $serviceId, 'sub_type' => $subType, 'sub_id' => $subId, 'status' => $containerStatus]); + } elseif ($subType === 'database') { + $database = $service->databases()->where('id', $subId)->first(); + $database->status = $containerStatus; + $database->save(); + logger('Service database updated', ['service_id' => $serviceId, 'sub_type' => $subType, 'sub_id' => $subId, 'status' => $containerStatus]); } else { - $application = ApplicationPreview::where('application_id', $applicationId)->where('pull_request_id', $pullRequestId)->first(); - if (! $application) { - return; - } - $application->status = $containerStatus; - $application->save(); + logger()->warning('Unknown sub type', ['service_id' => $serviceId, 'sub_type' => $subType, 'sub_id' => $subId, 'status' => $containerStatus]); } } - private function updateNotFoundApplications(Collection $applicationIds) + private function updateNotFoundServiceStatus() { - $applicationIds->each(function ($applicationId) { - Log::info('Updating application status', ['application_id' => $applicationId, 'status' => 'exited']); - $application = Application::find($applicationId); - if ($application) { - $application->status = 'exited'; - $application->save(); - Log::info('Application status updated', ['application_id' => $applicationId, 'status' => 'exited']); - } + $notFoundServiceApplicationIds = $this->allServiceApplicationIds->diff($this->foundServiceApplicationIds); + $notFoundServiceDatabaseIds = $this->allServiceDatabaseIds->diff($this->foundServiceDatabaseIds); + if ($notFoundServiceApplicationIds->isNotEmpty()) { + logger('Not found service application ids', ['service_application_ids' => $notFoundServiceApplicationIds]); + $notFoundServiceApplicationIds->each(function ($serviceApplicationId) { + logger('Updating service application status', ['service_application_id' => $serviceApplicationId, 'status' => 'exited']); + $application = ServiceApplication::find($serviceApplicationId); + if ($application) { + $application->status = 'exited'; + $application->save(); + logger('Service application status updated', ['service_application_id' => $serviceApplicationId, 'status' => 'exited']); + } + }); + } + if ($notFoundServiceDatabaseIds->isNotEmpty()) { + logger('Not found service database ids', ['service_database_ids' => $notFoundServiceDatabaseIds]); + $notFoundServiceDatabaseIds->each(function ($serviceDatabaseId) { + logger('Updating service database status', ['service_database_id' => $serviceDatabaseId, 'status' => 'exited']); + $database = ServiceDatabase::find($serviceDatabaseId); + if ($database) { + $database->status = 'exited'; + $database->save(); + logger('Service database status updated', ['service_database_id' => $serviceDatabaseId, 'status' => 'exited']); + } + }); + } + } + + private function updateAdditionalServersStatus() + { + $this->allApplicationsWithAdditionalServers->each(function ($application) { + logger('Updating additional servers status for application', ['application_id' => $application->id]); + ComplexStatusCheck::run($application); }); } } From 1f72321681e197603488700b98aff43e830f4792 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 18:04:36 +0200 Subject: [PATCH 51/56] fix: sentinel --- app/Jobs/PushServerUpdateJob.php | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/Jobs/PushServerUpdateJob.php b/app/Jobs/PushServerUpdateJob.php index a426e8532..3b4bd0598 100644 --- a/app/Jobs/PushServerUpdateJob.php +++ b/app/Jobs/PushServerUpdateJob.php @@ -60,6 +60,7 @@ class PushServerUpdateJob implements ShouldQueue { // TODO: Handle multiple servers - done - NOT TESTED // TODO: Handle Preview deployments - done - NOT TESTED + // TODO: Emails $this->containers = collect(); $this->foundApplicationIds = collect(); $this->foundDatabaseUuids = collect(); @@ -148,7 +149,10 @@ class PushServerUpdateJob implements ShouldQueue $uuid = $labels->get('com.docker.compose.service'); $type = $labels->get('coolify.type'); if ($name === 'coolify-proxy') { - $this->foundProxy = true; + logger("Proxy: $uuid, $containerStatus"); + if (str($containerStatus)->contains('running')) { + $this->foundProxy = true; + } } elseif ($type === 'service') { logger("Service: $uuid, $containerStatus"); } else { @@ -234,6 +238,7 @@ class PushServerUpdateJob implements ShouldQueue private function updateProxyStatus() { // If proxy is not found, start it + logger('Proxy not found', ['foundProxy' => $this->foundProxy, 'isProxyShouldRun' => $this->server->isProxyShouldRun()]); if (! $this->foundProxy && $this->server->isProxyShouldRun()) { logger('Proxy not found, starting it.'); StartProxy::dispatch($this->server); @@ -249,12 +254,12 @@ class PushServerUpdateJob implements ShouldQueue } $database->status = $containerStatus; $database->save(); - + logger('Database status updated', ['database_uuid' => $databaseUuid, 'status' => $containerStatus]); if (str($containerStatus)->contains('running') && $tcpProxy) { $tcpProxyContainerFound = $this->containers->filter(function ($value, $key) use ($databaseUuid) { - return data_get($value, 'name') === "$databaseUuid-proxy"; + return data_get($value, 'name') === "$databaseUuid-proxy" && data_get($value, 'state') === 'running'; })->first(); - + logger('TCP proxy container found', ['tcpProxyContainerFound' => $tcpProxyContainerFound]); if (! $tcpProxyContainerFound) { logger('Starting TCP proxy for database', ['database_uuid' => $databaseUuid]); StartDatabaseProxy::dispatch($database); From bdd6597451e93a5aface19876e79e3b736045a9e Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 19:42:44 +0200 Subject: [PATCH 52/56] chore: Update project resource index page --- app/Livewire/Project/Resource/Index.php | 4 +++- .../views/livewire/project/resource/index.blade.php | 10 +++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/Livewire/Project/Resource/Index.php b/app/Livewire/Project/Resource/Index.php index 71ce2c356..283496887 100644 --- a/app/Livewire/Project/Resource/Index.php +++ b/app/Livewire/Project/Resource/Index.php @@ -32,8 +32,11 @@ class Index extends Component public $services = []; + public array $parameters; + public function mount() { + $this->parameters = get_route_parameters(); $project = currentTeam()->load(['projects'])->projects->where('uuid', request()->route('project_uuid'))->first(); if (! $project) { return redirect()->route('dashboard'); @@ -44,7 +47,6 @@ class Index extends Component } $this->project = $project; $this->environment = $environment; - $this->applications = $this->environment->applications->load(['tags']); $this->applications = $this->applications->map(function ($application) { if (data_get($application, 'environment.project.uuid')) { diff --git a/resources/views/livewire/project/resource/index.blade.php b/resources/views/livewire/project/resource/index.blade.php index f6502762a..0e16b7266 100644 --- a/resources/views/livewire/project/resource/index.blade.php +++ b/resources/views/livewire/project/resource/index.blade.php @@ -7,15 +7,15 @@

Resources

@if ($environment->isEmpty()) + href="{{ route('project.clone-me', ['project_uuid' => data_get($project, 'uuid'), 'environment_name' => data_get($parameters, 'environment_name')]) }}"> Clone @else - + New + href="{{ route('project.clone-me', ['project_uuid' => data_get($project, 'uuid'), 'environment_name' => data_get($parameters, 'environment_name')]) }}"> Clone @endif @@ -25,7 +25,7 @@
  1. + href="{{ route('project.show', ['project_uuid' => data_get($parameters, 'project_uuid')]) }}"> {{ $project->name }}
  2. @@ -44,7 +44,7 @@
@if ($environment->isEmpty()) - + Add New Resource @else
From fdeb9353bea2c751917ddd5357543594fac8a0f6 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 19:45:03 +0200 Subject: [PATCH 53/56] chore: Update project service configuration view --- app/Jobs/PushServerUpdateJob.php | 247 +++++++++--------- .../project/service/configuration.blade.php | 2 +- 2 files changed, 130 insertions(+), 119 deletions(-) diff --git a/app/Jobs/PushServerUpdateJob.php b/app/Jobs/PushServerUpdateJob.php index 3b4bd0598..9bed82015 100644 --- a/app/Jobs/PushServerUpdateJob.php +++ b/app/Jobs/PushServerUpdateJob.php @@ -3,6 +3,7 @@ namespace App\Jobs; use App\Actions\Database\StartDatabaseProxy; +use App\Actions\Database\StopDatabaseProxy; use App\Actions\Proxy\StartProxy; use App\Actions\Shared\ComplexStatusCheck; use App\Models\Application; @@ -76,107 +77,109 @@ class PushServerUpdateJob implements ShouldQueue public function handle() { - if (! $this->data) { - throw new \Exception('No data provided'); - } - $data = collect($this->data); - $this->containers = collect(data_get($data, 'containers')); - if ($this->containers->isEmpty()) { - return; - } - $this->allApplicationIds = $this->server->applications() - ->filter(function ($application) { - return $application->additional_servers->count() === 0; - }) - ->pluck('id'); - $this->allApplicationsWithAdditionalServers = $this->server->applications() - ->filter(function ($application) { - return $application->additional_servers->count() > 0; + try { + if (! $this->data) { + throw new \Exception('No data provided'); + } + $data = collect($this->data); + $this->containers = collect(data_get($data, 'containers')); + if ($this->containers->isEmpty()) { + return; + } + $this->allApplicationIds = $this->server->applications() + ->filter(function ($application) { + return $application->additional_servers->count() === 0; + }) + ->pluck('id'); + $this->allApplicationsWithAdditionalServers = $this->server->applications() + ->filter(function ($application) { + return $application->additional_servers->count() > 0; + }); + $this->allApplicationPreviewsIds = $this->server->previews()->pluck('id'); + $this->allDatabaseUuids = $this->server->databases()->pluck('uuid'); + $this->allTcpProxyUuids = $this->server->databases()->where('is_public', true)->pluck('uuid'); + $this->server->services()->each(function ($service) { + $service->applications()->pluck('id')->each(function ($applicationId) { + $this->allServiceApplicationIds->push($applicationId); + }); + $service->databases()->pluck('id')->each(function ($databaseId) { + $this->allServiceDatabaseIds->push($databaseId); + }); }); - $this->allApplicationPreviewsIds = $this->server->previews()->pluck('id'); - $this->allDatabaseUuids = $this->server->databases()->pluck('uuid'); - $this->allTcpProxyUuids = $this->server->databases()->where('is_public', true)->pluck('uuid'); - $this->server->services()->each(function ($service) { - $service->applications()->pluck('id')->each(function ($applicationId) { - $this->allServiceApplicationIds->push($applicationId); - }); - $service->databases()->pluck('id')->each(function ($databaseId) { - $this->allServiceDatabaseIds->push($databaseId); - }); - }); - logger('allServiceApplicationIds', ['allServiceApplicationIds' => $this->allServiceApplicationIds]); + ray('allServiceApplicationIds', ['allServiceApplicationIds' => $this->allServiceApplicationIds]); - foreach ($this->containers as $container) { - $containerStatus = data_get($container, 'state', 'exited'); - $containerHealth = data_get($container, 'health_status', 'unhealthy'); - $containerStatus = "$containerStatus ($containerHealth)"; - $labels = collect(data_get($container, 'labels')); - $coolify_managed = $labels->has('coolify.managed'); - if ($coolify_managed) { - if ($labels->has('coolify.applicationId')) { - $applicationId = $labels->get('coolify.applicationId'); - $pullRequestId = data_get($labels, 'coolify.pullRequestId', '0'); - try { - if ($pullRequestId === '0') { - if ($this->allApplicationIds->contains($applicationId)) { - $this->foundApplicationIds->push($applicationId); - } - $this->updateApplicationStatus($applicationId, $containerStatus); - } else { - if ($this->allApplicationPreviewsIds->contains($applicationId)) { - $this->foundApplicationPreviewsIds->push($applicationId); - } - $this->updateApplicationPreviewStatus($applicationId, $containerStatus); - } - } catch (\Exception $e) { - logger()->error($e); - } - } elseif ($labels->has('coolify.serviceId')) { - $serviceId = $labels->get('coolify.serviceId'); - $subType = $labels->get('coolify.service.subType'); - $subId = $labels->get('coolify.service.subId'); - if ($subType === 'application') { - $this->foundServiceApplicationIds->push($subId); - $this->updateServiceSubStatus($serviceId, $subType, $subId, $containerStatus); - } elseif ($subType === 'database') { - $this->foundServiceDatabaseIds->push($subId); - $this->updateServiceSubStatus($serviceId, $subType, $subId, $containerStatus); - } - - } else { - $name = data_get($container, 'name'); - $uuid = $labels->get('com.docker.compose.service'); - $type = $labels->get('coolify.type'); - if ($name === 'coolify-proxy') { - logger("Proxy: $uuid, $containerStatus"); - if (str($containerStatus)->contains('running')) { - $this->foundProxy = true; - } - } elseif ($type === 'service') { - logger("Service: $uuid, $containerStatus"); - } else { - if ($this->allDatabaseUuids->contains($uuid)) { - $this->foundDatabaseUuids->push($uuid); - if ($this->allTcpProxyUuids->contains($uuid)) { - $this->updateDatabaseStatus($uuid, $containerStatus, tcpProxy: true); + foreach ($this->containers as $container) { + $containerStatus = data_get($container, 'state', 'exited'); + $containerHealth = data_get($container, 'health_status', 'unhealthy'); + $containerStatus = "$containerStatus ($containerHealth)"; + $labels = collect(data_get($container, 'labels')); + $coolify_managed = $labels->has('coolify.managed'); + if ($coolify_managed) { + if ($labels->has('coolify.applicationId')) { + $applicationId = $labels->get('coolify.applicationId'); + $pullRequestId = data_get($labels, 'coolify.pullRequestId', '0'); + try { + if ($pullRequestId === '0') { + if ($this->allApplicationIds->contains($applicationId) && $this->isRunning($containerStatus)) { + $this->foundApplicationIds->push($applicationId); + } + $this->updateApplicationStatus($applicationId, $containerStatus); } else { - $this->updateDatabaseStatus($uuid, $containerStatus, tcpProxy: false); + if ($this->allApplicationPreviewsIds->contains($applicationId) && $this->isRunning($containerStatus)) { + $this->foundApplicationPreviewsIds->push($applicationId); + } + $this->updateApplicationPreviewStatus($applicationId, $containerStatus); + } + } catch (\Exception $e) { + ray()->error($e); + } + } elseif ($labels->has('coolify.serviceId')) { + $serviceId = $labels->get('coolify.serviceId'); + $subType = $labels->get('coolify.service.subType'); + $subId = $labels->get('coolify.service.subId'); + if ($subType === 'application' && $this->isRunning($containerStatus)) { + $this->foundServiceApplicationIds->push($subId); + $this->updateServiceSubStatus($serviceId, $subType, $subId, $containerStatus); + } elseif ($subType === 'database' && $this->isRunning($containerStatus)) { + $this->foundServiceDatabaseIds->push($subId); + $this->updateServiceSubStatus($serviceId, $subType, $subId, $containerStatus); + } + + } else { + $name = data_get($container, 'name'); + $uuid = $labels->get('com.docker.compose.service'); + $type = $labels->get('coolify.type'); + if ($name === 'coolify-proxy' && $this->isRunning($containerStatus)) { + $this->foundProxy = true; + } elseif ($type === 'service' && $this->isRunning($containerStatus)) { + ray("Service: $uuid, $containerStatus"); + } else { + if ($this->allDatabaseUuids->contains($uuid) && $this->isRunning($containerStatus)) { + $this->foundDatabaseUuids->push($uuid); + if ($this->allTcpProxyUuids->contains($uuid) && $this->isRunning($containerStatus)) { + $this->updateDatabaseStatus($uuid, $containerStatus, tcpProxy: true); + } else { + $this->updateDatabaseStatus($uuid, $containerStatus, tcpProxy: false); + } } } } } } + + $this->updateProxyStatus(); + + $this->updateNotFoundApplicationStatus(); + $this->updateNotFoundApplicationPreviewStatus(); + $this->updateNotFoundDatabaseStatus(); + $this->updateNotFoundServiceStatus(); + + $this->updateAdditionalServersStatus(); + } catch (\Exception $e) { + throw $e; } - $this->updateProxyStatus(); - - $this->updateNotFoundApplicationStatus(); - $this->updateNotFoundApplicationPreviewStatus(); - $this->updateNotFoundDatabaseStatus(); - $this->updateNotFoundServiceStatus(); - - $this->updateAdditionalServersStatus(); } private function updateApplicationStatus(string $applicationId, string $containerStatus) @@ -187,7 +190,7 @@ class PushServerUpdateJob implements ShouldQueue } $application->status = $containerStatus; $application->save(); - logger('Application updated', ['application_id' => $applicationId, 'status' => $containerStatus]); + ray('Application updated', ['application_id' => $applicationId, 'status' => $containerStatus]); } private function updateApplicationPreviewStatus(string $applicationId, string $containerStatus) @@ -198,21 +201,21 @@ class PushServerUpdateJob implements ShouldQueue } $application->status = $containerStatus; $application->save(); - logger('Application preview updated', ['application_id' => $applicationId, 'status' => $containerStatus]); + ray('Application preview updated', ['application_id' => $applicationId, 'status' => $containerStatus]); } private function updateNotFoundApplicationStatus() { $notFoundApplicationIds = $this->allApplicationIds->diff($this->foundApplicationIds); if ($notFoundApplicationIds->isNotEmpty()) { - logger('Not found application ids', ['application_ids' => $notFoundApplicationIds]); + ray('Not found application ids', ['application_ids' => $notFoundApplicationIds]); $notFoundApplicationIds->each(function ($applicationId) { - logger('Updating application status', ['application_id' => $applicationId, 'status' => 'exited']); + ray('Updating application status', ['application_id' => $applicationId, 'status' => 'exited']); $application = Application::find($applicationId); if ($application) { $application->status = 'exited'; $application->save(); - logger('Application status updated', ['application_id' => $applicationId, 'status' => 'exited']); + ray('Application status updated', ['application_id' => $applicationId, 'status' => 'exited']); } }); } @@ -222,14 +225,14 @@ class PushServerUpdateJob implements ShouldQueue { $notFoundApplicationPreviewsIds = $this->allApplicationPreviewsIds->diff($this->foundApplicationPreviewsIds); if ($notFoundApplicationPreviewsIds->isNotEmpty()) { - logger('Not found application previews ids', ['application_previews_ids' => $notFoundApplicationPreviewsIds]); + ray('Not found application previews ids', ['application_previews_ids' => $notFoundApplicationPreviewsIds]); $notFoundApplicationPreviewsIds->each(function ($applicationPreviewId) { - logger('Updating application preview status', ['application_preview_id' => $applicationPreviewId, 'status' => 'exited']); + ray('Updating application preview status', ['application_preview_id' => $applicationPreviewId, 'status' => 'exited']); $applicationPreview = ApplicationPreview::find($applicationPreviewId); if ($applicationPreview) { $applicationPreview->status = 'exited'; $applicationPreview->save(); - logger('Application preview status updated', ['application_preview_id' => $applicationPreviewId, 'status' => 'exited']); + ray('Application preview status updated', ['application_preview_id' => $applicationPreviewId, 'status' => 'exited']); } }); } @@ -238,9 +241,8 @@ class PushServerUpdateJob implements ShouldQueue private function updateProxyStatus() { // If proxy is not found, start it - logger('Proxy not found', ['foundProxy' => $this->foundProxy, 'isProxyShouldRun' => $this->server->isProxyShouldRun()]); if (! $this->foundProxy && $this->server->isProxyShouldRun()) { - logger('Proxy not found, starting it.'); + ray('Proxy not found, starting it.'); StartProxy::dispatch($this->server); } @@ -254,17 +256,16 @@ class PushServerUpdateJob implements ShouldQueue } $database->status = $containerStatus; $database->save(); - logger('Database status updated', ['database_uuid' => $databaseUuid, 'status' => $containerStatus]); - if (str($containerStatus)->contains('running') && $tcpProxy) { + ray('Database status updated', ['database_uuid' => $databaseUuid, 'status' => $containerStatus]); + if ($this->isRunning($containerStatus) && $tcpProxy) { $tcpProxyContainerFound = $this->containers->filter(function ($value, $key) use ($databaseUuid) { return data_get($value, 'name') === "$databaseUuid-proxy" && data_get($value, 'state') === 'running'; })->first(); - logger('TCP proxy container found', ['tcpProxyContainerFound' => $tcpProxyContainerFound]); if (! $tcpProxyContainerFound) { - logger('Starting TCP proxy for database', ['database_uuid' => $databaseUuid]); + ray('Starting TCP proxy for database', ['database_uuid' => $databaseUuid]); StartDatabaseProxy::dispatch($database); } else { - logger('TCP proxy for database found in containers', ['database_uuid' => $databaseUuid]); + ray('TCP proxy for database found in containers', ['database_uuid' => $databaseUuid]); } } } @@ -273,14 +274,19 @@ class PushServerUpdateJob implements ShouldQueue { $notFoundDatabaseUuids = $this->allDatabaseUuids->diff($this->foundDatabaseUuids); if ($notFoundDatabaseUuids->isNotEmpty()) { - logger('Not found database uuids', ['database_uuids' => $notFoundDatabaseUuids]); + ray('Not found database uuids', ['database_uuids' => $notFoundDatabaseUuids]); $notFoundDatabaseUuids->each(function ($databaseUuid) { - logger('Updating database status', ['database_uuid' => $databaseUuid, 'status' => 'exited']); + ray('Updating database status', ['database_uuid' => $databaseUuid, 'status' => 'exited']); $database = $this->server->databases()->where('uuid', $databaseUuid)->first(); if ($database) { $database->status = 'exited'; $database->save(); - logger('Database status updated', ['database_uuid' => $databaseUuid, 'status' => 'exited']); + ray('Database status updated', ['database_uuid' => $databaseUuid, 'status' => 'exited']); + ray('Database is public', ['database_uuid' => $databaseUuid, 'is_public' => $database->is_public]); + if ($database->is_public) { + ray('Stopping TCP proxy for database', ['database_uuid' => $databaseUuid]); + StopDatabaseProxy::dispatch($database); + } } }); } @@ -296,14 +302,14 @@ class PushServerUpdateJob implements ShouldQueue $application = $service->applications()->where('id', $subId)->first(); $application->status = $containerStatus; $application->save(); - logger('Service application updated', ['service_id' => $serviceId, 'sub_type' => $subType, 'sub_id' => $subId, 'status' => $containerStatus]); + ray('Service application updated', ['service_id' => $serviceId, 'sub_type' => $subType, 'sub_id' => $subId, 'status' => $containerStatus]); } elseif ($subType === 'database') { $database = $service->databases()->where('id', $subId)->first(); $database->status = $containerStatus; $database->save(); - logger('Service database updated', ['service_id' => $serviceId, 'sub_type' => $subType, 'sub_id' => $subId, 'status' => $containerStatus]); + ray('Service database updated', ['service_id' => $serviceId, 'sub_type' => $subType, 'sub_id' => $subId, 'status' => $containerStatus]); } else { - logger()->warning('Unknown sub type', ['service_id' => $serviceId, 'sub_type' => $subType, 'sub_id' => $subId, 'status' => $containerStatus]); + ray()->warning('Unknown sub type', ['service_id' => $serviceId, 'sub_type' => $subType, 'sub_id' => $subId, 'status' => $containerStatus]); } } @@ -312,26 +318,26 @@ class PushServerUpdateJob implements ShouldQueue $notFoundServiceApplicationIds = $this->allServiceApplicationIds->diff($this->foundServiceApplicationIds); $notFoundServiceDatabaseIds = $this->allServiceDatabaseIds->diff($this->foundServiceDatabaseIds); if ($notFoundServiceApplicationIds->isNotEmpty()) { - logger('Not found service application ids', ['service_application_ids' => $notFoundServiceApplicationIds]); + ray('Not found service application ids', ['service_application_ids' => $notFoundServiceApplicationIds]); $notFoundServiceApplicationIds->each(function ($serviceApplicationId) { - logger('Updating service application status', ['service_application_id' => $serviceApplicationId, 'status' => 'exited']); + ray('Updating service application status', ['service_application_id' => $serviceApplicationId, 'status' => 'exited']); $application = ServiceApplication::find($serviceApplicationId); if ($application) { $application->status = 'exited'; $application->save(); - logger('Service application status updated', ['service_application_id' => $serviceApplicationId, 'status' => 'exited']); + ray('Service application status updated', ['service_application_id' => $serviceApplicationId, 'status' => 'exited']); } }); } if ($notFoundServiceDatabaseIds->isNotEmpty()) { - logger('Not found service database ids', ['service_database_ids' => $notFoundServiceDatabaseIds]); + ray('Not found service database ids', ['service_database_ids' => $notFoundServiceDatabaseIds]); $notFoundServiceDatabaseIds->each(function ($serviceDatabaseId) { - logger('Updating service database status', ['service_database_id' => $serviceDatabaseId, 'status' => 'exited']); + ray('Updating service database status', ['service_database_id' => $serviceDatabaseId, 'status' => 'exited']); $database = ServiceDatabase::find($serviceDatabaseId); if ($database) { $database->status = 'exited'; $database->save(); - logger('Service database status updated', ['service_database_id' => $serviceDatabaseId, 'status' => 'exited']); + ray('Service database status updated', ['service_database_id' => $serviceDatabaseId, 'status' => 'exited']); } }); } @@ -340,8 +346,13 @@ class PushServerUpdateJob implements ShouldQueue private function updateAdditionalServersStatus() { $this->allApplicationsWithAdditionalServers->each(function ($application) { - logger('Updating additional servers status for application', ['application_id' => $application->id]); + ray('Updating additional servers status for application', ['application_id' => $application->id]); ComplexStatusCheck::run($application); }); } + + private function isRunning(string $containerStatus) + { + return str($containerStatus)->contains('running'); + } } diff --git a/resources/views/livewire/project/service/configuration.blade.php b/resources/views/livewire/project/service/configuration.blade.php index d7d9d21d3..ed2a6dec9 100644 --- a/resources/views/livewire/project/service/configuration.blade.php +++ b/resources/views/livewire/project/service/configuration.blade.php @@ -1,4 +1,4 @@ -
+
{{ data_get_str($service, 'name')->limit(10) }} > Configuration | Coolify From bea492165f184486c338db63918bd195ca0d1723 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 21:05:33 +0200 Subject: [PATCH 54/56] sentinel updates --- app/Actions/Server/StartSentinel.php | 48 ++++++++++++------- app/Livewire/Server/Form.php | 21 ++++++-- .../views/livewire/server/form.blade.php | 7 ++- 3 files changed, 51 insertions(+), 25 deletions(-) diff --git a/app/Actions/Server/StartSentinel.php b/app/Actions/Server/StartSentinel.php index 4b45d0738..a52fb4125 100644 --- a/app/Actions/Server/StartSentinel.php +++ b/app/Actions/Server/StartSentinel.php @@ -10,32 +10,48 @@ class StartSentinel { use AsAction; - public function handle(Server $server, $version = 'latest', bool $restart = false) + public function handle(Server $server, $version = 'next', bool $restart = false) { if ($restart) { StopSentinel::run($server); } - $metrics_history = $server->settings->metrics_history_days; - $refresh_rate = $server->settings->metrics_refresh_rate_seconds; + $metrics_history = $server->settings->sentinel_metrics_history_days; + $refresh_rate = $server->settings->sentinel_metrics_refresh_rate_seconds; $token = $server->settings->sentinel_token; - $fqdn = InstanceSettings::get()->fqdn; - if (str($fqdn)->startsWith('http')) { - throw new \Exception('You should use https to run Sentinel.'); + $endpoint = InstanceSettings::get()->fqdn; + if (isDev()) { + $endpoint = 'http://host.docker.internal:8000'; + } else { + if (str($endpoint)->startsWith('http')) { + throw new \Exception('You should use https to run Sentinel.'); + } + } + if (! $endpoint) { + throw new \Exception('You should set FQDN in Instance Settings.'); } $environments = [ 'TOKEN' => $token, - 'ENDPOINT' => InstanceSettings::get()->fqdn, + 'ENDPOINT' => $endpoint, 'COLLECTOR_ENABLED' => 'true', 'COLLECTOR_REFRESH_RATE_SECONDS' => $refresh_rate, - 'COLLECTOR_RETENTION_PERIOD_DAYS' => $metrics_history + 'COLLECTOR_RETENTION_PERIOD_DAYS' => $metrics_history, ]; - $docker_environments = "-e \"" . implode("\" -e \"", array_map(fn($key, $value) => "$key=$value", array_keys($environments), $environments)) . "\""; - ray($docker_environments); - return true; - // instant_remote_process([ - // "docker run --rm --pull always -d $docker_environments --name coolify-sentinel -v /var/run/docker.sock:/var/run/docker.sock -v /data/coolify/sentinel:/app/sentinel --pid host --health-cmd \"curl --fail http://127.0.0.1:8888/api/health || exit 1\" --health-interval 10s --health-retries 3 ghcr.io/coollabsio/sentinel:$version", - // 'chown -R 9999:root /data/coolify/sentinel', - // 'chmod -R 700 /data/coolify/sentinel', - // ], $server, true); + if (isDev()) { + data_set($environments, 'GIN_MODE', 'debug'); + } + $mount_dir = '/data/coolify/sentinel'; + if (isDev()) { + $mount_dir = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/sentinel'; + } + $docker_environments = '-e "'.implode('" -e "', array_map(fn ($key, $value) => "$key=$value", array_keys($environments), $environments)).'"'; + $docker_command = "docker run --pull always --rm -d $docker_environments --name coolify-sentinel -v /var/run/docker.sock:/var/run/docker.sock -v $mount_dir:/app/db --pid host --health-cmd \"curl --fail http://127.0.0.1:8888/api/health || exit 1\" --health-interval 10s --health-retries 3 --add-host=host.docker.internal:host-gateway ghcr.io/coollabsio/sentinel:$version"; + + return instant_remote_process([ + 'docker rm -f coolify-sentinel || true', + "mkdir -p $mount_dir", + $docker_command, + "chown -R 9999:root $mount_dir", + "chmod -R 700 $mount_dir", + ], $server, true); } } diff --git a/app/Livewire/Server/Form.php b/app/Livewire/Server/Form.php index 6efff504b..0bb7e4742 100644 --- a/app/Livewire/Server/Form.php +++ b/app/Livewire/Server/Form.php @@ -101,7 +101,9 @@ class Form extends Component $this->server->settings->delete_unused_volumes = $server->settings->delete_unused_volumes; $this->server->settings->delete_unused_networks = $server->settings->delete_unused_networks; } - public function regenerateSentinelToken() { + + public function regenerateSentinelToken() + { try { $this->server->generateSentinelToken(); $this->server->settings->refresh(); @@ -110,6 +112,7 @@ class Form extends Component return handleError($e, $this); } } + public function updated($field) { if ($field === 'server.settings.docker_cleanup_frequency') { @@ -186,25 +189,26 @@ class Form extends Component public function getPushData() { try { - if (!isDev()) { + if (! isDev()) { throw new \Exception('This feature is only available in dev mode.'); } $response = Http::withHeaders([ - 'Authorization' => 'Bearer ' . $this->server->settings->sentinel_token, + 'Authorization' => 'Bearer '.$this->server->settings->sentinel_token, ])->post('http://host.docker.internal:8888/api/push', [ 'data' => 'test', ]); if ($response->successful()) { $this->dispatch('success', 'Push data sent.'); + return; } $error = data_get($response->json(), 'error'); throw new \Exception($error); - - } catch(\Throwable $e) { + } catch (\Throwable $e) { return handleError($e, $this); } } + public function restartSentinel() { try { @@ -285,6 +289,7 @@ class Form extends Component return handleError($e, $this); } } + public function manualCleanup() { try { @@ -302,4 +307,10 @@ class Form extends Component $this->server->refresh(); $this->dispatch('success', 'Cloudflare Tunnels enabled.'); } + + public function startSentinel() + { + StartSentinel::run($this->server); + $this->dispatch('success', 'Sentinel started.'); + } } diff --git a/resources/views/livewire/server/form.blade.php b/resources/views/livewire/server/form.blade.php index ace297712..47b686c1e 100644 --- a/resources/views/livewire/server/form.blade.php +++ b/resources/views/livewire/server/form.blade.php @@ -282,11 +282,10 @@ {{-- @endif --}}
@if (isDev()) - Push Test - {{--
+
- Start Sentinel -
--}} + Start Sentinel +
Date: Mon, 14 Oct 2024 22:35:18 +0200 Subject: [PATCH 55/56] Refactor StartSentinel to ensure endpoint uses HTTPS --- app/Actions/Server/StartSentinel.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/app/Actions/Server/StartSentinel.php b/app/Actions/Server/StartSentinel.php index a52fb4125..e7c613eb0 100644 --- a/app/Actions/Server/StartSentinel.php +++ b/app/Actions/Server/StartSentinel.php @@ -21,14 +21,12 @@ class StartSentinel $endpoint = InstanceSettings::get()->fqdn; if (isDev()) { $endpoint = 'http://host.docker.internal:8000'; - } else { - if (str($endpoint)->startsWith('http')) { - throw new \Exception('You should use https to run Sentinel.'); - } } if (! $endpoint) { throw new \Exception('You should set FQDN in Instance Settings.'); } + // Ensure the endpoint is using HTTPS + $endpoint = str($endpoint)->replace('http://', 'https://')->value(); $environments = [ 'TOKEN' => $token, 'ENDPOINT' => $endpoint, From 81db57002b3dbe695aed2320478c13a76102874e Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 14 Oct 2024 22:53:16 +0200 Subject: [PATCH 56/56] Refactor PushServerUpdateJob to handle multiple servers, previews, and emails --- app/Jobs/PushServerUpdateJob.php | 48 ++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/app/Jobs/PushServerUpdateJob.php b/app/Jobs/PushServerUpdateJob.php index 9bed82015..e029a3bf5 100644 --- a/app/Jobs/PushServerUpdateJob.php +++ b/app/Jobs/PushServerUpdateJob.php @@ -28,6 +28,14 @@ class PushServerUpdateJob implements ShouldQueue public Collection $containers; + public Collection $applications; + + public Collection $previews; + + public Collection $databases; + + public Collection $services; + public Collection $allApplicationIds; public Collection $allDatabaseUuids; @@ -59,9 +67,6 @@ class PushServerUpdateJob implements ShouldQueue public function __construct(public Server $server, public $data) { - // TODO: Handle multiple servers - done - NOT TESTED - // TODO: Handle Preview deployments - done - NOT TESTED - // TODO: Emails $this->containers = collect(); $this->foundApplicationIds = collect(); $this->foundDatabaseUuids = collect(); @@ -86,19 +91,20 @@ class PushServerUpdateJob implements ShouldQueue if ($this->containers->isEmpty()) { return; } - $this->allApplicationIds = $this->server->applications() - ->filter(function ($application) { - return $application->additional_servers->count() === 0; - }) - ->pluck('id'); - $this->allApplicationsWithAdditionalServers = $this->server->applications() - ->filter(function ($application) { - return $application->additional_servers->count() > 0; - }); - $this->allApplicationPreviewsIds = $this->server->previews()->pluck('id'); - $this->allDatabaseUuids = $this->server->databases()->pluck('uuid'); - $this->allTcpProxyUuids = $this->server->databases()->where('is_public', true)->pluck('uuid'); - $this->server->services()->each(function ($service) { + $this->applications = $this->server->applications(); + $this->databases = $this->server->databases(); + $this->previews = $this->server->previews(); + $this->services = $this->server->services()->get(); + $this->allApplicationIds = $this->applications->filter(function ($application) { + return $application->additional_servers->count() === 0; + })->pluck('id'); + $this->allApplicationsWithAdditionalServers = $this->applications->filter(function ($application) { + return $application->additional_servers->count() > 0; + }); + $this->allApplicationPreviewsIds = $this->previews->pluck('id'); + $this->allDatabaseUuids = $this->databases->pluck('uuid'); + $this->allTcpProxyUuids = $this->databases->where('is_public', true)->pluck('uuid'); + $this->services->each(function ($service) { $service->applications()->pluck('id')->each(function ($applicationId) { $this->allServiceApplicationIds->push($applicationId); }); @@ -184,7 +190,7 @@ class PushServerUpdateJob implements ShouldQueue private function updateApplicationStatus(string $applicationId, string $containerStatus) { - $application = $this->server->applications()->where('id', $applicationId)->first(); + $application = $this->applications->where('id', $applicationId)->first(); if (! $application) { return; } @@ -195,7 +201,7 @@ class PushServerUpdateJob implements ShouldQueue private function updateApplicationPreviewStatus(string $applicationId, string $containerStatus) { - $application = $this->server->previews()->where('id', $applicationId)->first(); + $application = $this->previews->where('id', $applicationId)->first(); if (! $application) { return; } @@ -250,7 +256,7 @@ class PushServerUpdateJob implements ShouldQueue private function updateDatabaseStatus(string $databaseUuid, string $containerStatus, bool $tcpProxy = false) { - $database = $this->server->databases()->where('uuid', $databaseUuid)->first(); + $database = $this->databases->where('uuid', $databaseUuid)->first(); if (! $database) { return; } @@ -277,7 +283,7 @@ class PushServerUpdateJob implements ShouldQueue ray('Not found database uuids', ['database_uuids' => $notFoundDatabaseUuids]); $notFoundDatabaseUuids->each(function ($databaseUuid) { ray('Updating database status', ['database_uuid' => $databaseUuid, 'status' => 'exited']); - $database = $this->server->databases()->where('uuid', $databaseUuid)->first(); + $database = $this->databases->where('uuid', $databaseUuid)->first(); if ($database) { $database->status = 'exited'; $database->save(); @@ -294,7 +300,7 @@ class PushServerUpdateJob implements ShouldQueue private function updateServiceSubStatus(string $serviceId, string $subType, string $subId, string $containerStatus) { - $service = $this->server->services()->where('id', $serviceId)->first(); + $service = $this->services->where('id', $serviceId)->first(); if (! $service) { return; }