This commit is contained in:
ShadowArcanist 2026-03-10 07:29:35 +05:30 committed by GitHub
commit 2e75bd51bc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 186 additions and 18 deletions

View file

@ -22,6 +22,17 @@ class StartDatabaseProxy
public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|StandaloneKeydb|StandaloneDragonfly|StandaloneClickhouse|ServiceDatabase $database)
{
// Validate proxy timeout
if (!isset($database->proxy_timeout) || $database->proxy_timeout === null) {
throw new \Exception('Proxy timeout is required.');
}
if ($database->proxy_timeout <= 0) {
throw new \Exception('Proxy timeout must be greater than 0.');
}
if ($database->proxy_timeout > 31536000) {
throw new \Exception('Proxy timeout must not exceed 31536000 seconds (1 year).');
}
$databaseType = $database->database_type;
$network = data_get($database, 'destination.network');
$server = data_get($database, 'destination.server');
@ -54,6 +65,8 @@ class StartDatabaseProxy
if (isDev()) {
$configuration_dir = '/var/lib/docker/volumes/coolify_dev_coolify_data/_data/databases/'.$database->uuid.'/proxy';
}
$proxyTimeout = $database->proxy_timeout ?? 1800;
$timeoutDirective = "proxy_timeout {$proxyTimeout}s;";
$nginxconf = <<<EOF
user nginx;
worker_processes auto;
@ -64,10 +77,12 @@ class StartDatabaseProxy
worker_connections 1024;
}
stream {
server {
server {
listen $database->public_port;
proxy_pass $containerName:$internalPort;
}
proxy_socket_keepalive on;
{$timeoutDirective}
}
}
EOF;
$docker_compose = [

View file

@ -36,6 +36,8 @@ class General extends Component
public ?int $publicPort = null;
public ?int $proxyTimeout = null;
public ?string $customDockerRunOptions = null;
public ?string $dbUrl = null;
@ -80,6 +82,7 @@ class General extends Component
'portsMappings' => 'nullable|string',
'isPublic' => 'nullable|boolean',
'publicPort' => 'nullable|integer',
'proxyTimeout' => 'nullable|integer|min:0|max:31536000',
'customDockerRunOptions' => 'nullable|string',
'dbUrl' => 'nullable|string',
'dbUrlPublic' => 'nullable|string',
@ -115,6 +118,7 @@ class General extends Component
$this->database->ports_mappings = $this->portsMappings;
$this->database->is_public = $this->isPublic;
$this->database->public_port = $this->publicPort;
$this->database->proxy_timeout = $this->proxyTimeout;
$this->database->custom_docker_run_options = $this->customDockerRunOptions;
$this->database->is_log_drain_enabled = $this->isLogDrainEnabled;
$this->database->save();
@ -130,6 +134,7 @@ class General extends Component
$this->portsMappings = $this->database->ports_mappings;
$this->isPublic = $this->database->is_public;
$this->publicPort = $this->database->public_port;
$this->proxyTimeout = $this->database->proxy_timeout;
$this->customDockerRunOptions = $this->database->custom_docker_run_options;
$this->isLogDrainEnabled = $this->database->is_log_drain_enabled;
$this->dbUrl = $this->database->internal_db_url;

View file

@ -36,6 +36,8 @@ class General extends Component
public ?int $publicPort = null;
public ?int $proxyTimeout = null;
public ?string $customDockerRunOptions = null;
public ?string $dbUrl = null;
@ -91,6 +93,7 @@ class General extends Component
'portsMappings' => 'nullable|string',
'isPublic' => 'nullable|boolean',
'publicPort' => 'nullable|integer',
'proxyTimeout' => 'nullable|integer|min:0|max:31536000',
'customDockerRunOptions' => 'nullable|string',
'dbUrl' => 'nullable|string',
'dbUrlPublic' => 'nullable|string',
@ -124,6 +127,7 @@ class General extends Component
$this->database->ports_mappings = $this->portsMappings;
$this->database->is_public = $this->isPublic;
$this->database->public_port = $this->publicPort;
$this->database->proxy_timeout = $this->proxyTimeout;
$this->database->custom_docker_run_options = $this->customDockerRunOptions;
$this->database->is_log_drain_enabled = $this->isLogDrainEnabled;
$this->database->enable_ssl = $this->enable_ssl;
@ -139,6 +143,7 @@ class General extends Component
$this->portsMappings = $this->database->ports_mappings;
$this->isPublic = $this->database->is_public;
$this->publicPort = $this->database->public_port;
$this->proxyTimeout = $this->database->proxy_timeout;
$this->customDockerRunOptions = $this->database->custom_docker_run_options;
$this->isLogDrainEnabled = $this->database->is_log_drain_enabled;
$this->enable_ssl = $this->database->enable_ssl;

View file

@ -38,6 +38,8 @@ class General extends Component
public ?int $publicPort = null;
public ?int $proxyTimeout = null;
public ?string $customDockerRunOptions = null;
public ?string $dbUrl = null;
@ -94,6 +96,7 @@ class General extends Component
'portsMappings' => 'nullable|string',
'isPublic' => 'nullable|boolean',
'publicPort' => 'nullable|integer',
'proxyTimeout' => 'nullable|integer|min:0|max:31536000',
'customDockerRunOptions' => 'nullable|string',
'dbUrl' => 'nullable|string',
'dbUrlPublic' => 'nullable|string',
@ -130,6 +133,7 @@ class General extends Component
$this->database->ports_mappings = $this->portsMappings;
$this->database->is_public = $this->isPublic;
$this->database->public_port = $this->publicPort;
$this->database->proxy_timeout = $this->proxyTimeout;
$this->database->custom_docker_run_options = $this->customDockerRunOptions;
$this->database->is_log_drain_enabled = $this->isLogDrainEnabled;
$this->database->enable_ssl = $this->enable_ssl;
@ -146,6 +150,7 @@ class General extends Component
$this->portsMappings = $this->database->ports_mappings;
$this->isPublic = $this->database->is_public;
$this->publicPort = $this->database->public_port;
$this->proxyTimeout = $this->database->proxy_timeout;
$this->customDockerRunOptions = $this->database->custom_docker_run_options;
$this->isLogDrainEnabled = $this->database->is_log_drain_enabled;
$this->enable_ssl = $this->database->enable_ssl;

View file

@ -44,6 +44,8 @@ class General extends Component
public ?int $publicPort = null;
public ?int $proxyTimeout = null;
public bool $isLogDrainEnabled = false;
public ?string $customDockerRunOptions = null;
@ -79,6 +81,7 @@ class General extends Component
'portsMappings' => 'nullable',
'isPublic' => 'nullable|boolean',
'publicPort' => 'nullable|integer',
'proxyTimeout' => 'nullable|integer|min:0|max:31536000',
'isLogDrainEnabled' => 'nullable|boolean',
'customDockerRunOptions' => 'nullable',
'enableSsl' => 'boolean',
@ -113,6 +116,7 @@ class General extends Component
'portsMappings' => 'Port Mapping',
'isPublic' => 'Is Public',
'publicPort' => 'Public Port',
'proxyTimeout' => 'Proxy Timeout',
'customDockerRunOptions' => 'Custom Docker Options',
'enableSsl' => 'Enable SSL',
];
@ -154,6 +158,7 @@ class General extends Component
$this->database->ports_mappings = $this->portsMappings;
$this->database->is_public = $this->isPublic;
$this->database->public_port = $this->publicPort;
$this->database->proxy_timeout = $this->proxyTimeout;
$this->database->is_log_drain_enabled = $this->isLogDrainEnabled;
$this->database->custom_docker_run_options = $this->customDockerRunOptions;
$this->database->enable_ssl = $this->enableSsl;
@ -173,6 +178,7 @@ class General extends Component
$this->portsMappings = $this->database->ports_mappings;
$this->isPublic = $this->database->is_public;
$this->publicPort = $this->database->public_port;
$this->proxyTimeout = $this->database->proxy_timeout;
$this->isLogDrainEnabled = $this->database->is_log_drain_enabled;
$this->customDockerRunOptions = $this->database->custom_docker_run_options;
$this->enableSsl = $this->database->enable_ssl;

