From 6d47d24169d28fae525dfb55895ab20cfb591039 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Wed, 17 Dec 2025 16:25:41 +0100 Subject: [PATCH 1/2] Fix standalone database "restarting" status flickering and add restart tracking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix status flickering: Track databases in active/transient states (restarting, starting, created, paused) not just running - Add isActiveOrTransient() helper to distinguish between active states and terminal states (exited, dead) - Add safeguard: Protect updateNotFoundDatabaseStatus() from marking as exited when containers collection is empty - Add restart_count tracking: New migration adds restart_count, last_restart_at, last_restart_type to all standalone database tables - Update 8 database models with $casts for new restart tracking fields - Update GetContainersStatus to extract RestartCount from Docker and update database models - Reset restart tracking when database exits completely 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Haiku 4.5 --- app/Actions/Docker/GetContainersStatus.php | 35 +++++++++- app/Jobs/PushServerUpdateJob.php | 54 +++++++++++---- app/Models/StandaloneClickhouse.php | 4 ++ app/Models/StandaloneDragonfly.php | 2 + app/Models/StandaloneKeydb.php | 2 + app/Models/StandaloneMariadb.php | 2 + app/Models/StandaloneMongodb.php | 5 ++ app/Models/StandaloneMysql.php | 2 + app/Models/StandalonePostgresql.php | 2 + app/Models/StandaloneRedis.php | 5 ++ ...start_tracking_to_standalone_databases.php | 66 +++++++++++++++++++ templates/service-templates-latest.json | 16 +++++ templates/service-templates.json | 16 +++++ 13 files changed, 194 insertions(+), 17 deletions(-) create mode 100644 database/migrations/2025_12_17_000002_add_restart_tracking_to_standalone_databases.php diff --git a/app/Actions/Docker/GetContainersStatus.php b/app/Actions/Docker/GetContainersStatus.php index a1476e120..df0d8cf14 100644 --- a/app/Actions/Docker/GetContainersStatus.php +++ b/app/Actions/Docker/GetContainersStatus.php @@ -199,10 +199,33 @@ public function handle(Server $server, ?Collection $containers = null, ?Collecti $isPublic = data_get($database, 'is_public'); $foundDatabases[] = $database->id; $statusFromDb = $database->status; + + // Track restart count for databases (single-container) + $restartCount = data_get($container, 'RestartCount', 0); + $previousRestartCount = $database->restart_count ?? 0; + if ($statusFromDb !== $containerStatus) { - $database->update(['status' => $containerStatus]); + $updateData = ['status' => $containerStatus]; + + // Update restart tracking if restart count increased + if ($restartCount > $previousRestartCount) { + $updateData['restart_count'] = $restartCount; + $updateData['last_restart_at'] = now(); + $updateData['last_restart_type'] = 'crash'; + } + + $database->update($updateData); } else { - $database->update(['last_online_at' => now()]); + $updateData = ['last_online_at' => now()]; + + // Update restart tracking even if status unchanged + if ($restartCount > $previousRestartCount) { + $updateData['restart_count'] = $restartCount; + $updateData['last_restart_at'] = now(); + $updateData['last_restart_type'] = 'crash'; + } + + $database->update($updateData); } if ($isPublic) { @@ -365,7 +388,13 @@ public function handle(Server $server, ?Collection $containers = null, ?Collecti if (str($database->status)->startsWith('exited')) { continue; } - $database->update(['status' => 'exited']); + // Reset restart tracking when database exits completely + $database->update([ + 'status' => 'exited', + 'restart_count' => 0, + 'last_restart_at' => null, + 'last_restart_type' => null, + ]); $name = data_get($database, 'name'); $fqdn = data_get($database, 'fqdn'); diff --git a/app/Jobs/PushServerUpdateJob.php b/app/Jobs/PushServerUpdateJob.php index 611e06b0b..e5a6e0c99 100644 --- a/app/Jobs/PushServerUpdateJob.php +++ b/app/Jobs/PushServerUpdateJob.php @@ -237,8 +237,9 @@ public function handle() $this->foundProxy = true; } elseif ($type === 'service' && $this->isRunning($containerStatus)) { } else { - if ($this->allDatabaseUuids->contains($uuid) && $this->isRunning($containerStatus)) { + if ($this->allDatabaseUuids->contains($uuid) && $this->isActiveOrTransient($containerStatus)) { $this->foundDatabaseUuids->push($uuid); + // TCP proxy should only be started/managed when database is actually running if ($this->allTcpProxyUuids->contains($uuid) && $this->isRunning($containerStatus)) { $this->updateDatabaseStatus($uuid, $containerStatus, tcpProxy: true); } else { @@ -503,20 +504,28 @@ private function updateDatabaseStatus(string $databaseUuid, string $containerSta private function updateNotFoundDatabaseStatus() { $notFoundDatabaseUuids = $this->allDatabaseUuids->diff($this->foundDatabaseUuids); - if ($notFoundDatabaseUuids->isNotEmpty()) { - $notFoundDatabaseUuids->each(function ($databaseUuid) { - $database = $this->databases->where('uuid', $databaseUuid)->first(); - if ($database) { - if ($database->status !== 'exited') { - $database->status = 'exited'; - $database->save(); - } - if ($database->is_public) { - StopDatabaseProxy::dispatch($database); - } - } - }); + if ($notFoundDatabaseUuids->isEmpty()) { + return; } + + // Only protection: Verify we received any container data at all + // If containers collection is completely empty, Sentinel might have failed + if ($this->containers->isEmpty()) { + return; + } + + $notFoundDatabaseUuids->each(function ($databaseUuid) { + $database = $this->databases->where('uuid', $databaseUuid)->first(); + if ($database) { + if (! str($database->status)->startsWith('exited')) { + $database->status = 'exited'; + $database->save(); + } + if ($database->is_public) { + StopDatabaseProxy::dispatch($database); + } + } + }); } private function updateServiceSubStatus(string $serviceId, string $subType, string $subId, string $containerStatus) @@ -576,6 +585,23 @@ private function isRunning(string $containerStatus) return str($containerStatus)->contains('running'); } + /** + * Check if container is in an active or transient state. + * Active states: running + * Transient states: restarting, starting, created, paused + * + * These states indicate the container exists and should be tracked. + * Terminal states (exited, dead, removing) should NOT be tracked. + */ + private function isActiveOrTransient(string $containerStatus): bool + { + return str($containerStatus)->contains('running') || + str($containerStatus)->contains('restarting') || + str($containerStatus)->contains('starting') || + str($containerStatus)->contains('created') || + str($containerStatus)->contains('paused'); + } + private function checkLogDrainContainer() { if ($this->server->isLogDrainEnabled() && $this->foundLogDrainContainer === false) { diff --git a/app/Models/StandaloneClickhouse.php b/app/Models/StandaloneClickhouse.php index 7acef5aae..63485c612 100644 --- a/app/Models/StandaloneClickhouse.php +++ b/app/Models/StandaloneClickhouse.php @@ -18,6 +18,8 @@ class StandaloneClickhouse extends BaseModel protected $casts = [ 'clickhouse_password' => 'encrypted', + 'restart_count' => 'integer', + 'last_restart_at' => 'datetime', ]; protected static function booted() @@ -247,6 +249,7 @@ protected function internalDbUrl(): Attribute $encodedUser = rawurlencode($this->clickhouse_admin_user); $encodedPass = rawurlencode($this->clickhouse_admin_password); $database = $this->clickhouse_db ?? 'default'; + return "clickhouse://{$encodedUser}:{$encodedPass}@{$this->uuid}:9000/{$database}"; }, ); @@ -264,6 +267,7 @@ protected function externalDbUrl(): Attribute $encodedUser = rawurlencode($this->clickhouse_admin_user); $encodedPass = rawurlencode($this->clickhouse_admin_password); $database = $this->clickhouse_db ?? 'default'; + return "clickhouse://{$encodedUser}:{$encodedPass}@{$serverIp}:{$this->public_port}/{$database}"; } diff --git a/app/Models/StandaloneDragonfly.php b/app/Models/StandaloneDragonfly.php index 47170056f..09f16752d 100644 --- a/app/Models/StandaloneDragonfly.php +++ b/app/Models/StandaloneDragonfly.php @@ -18,6 +18,8 @@ class StandaloneDragonfly extends BaseModel protected $casts = [ 'dragonfly_password' => 'encrypted', + 'restart_count' => 'integer', + 'last_restart_at' => 'datetime', ]; protected static function booted() diff --git a/app/Models/StandaloneKeydb.php b/app/Models/StandaloneKeydb.php index 266110d0a..c420bde15 100644 --- a/app/Models/StandaloneKeydb.php +++ b/app/Models/StandaloneKeydb.php @@ -18,6 +18,8 @@ class StandaloneKeydb extends BaseModel protected $casts = [ 'keydb_password' => 'encrypted', + 'restart_count' => 'integer', + 'last_restart_at' => 'datetime', ]; protected static function booted() diff --git a/app/Models/StandaloneMariadb.php b/app/Models/StandaloneMariadb.php index aa7f2d31a..52ae136bb 100644 --- a/app/Models/StandaloneMariadb.php +++ b/app/Models/StandaloneMariadb.php @@ -19,6 +19,8 @@ class StandaloneMariadb extends BaseModel protected $casts = [ 'mariadb_password' => 'encrypted', + 'restart_count' => 'integer', + 'last_restart_at' => 'datetime', ]; protected static function booted() diff --git a/app/Models/StandaloneMongodb.php b/app/Models/StandaloneMongodb.php index 9046ab013..f17c72dbc 100644 --- a/app/Models/StandaloneMongodb.php +++ b/app/Models/StandaloneMongodb.php @@ -16,6 +16,11 @@ class StandaloneMongodb extends BaseModel protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status']; + protected $casts = [ + 'restart_count' => 'integer', + 'last_restart_at' => 'datetime', + ]; + protected static function booted() { static::created(function ($database) { diff --git a/app/Models/StandaloneMysql.php b/app/Models/StandaloneMysql.php index 719387b36..f4e192047 100644 --- a/app/Models/StandaloneMysql.php +++ b/app/Models/StandaloneMysql.php @@ -19,6 +19,8 @@ class StandaloneMysql extends BaseModel protected $casts = [ 'mysql_password' => 'encrypted', 'mysql_root_password' => 'encrypted', + 'restart_count' => 'integer', + 'last_restart_at' => 'datetime', ]; protected static function booted() diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php index 03080fd3d..9e6c968aa 100644 --- a/app/Models/StandalonePostgresql.php +++ b/app/Models/StandalonePostgresql.php @@ -19,6 +19,8 @@ class StandalonePostgresql extends BaseModel protected $casts = [ 'init_scripts' => 'array', 'postgres_password' => 'encrypted', + 'restart_count' => 'integer', + 'last_restart_at' => 'datetime', ]; protected static function booted() diff --git a/app/Models/StandaloneRedis.php b/app/Models/StandaloneRedis.php index 6aca8af9a..05f8ae6c6 100644 --- a/app/Models/StandaloneRedis.php +++ b/app/Models/StandaloneRedis.php @@ -16,6 +16,11 @@ class StandaloneRedis extends BaseModel protected $appends = ['internal_db_url', 'external_db_url', 'database_type', 'server_status']; + protected $casts = [ + 'restart_count' => 'integer', + 'last_restart_at' => 'datetime', + ]; + protected static function booted() { static::created(function ($database) { diff --git a/database/migrations/2025_12_17_000002_add_restart_tracking_to_standalone_databases.php b/database/migrations/2025_12_17_000002_add_restart_tracking_to_standalone_databases.php new file mode 100644 index 000000000..2798affd4 --- /dev/null +++ b/database/migrations/2025_12_17_000002_add_restart_tracking_to_standalone_databases.php @@ -0,0 +1,66 @@ +tables as $table) { + if (! Schema::hasColumn($table, 'restart_count')) { + Schema::table($table, function (Blueprint $blueprint) { + $blueprint->integer('restart_count')->default(0)->after('status'); + }); + } + + if (! Schema::hasColumn($table, 'last_restart_at')) { + Schema::table($table, function (Blueprint $blueprint) { + $blueprint->timestamp('last_restart_at')->nullable()->after('restart_count'); + }); + } + + if (! Schema::hasColumn($table, 'last_restart_type')) { + Schema::table($table, function (Blueprint $blueprint) { + $blueprint->string('last_restart_type', 10)->nullable()->after('last_restart_at'); + }); + } + } + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + $columns = ['restart_count', 'last_restart_at', 'last_restart_type']; + + foreach ($this->tables as $table) { + foreach ($columns as $column) { + if (Schema::hasColumn($table, $column)) { + Schema::table($table, function (Blueprint $blueprint) use ($column) { + $blueprint->dropColumn($column); + }); + } + } + } + } +}; diff --git a/templates/service-templates-latest.json b/templates/service-templates-latest.json index c3addcc82..9a7af8787 100644 --- a/templates/service-templates-latest.json +++ b/templates/service-templates-latest.json @@ -3953,6 +3953,22 @@ "logo": "svgs/default.webp", "minversion": "0.0.0" }, + "soju": { + "documentation": "https://soju.im/?utm_source=coolify.io", + "slogan": "A user-friendly IRC bouncer with a modern web interface", + "compose": "c2VydmljZXM6CiAgc29qdToKICAgIGltYWdlOiAnY29kZWJlcmcub3JnL2VtZXJzaW9uL3NvanU6bGF0ZXN0JwogICAgdm9sdW1lczoKICAgICAgLSAnc29qdS1kYjovZGInCiAgICAgIC0gJ3NvanUtdXBsb2FkczovdXBsb2FkcycKICAgICAgLSAnc29qdS1ydW46L3J1bi9zb2p1JwogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi9zb2p1L2NvbmZpZwogICAgICAgIHRhcmdldDogL3NvanUtY29uZmlnCiAgICAgICAgY29udGVudDogImRiIHNxbGl0ZTMgL2RiL21haW4uZGJcbm1lc3NhZ2Utc3RvcmUgZGJcbmZpbGUtdXBsb2FkIGZzIC91cGxvYWRzL1xubGlzdGVuIGlyYytpbnNlY3VyZTovLzAuMC4wLjA6NjY2N1xubGlzdGVuIHdzK2luc2VjdXJlOi8vMC4wLjAuMDo4MFxubGlzdGVuIHVuaXgrYWRtaW46Ly8vcnVuL3NvanUvYWRtaW5cbiIKICAgIG5ldHdvcmtzOgogICAgICBkZWZhdWx0OgogICAgICAgIGFsaWFzZXM6CiAgICAgICAgICAtIGdhbWphLWJhY2tlbmQKICBnYW1qYToKICAgIGltYWdlOiAnY29kZWJlcmcub3JnL2VtZXJzaW9uL2dhbWphOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9HQU1KQV84MAogICAgZGVwZW5kc19vbjoKICAgICAgLSBzb2p1CnZvbHVtZXM6CiAgc29qdS1kYjogbnVsbAogIHNvanUtdXBsb2FkczogbnVsbAogIHNvanUtcnVuOiBudWxsCg==", + "tags": [ + "irc", + "bouncer", + "chat", + "messaging", + "relay" + ], + "category": "communication", + "logo": "svgs/soju.svg", + "minversion": "0.0.0", + "port": "80" + }, "soketi": { "documentation": "https://docs.soketi.app?utm_source=coolify.io", "slogan": "Soketi is your simple, fast, and resilient open-source WebSockets server.", diff --git a/templates/service-templates.json b/templates/service-templates.json index 5da51e9f0..7791c1750 100644 --- a/templates/service-templates.json +++ b/templates/service-templates.json @@ -3953,6 +3953,22 @@ "logo": "svgs/default.webp", "minversion": "0.0.0" }, + "soju": { + "documentation": "https://soju.im/?utm_source=coolify.io", + "slogan": "A user-friendly IRC bouncer with a modern web interface", + "compose": "c2VydmljZXM6CiAgc29qdToKICAgIGltYWdlOiAnY29kZWJlcmcub3JnL2VtZXJzaW9uL3NvanU6bGF0ZXN0JwogICAgdm9sdW1lczoKICAgICAgLSAnc29qdS1kYjovZGInCiAgICAgIC0gJ3NvanUtdXBsb2FkczovdXBsb2FkcycKICAgICAgLSAnc29qdS1ydW46L3J1bi9zb2p1JwogICAgICAtCiAgICAgICAgdHlwZTogYmluZAogICAgICAgIHNvdXJjZTogLi9zb2p1L2NvbmZpZwogICAgICAgIHRhcmdldDogL3NvanUtY29uZmlnCiAgICAgICAgY29udGVudDogImRiIHNxbGl0ZTMgL2RiL21haW4uZGJcbm1lc3NhZ2Utc3RvcmUgZGJcbmZpbGUtdXBsb2FkIGZzIC91cGxvYWRzL1xubGlzdGVuIGlyYytpbnNlY3VyZTovLzAuMC4wLjA6NjY2N1xubGlzdGVuIHdzK2luc2VjdXJlOi8vMC4wLjAuMDo4MFxubGlzdGVuIHVuaXgrYWRtaW46Ly8vcnVuL3NvanUvYWRtaW5cbiIKICAgIG5ldHdvcmtzOgogICAgICBkZWZhdWx0OgogICAgICAgIGFsaWFzZXM6CiAgICAgICAgICAtIGdhbWphLWJhY2tlbmQKICBnYW1qYToKICAgIGltYWdlOiAnY29kZWJlcmcub3JnL2VtZXJzaW9uL2dhbWphOmxhdGVzdCcKICAgIGVudmlyb25tZW50OgogICAgICAtIFNFUlZJQ0VfRlFETl9HQU1KQV84MAogICAgZGVwZW5kc19vbjoKICAgICAgLSBzb2p1CnZvbHVtZXM6CiAgc29qdS1kYjogbnVsbAogIHNvanUtdXBsb2FkczogbnVsbAogIHNvanUtcnVuOiBudWxsCg==", + "tags": [ + "irc", + "bouncer", + "chat", + "messaging", + "relay" + ], + "category": "communication", + "logo": "svgs/soju.svg", + "minversion": "0.0.0", + "port": "80" + }, "soketi": { "documentation": "https://docs.soketi.app?utm_source=coolify.io", "slogan": "Soketi is your simple, fast, and resilient open-source WebSockets server.", From d04d0ab49979e50f28ca2e069178e9ea45809109 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Wed, 17 Dec 2025 17:45:58 +0100 Subject: [PATCH 2/2] Refactor restart tracking and add missing model casts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Consolidate duplicate restart tracking logic in GetContainersStatus - Add last_restart_type string cast to all 8 standalone database models 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- app/Actions/Docker/GetContainersStatus.php | 27 ++++++++-------------- app/Models/StandaloneClickhouse.php | 1 + app/Models/StandaloneDragonfly.php | 1 + app/Models/StandaloneKeydb.php | 1 + app/Models/StandaloneMariadb.php | 1 + app/Models/StandaloneMongodb.php | 1 + app/Models/StandaloneMysql.php | 1 + app/Models/StandalonePostgresql.php | 1 + app/Models/StandaloneRedis.php | 1 + 9 files changed, 17 insertions(+), 18 deletions(-) diff --git a/app/Actions/Docker/GetContainersStatus.php b/app/Actions/Docker/GetContainersStatus.php index df0d8cf14..3631cca24 100644 --- a/app/Actions/Docker/GetContainersStatus.php +++ b/app/Actions/Docker/GetContainersStatus.php @@ -206,28 +206,19 @@ public function handle(Server $server, ?Collection $containers = null, ?Collecti if ($statusFromDb !== $containerStatus) { $updateData = ['status' => $containerStatus]; - - // Update restart tracking if restart count increased - if ($restartCount > $previousRestartCount) { - $updateData['restart_count'] = $restartCount; - $updateData['last_restart_at'] = now(); - $updateData['last_restart_type'] = 'crash'; - } - - $database->update($updateData); } else { $updateData = ['last_online_at' => now()]; - - // Update restart tracking even if status unchanged - if ($restartCount > $previousRestartCount) { - $updateData['restart_count'] = $restartCount; - $updateData['last_restart_at'] = now(); - $updateData['last_restart_type'] = 'crash'; - } - - $database->update($updateData); } + // Update restart tracking if restart count increased + if ($restartCount > $previousRestartCount) { + $updateData['restart_count'] = $restartCount; + $updateData['last_restart_at'] = now(); + $updateData['last_restart_type'] = 'crash'; + } + + $database->update($updateData); + if ($isPublic) { $foundTcpProxy = $this->containers->filter(function ($value, $key) use ($uuid) { if ($this->server->isSwarm()) { diff --git a/app/Models/StandaloneClickhouse.php b/app/Models/StandaloneClickhouse.php index 63485c612..a76d55abb 100644 --- a/app/Models/StandaloneClickhouse.php +++ b/app/Models/StandaloneClickhouse.php @@ -20,6 +20,7 @@ class StandaloneClickhouse extends BaseModel 'clickhouse_password' => 'encrypted', 'restart_count' => 'integer', 'last_restart_at' => 'datetime', + 'last_restart_type' => 'string', ]; protected static function booted() diff --git a/app/Models/StandaloneDragonfly.php b/app/Models/StandaloneDragonfly.php index 09f16752d..f5337b1d5 100644 --- a/app/Models/StandaloneDragonfly.php +++ b/app/Models/StandaloneDragonfly.php @@ -20,6 +20,7 @@ class StandaloneDragonfly extends BaseModel 'dragonfly_password' => 'encrypted', 'restart_count' => 'integer', 'last_restart_at' => 'datetime', + 'last_restart_type' => 'string', ]; protected static function booted() diff --git a/app/Models/StandaloneKeydb.php b/app/Models/StandaloneKeydb.php index c420bde15..ab24cae2c 100644 --- a/app/Models/StandaloneKeydb.php +++ b/app/Models/StandaloneKeydb.php @@ -20,6 +20,7 @@ class StandaloneKeydb extends BaseModel 'keydb_password' => 'encrypted', 'restart_count' => 'integer', 'last_restart_at' => 'datetime', + 'last_restart_type' => 'string', ]; protected static function booted() diff --git a/app/Models/StandaloneMariadb.php b/app/Models/StandaloneMariadb.php index 52ae136bb..e48cfc1e6 100644 --- a/app/Models/StandaloneMariadb.php +++ b/app/Models/StandaloneMariadb.php @@ -21,6 +21,7 @@ class StandaloneMariadb extends BaseModel 'mariadb_password' => 'encrypted', 'restart_count' => 'integer', 'last_restart_at' => 'datetime', + 'last_restart_type' => 'string', ]; protected static function booted() diff --git a/app/Models/StandaloneMongodb.php b/app/Models/StandaloneMongodb.php index f17c72dbc..9e271b19a 100644 --- a/app/Models/StandaloneMongodb.php +++ b/app/Models/StandaloneMongodb.php @@ -19,6 +19,7 @@ class StandaloneMongodb extends BaseModel protected $casts = [ 'restart_count' => 'integer', 'last_restart_at' => 'datetime', + 'last_restart_type' => 'string', ]; protected static function booted() diff --git a/app/Models/StandaloneMysql.php b/app/Models/StandaloneMysql.php index f4e192047..377765697 100644 --- a/app/Models/StandaloneMysql.php +++ b/app/Models/StandaloneMysql.php @@ -21,6 +21,7 @@ class StandaloneMysql extends BaseModel 'mysql_root_password' => 'encrypted', 'restart_count' => 'integer', 'last_restart_at' => 'datetime', + 'last_restart_type' => 'string', ]; protected static function booted() diff --git a/app/Models/StandalonePostgresql.php b/app/Models/StandalonePostgresql.php index 9e6c968aa..d9993426a 100644 --- a/app/Models/StandalonePostgresql.php +++ b/app/Models/StandalonePostgresql.php @@ -21,6 +21,7 @@ class StandalonePostgresql extends BaseModel 'postgres_password' => 'encrypted', 'restart_count' => 'integer', 'last_restart_at' => 'datetime', + 'last_restart_type' => 'string', ]; protected static function booted() diff --git a/app/Models/StandaloneRedis.php b/app/Models/StandaloneRedis.php index 05f8ae6c6..684bcaeb7 100644 --- a/app/Models/StandaloneRedis.php +++ b/app/Models/StandaloneRedis.php @@ -19,6 +19,7 @@ class StandaloneRedis extends BaseModel protected $casts = [ 'restart_count' => 'integer', 'last_restart_at' => 'datetime', + 'last_restart_type' => 'string', ]; protected static function booted()