From 4aeb8ff02b23de2773c8065d28ad975fdf8c2463 Mon Sep 17 00:00:00 2001 From: peaklabs-dev <122374094+peaklabs-dev@users.noreply.github.com> Date: Thu, 12 Sep 2024 10:40:06 +0200 Subject: [PATCH 1/7] Fix: SSH Multiplexing on docker desktop on Windows --- bootstrap/helpers/remoteProcess.php | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index f6cf9fbe5..9c66bd21c 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -98,12 +98,10 @@ function generateScpCommand(Server $server, string $source, string $dest) $muxPersistTime = config('constants.ssh.mux_persist_time'); $scp_command = "timeout $timeout scp "; - // Check if multiplexing is enabled - $muxEnabled = config('constants.ssh.mux_enabled', true); + $muxEnabled = config('constants.ssh.mux_enabled', true) && config('coolify.is_windows_docker_desktop') == false; // ray('SSH Multiplexing Enabled:', $muxEnabled)->blue(); if ($muxEnabled) { - // Always use multiplexing when enabled $muxSocket = "/var/www/html/storage/app/ssh/mux/{$server->muxFilename()}"; $scp_command .= "-o ControlMaster=auto -o ControlPath=$muxSocket -o ControlPersist={$muxPersistTime} "; ensureMultiplexedConnection($server); @@ -163,9 +161,7 @@ function generateSshCommand(Server $server, string $command) $ssh_command = "timeout $timeout ssh "; - // Check if multiplexing is enabled - $muxEnabled = config('constants.ssh.mux_enabled', true); - // ray('SSH Multiplexing Enabled:', $muxEnabled)->blue(); + $muxEnabled = config('coolify.mux_enabled') && config('coolify.is_windows_docker_desktop') == false; if ($muxEnabled) { // Always use multiplexing when enabled @@ -201,6 +197,10 @@ function generateSshCommand(Server $server, string $command) function ensureMultiplexedConnection(Server $server) { + if (!(config('coolify.mux_enabled') && config('coolify.is_windows_docker_desktop') == false)) { + return; + } + static $ensuredConnections = []; if (isset($ensuredConnections[$server->id])) { @@ -260,6 +260,10 @@ function ensureMultiplexedConnection(Server $server) function shouldResetMultiplexedConnection(Server $server) { + if (!(config('coolify.mux_enabled') && config('coolify.is_windows_docker_desktop') == false)) { + return false; + } + static $ensuredConnections = []; if (! isset($ensuredConnections[$server->id])) { @@ -275,6 +279,10 @@ function shouldResetMultiplexedConnection(Server $server) function resetMultiplexedConnection(Server $server) { + if (!(config('coolify.mux_enabled') && config('coolify.is_windows_docker_desktop') == false)) { + return; + } + static $ensuredConnections = []; if (isset($ensuredConnections[$server->id])) { From 90fd0ebf124152c9d8e97438b4b79d696e46891e Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 12 Sep 2024 10:51:14 +0200 Subject: [PATCH 2/7] chore: Update release version to 4.0.0-beta.335 --- config/sentry.php | 2 +- config/version.php | 2 +- versions.json | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/config/sentry.php b/config/sentry.php index 5a0bfdaac..253202507 100644 --- a/config/sentry.php +++ b/config/sentry.php @@ -7,7 +7,7 @@ return [ // 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.334', + 'release' => '4.0.0-beta.335', // 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 f4b7ee9f7..c41d57f66 100644 --- a/config/version.php +++ b/config/version.php @@ -1,3 +1,3 @@ Date: Thu, 12 Sep 2024 12:07:50 +0200 Subject: [PATCH 3/7] fix: cloudflare tunnel with new multiplexing feature --- .env.development.example | 2 +- app/Livewire/Boarding/Index.php | 2 +- app/Models/Server.php | 2 +- bootstrap/helpers/proxy.php | 2 ++ bootstrap/helpers/remoteProcess.php | 17 ++++++++++++----- config/constants.php | 3 ++- config/coolify.php | 1 - docker-compose.prod.yml | 1 + docker-compose.windows.yml | 2 +- 9 files changed, 21 insertions(+), 11 deletions(-) diff --git a/.env.development.example b/.env.development.example index 511e3d5fd..3023a21a6 100644 --- a/.env.development.example +++ b/.env.development.example @@ -6,7 +6,7 @@ APP_KEY= APP_URL=http://localhost APP_PORT=8000 APP_DEBUG=true -MUX_ENABLED=false +SSH_MUX_ENABLED=false # PostgreSQL Database Configuration DB_DATABASE=coolify diff --git a/app/Livewire/Boarding/Index.php b/app/Livewire/Boarding/Index.php index 0bfcaf729..af05ad767 100644 --- a/app/Livewire/Boarding/Index.php +++ b/app/Livewire/Boarding/Index.php @@ -282,7 +282,7 @@ uZx9iFkCELtxrh31QJ68AAAAEXNhaWxANzZmZjY2ZDJlMmRkAQIDBA== public function validateServer() { try { - config()->set('coolify.mux_enabled', false); + config()->set('constants.ssh.mux_enabled', false); // EC2 does not have `uptime` command, lol instant_remote_process(['ls /'], $this->createdServer, true); diff --git a/app/Models/Server.php b/app/Models/Server.php index 46536ed47..65d70083f 100644 --- a/app/Models/Server.php +++ b/app/Models/Server.php @@ -967,7 +967,7 @@ $schema://$host { public function validateConnection() { - config()->set('coolify.mux_enabled', false); + config()->set('constants.ssh.mux_enabled', false); $server = Server::find($this->id); if (! $server) { diff --git a/bootstrap/helpers/proxy.php b/bootstrap/helpers/proxy.php index c4c15b8fe..127404d4b 100644 --- a/bootstrap/helpers/proxy.php +++ b/bootstrap/helpers/proxy.php @@ -137,6 +137,8 @@ function generate_default_proxy_configuration(Server $server) 'external' => true, ]; }); + // TODO: This should not be null on new servers, but it is. + ray($proxy_type); if ($proxy_type === ProxyTypes::TRAEFIK->value) { $labels = [ 'traefik.enable=true', diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index f6cf9fbe5..0e5e932cf 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -166,7 +166,6 @@ function generateSshCommand(Server $server, string $command) // Check if multiplexing is enabled $muxEnabled = config('constants.ssh.mux_enabled', true); // ray('SSH Multiplexing Enabled:', $muxEnabled)->blue(); - if ($muxEnabled) { // Always use multiplexing when enabled $muxSocket = "/var/www/html/storage/app/ssh/mux/{$server->muxFilename()}"; @@ -212,7 +211,11 @@ function ensureMultiplexedConnection(Server $server) } $muxSocket = "/var/www/html/storage/app/ssh/mux/{$server->muxFilename()}"; - $checkCommand = "ssh -O check -o ControlPath=$muxSocket {$server->user}@{$server->ip} 2>/dev/null"; + $checkCommand = "ssh -O check -o ControlPath=$muxSocket "; + if (data_get($server, 'settings.is_cloudflare_tunnel')) { + $checkCommand .= '-o ProxyCommand="/usr/local/bin/cloudflared access ssh --hostname %h" '; + } + $checkCommand .= " {$server->user}@{$server->ip}"; $process = Process::run($checkCommand); @@ -233,8 +236,12 @@ function ensureMultiplexedConnection(Server $server) $serverInterval = config('constants.ssh.server_interval'); $muxPersistTime = config('constants.ssh.mux_persist_time'); - $establishCommand = "ssh -fNM -o ControlMaster=auto -o ControlPath=$muxSocket -o ControlPersist={$muxPersistTime} " - ."-i {$privateKeyLocation} " + $establishCommand = "ssh -fNM -o ControlMaster=auto -o ControlPath=$muxSocket -o ControlPersist={$muxPersistTime} "; + + if (data_get($server, 'settings.is_cloudflare_tunnel')) { + $establishCommand .= '-o ProxyCommand="/usr/local/bin/cloudflared access ssh --hostname %h" '; + } + $establishCommand .= "-i {$privateKeyLocation} " .'-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ' .'-o PasswordAuthentication=no ' ."-o ConnectTimeout=$connectionTimeout " @@ -305,7 +312,7 @@ function instant_remote_process(Collection|array $command, Server $server, bool $end_time = microtime(true); $execution_time = ($end_time - $start_time) * 1000; // Convert to milliseconds - // ray('SSH command execution time:', $execution_time.' ms')->orange(); + ray('SSH command execution time:', $execution_time.' ms')->orange(); $output = trim($process->output()); $exitCode = $process->exitCode(); diff --git a/config/constants.php b/config/constants.php index c223e6418..906ef3ba2 100644 --- a/config/constants.php +++ b/config/constants.php @@ -6,7 +6,8 @@ return [ 'contact' => 'https://coolify.io/docs/contact', ], 'ssh' => [ - 'mux_enabled' => env('SSH_MUX_ENABLED', true), + // Using MUX + 'mux_enabled' => env('MUX_ENABLED', env('SSH_MUX_ENABLED', true), true), 'mux_persist_time' => env('SSH_MUX_PERSIST_TIME', '1h'), 'connection_timeout' => 10, 'server_interval' => 20, diff --git a/config/coolify.php b/config/coolify.php index 6e284fe9e..f9878fff7 100644 --- a/config/coolify.php +++ b/config/coolify.php @@ -7,7 +7,6 @@ return [ 'self_hosted' => env('SELF_HOSTED', true), 'waitlist' => env('WAITLIST', false), 'license_url' => 'https://licenses.coollabs.io', - 'mux_enabled' => env('MUX_ENABLED', true), 'dev_webhook' => env('SERVEO_URL'), 'is_windows_docker_desktop' => env('IS_WINDOWS_DOCKER_DESKTOP', false), 'base_config_path' => env('BASE_CONFIG_PATH', '/data/coolify'), diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index b26cd5746..65a708acb 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -48,6 +48,7 @@ services: - PUSHER_APP_SECRET - AUTOUPDATE - SELF_HOSTED + - SSH_MUX_ENABLED - SSH_MUX_PERSIST_TIME - FEEDBACK_DISCORD_WEBHOOK - WAITLIST diff --git a/docker-compose.windows.yml b/docker-compose.windows.yml index a1ee1aeea..3f45b62cd 100644 --- a/docker-compose.windows.yml +++ b/docker-compose.windows.yml @@ -45,7 +45,7 @@ services: - PUSHER_APP_SECRET - AUTOUPDATE=true - SELF_HOSTED=true - - MUX_ENABLED=false + - SSH_MUX_ENABLED=false - IS_WINDOWS_DOCKER_DESKTOP=true ports: - "${APP_PORT:-8000}:80" From 16e472da19e8a0ff0146e0aa90eff1b43c856ba6 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 12 Sep 2024 12:16:20 +0200 Subject: [PATCH 4/7] chore: Update constants.ssh.mux_enabled in remoteProcess.php --- bootstrap/helpers/remoteProcess.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index 9c147639a..3b63a5b97 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -197,7 +197,7 @@ function generateSshCommand(Server $server, string $command) function ensureMultiplexedConnection(Server $server) { - if (!(config('coolify.mux_enabled') && config('coolify.is_windows_docker_desktop') == false)) { + if (! (config('constants.ssh.mux_enabled') && config('coolify.is_windows_docker_desktop') == false)) { return; } @@ -268,7 +268,7 @@ function ensureMultiplexedConnection(Server $server) function shouldResetMultiplexedConnection(Server $server) { - if (!(config('coolify.mux_enabled') && config('coolify.is_windows_docker_desktop') == false)) { + if (! (config('constants.ssh.mux_enabled') && config('coolify.is_windows_docker_desktop') == false)) { return false; } @@ -287,7 +287,7 @@ function shouldResetMultiplexedConnection(Server $server) function resetMultiplexedConnection(Server $server) { - if (!(config('coolify.mux_enabled') && config('coolify.is_windows_docker_desktop') == false)) { + if (! (config('constants.ssh.mux_enabled') && config('coolify.is_windows_docker_desktop') == false)) { return; } From 664a990c60b96ebebf863a35520e7ee5193a6e65 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 12 Sep 2024 12:34:09 +0200 Subject: [PATCH 5/7] chore: Update listeners and proxy settings in server form and new server components --- app/Livewire/Server/Form.php | 6 +++++- app/Livewire/Server/New/ByIp.php | 12 +++++------- app/Livewire/Server/Show.php | 8 +++++++- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/app/Livewire/Server/Form.php b/app/Livewire/Server/Form.php index 8a4efb21d..3b3747a81 100644 --- a/app/Livewire/Server/Form.php +++ b/app/Livewire/Server/Form.php @@ -24,7 +24,11 @@ class Form extends Component public $timezones; - protected $listeners = ['serverInstalled', 'revalidate' => '$refresh']; + protected $listeners = [ + 'serverInstalled', + 'refreshServerShow' => 'serverInstalled', + 'revalidate' => '$refresh', + ]; protected $rules = [ 'server.name' => 'required', diff --git a/app/Livewire/Server/New/ByIp.php b/app/Livewire/Server/New/ByIp.php index 5f69835d7..f80152435 100644 --- a/app/Livewire/Server/New/ByIp.php +++ b/app/Livewire/Server/New/ByIp.php @@ -2,10 +2,10 @@ namespace App\Livewire\Server\New; -use App\Enums\ProxyStatus; use App\Enums\ProxyTypes; use App\Models\Server; use App\Models\Team; +use Illuminate\Support\Collection; use Livewire\Component; class ByIp extends Component @@ -40,7 +40,7 @@ class ByIp extends Component public bool $is_build_server = false; - public $swarm_managers = []; + public Collection $swarm_managers; protected $rules = [ 'name' => 'required|string', @@ -102,11 +102,6 @@ class ByIp extends Component 'port' => $this->port, 'team_id' => currentTeam()->id, 'private_key_id' => $this->private_key_id, - 'proxy' => [ - // set default proxy type to traefik v2 - 'type' => ProxyTypes::TRAEFIK->value, - 'status' => ProxyStatus::EXITED->value, - ], ]; if ($this->is_swarm_worker) { $payload['swarm_cluster'] = $this->selected_swarm_cluster; @@ -115,6 +110,9 @@ class ByIp extends Component data_forget($payload, 'proxy'); } $server = Server::create($payload); + $server->proxy->set('status', 'exited'); + $server->proxy->set('type', ProxyTypes::TRAEFIK->value); + $server->save(); if ($this->is_build_server) { $this->is_swarm_manager = false; $this->is_swarm_worker = false; diff --git a/app/Livewire/Server/Show.php b/app/Livewire/Server/Show.php index 0751b186e..a5e94a19a 100644 --- a/app/Livewire/Server/Show.php +++ b/app/Livewire/Server/Show.php @@ -14,7 +14,7 @@ class Show extends Component public $parameters = []; - protected $listeners = ['refreshServerShow' => '$refresh']; + protected $listeners = ['refreshServerShow']; public function mount() { @@ -29,6 +29,12 @@ class Show extends Component } } + public function refreshServerShow() + { + $this->server->refresh(); + $this->dispatch('$refresh'); + } + public function submit() { $this->dispatch('serverRefresh', false); From b5a56892fdcf6f3b4b4224a2d4d9f77523003686 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 12 Sep 2024 12:39:34 +0200 Subject: [PATCH 6/7] chore: Remove unnecessary null check for proxy_type in generate_default_proxy_configuration --- bootstrap/helpers/proxy.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/bootstrap/helpers/proxy.php b/bootstrap/helpers/proxy.php index 127404d4b..c4c15b8fe 100644 --- a/bootstrap/helpers/proxy.php +++ b/bootstrap/helpers/proxy.php @@ -137,8 +137,6 @@ function generate_default_proxy_configuration(Server $server) 'external' => true, ]; }); - // TODO: This should not be null on new servers, but it is. - ray($proxy_type); if ($proxy_type === ProxyTypes::TRAEFIK->value) { $labels = [ 'traefik.enable=true', From 8862b50c9896f1d74fd3d1074758f9ec44ebe73c Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Thu, 12 Sep 2024 12:42:47 +0200 Subject: [PATCH 7/7] chore: Remove unnecessary SSH command execution time logging --- bootstrap/helpers/remoteProcess.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstrap/helpers/remoteProcess.php b/bootstrap/helpers/remoteProcess.php index 3b63a5b97..4ba378e67 100644 --- a/bootstrap/helpers/remoteProcess.php +++ b/bootstrap/helpers/remoteProcess.php @@ -321,7 +321,7 @@ function instant_remote_process(Collection|array $command, Server $server, bool $end_time = microtime(true); $execution_time = ($end_time - $start_time) * 1000; // Convert to milliseconds - ray('SSH command execution time:', $execution_time.' ms')->orange(); + // ray('SSH command execution time:', $execution_time.' ms')->orange(); $output = trim($process->output()); $exitCode = $process->exitCode();