View file

@ -42,6 +42,8 @@ class General extends Component
public ?int $publicPort = null;
public ?int $proxyTimeout = null;
public bool $isLogDrainEnabled = false;
public ?string $customDockerRunOptions = null;
@ -78,6 +80,7 @@ class General extends Component
'portsMappings' => 'nullable',
'isPublic' => 'nullable|boolean',
'publicPort' => 'nullable|integer',
'proxyTimeout' => 'nullable|integer|min:0|max:31536000',
'isLogDrainEnabled' => 'nullable|boolean',
'customDockerRunOptions' => 'nullable',
'enableSsl' => 'boolean',
@ -112,6 +115,7 @@ class General extends Component
'portsMappings' => 'Port Mapping',
'isPublic' => 'Is Public',
'publicPort' => 'Public Port',
'proxyTimeout' => 'Proxy Timeout',
'customDockerRunOptions' => 'Custom Docker Run Options',
'enableSsl' => 'Enable SSL',
'sslMode' => 'SSL Mode',
@ -153,6 +157,7 @@ class General extends Component
$this->database->ports_mappings = $this->portsMappings;
$this->database->is_public = $this->isPublic;
$this->database->public_port = $this->publicPort;
$this->database->proxy_timeout = $this->proxyTimeout;
$this->database->is_log_drain_enabled = $this->isLogDrainEnabled;
$this->database->custom_docker_run_options = $this->customDockerRunOptions;
$this->database->enable_ssl = $this->enableSsl;
@ -172,6 +177,7 @@ class General extends Component
$this->portsMappings = $this->database->ports_mappings;
$this->isPublic = $this->database->is_public;
$this->publicPort = $this->database->public_port;
$this->proxyTimeout = $this->database->proxy_timeout;
$this->isLogDrainEnabled = $this->database->is_log_drain_enabled;
$this->customDockerRunOptions = $this->database->custom_docker_run_options;
$this->enableSsl = $this->database->enable_ssl;

