From 59eae3a44e72a1ee47732c9ced2c12f5f28a0f7b Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Fri, 13 Oct 2023 14:25:30 +0200 Subject: [PATCH] fix: proxy check for ports, do not kill anything listening on port 80/443 --- app/Actions/Proxy/CheckProxy.php | 42 +++++++++ app/Actions/Proxy/StartProxy.php | 88 +++++++++---------- app/Http/Livewire/Server/Proxy/Deploy.php | 18 +++- app/Http/Livewire/Server/Proxy/Modal.php | 2 - app/Http/Livewire/Server/Proxy/Status.php | 40 +++++++-- app/Jobs/ContainerStatusJob.php | 10 +-- bootstrap/helpers/proxy.php | 2 +- .../livewire/server/proxy/deploy.blade.php | 16 +++- .../livewire/server/proxy/status.blade.php | 6 +- 9 files changed, 152 insertions(+), 72 deletions(-) create mode 100644 app/Actions/Proxy/CheckProxy.php diff --git a/app/Actions/Proxy/CheckProxy.php b/app/Actions/Proxy/CheckProxy.php new file mode 100644 index 000000000..84dc4e955 --- /dev/null +++ b/app/Actions/Proxy/CheckProxy.php @@ -0,0 +1,42 @@ +isProxyShouldRun()) { + throw new \Exception("Proxy should not run"); + } + $status = getContainerStatus($server, 'coolify-proxy'); + if ($status === 'running') { + $server->proxy->set('status', 'running'); + $server->save(); + return 'OK'; + } + $ip = $server->ip; + if ($server->id === 0) { + $ip = 'host.docker.internal'; + } + + $connection = @fsockopen($ip, '80'); + $connection = @fsockopen($ip, '443'); + $port80 = is_resource($connection) && fclose($connection); + $port443 = is_resource($connection) && fclose($connection); + ray($ip); + if ($port80) { + throw new \Exception("Port 80 is in use.
You must stop the process using this port.
Docs: https://coolify.io/docs
Discord: https://coollabs.io/discord"); + } + if ($port443) { + throw new \Exception("Port 443 is in use.
You must stop the process using this port.
Docs: https://coolify.io/docs
Discord: https://coollabs.io/discord>"); + } + } +} diff --git a/app/Actions/Proxy/StartProxy.php b/app/Actions/Proxy/StartProxy.php index d6ae7eec8..14b7fefb5 100644 --- a/app/Actions/Proxy/StartProxy.php +++ b/app/Actions/Proxy/StartProxy.php @@ -2,7 +2,6 @@ namespace App\Actions\Proxy; -use App\Enums\ProxyTypes; use App\Models\Server; use Illuminate\Support\Str; use Lorisleiva\Actions\Concerns\AsAction; @@ -11,56 +10,49 @@ use Spatie\Activitylog\Models\Activity; class StartProxy { use AsAction; - public function handle(Server $server, bool $async = true): Activity|string + public function handle(Server $server, bool $async = true): string|Activity { - $commands = collect([]); - $proxyType = $server->proxyType(); - if ($proxyType === ProxyTypes::NONE->value) { - return 'OK'; - } - $proxy_path = get_proxy_path(); - $configuration = CheckConfiguration::run($server); - if (!$configuration) { - throw new \Exception("Configuration is not synced"); - } - SaveConfiguration::run($server, $configuration); - $docker_compose_yml_base64 = base64_encode($configuration); - $server->proxy->last_applied_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value; - $server->save(); + try { + CheckProxy::run($server); - $commands = $commands->merge([ - "apt-get update > /dev/null 2>&1 || true", - "command -v lsof >/dev/null || echo '####### Installing lsof.'", - "command -v lsof >/dev/null || apt install -y lsof", - "command -v lsof >/dev/null || command -v fuser >/dev/null || apt install -y psmisc", - "mkdir -p $proxy_path && cd $proxy_path", - "echo '####### Creating Docker Compose file.'", - "echo '####### Pulling docker image.'", - 'docker compose pull', - "echo '####### Stopping existing coolify-proxy.'", - "docker compose down -v --remove-orphans > /dev/null 2>&1", - "command -v fuser >/dev/null || command -v lsof >/dev/null || echo '####### Could not kill existing processes listening on port 80 & 443. Please stop the process holding these ports...'", - "command -v lsof >/dev/null && lsof -nt -i:80 | xargs -r kill -9 || true", - "command -v lsof >/dev/null && lsof -nt -i:443 | xargs -r kill -9 || true", - "command -v fuser >/dev/null && fuser -k 80/tcp || true", - "command -v fuser >/dev/null && fuser -k 443/tcp || true", - "systemctl disable nginx > /dev/null 2>&1 || true", - "systemctl disable apache2 > /dev/null 2>&1 || true", - "systemctl disable apache > /dev/null 2>&1 || true", - "echo '####### Starting coolify-proxy.'", - 'docker compose up -d --remove-orphans', - "echo '####### Proxy installed successfully.'" - ]); - $commands = $commands->merge(connectProxyToNetworks($server)); - if ($async) { - $activity = remote_process($commands, $server); - return $activity; - } else { - instant_remote_process($commands, $server); - $server->proxy->set('status', 'running'); - $server->proxy->set('type', $proxyType); + $proxyType = $server->proxyType(); + $commands = collect([]); + $proxy_path = get_proxy_path(); + $configuration = CheckConfiguration::run($server); + if (!$configuration) { + throw new \Exception("Configuration is not synced"); + } + SaveConfiguration::run($server, $configuration); + $docker_compose_yml_base64 = base64_encode($configuration); + $server->proxy->last_applied_settings = Str::of($docker_compose_yml_base64)->pipe('md5')->value; $server->save(); - return 'OK'; + $commands = $commands->merge([ + "mkdir -p $proxy_path && cd $proxy_path", + "echo 'Creating required Docker Compose file.'", + "echo 'Pulling docker image.'", + 'docker compose pull', + "echo 'Stopping existing coolify-proxy.'", + "docker compose down -v --remove-orphans > /dev/null 2>&1", + "echo 'Starting coolify-proxy.'", + 'docker compose up -d --remove-orphans', + "echo 'Proxy started successfully.'" + ]); + $commands = $commands->merge(connectProxyToNetworks($server)); + if ($async) { + $activity = remote_process($commands, $server); + return $activity; + } else { + instant_remote_process($commands, $server); + $server->proxy->set('status', 'running'); + $server->proxy->set('type', $proxyType); + $server->save(); + return 'OK'; + } + } catch(\Throwable $e) { + ray($e); + throw $e; } + + } } diff --git a/app/Http/Livewire/Server/Proxy/Deploy.php b/app/Http/Livewire/Server/Proxy/Deploy.php index ad5884e18..44ff4b917 100644 --- a/app/Http/Livewire/Server/Proxy/Deploy.php +++ b/app/Http/Livewire/Server/Proxy/Deploy.php @@ -2,6 +2,7 @@ namespace App\Http\Livewire\Server\Proxy; +use App\Actions\Proxy\CheckProxy; use App\Actions\Proxy\StartProxy; use App\Models\Server; use Livewire\Component; @@ -11,18 +12,29 @@ class Deploy extends Component public Server $server; public bool $traefikDashboardAvailable = false; public ?string $currentRoute = null; - protected $listeners = ['proxyStatusUpdated', 'traefikDashboardAvailable', 'serverRefresh' => 'proxyStatusUpdated']; + protected $listeners = ['proxyStatusUpdated', 'traefikDashboardAvailable', 'serverRefresh' => 'proxyStatusUpdated', "checkProxy", "startProxy"]; - public function mount() { + public function mount() + { $this->currentRoute = request()->route()->getName(); } - public function traefikDashboardAvailable(bool $data) { + public function traefikDashboardAvailable(bool $data) + { $this->traefikDashboardAvailable = $data; } public function proxyStatusUpdated() { $this->server->refresh(); } + public function checkProxy() { + try { + CheckProxy::run($this->server); + $this->emit('startProxyPolling'); + $this->emit('proxyChecked'); + } catch (\Throwable $e) { + return handleError($e, $this); + } + } public function startProxy() { try { diff --git a/app/Http/Livewire/Server/Proxy/Modal.php b/app/Http/Livewire/Server/Proxy/Modal.php index ef9948910..2674abe3d 100644 --- a/app/Http/Livewire/Server/Proxy/Modal.php +++ b/app/Http/Livewire/Server/Proxy/Modal.php @@ -11,8 +11,6 @@ class Modal extends Component public function proxyStatusUpdated() { - $this->server->proxy->set('status', 'running'); - $this->server->save(); $this->emit('proxyStatusUpdated'); } } diff --git a/app/Http/Livewire/Server/Proxy/Status.php b/app/Http/Livewire/Server/Proxy/Status.php index 5cfd22082..90deb1455 100644 --- a/app/Http/Livewire/Server/Proxy/Status.php +++ b/app/Http/Livewire/Server/Proxy/Status.php @@ -2,6 +2,7 @@ namespace App\Http\Livewire\Server\Proxy; +use App\Actions\Proxy\CheckProxy; use App\Jobs\ContainerStatusJob; use App\Models\Server; use Livewire\Component; @@ -9,12 +10,42 @@ use Livewire\Component; class Status extends Component { public Server $server; + public bool $polling = false; + public int $numberOfPolls = 0; - protected $listeners = ['proxyStatusUpdated']; + protected $listeners = ['proxyStatusUpdated', 'startProxyPolling']; + public function startProxyPolling() + { + $this->polling = true; + } public function proxyStatusUpdated() { $this->server->refresh(); } + public function checkProxy(bool $notification = false) + { + try { + if ($this->polling) { + if ($this->numberOfPolls >= 10) { + $this->polling = false; + $this->numberOfPolls = 0; + $notification && $this->emit('error', 'Proxy is not running.'); + return; + } + $this->numberOfPolls++; + } + CheckProxy::run($this->server); + $this->emit('proxyStatusUpdated'); + if ($this->server->proxy->status === 'running') { + $this->polling = false; + $notification && $this->emit('success', 'Proxy is running.'); + } else { + $notification && $this->emit('error', 'Proxy is not running.'); + } + } catch (\Throwable $e) { + return handleError($e, $this); + } + } public function getProxyStatus() { try { @@ -24,11 +55,4 @@ class Status extends Component return handleError($e, $this); } } - public function getProxyStatusWithNoti() - { - if ($this->server->isFunctional()) { - $this->emit('success', 'Refreshed proxy status.'); - $this->getProxyStatus(); - } - } } diff --git a/app/Jobs/ContainerStatusJob.php b/app/Jobs/ContainerStatusJob.php index 9b4ef5699..00e6b31fb 100644 --- a/app/Jobs/ContainerStatusJob.php +++ b/app/Jobs/ContainerStatusJob.php @@ -27,11 +27,6 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted public $tries = 1; public $timeout = 120; - public function __construct(public Server $server) - { - - } - public function middleware(): array { return [(new WithoutOverlapping($this->server->uuid))->dontRelease()]; @@ -41,6 +36,11 @@ class ContainerStatusJob implements ShouldQueue, ShouldBeEncrypted { return $this->server->uuid; } + + public function __construct(public Server $server) + { + } + public function handle() { try { diff --git a/bootstrap/helpers/proxy.php b/bootstrap/helpers/proxy.php index 81cb92c49..08f134d15 100644 --- a/bootstrap/helpers/proxy.php +++ b/bootstrap/helpers/proxy.php @@ -22,7 +22,7 @@ function connectProxyToNetworks(Server $server) } $commands = $networks->map(function ($network) { return [ - "echo '####### Connecting coolify-proxy to $network network...'", + "echo 'Connecting coolify-proxy to $network network...'", "docker network ls --format '{{.Name}}' | grep '^$network$' >/dev/null || docker network create --attachable $network >/dev/null", "docker network connect $network coolify-proxy >/dev/null 2>&1 || true", ]; diff --git a/resources/views/livewire/server/proxy/deploy.blade.php b/resources/views/livewire/server/proxy/deploy.blade.php index 41444fde4..933133408 100644 --- a/resources/views/livewire/server/proxy/deploy.blade.php +++ b/resources/views/livewire/server/proxy/deploy.blade.php @@ -20,8 +20,9 @@ @endif - + @@ -30,7 +31,7 @@ @else -