From 268fca3477a5ce594f96ba17a4d9ec94e9f21c31 Mon Sep 17 00:00:00 2001
From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com>
Date: Mon, 10 Feb 2025 21:31:31 +0100
Subject: [PATCH 82/90] feat: SSL notification
---
.../SslExpirationNotification.php | 151 ++++++++++++++++++
.../emails/ssl-certificate-renewed.blade.php | 28 ++++
2 files changed, 179 insertions(+)
create mode 100644 app/Notifications/SslExpirationNotification.php
create mode 100644 resources/views/emails/ssl-certificate-renewed.blade.php
diff --git a/app/Notifications/SslExpirationNotification.php b/app/Notifications/SslExpirationNotification.php
new file mode 100644
index 000000000..78e1e8be9
--- /dev/null
+++ b/app/Notifications/SslExpirationNotification.php
@@ -0,0 +1,151 @@
+onQueue('high');
+ $this->resources = collect($resources);
+
+ // Collect URLs for each resource
+ $this->resources->each(function ($resource) {
+ if (data_get($resource, 'environment.project.uuid')) {
+ $routeName = match ($resource->type()) {
+ 'application' => 'project.application.configuration',
+ 'database' => 'project.database.configuration',
+ 'service' => 'project.service.configuration',
+ default => null
+ };
+
+ if ($routeName) {
+ $route = route($routeName, [
+ 'project_uuid' => data_get($resource, 'environment.project.uuid'),
+ 'environment_uuid' => data_get($resource, 'environment.uuid'),
+ $resource->type().'_uuid' => data_get($resource, 'uuid'),
+ ]);
+
+ $settings = instanceSettings();
+ if (data_get($settings, 'fqdn')) {
+ $url = Url::fromString($route);
+ $url = $url->withPort(null);
+ $fqdn = data_get($settings, 'fqdn');
+ $fqdn = str_replace(['http://', 'https://'], '', $fqdn);
+ $url = $url->withHost($fqdn);
+
+ $this->urls[$resource->name] = $url->__toString();
+ } else {
+ $this->urls[$resource->name] = $route;
+ }
+ }
+ }
+ });
+ }
+
+ public function via(object $notifiable): array
+ {
+ return $notifiable->getEnabledChannels('ssl_certificate_renewal');
+ }
+
+ public function toMail(): MailMessage
+ {
+ $mail = new MailMessage;
+ $mail->subject('Coolify: [Action Required] SSL Certificates Renewed - Manual Redeployment Needed');
+ $mail->view('emails.ssl-certificate-renewed', [
+ 'resources' => $this->resources,
+ 'urls' => $this->urls,
+ ]);
+
+ return $mail;
+ }
+
+ public function toDiscord(): DiscordMessage
+ {
+ $resourceNames = $this->resources->pluck('name')->join(', ');
+
+ $message = new DiscordMessage(
+ title: '🔒 SSL Certificates Renewed',
+ description: "SSL certificates have been renewed for: {$resourceNames}.\n\n**Action Required:** These resources need to be redeployed manually.",
+ color: DiscordMessage::warningColor(),
+ );
+
+ foreach ($this->urls as $name => $url) {
+ $message->addField($name, "[View Resource]({$url})");
+ }
+
+ return $message;
+ }
+
+ public function toTelegram(): array
+ {
+ $resourceNames = $this->resources->pluck('name')->join(', ');
+ $message = "Coolify: SSL certificates have been renewed for: {$resourceNames}.\n\nAction Required: These resources need to be redeployed manually for the new SSL certificates to take effect.";
+
+ $buttons = [];
+ foreach ($this->urls as $name => $url) {
+ $buttons[] = [
+ 'text' => "View {$name}",
+ 'url' => $url,
+ ];
+ }
+
+ return [
+ 'message' => $message,
+ 'buttons' => $buttons,
+ ];
+ }
+
+ public function toPushover(): PushoverMessage
+ {
+ $resourceNames = $this->resources->pluck('name')->join(', ');
+ $message = "SSL certificates have been renewed for: {$resourceNames}
";
+ $message .= '
Action Required: These resources need to be redeployed manually for the new SSL certificates to take effect.';
+
+ $buttons = [];
+ foreach ($this->urls as $name => $url) {
+ $buttons[] = [
+ 'text' => "View {$name}",
+ 'url' => $url,
+ ];
+ }
+
+ return new PushoverMessage(
+ title: 'SSL Certificates Renewed',
+ level: 'warning',
+ message: $message,
+ buttons: $buttons,
+ );
+ }
+
+ public function toSlack(): SlackMessage
+ {
+ $resourceNames = $this->resources->pluck('name')->join(', ');
+ $description = "SSL certificates have been renewed for: {$resourceNames}\n\n";
+ $description .= '**Action Required:** These resources need to be redeployed manually for the new SSL certificates to take effect.';
+
+ if (! empty($this->urls)) {
+ $description .= "\n\n**Resource URLs:**\n";
+ foreach ($this->urls as $name => $url) {
+ $description .= "• {$name}: {$url}\n";
+ }
+ }
+
+ return new SlackMessage(
+ title: '🔒 SSL Certificates Renewed',
+ description: $description,
+ color: SlackMessage::warningColor()
+ );
+ }
+}
diff --git a/resources/views/emails/ssl-certificate-renewed.blade.php b/resources/views/emails/ssl-certificate-renewed.blade.php
new file mode 100644
index 000000000..3d0d7a7b2
--- /dev/null
+++ b/resources/views/emails/ssl-certificate-renewed.blade.php
@@ -0,0 +1,28 @@
+
+SSL Certificates Renewed
+
+SSL certificates have been renewed for the following resources:
+
+
+@foreach($resources as $resource)
+ - {{ $resource->name }}
+@endforeach
+
+
+
+ ⚠️ Action Required: These resources need to be redeployed manually for the new SSL certificates to take effect. Please do this in the next few days to ensure your database connections remain accessible.
+
+
+The old SSL certificates will remain valid for approximately 14 more days, as we renew certificates 14 days before their expiration.
+
+@if(isset($urls) && count($urls) > 0)
+
+
You can redeploy these resources here:
+
+ @foreach($urls as $name => $url)
+ - {{ $name }}
+ @endforeach
+
+
+@endif
+
From 0a738e6bff5a25f553214c3d8c3756f91eec26b4 Mon Sep 17 00:00:00 2001
From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com>
Date: Tue, 11 Feb 2025 20:18:19 +0100
Subject: [PATCH 83/90] fix(ssl): KeyDB port and caCert args are missing
---
app/Actions/Database/StartKeydb.php | 2 ++
1 file changed, 2 insertions(+)
diff --git a/app/Actions/Database/StartKeydb.php b/app/Actions/Database/StartKeydb.php
index 1e601e689..8ec076dd2 100644
--- a/app/Actions/Database/StartKeydb.php
+++ b/app/Actions/Database/StartKeydb.php
@@ -287,9 +287,11 @@ class StartKeydb
if ($this->database->enable_ssl) {
$sslArgs = [
+ '--tls-port 6380',
'--tls-cert-file /etc/keydb/certs/server.crt',
'--tls-key-file /etc/keydb/certs/server.key',
'--tls-ca-cert-file /etc/keydb/certs/coolify-ca.crt',
+ '--tls-auth-clients optional',
];
$command .= ' '.implode(' ', $sslArgs);
}
From 4fdd5679c9ea417e1aecded3c2074e3812de369b Mon Sep 17 00:00:00 2001
From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com>
Date: Tue, 11 Feb 2025 20:18:42 +0100
Subject: [PATCH 84/90] fix(ui): enable SSL is not working correctly for KeyDB
---
app/Livewire/Project/Database/Keydb/General.php | 2 +-
.../views/livewire/project/database/keydb/general.blade.php | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/Livewire/Project/Database/Keydb/General.php b/app/Livewire/Project/Database/Keydb/General.php
index 58db162a8..fd7737343 100644
--- a/app/Livewire/Project/Database/Keydb/General.php
+++ b/app/Livewire/Project/Database/Keydb/General.php
@@ -57,7 +57,7 @@ class General extends Component
public $certificateValidUntil = null;
- #[Validate(['nullable', 'boolean'])]
+ #[Validate(['boolean'])]
public bool $enable_ssl = false;
public function getListeners()
diff --git a/resources/views/livewire/project/database/keydb/general.blade.php b/resources/views/livewire/project/database/keydb/general.blade.php
index 8939bd00d..58a41c289 100644
--- a/resources/views/livewire/project/database/keydb/general.blade.php
+++ b/resources/views/livewire/project/database/keydb/general.blade.php
@@ -80,7 +80,7 @@
@endif
-
+
From d74c578a4a7fc6be460de6141a66e9d85217e9d8 Mon Sep 17 00:00:00 2001
From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com>
Date: Tue, 11 Feb 2025 20:34:45 +0100
Subject: [PATCH 85/90] fix(ssl): add `--tls` arg to DrangflyDB
---
app/Actions/Database/StartDragonfly.php | 1 +
1 file changed, 1 insertion(+)
diff --git a/app/Actions/Database/StartDragonfly.php b/app/Actions/Database/StartDragonfly.php
index c9a2f173c..99bb5fa89 100644
--- a/app/Actions/Database/StartDragonfly.php
+++ b/app/Actions/Database/StartDragonfly.php
@@ -197,6 +197,7 @@ class StartDragonfly
if ($this->database->enable_ssl) {
$sslArgs = [
+ '--tls',
'--tls_cert_file /etc/dragonfly/certs/server.crt',
'--tls_key_file /etc/dragonfly/certs/server.key',
'--tls_ca_cert_file /etc/dragonfly/certs/coolify-ca.crt',
From f2888527534bdadeb3b3d16bc672c3569e6585a7 Mon Sep 17 00:00:00 2001
From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com>
Date: Tue, 11 Feb 2025 20:55:33 +0100
Subject: [PATCH 86/90] fix(notification): always send SSL notifications
---
app/Traits/HasNotificationSettings.php | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/Traits/HasNotificationSettings.php b/app/Traits/HasNotificationSettings.php
index ef858d0b6..236e4d97c 100644
--- a/app/Traits/HasNotificationSettings.php
+++ b/app/Traits/HasNotificationSettings.php
@@ -4,9 +4,9 @@ namespace App\Traits;
use App\Notifications\Channels\DiscordChannel;
use App\Notifications\Channels\EmailChannel;
+use App\Notifications\Channels\PushoverChannel;
use App\Notifications\Channels\SlackChannel;
use App\Notifications\Channels\TelegramChannel;
-use App\Notifications\Channels\PushoverChannel;
use Illuminate\Database\Eloquent\Model;
trait HasNotificationSettings
@@ -16,6 +16,7 @@ trait HasNotificationSettings
'server_force_disabled',
'general',
'test',
+ 'ssl_certificate_renewal',
];
/**
From 225f24e6507405c3bb39f0db835d37486e907b08 Mon Sep 17 00:00:00 2001
From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com>
Date: Wed, 19 Feb 2025 18:04:58 +0100
Subject: [PATCH 87/90] chore: improve code quality suggested by code rabbit
---
app/Actions/Database/StartDragonfly.php | 8 +--
app/Actions/Database/StartKeydb.php | 8 +--
app/Actions/Database/StartMariadb.php | 6 +--
app/Actions/Database/StartMongodb.php | 6 +--
app/Actions/Database/StartMysql.php | 6 +--
app/Actions/Database/StartPostgresql.php | 6 +--
app/Actions/Database/StartRedis.php | 6 +--
app/Actions/Server/InstallDocker.php | 2 +-
app/Jobs/RegenerateSslCertJob.php | 18 +++----
.../Project/Database/Dragonfly/General.php | 12 ++---
.../Project/Database/Keydb/General.php | 12 ++---
.../Project/Database/Mariadb/General.php | 12 ++---
.../Project/Database/Mongodb/General.php | 12 ++---
.../Project/Database/Mysql/General.php | 12 ++---
.../Project/Database/Postgresql/General.php | 12 ++---
.../Project/Database/Redis/General.php | 12 ++---
app/Livewire/Server/Advanced.php | 5 +-
app/Models/StandaloneClickhouse.php | 12 ++++-
app/Models/StandaloneDragonfly.php | 6 ++-
app/Models/StandaloneKeydb.php | 6 ++-
app/Models/StandaloneMariadb.php | 12 ++++-
app/Models/StandaloneMongodb.php | 9 ++--
app/Models/StandaloneMysql.php | 8 ++-
app/Models/StandalonePostgresql.php | 8 ++-
app/Models/StandaloneRedis.php | 10 ++--
...5223_encrypt_local_file_volumes_fields.php | 54 ++++++++++---------
database/seeders/CaSslCertSeeder.php | 2 +-
27 files changed, 138 insertions(+), 144 deletions(-)
diff --git a/app/Actions/Database/StartDragonfly.php b/app/Actions/Database/StartDragonfly.php
index 99bb5fa89..882ed3c2e 100644
--- a/app/Actions/Database/StartDragonfly.php
+++ b/app/Actions/Database/StartDragonfly.php
@@ -36,9 +36,7 @@ class StartDragonfly
if (! $this->database->enable_ssl) {
$this->commands[] = "rm -rf $this->configuration_dir/ssl";
- SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->delete();
+ $this->database->sslCertificates()->delete();
$this->database->fileStorages()
->where('resource_type', $this->database->getMorphClass())
->where('resource_id', $this->database->id)
@@ -59,9 +57,7 @@ class StartDragonfly
$server = $this->database->destination->server;
$caCert = SslCertificate::where('server_id', $server->id)->where('is_ca_certificate', true)->first();
- $this->ssl_certificate = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->first();
+ $this->ssl_certificate = $this->database->sslCertificates()->first();
if (! $this->ssl_certificate) {
$this->commands[] = "echo 'No SSL certificate found, generating new SSL certificate for this database.'";
diff --git a/app/Actions/Database/StartKeydb.php b/app/Actions/Database/StartKeydb.php
index 8ec076dd2..311b5094a 100644
--- a/app/Actions/Database/StartKeydb.php
+++ b/app/Actions/Database/StartKeydb.php
@@ -37,9 +37,7 @@ class StartKeydb
if (! $this->database->enable_ssl) {
$this->commands[] = "rm -rf $this->configuration_dir/ssl";
- SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->delete();
+ $this->database->sslCertificates()->delete();
$this->database->fileStorages()
->where('resource_type', $this->database->getMorphClass())
->where('resource_id', $this->database->id)
@@ -60,9 +58,7 @@ class StartKeydb
$server = $this->database->destination->server;
$caCert = SslCertificate::where('server_id', $server->id)->where('is_ca_certificate', true)->first();
- $this->ssl_certificate = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->first();
+ $this->ssl_certificate = $this->database->sslCertificates()->first();
if (! $this->ssl_certificate) {
$this->commands[] = "echo 'No SSL certificate found, generating new SSL certificate for this database.'";
diff --git a/app/Actions/Database/StartMariadb.php b/app/Actions/Database/StartMariadb.php
index 87185d064..14df9b017 100644
--- a/app/Actions/Database/StartMariadb.php
+++ b/app/Actions/Database/StartMariadb.php
@@ -37,9 +37,7 @@ class StartMariadb
if (! $this->database->enable_ssl) {
$this->commands[] = "rm -rf $this->configuration_dir/ssl";
- SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->delete();
+ $this->database->sslCertificates()->delete();
$this->database->fileStorages()
->where('resource_type', $this->database->getMorphClass())
@@ -61,7 +59,7 @@ class StartMariadb
$server = $this->database->destination->server;
$caCert = SslCertificate::where('server_id', $server->id)->where('is_ca_certificate', true)->first();
- $this->ssl_certificate = SslCertificate::where('resource_type', $this->database->getMorphClass())->where('resource_id', $this->database->id)->first();
+ $this->ssl_certificate = $this->database->sslCertificates()->first();
if (! $this->ssl_certificate) {
$this->commands[] = "echo 'No SSL certificate found, generating new SSL certificate for this database.'";
diff --git a/app/Actions/Database/StartMongodb.php b/app/Actions/Database/StartMongodb.php
index 250cb321d..3ea8287ac 100644
--- a/app/Actions/Database/StartMongodb.php
+++ b/app/Actions/Database/StartMongodb.php
@@ -42,9 +42,7 @@ class StartMongodb
if (! $this->database->enable_ssl) {
$this->commands[] = "rm -rf $this->configuration_dir/ssl";
- SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->delete();
+ $this->database->sslCertificates()->delete();
$this->database->fileStorages()
->where('resource_type', $this->database->getMorphClass())
@@ -65,7 +63,7 @@ class StartMongodb
$server = $this->database->destination->server;
$caCert = SslCertificate::where('server_id', $server->id)->where('is_ca_certificate', true)->first();
- $this->ssl_certificate = SslCertificate::where('resource_type', $this->database->getMorphClass())->where('resource_id', $this->database->id)->first();
+ $this->ssl_certificate = $this->database->sslCertificates()->first();
if (! $this->ssl_certificate) {
$this->commands[] = "echo 'No SSL certificate found, generating new SSL certificate for this database.'";
diff --git a/app/Actions/Database/StartMysql.php b/app/Actions/Database/StartMysql.php
index 2a9e37f9c..a2e08c316 100644
--- a/app/Actions/Database/StartMysql.php
+++ b/app/Actions/Database/StartMysql.php
@@ -37,9 +37,7 @@ class StartMysql
if (! $this->database->enable_ssl) {
$this->commands[] = "rm -rf $this->configuration_dir/ssl";
- SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->delete();
+ $this->database->sslCertificates()->delete();
$this->database->fileStorages()
->where('resource_type', $this->database->getMorphClass())
@@ -61,7 +59,7 @@ class StartMysql
$server = $this->database->destination->server;
$caCert = SslCertificate::where('server_id', $server->id)->where('is_ca_certificate', true)->first();
- $this->ssl_certificate = SslCertificate::where('resource_type', $this->database->getMorphClass())->where('resource_id', $this->database->id)->first();
+ $this->ssl_certificate = $this->database->sslCertificates()->first();
if (! $this->ssl_certificate) {
$this->commands[] = "echo 'No SSL certificate found, generating new SSL certificate for this database.'";
diff --git a/app/Actions/Database/StartPostgresql.php b/app/Actions/Database/StartPostgresql.php
index 8f4bcb0d9..97e565ec8 100644
--- a/app/Actions/Database/StartPostgresql.php
+++ b/app/Actions/Database/StartPostgresql.php
@@ -42,9 +42,7 @@ class StartPostgresql
if (! $this->database->enable_ssl) {
$this->commands[] = "rm -rf $this->configuration_dir/ssl";
- SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->delete();
+ $this->database->sslCertificates()->delete();
$this->database->fileStorages()
->where('resource_type', $this->database->getMorphClass())
@@ -66,7 +64,7 @@ class StartPostgresql
$server = $this->database->destination->server;
$caCert = SslCertificate::where('server_id', $server->id)->where('is_ca_certificate', true)->first();
- $this->ssl_certificate = SslCertificate::where('resource_type', $this->database->getMorphClass())->where('resource_id', $this->database->id)->first();
+ $this->ssl_certificate = $this->database->sslCertificates()->first();
if (! $this->ssl_certificate) {
$this->commands[] = "echo 'No SSL certificate found, generating new SSL certificate for this database.'";
diff --git a/app/Actions/Database/StartRedis.php b/app/Actions/Database/StartRedis.php
index edc7e0cce..9e7a2a084 100644
--- a/app/Actions/Database/StartRedis.php
+++ b/app/Actions/Database/StartRedis.php
@@ -37,9 +37,7 @@ class StartRedis
if (! $this->database->enable_ssl) {
$this->commands[] = "rm -rf $this->configuration_dir/ssl";
- SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->delete();
+ $this->database->sslCertificates()->delete();
$this->database->fileStorages()
->where('resource_type', $this->database->getMorphClass())
->where('resource_id', $this->database->id)
@@ -60,7 +58,7 @@ class StartRedis
$server = $this->database->destination->server;
$caCert = SslCertificate::where('server_id', $server->id)->where('is_ca_certificate', true)->first();
- $this->ssl_certificate = SslCertificate::where('resource_type', $this->database->getMorphClass())->where('resource_id', $this->database->id)->first();
+ $this->ssl_certificate = $this->database->sslCertificates()->first();
if (! $this->ssl_certificate) {
$this->commands[] = "echo 'No SSL certificate found, generating new SSL certificate for this database.'";
diff --git a/app/Actions/Server/InstallDocker.php b/app/Actions/Server/InstallDocker.php
index bbb3ea066..5410b1cbd 100644
--- a/app/Actions/Server/InstallDocker.php
+++ b/app/Actions/Server/InstallDocker.php
@@ -25,7 +25,7 @@ class InstallDocker
commonName: 'Coolify CA Certificate',
serverId: $server->id,
isCaCertificate: true,
- validityDays: 15 * 365
+ validityDays: 10 * 365
);
$caCertPath = config('constants.coolify.base_config_path').'/ssl/';
diff --git a/app/Jobs/RegenerateSslCertJob.php b/app/Jobs/RegenerateSslCertJob.php
index 3e4bf9070..0570227b6 100644
--- a/app/Jobs/RegenerateSslCertJob.php
+++ b/app/Jobs/RegenerateSslCertJob.php
@@ -17,6 +17,10 @@ class RegenerateSslCertJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
+ public $tries = 3;
+
+ public $backoff = 60;
+
public function __construct(
protected ?Team $team = null,
protected ?int $server_id = null,
@@ -37,17 +41,13 @@ class RegenerateSslCertJob implements ShouldQueue
$query->where('is_ca_certificate', false);
- $certificates = $query->get();
-
- if ($certificates->isEmpty()) {
- return;
- }
-
$regenerated = collect();
- foreach ($certificates as $certificate) {
+ $query->cursor()->each(function ($certificate) use ($regenerated) {
try {
- $caCert = SslCertificate::where('server_id', $certificate->server_id)->where('is_ca_certificate', true)->first();
+ $caCert = SslCertificate::where('server_id', $certificate->server_id)
+ ->where('is_ca_certificate', true)
+ ->first();
SSLHelper::generateSslCertificate(
commonName: $certificate->common_name,
@@ -64,7 +64,7 @@ class RegenerateSslCertJob implements ShouldQueue
} catch (\Exception $e) {
Log::error('Failed to regenerate SSL certificate: '.$e->getMessage());
}
- }
+ });
if ($regenerated->isNotEmpty()) {
$this->team?->notify(new SslExpirationNotification($regenerated));
diff --git a/app/Livewire/Project/Database/Dragonfly/General.php b/app/Livewire/Project/Database/Dragonfly/General.php
index bd04e4d38..51f8b5a66 100644
--- a/app/Livewire/Project/Database/Dragonfly/General.php
+++ b/app/Livewire/Project/Database/Dragonfly/General.php
@@ -8,6 +8,7 @@ use App\Helpers\SslHelper;
use App\Models\Server;
use App\Models\SslCertificate;
use App\Models\StandaloneDragonfly;
+use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\Auth;
use Livewire\Attributes\Validate;
@@ -52,7 +53,7 @@ class General extends Component
#[Validate(['nullable', 'boolean'])]
public bool $isLogDrainEnabled = false;
- public $certificateValidUntil = null;
+ public ?Carbon $certificateValidUntil = null;
#[Validate(['nullable', 'boolean'])]
public bool $enable_ssl = false;
@@ -72,9 +73,7 @@ class General extends Component
$this->syncData();
$this->server = data_get($this->database, 'destination.server');
- $existingCert = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->first();
+ $existingCert = $this->database->sslCertificates()->first();
if ($existingCert) {
$this->certificateValidUntil = $existingCert->valid_until;
@@ -205,10 +204,7 @@ class General extends Component
public function regenerateSslCertificate()
{
try {
- $existingCert = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->where('server_id', $this->server->id)
- ->first();
+ $existingCert = $this->database->sslCertificates()->first();
if (! $existingCert) {
$this->dispatch('error', 'No existing SSL certificate found for this database.');
diff --git a/app/Livewire/Project/Database/Keydb/General.php b/app/Livewire/Project/Database/Keydb/General.php
index fd7737343..213b0d2d3 100644
--- a/app/Livewire/Project/Database/Keydb/General.php
+++ b/app/Livewire/Project/Database/Keydb/General.php
@@ -8,6 +8,7 @@ use App\Helpers\SslHelper;
use App\Models\Server;
use App\Models\SslCertificate;
use App\Models\StandaloneKeydb;
+use Carbon\Carbon;
use Exception;
use Illuminate\Support\Facades\Auth;
use Livewire\Attributes\Validate;
@@ -55,7 +56,7 @@ class General extends Component
#[Validate(['nullable', 'boolean'])]
public bool $isLogDrainEnabled = false;
- public $certificateValidUntil = null;
+ public ?Carbon $certificateValidUntil = null;
#[Validate(['boolean'])]
public bool $enable_ssl = false;
@@ -75,9 +76,7 @@ class General extends Component
$this->syncData();
$this->server = data_get($this->database, 'destination.server');
- $existingCert = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->first();
+ $existingCert = $this->database->sslCertificates()->first();
if ($existingCert) {
$this->certificateValidUntil = $existingCert->valid_until;
@@ -210,10 +209,7 @@ class General extends Component
public function regenerateSslCertificate()
{
try {
- $existingCert = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->where('server_id', $this->server->id)
- ->first();
+ $existingCert = $this->database->sslCertificates()->first();
if (! $existingCert) {
$this->dispatch('error', 'No existing SSL certificate found for this database.');
diff --git a/app/Livewire/Project/Database/Mariadb/General.php b/app/Livewire/Project/Database/Mariadb/General.php
index a963e0ca3..b0c4f5d3e 100644
--- a/app/Livewire/Project/Database/Mariadb/General.php
+++ b/app/Livewire/Project/Database/Mariadb/General.php
@@ -8,6 +8,7 @@ use App\Helpers\SslHelper;
use App\Models\Server;
use App\Models\SslCertificate;
use App\Models\StandaloneMariadb;
+use Carbon\Carbon;
use Exception;
use Livewire\Component;
@@ -23,7 +24,7 @@ class General extends Component
public ?string $db_url_public = null;
- public $certificateValidUntil = null;
+ public ?Carbon $certificateValidUntil = null;
protected $rules = [
'database.name' => 'required',
@@ -64,9 +65,7 @@ class General extends Component
$this->db_url_public = $this->database->external_db_url;
$this->server = data_get($this->database, 'destination.server');
- $existingCert = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->first();
+ $existingCert = $this->database->sslCertificates()->first();
if ($existingCert) {
$this->certificateValidUntil = $existingCert->valid_until;
@@ -155,10 +154,7 @@ class General extends Component
public function regenerateSslCertificate()
{
try {
- $existingCert = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->where('server_id', $this->server->id)
- ->first();
+ $existingCert = $this->database->sslCertificates()->first();
if (! $existingCert) {
$this->dispatch('error', 'No existing SSL certificate found for this database.');
diff --git a/app/Livewire/Project/Database/Mongodb/General.php b/app/Livewire/Project/Database/Mongodb/General.php
index 526aae9ea..28be1c69d 100644
--- a/app/Livewire/Project/Database/Mongodb/General.php
+++ b/app/Livewire/Project/Database/Mongodb/General.php
@@ -8,6 +8,7 @@ use App\Helpers\SslHelper;
use App\Models\Server;
use App\Models\SslCertificate;
use App\Models\StandaloneMongodb;
+use Carbon\Carbon;
use Exception;
use Livewire\Component;
@@ -23,7 +24,7 @@ class General extends Component
public ?string $db_url_public = null;
- public $certificateValidUntil = null;
+ public ?Carbon $certificateValidUntil = null;
protected $rules = [
'database.name' => 'required',
@@ -64,9 +65,7 @@ class General extends Component
$this->db_url_public = $this->database->external_db_url;
$this->server = data_get($this->database, 'destination.server');
- $existingCert = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->first();
+ $existingCert = $this->database->sslCertificates()->first();
if ($existingCert) {
$this->certificateValidUntil = $existingCert->valid_until;
@@ -159,10 +158,7 @@ class General extends Component
public function regenerateSslCertificate()
{
try {
- $existingCert = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->where('server_id', $this->server->id)
- ->first();
+ $existingCert = $this->database->sslCertificates()->first();
if (! $existingCert) {
$this->dispatch('error', 'No existing SSL certificate found for this database.');
diff --git a/app/Livewire/Project/Database/Mysql/General.php b/app/Livewire/Project/Database/Mysql/General.php
index ad19db2a3..3e164d885 100644
--- a/app/Livewire/Project/Database/Mysql/General.php
+++ b/app/Livewire/Project/Database/Mysql/General.php
@@ -8,6 +8,7 @@ use App\Helpers\SslHelper;
use App\Models\Server;
use App\Models\SslCertificate;
use App\Models\StandaloneMysql;
+use Carbon\Carbon;
use Exception;
use Livewire\Component;
@@ -23,7 +24,7 @@ class General extends Component
public ?string $db_url_public = null;
- public $certificateValidUntil = null;
+ public ?Carbon $certificateValidUntil = null;
protected $rules = [
'database.name' => 'required',
@@ -66,9 +67,7 @@ class General extends Component
$this->db_url_public = $this->database->external_db_url;
$this->server = data_get($this->database, 'destination.server');
- $existingCert = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->first();
+ $existingCert = $this->database->sslCertificates()->first();
if ($existingCert) {
$this->certificateValidUntil = $existingCert->valid_until;
@@ -158,10 +157,7 @@ class General extends Component
public function regenerateSslCertificate()
{
try {
- $existingCert = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->where('server_id', $this->server->id)
- ->first();
+ $existingCert = $this->database->sslCertificates()->first();
if (! $existingCert) {
$this->dispatch('error', 'No existing SSL certificate found for this database.');
diff --git a/app/Livewire/Project/Database/Postgresql/General.php b/app/Livewire/Project/Database/Postgresql/General.php
index f5ea25865..881c74d53 100644
--- a/app/Livewire/Project/Database/Postgresql/General.php
+++ b/app/Livewire/Project/Database/Postgresql/General.php
@@ -8,6 +8,7 @@ use App\Helpers\SslHelper;
use App\Models\Server;
use App\Models\SslCertificate;
use App\Models\StandalonePostgresql;
+use Carbon\Carbon;
use Exception;
use Livewire\Component;
@@ -25,7 +26,7 @@ class General extends Component
public ?string $db_url_public = null;
- public $certificateValidUntil = null;
+ public ?Carbon $certificateValidUntil = null;
public function getListeners()
{
@@ -81,9 +82,7 @@ class General extends Component
$this->db_url_public = $this->database->external_db_url;
$this->server = data_get($this->database, 'destination.server');
- $existingCert = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->first();
+ $existingCert = $this->database->sslCertificates()->first();
if ($existingCert) {
$this->certificateValidUntil = $existingCert->valid_until;
@@ -122,10 +121,7 @@ class General extends Component
public function regenerateSslCertificate()
{
try {
- $existingCert = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->where('server_id', $this->server->id)
- ->first();
+ $existingCert = $this->database->sslCertificates()->first();
if (! $existingCert) {
$this->dispatch('error', 'No existing SSL certificate found for this database.');
diff --git a/app/Livewire/Project/Database/Redis/General.php b/app/Livewire/Project/Database/Redis/General.php
index ea896e294..a3916277d 100644
--- a/app/Livewire/Project/Database/Redis/General.php
+++ b/app/Livewire/Project/Database/Redis/General.php
@@ -8,6 +8,7 @@ use App\Helpers\SslHelper;
use App\Models\Server;
use App\Models\SslCertificate;
use App\Models\StandaloneRedis;
+use Carbon\Carbon;
use Exception;
use Livewire\Component;
@@ -32,7 +33,7 @@ class General extends Component
public ?string $db_url_public = null;
- public $certificateValidUntil = null;
+ public ?Carbon $certificateValidUntil = null;
protected $rules = [
'database.name' => 'required',
@@ -67,9 +68,7 @@ class General extends Component
{
$this->server = data_get($this->database, 'destination.server');
$this->refreshView();
- $existingCert = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->first();
+ $existingCert = $this->database->sslCertificates()->first();
if ($existingCert) {
$this->certificateValidUntil = $existingCert->valid_until;
@@ -163,10 +162,7 @@ class General extends Component
public function regenerateSslCertificate()
{
try {
- $existingCert = SslCertificate::where('resource_type', $this->database->getMorphClass())
- ->where('resource_id', $this->database->id)
- ->where('server_id', $this->server->id)
- ->first();
+ $existingCert = $this->database->sslCertificates()->first();
if (! $existingCert) {
$this->dispatch('error', 'No existing SSL certificate found for this database.');
diff --git a/app/Livewire/Server/Advanced.php b/app/Livewire/Server/Advanced.php
index 497ec697e..b2b8b1518 100644
--- a/app/Livewire/Server/Advanced.php
+++ b/app/Livewire/Server/Advanced.php
@@ -6,6 +6,7 @@ use App\Helpers\SslHelper;
use App\Jobs\RegenerateSslCertJob;
use App\Models\Server;
use App\Models\SslCertificate;
+use Carbon\Carbon;
use Livewire\Attributes\Validate;
use Livewire\Component;
@@ -19,7 +20,7 @@ class Advanced extends Component
public $certificateContent = '';
- public $certificateValidUntil = null;
+ public ?Carbon $certificateValidUntil = null;
public array $parameters = [];
@@ -99,7 +100,7 @@ class Advanced extends Component
commonName: 'Coolify CA Certificate',
serverId: $this->server->id,
isCaCertificate: true,
- validityDays: 15 * 365
+ validityDays: 10 * 365
);
$this->loadCaCertificate();
diff --git a/app/Models/StandaloneClickhouse.php b/app/Models/StandaloneClickhouse.php
index 2f86c2060..bc1f9b4b3 100644
--- a/app/Models/StandaloneClickhouse.php
+++ b/app/Models/StandaloneClickhouse.php
@@ -223,7 +223,12 @@ class StandaloneClickhouse extends BaseModel
protected function internalDbUrl(): Attribute
{
return new Attribute(
- get: fn () => "clickhouse://{$this->clickhouse_admin_user}:{$this->clickhouse_admin_password}@{$this->uuid}:9000/{$this->clickhouse_db}",
+ get: function () {
+ $encodedUser = rawurlencode($this->clickhouse_admin_user);
+ $encodedPass = rawurlencode($this->clickhouse_admin_password);
+
+ return "clickhouse://{$encodedUser}:{$encodedPass}@{$this->uuid}:9000/{$this->clickhouse_db}";
+ },
);
}
@@ -232,7 +237,10 @@ class StandaloneClickhouse extends BaseModel
return new Attribute(
get: function () {
if ($this->is_public && $this->public_port) {
- return "clickhouse://{$this->clickhouse_admin_user}:{$this->clickhouse_admin_password}@{$this->destination->server->getIp}:{$this->public_port}/{$this->clickhouse_db}";
+ $encodedUser = rawurlencode($this->clickhouse_admin_user);
+ $encodedPass = rawurlencode($this->clickhouse_admin_password);
+
+ return "clickhouse://{$encodedUser}:{$encodedPass}@{$this->destination->server->getIp}:{$this->public_port}/{$this->clickhouse_db}";
}
return null;
diff --git a/app/Models/StandaloneDragonfly.php b/app/Models/StandaloneDragonfly.php
index 3aaedfc52..a14c5e378 100644
--- a/app/Models/StandaloneDragonfly.php
+++ b/app/Models/StandaloneDragonfly.php
@@ -226,7 +226,8 @@ class StandaloneDragonfly extends BaseModel
get: function () {
$scheme = $this->enable_ssl ? 'rediss' : 'redis';
$port = $this->enable_ssl ? 6380 : 6379;
- $url = "{$scheme}://:{$this->dragonfly_password}@{$this->uuid}:{$port}/0";
+ $encodedPass = rawurlencode($this->dragonfly_password);
+ $url = "{$scheme}://:{$encodedPass}@{$this->uuid}:{$port}/0";
if ($this->enable_ssl && $this->ssl_mode === 'verify-ca') {
$url .= '?cacert=/etc/ssl/certs/coolify-ca.crt';
@@ -243,7 +244,8 @@ class StandaloneDragonfly extends BaseModel
get: function () {
if ($this->is_public && $this->public_port) {
$scheme = $this->enable_ssl ? 'rediss' : 'redis';
- $url = "{$scheme}://:{$this->dragonfly_password}@{$this->destination->server->getIp}:{$this->public_port}/0";
+ $encodedPass = rawurlencode($this->dragonfly_password);
+ $url = "{$scheme}://:{$encodedPass}@{$this->destination->server->getIp}:{$this->public_port}/0";
if ($this->enable_ssl && $this->ssl_mode === 'verify-ca') {
$url .= '?cacert=/etc/ssl/certs/coolify-ca.crt';
diff --git a/app/Models/StandaloneKeydb.php b/app/Models/StandaloneKeydb.php
index af95d58e5..2d3aea755 100644
--- a/app/Models/StandaloneKeydb.php
+++ b/app/Models/StandaloneKeydb.php
@@ -226,7 +226,8 @@ class StandaloneKeydb extends BaseModel
get: function () {
$scheme = $this->enable_ssl ? 'rediss' : 'redis';
$port = $this->enable_ssl ? 6380 : 6379;
- $url = "{$scheme}://:{$this->keydb_password}@{$this->uuid}:{$port}/0";
+ $encodedPass = rawurlencode($this->keydb_password);
+ $url = "{$scheme}://:{$encodedPass}@{$this->uuid}:{$port}/0";
if ($this->enable_ssl && $this->ssl_mode === 'verify-ca') {
$url .= '?cacert=/etc/ssl/certs/coolify-ca.crt';
@@ -243,7 +244,8 @@ class StandaloneKeydb extends BaseModel
get: function () {
if ($this->is_public && $this->public_port) {
$scheme = $this->enable_ssl ? 'rediss' : 'redis';
- $url = "{$scheme}://:{$this->keydb_password}@{$this->destination->server->getIp}:{$this->public_port}/0";
+ $encodedPass = rawurlencode($this->keydb_password);
+ $url = "{$scheme}://:{$encodedPass}@{$this->destination->server->getIp}:{$this->public_port}/0";
if ($this->enable_ssl && $this->ssl_mode === 'verify-ca') {
$url .= '?cacert=/etc/ssl/certs/coolify-ca.crt';
diff --git a/app/Models/StandaloneMariadb.php b/app/Models/StandaloneMariadb.php
index 523fde3c5..7549ace3e 100644
--- a/app/Models/StandaloneMariadb.php
+++ b/app/Models/StandaloneMariadb.php
@@ -218,7 +218,12 @@ class StandaloneMariadb extends BaseModel
protected function internalDbUrl(): Attribute
{
return new Attribute(
- get: fn () => "mysql://{$this->mariadb_user}:{$this->mariadb_password}@{$this->uuid}:3306/{$this->mariadb_database}",
+ get: function () {
+ $encodedUser = rawurlencode($this->mariadb_user);
+ $encodedPass = rawurlencode($this->mariadb_password);
+
+ return "mysql://{$encodedUser}:{$encodedPass}@{$this->uuid}:3306/{$this->mariadb_database}";
+ },
);
}
@@ -227,7 +232,10 @@ class StandaloneMariadb extends BaseModel
return new Attribute(
get: function () {
if ($this->is_public && $this->public_port) {
- return "mysql://{$this->mariadb_user}:{$this->mariadb_password}@{$this->destination->server->getIp}:{$this->public_port}/{$this->mariadb_database}";
+ $encodedUser = rawurlencode($this->mariadb_user);
+ $encodedPass = rawurlencode($this->mariadb_password);
+
+ return "mysql://{$encodedUser}:{$encodedPass}@{$this->destination->server->getIp}:{$this->public_port}/{$this->mariadb_database}";
}
return null;
diff --git a/app/Models/StandaloneMongodb.php b/app/Models/StandaloneMongodb.php
index 0367b8650..1b181e7d5 100644
--- a/app/Models/StandaloneMongodb.php
+++ b/app/Models/StandaloneMongodb.php
@@ -244,13 +244,14 @@ class StandaloneMongodb extends BaseModel
{
return new Attribute(
get: function () {
- $url = "mongodb://{$this->mongo_initdb_root_username}:{$this->mongo_initdb_root_password}@{$this->uuid}:27017/?directConnection=true";
+ $encodedUser = rawurlencode($this->mongo_initdb_root_username);
+ $encodedPass = rawurlencode($this->mongo_initdb_root_password);
+ $url = "mongodb://{$encodedUser}:{$encodedPass}@{$this->uuid}:27017/?directConnection=true";
if ($this->enable_ssl) {
$url .= '&tls=true';
if (in_array($this->ssl_mode, ['verify-full'])) {
$url .= '&tlsCAFile=/etc/ssl/certs/coolify-ca.crt';
}
-
}
return $url;
@@ -263,7 +264,9 @@ class StandaloneMongodb extends BaseModel
return new Attribute(
get: function () {
if ($this->is_public && $this->public_port) {
- $url = "mongodb://{$this->mongo_initdb_root_username}:{$this->mongo_initdb_root_password}@{$this->destination->server->getIp}:{$this->public_port}/?directConnection=true";
+ $encodedUser = rawurlencode($this->mongo_initdb_root_username);
+ $encodedPass = rawurlencode($this->mongo_initdb_root_password);
+ $url = "mongodb://{$encodedUser}:{$encodedPass}@{$this->destination->server->getIp}:{$this->public_port}/?directConnection=true";
if ($this->enable_ssl) {
$url .= '&tls=true';
if (in_array($this->ssl_mode, ['verify-full'])) {
diff --git a/app/Models/StandaloneMysql.php b/app/Models/StandaloneMysql.php
index cf45df578..dbb5b1ae6 100644
--- a/app/Models/StandaloneMysql.php
+++ b/app/Models/StandaloneMysql.php
@@ -225,7 +225,9 @@ class StandaloneMysql extends BaseModel
{
return new Attribute(
get: function () {
- $url = "mysql://{$this->mysql_user}:{$this->mysql_password}@{$this->uuid}:3306/{$this->mysql_database}";
+ $encodedUser = rawurlencode($this->mysql_user);
+ $encodedPass = rawurlencode($this->mysql_password);
+ $url = "mysql://{$encodedUser}:{$encodedPass}@{$this->uuid}:3306/{$this->mysql_database}";
if ($this->enable_ssl) {
$url .= "?ssl-mode={$this->ssl_mode}";
if (in_array($this->ssl_mode, ['VERIFY_CA', 'VERIFY_IDENTITY'])) {
@@ -243,7 +245,9 @@ class StandaloneMysql extends BaseModel
return new Attribute(
get: function () {
if ($this->is_public && $this->public_port) {
- $url = "mysql://{$this->mysql_user}:{$this->mysql_password}@{$this->destination->server->getIp}:{$this->public_port}/{$this->mysql_database}";
+ $encodedUser = rawurlencode($this->mysql_user);
+ $encodedPass = rawurlencode($this->mysql_password);
+ $url = "mysql://{$encodedUser}:{$encodedPass}@{$this->destination->server->getIp}:{$this->public_port}/{$this->mysql_database}";
if ($this->enable_ssl) {
$url .= "?ssl-mode={$this->ssl_mode}";
if (in_array($this->ssl_mode, ['VERIFY_CA', 'VERIFY_IDENTITY'])) {
diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php
index 51b9d2c31..a74d567a0 100644
--- a/app/Models/StandalonePostgresql.php
+++ b/app/Models/StandalonePostgresql.php
@@ -220,7 +220,9 @@ class StandalonePostgresql extends BaseModel
{
return new Attribute(
get: function () {
- $url = "postgres://{$this->postgres_user}:{$this->postgres_password}@{$this->uuid}:5432/{$this->postgres_db}";
+ $encodedUser = rawurlencode($this->postgres_user);
+ $encodedPass = rawurlencode($this->postgres_password);
+ $url = "postgres://{$encodedUser}:{$encodedPass}@{$this->uuid}:5432/{$this->postgres_db}";
if ($this->enable_ssl) {
$url .= "?sslmode={$this->ssl_mode}";
if (in_array($this->ssl_mode, ['verify-ca', 'verify-full'])) {
@@ -238,7 +240,9 @@ class StandalonePostgresql extends BaseModel
return new Attribute(
get: function () {
if ($this->is_public && $this->public_port) {
- $url = "postgres://{$this->postgres_user}:{$this->postgres_password}@{$this->destination->server->getIp}:{$this->public_port}/{$this->postgres_db}";
+ $encodedUser = rawurlencode($this->postgres_user);
+ $encodedPass = rawurlencode($this->postgres_password);
+ $url = "postgres://{$encodedUser}:{$encodedPass}@{$this->destination->server->getIp}:{$this->public_port}/{$this->postgres_db}";
if ($this->enable_ssl) {
$url .= "?sslmode={$this->ssl_mode}";
if (in_array($this->ssl_mode, ['verify-ca', 'verify-full'])) {
diff --git a/app/Models/StandaloneRedis.php b/app/Models/StandaloneRedis.php
index 2b565aa4f..b40d8bb9d 100644
--- a/app/Models/StandaloneRedis.php
+++ b/app/Models/StandaloneRedis.php
@@ -221,10 +221,11 @@ class StandaloneRedis extends BaseModel
return new Attribute(
get: function () {
$redis_version = $this->getRedisVersion();
- $username_part = version_compare($redis_version, '6.0', '>=') ? "{$this->redis_username}:" : '';
+ $username_part = version_compare($redis_version, '6.0', '>=') ? rawurlencode($this->redis_username).':' : '';
+ $encodedPass = rawurlencode($this->redis_password);
$scheme = $this->enable_ssl ? 'rediss' : 'redis';
$port = $this->enable_ssl ? 6380 : 6379;
- $url = "{$scheme}://{$username_part}{$this->redis_password}@{$this->uuid}:{$port}/0";
+ $url = "{$scheme}://{$username_part}{$encodedPass}@{$this->uuid}:{$port}/0";
if ($this->enable_ssl && $this->ssl_mode === 'verify-ca') {
$url .= '?cacert=/etc/ssl/certs/coolify-ca.crt';
@@ -241,9 +242,10 @@ class StandaloneRedis extends BaseModel
get: function () {
if ($this->is_public && $this->public_port) {
$redis_version = $this->getRedisVersion();
- $username_part = version_compare($redis_version, '6.0', '>=') ? "{$this->redis_username}:" : '';
+ $username_part = version_compare($redis_version, '6.0', '>=') ? rawurlencode($this->redis_username).':' : '';
+ $encodedPass = rawurlencode($this->redis_password);
$scheme = $this->enable_ssl ? 'rediss' : 'redis';
- $url = "{$scheme}://{$username_part}{$this->redis_password}@{$this->destination->server->getIp}:{$this->public_port}/0";
+ $url = "{$scheme}://{$username_part}{$encodedPass}@{$this->destination->server->getIp}:{$this->public_port}/0";
if ($this->enable_ssl && $this->ssl_mode === 'verify-ca') {
$url .= '?cacert=/etc/ssl/certs/coolify-ca.crt';
diff --git a/database/migrations/2025_01_30_125223_encrypt_local_file_volumes_fields.php b/database/migrations/2025_01_30_125223_encrypt_local_file_volumes_fields.php
index f29cdaa23..c6b4f8514 100644
--- a/database/migrations/2025_01_30_125223_encrypt_local_file_volumes_fields.php
+++ b/database/migrations/2025_01_30_125223_encrypt_local_file_volumes_fields.php
@@ -19,18 +19,21 @@ return new class extends Migration
});
if (DB::table('local_file_volumes')->exists()) {
- $volumes = DB::table('local_file_volumes')->get();
- foreach ($volumes as $volume) {
- try {
- DB::table('local_file_volumes')->where('id', $volume->id)->update([
- 'fs_path' => $volume->fs_path ? Crypt::encryptString($volume->fs_path) : null,
- 'mount_path' => $volume->mount_path ? Crypt::encryptString($volume->mount_path) : null,
- 'content' => $volume->content ? Crypt::encryptString($volume->content) : null,
- ]);
- } catch (\Exception $e) {
- Log::error('Error encrypting local file volume fields: '.$e->getMessage());
- }
- }
+ DB::table('local_file_volumes')
+ ->orderBy('id')
+ ->chunk(100, function ($volumes) {
+ foreach ($volumes as $volume) {
+ try {
+ DB::table('local_file_volumes')->where('id', $volume->id)->update([
+ 'fs_path' => $volume->fs_path ? Crypt::encryptString($volume->fs_path) : null,
+ 'mount_path' => $volume->mount_path ? Crypt::encryptString($volume->mount_path) : null,
+ 'content' => $volume->content ? Crypt::encryptString($volume->content) : null,
+ ]);
+ } catch (\Exception $e) {
+ Log::error('Error encrypting local file volume fields: '.$e->getMessage());
+ }
+ }
+ });
}
}
@@ -46,18 +49,21 @@ return new class extends Migration
});
if (DB::table('local_file_volumes')->exists()) {
- $volumes = DB::table('local_file_volumes')->get();
- foreach ($volumes as $volume) {
- try {
- DB::table('local_file_volumes')->where('id', $volume->id)->update([
- 'fs_path' => $volume->fs_path ? Crypt::decryptString($volume->fs_path) : null,
- 'mount_path' => $volume->mount_path ? Crypt::decryptString($volume->mount_path) : null,
- 'content' => $volume->content ? Crypt::decryptString($volume->content) : null,
- ]);
- } catch (\Exception $e) {
- Log::error('Error decrypting local file volume fields: '.$e->getMessage());
- }
- }
+ DB::table('local_file_volumes')
+ ->orderBy('id')
+ ->chunk(100, function ($volumes) {
+ foreach ($volumes as $volume) {
+ try {
+ DB::table('local_file_volumes')->where('id', $volume->id)->update([
+ 'fs_path' => $volume->fs_path ? Crypt::decryptString($volume->fs_path) : null,
+ 'mount_path' => $volume->mount_path ? Crypt::decryptString($volume->mount_path) : null,
+ 'content' => $volume->content ? Crypt::decryptString($volume->content) : null,
+ ]);
+ } catch (\Exception $e) {
+ Log::error('Error decrypting local file volume fields: '.$e->getMessage());
+ }
+ }
+ });
}
}
};
diff --git a/database/seeders/CaSslCertSeeder.php b/database/seeders/CaSslCertSeeder.php
index b869ff96a..09f6cc984 100644
--- a/database/seeders/CaSslCertSeeder.php
+++ b/database/seeders/CaSslCertSeeder.php
@@ -20,7 +20,7 @@ class CaSslCertSeeder extends Seeder
commonName: 'Coolify CA Certificate',
serverId: $server->id,
isCaCertificate: true,
- validityDays: 15 * 365
+ validityDays: 10 * 365
);
} else {
$caCert = $existingCaCert;
From 8ebbe396f4f0fb0dec52e3f5ed135a76207967a7 Mon Sep 17 00:00:00 2001
From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com>
Date: Mon, 17 Mar 2025 13:58:31 +0100
Subject: [PATCH 88/90] fix(database): change default value of enable_ssl to
false for multiple tables
---
.../2025_01_27_102616_add_ssl_fields_to_database_tables.php | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/database/migrations/2025_01_27_102616_add_ssl_fields_to_database_tables.php b/database/migrations/2025_01_27_102616_add_ssl_fields_to_database_tables.php
index 361e2fd32..14162133a 100644
--- a/database/migrations/2025_01_27_102616_add_ssl_fields_to_database_tables.php
+++ b/database/migrations/2025_01_27_102616_add_ssl_fields_to_database_tables.php
@@ -12,15 +12,15 @@ return new class extends Migration
public function up()
{
Schema::table('standalone_postgresqls', function (Blueprint $table) {
- $table->boolean('enable_ssl')->default(true);
+ $table->boolean('enable_ssl')->default(false);
$table->enum('ssl_mode', ['allow', 'prefer', 'require', 'verify-ca', 'verify-full'])->default('require');
});
Schema::table('standalone_mysqls', function (Blueprint $table) {
- $table->boolean('enable_ssl')->default(true);
+ $table->boolean('enable_ssl')->default(false);
$table->enum('ssl_mode', ['PREFERRED', 'REQUIRED', 'VERIFY_CA', 'VERIFY_IDENTITY'])->default('REQUIRED');
});
Schema::table('standalone_mariadbs', function (Blueprint $table) {
- $table->boolean('enable_ssl')->default(true);
+ $table->boolean('enable_ssl')->default(false);
});
Schema::table('standalone_redis', function (Blueprint $table) {
$table->boolean('enable_ssl')->default(false);
From 54db7523d5798223c2859e17cf99af06ec4c2bea Mon Sep 17 00:00:00 2001
From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com>
Date: Mon, 17 Mar 2025 14:27:07 +0100
Subject: [PATCH 89/90] refactor(app): remove unused MagicBar component and
related code
---
resources/js/app.js | 7 -
resources/js/components/MagicBar.vue | 682 ---------------------------
2 files changed, 689 deletions(-)
delete mode 100644 resources/js/components/MagicBar.vue
diff --git a/resources/js/app.js b/resources/js/app.js
index 613b80069..4dcae5f8e 100644
--- a/resources/js/app.js
+++ b/resources/js/app.js
@@ -1,10 +1,3 @@
-// import { createApp } from "vue";
-// import MagicBar from "./components/MagicBar.vue";
-
-// const app = createApp({});
-// app.component("magic-bar", MagicBar);
-// app.mount("#vue");
-
import { initializeTerminalComponent } from './terminal.js';
['livewire:navigated', 'alpine:init'].forEach((event) => {
diff --git a/resources/js/components/MagicBar.vue b/resources/js/components/MagicBar.vue
deleted file mode 100644
index 22af9dff4..000000000
--- a/resources/js/components/MagicBar.vue
+++ /dev/null
@@ -1,682 +0,0 @@
-
-
-
-
-
-
From 950acffe0b3715bb72997afb9e390eea5e1bd925 Mon Sep 17 00:00:00 2001
From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com>
Date: Mon, 17 Mar 2025 15:15:40 +0100
Subject: [PATCH 90/90] refactor(database): streamline SSL configuration
handling across database types
---
.../Project/Database/Mariadb/General.php | 1 -
.../Project/Database/Mongodb/General.php | 7 ++-
.../Project/Database/Mysql/General.php | 7 ++-
.../Project/Database/Postgresql/General.php | 7 ++-
.../Project/Database/Redis/General.php | 1 -
app/View/Components/Forms/Select.php | 2 +-
.../components/forms/copy-button.blade.php | 8 ++-
.../views/components/server/sidebar.blade.php | 8 ++-
.../database/dragonfly/general.blade.php | 37 +++++------
.../database/mongodb/general.blade.php | 59 +++++++++---------
.../project/database/mysql/general.blade.php | 58 +++++++++--------
.../database/postgresql/general.blade.php | 62 ++++++++++---------
12 files changed, 138 insertions(+), 119 deletions(-)
diff --git a/app/Livewire/Project/Database/Mariadb/General.php b/app/Livewire/Project/Database/Mariadb/General.php
index b0c4f5d3e..06dffdc22 100644
--- a/app/Livewire/Project/Database/Mariadb/General.php
+++ b/app/Livewire/Project/Database/Mariadb/General.php
@@ -143,7 +143,6 @@ class General extends Component
public function instantSaveSSL()
{
try {
- $this->database->enable_ssl = $this->database->enable_ssl;
$this->database->save();
$this->dispatch('success', 'SSL configuration updated.');
} catch (Exception $e) {
diff --git a/app/Livewire/Project/Database/Mongodb/General.php b/app/Livewire/Project/Database/Mongodb/General.php
index 28be1c69d..282547283 100644
--- a/app/Livewire/Project/Database/Mongodb/General.php
+++ b/app/Livewire/Project/Database/Mongodb/General.php
@@ -143,11 +143,14 @@ class General extends Component
}
}
+ public function updatedDatabaseSslMode()
+ {
+ $this->instantSaveSSL();
+ }
+
public function instantSaveSSL()
{
try {
- $this->database->enable_ssl = $this->database->enable_ssl;
- $this->database->ssl_mode = $this->database->ssl_mode;
$this->database->save();
$this->dispatch('success', 'SSL configuration updated.');
} catch (Exception $e) {
diff --git a/app/Livewire/Project/Database/Mysql/General.php b/app/Livewire/Project/Database/Mysql/General.php
index 3e164d885..c9424b506 100644
--- a/app/Livewire/Project/Database/Mysql/General.php
+++ b/app/Livewire/Project/Database/Mysql/General.php
@@ -142,11 +142,14 @@ class General extends Component
}
}
+ public function updatedDatabaseSslMode()
+ {
+ $this->instantSaveSSL();
+ }
+
public function instantSaveSSL()
{
try {
- $this->database->enable_ssl = $this->database->enable_ssl;
- $this->database->ssl_mode = $this->database->ssl_mode;
$this->database->save();
$this->dispatch('success', 'SSL configuration updated.');
} catch (Exception $e) {
diff --git a/app/Livewire/Project/Database/Postgresql/General.php b/app/Livewire/Project/Database/Postgresql/General.php
index 881c74d53..3057f5316 100644
--- a/app/Livewire/Project/Database/Postgresql/General.php
+++ b/app/Livewire/Project/Database/Postgresql/General.php
@@ -106,11 +106,14 @@ class General extends Component
}
}
+ public function updatedDatabaseSslMode()
+ {
+ $this->instantSaveSSL();
+ }
+
public function instantSaveSSL()
{
try {
- $this->database->enable_ssl = $this->database->enable_ssl;
- $this->database->ssl_mode = $this->database->ssl_mode;
$this->database->save();
$this->dispatch('success', 'SSL configuration updated.');
} catch (Exception $e) {
diff --git a/app/Livewire/Project/Database/Redis/General.php b/app/Livewire/Project/Database/Redis/General.php
index a3916277d..16519e287 100644
--- a/app/Livewire/Project/Database/Redis/General.php
+++ b/app/Livewire/Project/Database/Redis/General.php
@@ -151,7 +151,6 @@ class General extends Component
public function instantSaveSSL()
{
try {
- $this->database->enable_ssl = $this->database->enable_ssl;
$this->database->save();
$this->dispatch('success', 'SSL configuration updated.');
} catch (Exception $e) {
diff --git a/app/View/Components/Forms/Select.php b/app/View/Components/Forms/Select.php
index 86ae866c8..b75cedaae 100644
--- a/app/View/Components/Forms/Select.php
+++ b/app/View/Components/Forms/Select.php
@@ -18,7 +18,7 @@ class Select extends Component
public ?string $label = null,
public ?string $helper = null,
public bool $required = false,
- public string $defaultClass = 'select'
+ public string $defaultClass = 'select w-full'
) {
//
}
diff --git a/resources/views/components/forms/copy-button.blade.php b/resources/views/components/forms/copy-button.blade.php
index 2e5f64c1a..5ed41fe1a 100644
--- a/resources/views/components/forms/copy-button.blade.php
+++ b/resources/views/components/forms/copy-button.blade.php
@@ -2,9 +2,13 @@
-
-
- @if($database->enable_ssl)
-
-
-
-
-
-
+
+ @if ($database->enable_ssl)
+
+
+
+
+
+
+
+
@endif
diff --git a/resources/views/livewire/project/database/postgresql/general.blade.php b/resources/views/livewire/project/database/postgresql/general.blade.php
index e396b59c4..b90836ce8 100644
--- a/resources/views/livewire/project/database/postgresql/general.blade.php
+++ b/resources/views/livewire/project/database/postgresql/general.blade.php
@@ -77,42 +77,45 @@
SSL Configuration
- @if($database->enable_ssl && $certificateValidUntil)
-
+ @if ($database->enable_ssl && $certificateValidUntil)
+
@endif
- @if($database->enable_ssl && $certificateValidUntil)
-
Valid until:
- @if(now()->gt($certificateValidUntil))
- {{ $certificateValidUntil->format('d.m.Y H:i:s') }} - Expired
- @elseif(now()->addDays(30)->gt($certificateValidUntil))
- {{ $certificateValidUntil->format('d.m.Y H:i:s') }} - Expiring soon
- @else
- {{ $certificateValidUntil->format('d.m.Y H:i:s') }}
- @endif
+ @if ($database->enable_ssl && $certificateValidUntil)
+ Valid until:
+ @if (now()->gt($certificateValidUntil))
+ {{ $certificateValidUntil->format('d.m.Y H:i:s') }} - Expired
+ @elseif(now()->addDays(30)->gt($certificateValidUntil))
+ {{ $certificateValidUntil->format('d.m.Y H:i:s') }} - Expiring
+ soon
+ @else
+ {{ $certificateValidUntil->format('d.m.Y H:i:s') }}
+ @endif
@endif