View file

@ -44,6 +44,8 @@ class General extends Component
public ?int $publicPort = null;
public ?int $proxyTimeout = null;
public bool $isLogDrainEnabled = false;
public ?string $customDockerRunOptions = null;
@ -81,6 +83,7 @@ class General extends Component
'portsMappings' => 'nullable',
'isPublic' => 'nullable|boolean',
'publicPort' => 'nullable|integer',
'proxyTimeout' => 'nullable|integer|min:0|max:31536000',
'isLogDrainEnabled' => 'nullable|boolean',
'customDockerRunOptions' => 'nullable',
'enableSsl' => 'boolean',
@ -117,6 +120,7 @@ class General extends Component
'portsMappings' => 'Port Mapping',
'isPublic' => 'Is Public',
'publicPort' => 'Public Port',
'proxyTimeout' => 'Proxy Timeout',
'customDockerRunOptions' => 'Custom Docker Run Options',
'enableSsl' => 'Enable SSL',
'sslMode' => 'SSL Mode',
@ -159,6 +163,7 @@ class General extends Component
$this->database->ports_mappings = $this->portsMappings;
$this->database->is_public = $this->isPublic;
$this->database->public_port = $this->publicPort;
$this->database->proxy_timeout = $this->proxyTimeout;
$this->database->is_log_drain_enabled = $this->isLogDrainEnabled;
$this->database->custom_docker_run_options = $this->customDockerRunOptions;
$this->database->enable_ssl = $this->enableSsl;
@ -179,6 +184,7 @@ class General extends Component
$this->portsMappings = $this->database->ports_mappings;
$this->isPublic = $this->database->is_public;
$this->publicPort = $this->database->public_port;
$this->proxyTimeout = $this->database->proxy_timeout;
$this->isLogDrainEnabled = $this->database->is_log_drain_enabled;
$this->customDockerRunOptions = $this->database->custom_docker_run_options;
$this->enableSsl = $this->database->enable_ssl;

