From 1ed0158bed5de6a30b5f19dcff3a60ddd04c8ec4 Mon Sep 17 00:00:00 2001 From: Iisyourdad Date: Tue, 10 Mar 2026 21:47:48 -0500 Subject: [PATCH] merge conflict changes --- app/Actions/Database/StartDatabaseProxy.php | 36 +++++++- tests/Feature/StartDatabaseProxyTest.php | 20 ----- tests/Unit/DatabaseProxyMasterRoutingTest.php | 84 +++++++++++++++++++ 3 files changed, 116 insertions(+), 24 deletions(-) diff --git a/app/Actions/Database/StartDatabaseProxy.php b/app/Actions/Database/StartDatabaseProxy.php index 74243a5ec..f48d15817 100644 --- a/app/Actions/Database/StartDatabaseProxy.php +++ b/app/Actions/Database/StartDatabaseProxy.php @@ -80,6 +80,8 @@ class StartDatabaseProxy } $configuration_dir = $this->resolveConfigurationDirectory($database->uuid); + $host_configuration_dir = $this->resolveHostConfigurationDirectory($database->uuid, $configuration_dir); + $timeoutConfig = $this->buildProxyTimeoutConfig($database->public_port_timeout); $nginxconf = <<public_port; proxy_pass $upstreamTarget; + $timeoutConfig } } EOF; @@ -106,7 +109,7 @@ class StartDatabaseProxy 'volumes' => [ [ 'type' => 'bind', - 'source' => "$configuration_dir/nginx.conf", + 'source' => "$host_configuration_dir/nginx.conf", 'target' => '/etc/nginx/nginx.conf', ], ], @@ -184,14 +187,30 @@ class StartDatabaseProxy protected function resolveConfigurationDirectory(string $databaseUuid): string { - $configurationDirectory = database_proxy_dir($databaseUuid); - if (isDev()) { - $configurationDirectory = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/databases/'.$databaseUuid.'/proxy'; + return database_proxy_dir($databaseUuid); + } + + protected function resolveHostConfigurationDirectory(string $databaseUuid, ?string $configurationDirectory = null): string + { + $configurationDirectory ??= $this->resolveConfigurationDirectory($databaseUuid); + if ($this->isDevelopmentEnvironment()) { + return '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/databases/'.$databaseUuid.'/proxy'; } return $configurationDirectory; } + protected function isDevelopmentEnvironment(): bool + { + if (app()->bound('config')) { + return isDev(); + } + + $appEnv = $_ENV['APP_ENV'] ?? $_SERVER['APP_ENV'] ?? getenv('APP_ENV'); + + return $appEnv === 'local'; + } + protected function resolveEdgeProxyServerForTeamId(?int $teamId): ?Server { if (is_null($teamId)) { @@ -311,4 +330,13 @@ class StartDatabaseProxy return false; } + + private function buildProxyTimeoutConfig(?int $timeout): string + { + if ($timeout === null || $timeout < 1) { + $timeout = 3600; + } + + return "proxy_timeout {$timeout}s;"; + } } diff --git a/tests/Feature/StartDatabaseProxyTest.php b/tests/Feature/StartDatabaseProxyTest.php index c62569866..63a4ea387 100644 --- a/tests/Feature/StartDatabaseProxyTest.php +++ b/tests/Feature/StartDatabaseProxyTest.php @@ -1,28 +1,8 @@ create(); - - $database = StandalonePostgresql::factory()->create([ - 'team_id' => $team->id, - 'is_public' => true, - 'public_port' => 5432, - ]); - - expect($database->is_public)->toBeTrue(); - $action = new StartDatabaseProxy; // Use reflection to test the private method directly diff --git a/tests/Unit/DatabaseProxyMasterRoutingTest.php b/tests/Unit/DatabaseProxyMasterRoutingTest.php index 2ba28818d..c84379706 100644 --- a/tests/Unit/DatabaseProxyMasterRoutingTest.php +++ b/tests/Unit/DatabaseProxyMasterRoutingTest.php @@ -73,6 +73,65 @@ it('runs standalone database proxy on the master domain router server for remote ->and($dockerCompose)->not->toContain('standalone-network'); }); +it('keeps configurable database proxy timeout when routing through the master domain router server', function () { + $edgeServer = \Mockery::mock(Server::class)->makePartial(); + $edgeServer->id = 3; + + $deploymentServer = \Mockery::mock(Server::class)->makePartial(); + $deploymentServer->id = 4; + $deploymentServer->ip = '10.8.0.44'; + $deploymentServer->proxy = ['type' => 'NONE']; + + $database = new StandalonePostgresql; + $database->uuid = 'standalone-db-timeout-uuid'; + $database->name = 'standalone-db-timeout'; + $database->public_port = 15444; + $database->public_port_timeout = 7200; + $database->setRelation('destination', (object) [ + 'server' => $deploymentServer, + 'network' => 'standalone-timeout-network', + ]); + $database->setRelation('environment', (object) [ + 'project' => (object) ['team_id' => 124], + ]); + + $action = new class($edgeServer) extends StartDatabaseProxy + { + public array $calls = []; + + public function __construct(private ?Server $edgeServer) {} + + protected function runRemoteCommands(array $commands, Server $server, bool $throwError = true): ?string + { + $this->calls[] = [ + 'server_id' => $server->id, + 'commands' => $commands, + 'throw_error' => $throwError, + ]; + + return null; + } + + protected function resolveEdgeProxyServerForTeamId(?int $teamId): ?Server + { + return $this->edgeServer; + } + + protected function resolveConfigurationDirectory(string $databaseUuid): string + { + return "/tmp/database-proxy/{$databaseUuid}"; + } + }; + + $action->handle($database); + + preg_match("/echo '([^']+)' \\| base64 -d \\| tee .*nginx\\.conf/", $action->calls[2]['commands'][1], $nginxMatches); + $nginxConf = base64_decode($nginxMatches[1] ?? ''); + + expect($nginxConf)->toContain('proxy_pass 10.8.0.44:5432;') + ->and($nginxConf)->toContain('proxy_timeout 7200s;'); +}); + it('keeps standalone database proxy on deployment server when no master domain router server is configured', function () { $deploymentServer = \Mockery::mock(Server::class)->makePartial(); $deploymentServer->id = 2; @@ -418,6 +477,31 @@ it('supports service database deployment server fallback from service.server whe ->and($action->calls[1]['server_id'])->toBe(61); }); +it('uses the dev host configuration path only for the bind mount source', function () { + $action = new class extends StartDatabaseProxy + { + public function configurationDirectory(string $databaseUuid): string + { + return $this->resolveConfigurationDirectory($databaseUuid); + } + + public function hostConfigurationDirectory(string $databaseUuid): string + { + return $this->resolveHostConfigurationDirectory($databaseUuid); + } + + protected function isDevelopmentEnvironment(): bool + { + return true; + } + }; + + expect($action->configurationDirectory('dev-db-uuid')) + ->toBe('/data/coolify/databases/dev-db-uuid/proxy') + ->and($action->hostConfigurationDirectory('dev-db-uuid')) + ->toBe('/var/lib/docker/volumes/coolify_dev_coolify_data/_data/databases/dev-db-uuid/proxy'); +}); + it('uses ssl internal redis port 6380 for remote database proxy upstream target', function () { $edgeServer = \Mockery::mock(Server::class)->makePartial(); $edgeServer->id = 71;