diff --git a/app/Actions/Database/StartDatabaseProxy.php b/app/Actions/Database/StartDatabaseProxy.php index ffc91b86a..fe0976250 100644 --- a/app/Actions/Database/StartDatabaseProxy.php +++ b/app/Actions/Database/StartDatabaseProxy.php @@ -2,6 +2,7 @@ namespace App\Actions\Database; +use App\Models\ServiceDatabase; use App\Models\StandaloneMariadb; use App\Models\StandaloneMongodb; use App\Models\StandaloneMysql; @@ -14,18 +15,44 @@ class StartDatabaseProxy { use AsAction; - public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb $database) + public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|ServiceDatabase $database) { $internalPort = null; - if ($database->getMorphClass() === 'App\Models\StandaloneRedis') { + $type = $database->getMorphClass(); + $network = data_get($database, 'destination.network'); + $server = data_get($database, 'destination.server'); + if ($database->getMorphClass() === 'App\Models\ServiceDatabase') { + $databaseType = $database->databaseType(); + $network = data_get($database, 'service.destination.network'); + $server = data_get($database, 'service.destination.server'); + ray($databaseType, $network); + switch ($databaseType) { + case 'standalone-mariadb': + $type = 'App\Models\StandaloneMariadb'; + break; + case 'standalone-mongodb': + $type = 'App\Models\StandaloneMongodb'; + break; + case 'standalone-mysql': + $type = 'App\Models\StandaloneMysql'; + break; + case 'standalone-postgresql': + $type = 'App\Models\StandalonePostgresql'; + break; + case 'standalone-redis': + $type = 'App\Models\StandaloneRedis'; + break; + } + } + if ($type === 'App\Models\StandaloneRedis') { $internalPort = 6379; - } else if ($database->getMorphClass() === 'App\Models\StandalonePostgresql') { + } else if ($type === 'App\Models\StandalonePostgresql') { $internalPort = 5432; - } else if ($database->getMorphClass() === 'App\Models\StandaloneMongodb') { + } else if ($type === 'App\Models\StandaloneMongodb') { $internalPort = 27017; - } else if ($database->getMorphClass() === 'App\Models\StandaloneMysql') { + } else if ($type === 'App\Models\StandaloneMysql') { $internalPort = 3306; - } else if ($database->getMorphClass() === 'App\Models\StandaloneMariadb') { + } else if ($type === 'App\Models\StandaloneMariadb') { $internalPort = 3306; } $containerName = "{$database->uuid}-proxy"; @@ -66,7 +93,7 @@ public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|St "$database->public_port:$database->public_port", ], 'networks' => [ - $database->destination->network, + $network, ], 'healthcheck' => [ 'test' => [ @@ -81,9 +108,9 @@ public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|St ] ], 'networks' => [ - $database->destination->network => [ + $network => [ 'external' => true, - 'name' => $database->destination->network, + 'name' => $network, 'attachable' => true, ] ] @@ -97,6 +124,6 @@ public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|St "echo '{$nginxconf_base64}' | base64 -d > $configuration_dir/nginx.conf", "echo '{$dockercompose_base64}' | base64 -d > $configuration_dir/docker-compose.yaml", "docker compose --project-directory {$configuration_dir} up --build -d", - ], $database->destination->server); + ], $server); } } diff --git a/app/Actions/Database/StopDatabaseProxy.php b/app/Actions/Database/StopDatabaseProxy.php index d52d1961c..fc18985f1 100644 --- a/app/Actions/Database/StopDatabaseProxy.php +++ b/app/Actions/Database/StopDatabaseProxy.php @@ -2,6 +2,7 @@ namespace App\Actions\Database; +use App\Models\ServiceDatabase; use App\Models\StandaloneMariadb; use App\Models\StandaloneMongodb; use App\Models\StandaloneMysql; @@ -13,9 +14,13 @@ class StopDatabaseProxy { use AsAction; - public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb $database) + public function handle(StandaloneRedis|StandalonePostgresql|StandaloneMongodb|StandaloneMysql|StandaloneMariadb|ServiceDatabase $database) { - instant_remote_process(["docker rm -f {$database->uuid}-proxy"], $database->destination->server); + $server = data_get($database, 'destination.server'); + if ($database->getMorphClass() === 'App\Models\ServiceDatabase') { + $server = data_get($database, 'service.server'); + } + instant_remote_process(["docker rm -f {$database->uuid}-proxy"], $server); $database->is_public = false; $database->save(); } diff --git a/app/Http/Livewire/Project/Service/Database.php b/app/Http/Livewire/Project/Service/Database.php index e7eab5a3a..dee2785ba 100644 --- a/app/Http/Livewire/Project/Service/Database.php +++ b/app/Http/Livewire/Project/Service/Database.php @@ -2,28 +2,56 @@ namespace App\Http\Livewire\Project\Service; +use App\Actions\Database\StartDatabaseProxy; +use App\Actions\Database\StopDatabaseProxy; use App\Models\ServiceDatabase; use Livewire\Component; class Database extends Component { public ServiceDatabase $database; + public ?string $db_url_public = null; public $fileStorages; + protected $listeners = ["refreshFileStorages"]; protected $rules = [ 'database.human_name' => 'nullable', 'database.description' => 'nullable', 'database.image' => 'required', 'database.exclude_from_status' => 'required|boolean', + 'database.public_port' => 'nullable|integer', + 'database.is_public' => 'required|boolean', ]; public function render() { return view('livewire.project.service.database'); } public function mount() { + if ($this->database->is_public) { + $this->db_url_public = $this->database->getServiceDatabaseUrl(); + } $this->refreshFileStorages(); } public function instantSave() { + if ($this->database->is_public && !$this->database->public_port) { + $this->emit('error', 'Public port is required.'); + $this->database->is_public = false; + return; + } + if ($this->database->is_public) { + if (!str($this->database->status)->startsWith('running')) { + $this->emit('error', 'Database must be started to be publicly accessible.'); + $this->database->is_public = false; + return; + } + StartDatabaseProxy::run($this->database); + $this->db_url_public = $this->database->getServiceDatabaseUrl(); + $this->emit('success', 'Database is now publicly accessible.'); + } else { + StopDatabaseProxy::run($this->database); + $this->db_url_public = null; + $this->emit('success', 'Database is no longer publicly accessible.'); + } $this->submit(); } public function refreshFileStorages() diff --git a/app/Models/ServiceDatabase.php b/app/Models/ServiceDatabase.php index d5ecbd2a6..0dbbf6196 100644 --- a/app/Models/ServiceDatabase.php +++ b/app/Models/ServiceDatabase.php @@ -28,6 +28,16 @@ public function databaseType() } return "standalone-$image"; } + public function getServiceDatabaseUrl() { + // $type = $this->databaseType(); + $port = $this->public_port; + $realIp = $this->service->server->ip; + if ($realIp === 'host.docker.internal' || isDev()) { + $realIp = base_ip(); + } + $url = "{$realIp}:{$port}"; + return $url; + } public function service() { return $this->belongsTo(Service::class); diff --git a/app/Models/StandaloneRedis.php b/app/Models/StandaloneRedis.php index 9d12df040..a0de53a3e 100644 --- a/app/Models/StandaloneRedis.php +++ b/app/Models/StandaloneRedis.php @@ -58,8 +58,9 @@ public function type(): string { return 'standalone-redis'; } - public function getDbUrl(): string { - if ($this->is_public) { + public function getDbUrl(bool $useInternal = false): string + { + if ($this->is_public && !$useInternal) { return "redis://:{$this->redis_password}@{$this->destination->server->getIp}:{$this->public_port}/0"; } else { return "redis://:{$this->redis_password}@{$this->uuid}:6379/0"; diff --git a/config/sentry.php b/config/sentry.php index 4a285abf6..bcc77e76c 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ // The release version of your application // Example with dynamic git hash: trim(exec('git --git-dir ' . base_path('.git') . ' log --pretty="%h" -n1 HEAD')) - 'release' => '4.0.0-beta.118', + 'release' => '4.0.0-beta.119', // When left empty or `null` the Laravel environment will be used 'environment' => config('app.env'), diff --git a/config/version.php b/config/version.php index 81e37632e..14c1a5817 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ integer('public_port')->nullable(); + $table->boolean('is_public')->default(false); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('service_databases', function (Blueprint $table) { + $table->dropColumn('public_port'); + $table->dropColumn('is_public'); + }); + } +}; diff --git a/resources/views/livewire/project/service/database.blade.php b/resources/views/livewire/project/service/database.blade.php index 673d85268..e9318e13c 100644 --- a/resources/views/livewire/project/service/database.blade.php +++ b/resources/views/livewire/project/service/database.blade.php @@ -12,10 +12,19 @@
+
-
- +
+ @if ($db_url_public) + + @endif + +

Advanced

diff --git a/versions.json b/versions.json index 90be8f2ca..214a8884d 100644 --- a/versions.json +++ b/versions.json @@ -4,7 +4,7 @@ "version": "3.12.36" }, "v4": { - "version": "4.0.0-beta.118" + "version": "4.0.0-beta.119" } } }