View file

@ -48,6 +48,8 @@ class General extends Component
public ?int $publicPort = null;
public ?int $proxyTimeout = null;
public bool $isLogDrainEnabled = false;
public ?string $customDockerRunOptions = null;
@ -93,6 +95,7 @@ class General extends Component
'portsMappings' => 'nullable',
'isPublic' => 'nullable|boolean',
'publicPort' => 'nullable|integer',
'proxyTimeout' => 'nullable|integer|min:0|max:31536000',
'isLogDrainEnabled' => 'nullable|boolean',
'customDockerRunOptions' => 'nullable',
'enableSsl' => 'boolean',
@ -130,6 +133,7 @@ class General extends Component
'portsMappings' => 'Port Mapping',
'isPublic' => 'Is Public',
'publicPort' => 'Public Port',
'proxyTimeout' => 'Proxy Timeout',
'customDockerRunOptions' => 'Custom Docker Run Options',
'enableSsl' => 'Enable SSL',
'sslMode' => 'SSL Mode',
@ -174,6 +178,7 @@ class General extends Component
$this->database->ports_mappings = $this->portsMappings;
$this->database->is_public = $this->isPublic;
$this->database->public_port = $this->publicPort;
$this->database->proxy_timeout = $this->proxyTimeout;
$this->database->is_log_drain_enabled = $this->isLogDrainEnabled;
$this->database->custom_docker_run_options = $this->customDockerRunOptions;
$this->database->enable_ssl = $this->enableSsl;
@ -196,6 +201,7 @@ class General extends Component
$this->portsMappings = $this->database->ports_mappings;
$this->isPublic = $this->database->is_public;
$this->publicPort = $this->database->public_port;
$this->proxyTimeout = $this->database->proxy_timeout;
$this->isLogDrainEnabled = $this->database->is_log_drain_enabled;
$this->customDockerRunOptions = $this->database->custom_docker_run_options;
$this->enableSsl = $this->database->enable_ssl;

View file

@ -36,6 +36,8 @@ class General extends Component
public ?int $publicPort = null;
public ?int $proxyTimeout = null;
public bool $isLogDrainEnabled = false;
public ?string $customDockerRunOptions = null;
@ -74,6 +76,7 @@ class General extends Component
'portsMappings' => 'nullable',
'isPublic' => 'nullable|boolean',
'publicPort' => 'nullable|integer',
'proxyTimeout' => 'nullable|integer|min:0|max:31536000',
'isLogDrainEnabled' => 'nullable|boolean',
'customDockerRunOptions' => 'nullable',
'redisUsername' => 'required',
@ -104,6 +107,7 @@ class General extends Component
'portsMappings' => 'Port Mapping',
'isPublic' => 'Is Public',
'publicPort' => 'Public Port',
'proxyTimeout' => 'Proxy Timeout',
'customDockerRunOptions' => 'Custom Docker Options',
'redisUsername' => 'Redis Username',
'redisPassword' => 'Redis Password',
@ -143,6 +147,7 @@ class General extends Component
$this->database->ports_mappings = $this->portsMappings;
$this->database->is_public = $this->isPublic;
$this->database->public_port = $this->publicPort;
$this->database->proxy_timeout = $this->proxyTimeout;
$this->database->is_log_drain_enabled = $this->isLogDrainEnabled;
$this->database->custom_docker_run_options = $this->customDockerRunOptions;
$this->database->enable_ssl = $this->enableSsl;
@ -158,6 +163,7 @@ class General extends Component
$this->portsMappings = $this->database->ports_mappings;
$this->isPublic = $this->database->is_public;
$this->publicPort = $this->database->public_port;
$this->proxyTimeout = $this->database->proxy_timeout;
$this->isLogDrainEnabled = $this->database->is_log_drain_enabled;
$this->customDockerRunOptions = $this->database->custom_docker_run_options;
$this->enableSsl = $this->database->enable_ssl;

