fix(proxy): replace CheckConfiguration with GetProxyConfiguration and SaveConfiguration with SaveProxyConfiguration for improved clarity and consistency in proxy management

This commit is contained in:
Andras Bacsai
2025-09-09 12:52:19 +02:00
parent feacedbb04
commit 1ca94b90da
8 changed files with 103 additions and 79 deletions

View File

@@ -1,36 +0,0 @@
<?php
namespace App\Actions\Proxy;
use App\Models\Server;
use App\Services\ProxyDashboardCacheService;
use Lorisleiva\Actions\Concerns\AsAction;
class CheckConfiguration
{
use AsAction;
public function handle(Server $server, bool $reset = false)
{
$proxyType = $server->proxyType();
if ($proxyType === 'NONE') {
return 'OK';
}
$proxy_path = $server->proxyPath();
$payload = [
"mkdir -p $proxy_path",
"cat $proxy_path/docker-compose.yml",
];
$proxy_configuration = instant_remote_process($payload, $server, false);
if ($reset || ! $proxy_configuration || is_null($proxy_configuration)) {
$proxy_configuration = str(generate_default_proxy_configuration($server))->trim()->value();
}
if (! $proxy_configuration || is_null($proxy_configuration)) {
throw new \Exception('Could not generate proxy configuration');
}
ProxyDashboardCacheService::isTraefikDashboardAvailableFromConfiguration($server, $proxy_configuration);
return $proxy_configuration;
}
}

View File