View file

@ -0,0 +1,60 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
$tables = [
'standalone_postgresqls',
'standalone_mysqls',
'standalone_mariadbs',
'standalone_mongodbs',
'standalone_redis',
'standalone_keydbs',
'standalone_dragonflies',
'standalone_clickhouses',
'service_databases',
];
foreach ($tables as $table) {
if (Schema::hasTable($table)) {
Schema::table($table, function (Blueprint $table) {
$table->integer('proxy_timeout')->default(1800)->after('public_port'); // 30 minutes default
});
}
}
}
/**
* Reverse the migrations.
*/
public function down(): void
{
$tables = [
'standalone_postgresqls',
'standalone_mysqls',
'standalone_mariadbs',
'standalone_mongodbs',
'standalone_redis',
'standalone_keydbs',
'standalone_dragonflies',
'standalone_clickhouses',
'service_databases',
];
foreach ($tables as $table) {
if (Schema::hasTable($table) && Schema::hasColumn($table, 'proxy_timeout')) {
Schema::table($table, function (Blueprint $table) {
$table->dropColumn('proxy_timeout');
});
}
}
}
};

View file

@ -76,8 +76,14 @@
<x-forms.checkbox instantSave id="isPublic" label="Make it publicly available" canGate="update"
:canResource="$database" />
</div>
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}" id="publicPort" label="Public Port"
canGate="update" :canResource="$database" />
<div class="flex items-end gap-2">
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}" id="publicPort" label="Public Port"
canGate="update" :canResource="$database" />
<x-forms.input value="1800" id="proxyTimeout"
label="Proxy Timeout (seconds)"
helper="Maximum time in seconds to keep connections open. Default is 1800 seconds (30 minutes) and max is 31536000 seconds (1 year)"
canGate="update" :canResource="$database" />
</div>
</div>
</form>
<h3 class="pt-4">Advanced</h3>

View file

@ -113,8 +113,14 @@
<x-forms.checkbox instantSave id="isPublic" label="Make it publicly available" canGate="update"
:canResource="$database" />
</div>
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}" id="publicPort" label="Public Port"
canGate="update" :canResource="$database" />
<div class="flex items-end gap-2">
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}" id="publicPort" label="Public Port"
canGate="update" :canResource="$database" />
<x-forms.input value="1800" id="proxyTimeout"
label="Proxy Timeout (seconds)"
helper="Maximum time in seconds to keep connections open. Default is 1800 seconds (30 minutes) and max is 31536000 seconds (1 year)"
canGate="update" :canResource="$database" />
</div>
</div>
</form>
<h3 class="pt-4">Advanced</h3>

View file

@ -113,8 +113,14 @@
<x-forms.checkbox instantSave id="isPublic" label="Make it publicly available" canGate="update"
:canResource="$database" />
</div>
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}" id="publicPort" label="Public Port"
canGate="update" :canResource="$database" />
<div class="flex items-end gap-2">
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}" id="publicPort" label="Public Port"
canGate="update" :canResource="$database" />
<x-forms.input value="1800" id="proxyTimeout"
label="Proxy Timeout (seconds)"
helper="Maximum time in seconds to keep connections open. Default is 1800 seconds (30 minutes) and max is 31536000 seconds (1 year)"
canGate="update" :canResource="$database" />
</div>
</div>
<x-forms.textarea
helper="<a target='_blank' class='underline dark:text-white' href='https://raw.githubusercontent.com/Snapchat/KeyDB/unstable/keydb.conf'>KeyDB Default Configuration</a>"

View file

@ -137,8 +137,14 @@
<x-forms.checkbox instantSave id="isPublic" label="Make it publicly available"
canGate="update" :canResource="$database" />
</div>
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}"
id="publicPort" label="Public Port" canGate="update" :canResource="$database" />
<div class="flex items-end gap-2">
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}"
id="publicPort" label="Public Port" canGate="update" :canResource="$database" />
<x-forms.input value="1800" id="proxyTimeout"
label="Proxy Timeout (seconds)"
helper="Maximum time in seconds to keep connections open. Default is 1800 seconds (30 minutes) and max is 31536000 seconds (1 year)"
canGate="update" :canResource="$database" />
</div>
</div>
<x-forms.textarea label="Custom MariaDB Configuration" rows="10" id="mariadbConf"
canGate="update" :canResource="$database" />

View file

@ -151,8 +151,14 @@
<x-forms.checkbox instantSave id="isPublic" label="Make it publicly available"
canGate="update" :canResource="$database" />
</div>
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}"
id="publicPort" label="Public Port" canGate="update" :canResource="$database" />
<div class="flex items-end gap-2">
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}"
id="publicPort" label="Public Port" canGate="update" :canResource="$database" />
<x-forms.input value="1800" id="proxyTimeout"
label="Proxy Timeout (seconds)"
helper="Maximum time in seconds to keep connections open. Default is 1800 seconds (30 minutes) and max is 31536000 seconds (1 year)"
canGate="update" :canResource="$database" />
</div>
</div>
<x-forms.textarea label="Custom MongoDB Configuration" rows="10" id="mongoConf"
canGate="update" :canResource="$database" />

View file

@ -153,8 +153,14 @@
</div>
<x-forms.checkbox instantSave id="isPublic" label="Make it publicly available" canGate="update" :canResource="$database" />
</div>
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}"
id="publicPort" label="Public Port" canGate="update" :canResource="$database" />
<div class="flex items-end gap-2">
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}"
id="publicPort" label="Public Port" canGate="update" :canResource="$database" />
<x-forms.input value="1800" id="proxyTimeout"
label="Proxy Timeout (seconds)"
helper="Maximum time in seconds to keep connections open. Default is 1800 seconds (30 minutes) and max is 31536000 seconds (1 year)"
canGate="update" :canResource="$database" />
</div>
</div>
<x-forms.textarea label="Custom Mysql Configuration" rows="10" id="mysqlConf" canGate="update" :canResource="$database" />
<h3 class="pt-4">Advanced</h3>

View file

@ -163,8 +163,14 @@
<x-forms.checkbox instantSave id="isPublic" label="Make it publicly available"
canGate="update" :canResource="$database" />
</div>
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}" id="publicPort"
label="Public Port" canGate="update" :canResource="$database" />
<div class="flex items-end gap-2">
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}" id="publicPort"
label="Public Port" canGate="update" :canResource="$database" />
<x-forms.input value="1800" id="proxyTimeout"
label="Proxy Timeout (seconds)"
helper="Maximum time in seconds to keep connections open. Default is 1800 seconds (30 minutes) and max is 31536000 seconds (1 year)"
canGate="update" :canResource="$database" />
</div>
</div>
<div class="flex flex-col gap-2">

View file

@ -132,8 +132,14 @@
<x-forms.checkbox instantSave id="isPublic" label="Make it publicly available"
canGate="update" :canResource="$database" />
</div>
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}"
id="publicPort" label="Public Port" canGate="update" :canResource="$database" />
<div class="flex items-end gap-2">
<x-forms.input placeholder="5432" disabled="{{ $isPublic }}"
id="publicPort" label="Public Port" canGate="update" :canResource="$database" />
<x-forms.input value="1800" id="proxyTimeout"
label="Proxy Timeout (seconds)"
helper="Maximum time in seconds to keep connections open. Default is 1800 seconds (30 minutes) and max is 31536000 seconds (1 year)"
canGate="update" :canResource="$database" />
</div>
</div>
<x-forms.textarea placeholder="# maxmemory 256mb
# maxmemory-policy allkeys-lru