@@ -70,7 +70,7 @@ class CheckProxy
try { try {
if ($server->proxyType() !== ProxyTypes::NONE->value) { if ($server->proxyType() !== ProxyTypes::NONE->value) {
$proxyCompose = CheckConfiguration::run($server); $proxyCompose = GetProxyConfiguration::run($server);
if (isset($proxyCompose)) { if (isset($proxyCompose)) {
$yaml = Yaml::parse($proxyCompose); $yaml = Yaml::parse($proxyCompose);
$configPorts = []; $configPorts = [];

View File

@@ -0,0 +1,47 @@
<?php
namespace App\Actions\Proxy;
use App\Models\Server;
use App\Services\ProxyDashboardCacheService;
use Lorisleiva\Actions\Concerns\AsAction;
class GetProxyConfiguration
{
use AsAction;
public function handle(Server $server, bool $forceRegenerate = false): string
{
$proxyType = $server->proxyType();
if ($proxyType === 'NONE') {
return 'OK';
}
$proxy_path = $server->proxyPath();
$proxy_configuration = null;
// If not forcing regeneration, try to read existing configuration
if (! $forceRegenerate) {
$payload = [
"mkdir -p $proxy_path",
"cat $proxy_path/docker-compose.yml 2>/dev/null",
];
$proxy_configuration = instant_remote_process($payload, $server, false);
}
// Generate default configuration if:
// 1. Force regenerate is requested
// 2. Configuration file doesn't exist or is empty
if ($forceRegenerate || empty(trim($proxy_configuration ?? ''))) {
$proxy_configuration = str(generate_default_proxy_configuration($server))->trim()->value();
}
if (empty($proxy_configuration)) {
throw new \Exception('Could not get or generate proxy configuration');
}
ProxyDashboardCacheService::isTraefikDashboardAvailableFromConfiguration($server, $proxy_configuration);
return $proxy_configuration;
}
}

View File

@@ -5,22 +5,21 @@ namespace App\Actions\Proxy;
use App\Models\Server; use App\Models\Server;
use Lorisleiva\Actions\Concerns\AsAction; use Lorisleiva\Actions\Concerns\AsAction;
class SaveConfiguration class SaveProxyConfiguration
{ {
use AsAction; use AsAction;
public function handle(Server $server, ?string $proxy_settings = null) public function handle(Server $server, string $configuration): void
{ {
if (is_null($proxy_settings)) {
$proxy_settings = CheckConfiguration::run($server, true);
}
$proxy_path = $server->proxyPath(); $proxy_path = $server->proxyPath();
$docker_compose_yml_base64 = base64_encode($proxy_settings); $docker_compose_yml_base64 = base64_encode($configuration);
// Update the saved settings hash
$server->proxy->last_saved_settings = str($docker_compose_yml_base64)->pipe('md5')->value; $server->proxy->last_saved_settings = str($docker_compose_yml_base64)->pipe('md5')->value;
$server->save(); $server->save();
return instant_remote_process([ // Transfer the configuration file to the server
instant_remote_process([
"mkdir -p $proxy_path", "mkdir -p $proxy_path",
[ [
'transfer_file' => [ 'transfer_file' => [

View File

@@ -21,11 +21,11 @@ class StartProxy
} }
$commands = collect([]); $commands = collect([]);
$proxy_path = $server->proxyPath(); $proxy_path = $server->proxyPath();
$configuration = CheckConfiguration::run($server); $configuration = GetProxyConfiguration::run($server);
if (! $configuration) { if (! $configuration) {
throw new \Exception('Configuration is not synced'); throw new \Exception('Configuration is not synced');
} }
SaveConfiguration::run($server, $configuration); SaveProxyConfiguration::run($server, $configuration);
$docker_compose_yml_base64 = base64_encode($configuration); $docker_compose_yml_base64 = base64_encode($configuration);
$server->proxy->last_applied_settings = str($docker_compose_yml_base64)->pipe('md5')->value(); $server->proxy->last_applied_settings = str($docker_compose_yml_base64)->pipe('md5')->value();
$server->save(); $server->save();

View File

@@ -2,8 +2,8 @@
namespace App\Livewire\Server; namespace App\Livewire\Server;
use App\Actions\Proxy\CheckConfiguration; use App\Actions\Proxy\GetProxyConfiguration;
use App\Actions\Proxy\SaveConfiguration; use App\Actions\Proxy\SaveProxyConfiguration;
use App\Models\Server; use App\Models\Server;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests; use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Livewire\Component; use Livewire\Component;
@@ -16,11 +16,11 @@ class Proxy extends Component
public ?string $selectedProxy = null; public ?string $selectedProxy = null;
public $proxy_settings = null; public $proxySettings = null;
public bool $redirect_enabled = true; public bool $redirectEnabled = true;
public ?string $redirect_url = null; public ?string $redirectUrl = null;
public function getListeners() public function getListeners()
{ {
@@ -39,14 +39,14 @@ class Proxy extends Component
public function mount() public function mount()
{ {
$this->selectedProxy = $this->server->proxyType(); $this->selectedProxy = $this->server->proxyType();
$this->redirect_enabled = data_get($this->server, 'proxy.redirect_enabled', true); $this->redirectEnabled = data_get($this->server, 'proxy.redirect_enabled', true);
$this->redirect_url = data_get($this->server, 'proxy.redirect_url'); $this->redirectUrl = data_get($this->server, 'proxy.redirect_url');
} }
// public function proxyStatusUpdated() public function getConfigurationFilePathProperty()
// { {
// $this->dispatch('refresh')->self(); return $this->server->proxyPath().'/docker-compose.yml';
// } }
public function changeProxy() public function changeProxy()
{ {
@@ -86,7 +86,7 @@ class Proxy extends Component
{ {
try { try {
$this->authorize('update', $this->server); $this->authorize('update', $this->server);
$this->server->proxy->redirect_enabled = $this->redirect_enabled; $this->server->proxy->redirect_enabled = $this->redirectEnabled;
$this->server->save(); $this->server->save();
$this->server->setupDefaultRedirect(); $this->server->setupDefaultRedirect();
$this->dispatch('success', 'Proxy configuration saved.'); $this->dispatch('success', 'Proxy configuration saved.');
@@ -99,8 +99,8 @@ class Proxy extends Component
{ {
try { try {
$this->authorize('update', $this->server); $this->authorize('update', $this->server);
SaveConfiguration::run($this->server, $this->proxy_settings); SaveProxyConfiguration::run($this->server, $this->proxySettings);
$this->server->proxy->redirect_url = $this->redirect_url; $this->server->proxy->redirect_url = $this->redirectUrl;
$this->server->save(); $this->server->save();
$this->server->setupDefaultRedirect(); $this->server->setupDefaultRedirect();
$this->dispatch('success', 'Proxy configuration saved.'); $this->dispatch('success', 'Proxy configuration saved.');
@@ -109,14 +109,15 @@ class Proxy extends Component
} }
} }
public function reset_proxy_configuration() public function resetProxyConfiguration()
{ {
try { try {
$this->authorize('update', $this->server); $this->authorize('update', $this->server);
$this->proxy_settings = CheckConfiguration::run($this->server, true); // Explicitly regenerate default configuration
SaveConfiguration::run($this->server, $this->proxy_settings); $this->proxySettings = GetProxyConfiguration::run($this->server, forceRegenerate: true);
SaveProxyConfiguration::run($this->server, $this->proxySettings);
$this->server->save(); $this->server->save();
$this->dispatch('success', 'Proxy configuration saved.'); $this->dispatch('success', 'Proxy configuration reset to default.');
} catch (\Throwable $e) { } catch (\Throwable $e) {
return handleError($e, $this); return handleError($e, $this);
} }
@@ -125,7 +126,7 @@ class Proxy extends Component
public function loadProxyConfiguration() public function loadProxyConfiguration()
{ {
try { try {
$this->proxy_settings = CheckConfiguration::run($this->server); $this->proxySettings = GetProxyConfiguration::run($this->server);
} catch (\Throwable $e) { } catch (\Throwable $e) {
return handleError($e, $this); return handleError($e, $this);
} }

View File

@@ -1,6 +1,6 @@
<?php <?php
use App\Actions\Proxy\SaveConfiguration; use App\Actions\Proxy\SaveProxyConfiguration;
use App\Enums\ProxyTypes; use App\Enums\ProxyTypes;
use App\Models\Application; use App\Models\Application;
use App\Models\Server; use App\Models\Server;
@@ -267,7 +267,7 @@ function generate_default_proxy_configuration(Server $server)
} }
$config = Yaml::dump($config, 12, 2); $config = Yaml::dump($config, 12, 2);
SaveConfiguration::run($server, $config); SaveProxyConfiguration::run($server, $config);
return $config; return $config;
} }

View File

@@ -7,9 +7,11 @@
<div class="flex items-center gap-2"> <div class="flex items-center gap-2">
<h2>Configuration</h2> <h2>Configuration</h2>
@if ($server->proxy->status === 'exited' || $server->proxy->status === 'removing') @if ($server->proxy->status === 'exited' || $server->proxy->status === 'removing')
<x-forms.button canGate="update" :canResource="$server" wire:click.prevent="changeProxy">Switch Proxy</x-forms.button> <x-forms.button canGate="update" :canResource="$server" wire:click.prevent="changeProxy">Switch
Proxy</x-forms.button>
@else @else
<x-forms.button canGate="update" :canResource="$server" disabled wire:click.prevent="changeProxy">Switch Proxy</x-forms.button> <x-forms.button canGate="update" :canResource="$server" disabled
wire:click.prevent="changeProxy">Switch Proxy</x-forms.button>
@endif @endif
<x-forms.button canGate="update" :canResource="$server" type="submit">Save</x-forms.button> <x-forms.button canGate="update" :canResource="$server" type="submit">Save</x-forms.button>
</div> </div>
@@ -27,11 +29,11 @@
id="server.settings.generate_exact_labels" id="server.settings.generate_exact_labels"
label="Generate labels only for {{ str($server->proxyType())->title() }}" instantSave /> label="Generate labels only for {{ str($server->proxyType())->title() }}" instantSave />
<x-forms.checkbox canGate="update" :canResource="$server" instantSave="instantSaveRedirect" <x-forms.checkbox canGate="update" :canResource="$server" instantSave="instantSaveRedirect"
id="redirect_enabled" label="Override default request handler" id="redirectEnabled" label="Override default request handler"
helper="Requests to unknown hosts or stopped services will receive a 503 response or be redirected to the URL you set below (need to enable this first)." /> helper="Requests to unknown hosts or stopped services will receive a 503 response or be redirected to the URL you set below (need to enable this first)." />
@if ($redirect_enabled) @if ($redirectEnabled)
<x-forms.input canGate="update" :canResource="$server" placeholder="https://app.coolify.io" <x-forms.input canGate="update" :canResource="$server" placeholder="https://app.coolify.io"
id="redirect_url" label="Redirect to (optional)" /> id="redirectUrl" label="Redirect to (optional)" />
@endif @endif
</div> </div>
@if ($server->proxyType() === ProxyTypes::TRAEFIK->value) @if ($server->proxyType() === ProxyTypes::TRAEFIK->value)
@@ -50,15 +52,26 @@
<x-loading text="Loading proxy configuration..." /> <x-loading text="Loading proxy configuration..." />
</div> </div>
<div wire:loading.remove wire:target="loadProxyConfiguration"> <div wire:loading.remove wire:target="loadProxyConfiguration">
@if ($proxy_settings) @if ($proxySettings)
<div class="flex flex-col gap-2 pt-4"> <div class="flex flex-col gap-2 pt-4">
<x-forms.textarea canGate="update" :canResource="$server" useMonacoEditor <x-forms.textarea canGate="update" :canResource="$server" useMonacoEditor
monacoEditorLanguage="yaml" label="Configuration file" name="proxy_settings" monacoEditorLanguage="yaml"
id="proxy_settings" rows="30" /> label="Configuration file ({{ $this->configurationFilePath }})" name="proxySettings"
<x-forms.button canGate="update" :canResource="$server" id="proxySettings" rows="30" />
wire:click.prevent="reset_proxy_configuration"> @can('update', $server)
Reset configuration to default <x-modal-confirmation title="Reset Proxy Configuration?"
</x-forms.button> buttonTitle="Reset configuration to default" isErrorButton
submitAction="resetProxyConfiguration" :actions="[
'Reset proxy configuration to default settings',
'All custom configurations will be lost',
'Custom ports and entrypoints will be removed',
]"
confirmationText="{{ $server->name }}"
confirmationLabel="Please confirm by entering the server name below"
shortConfirmationLabel="Server Name" step2ButtonText="Reset Configuration"
:confirmWithPassword="false" :confirmWithText="true">
</x-modal-confirmation>
@endcan
</div> </div>
@endif @endif
</div> </div>