From b38a651a08862b1e2576257f8c700dea947eac97 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 5 Aug 2024 13:45:24 +0200 Subject: [PATCH] feat: coolify init should cleanup stuck networks in proxy --- app/Console/Commands/Init.php | 39 +++++++++++++++++++++++++++++++++-- bootstrap/helpers/proxy.php | 15 ++++++++++++-- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/app/Console/Commands/Init.php b/app/Console/Commands/Init.php index 4a276cfc4..a2e31e779 100644 --- a/app/Console/Commands/Init.php +++ b/app/Console/Commands/Init.php @@ -16,7 +16,7 @@ use Illuminate\Support\Facades\Http; class Init extends Command { - protected $signature = 'app:init {--full-cleanup} {--cleanup-deployments}'; + protected $signature = 'app:init {--full-cleanup} {--cleanup-deployments} {--cleanup-proxy-networks}'; protected $description = 'Cleanup instance related stuffs'; @@ -36,7 +36,7 @@ class Init extends Command $full_cleanup = $this->option('full-cleanup'); $cleanup_deployments = $this->option('cleanup-deployments'); - + $cleanup_proxy_networks = $this->option('cleanup-proxy-networks'); $this->replace_slash_in_environment_name(); if ($cleanup_deployments) { echo "Running cleanup deployments.\n"; @@ -44,9 +44,16 @@ class Init extends Command return; } + if ($cleanup_proxy_networks) { + echo "Running cleanup proxy networks.\n"; + $this->cleanup_unused_network_from_coolify_proxy(); + + return; + } if ($full_cleanup) { // Required for falsely deleted coolify db $this->restore_coolify_db_backup(); + $this->cleanup_unused_network_from_coolify_proxy(); $this->cleanup_in_progress_application_deployments(); $this->cleanup_stucked_helper_containers(); $this->call('cleanup:queue'); @@ -75,6 +82,34 @@ class Init extends Command $this->call('cleanup:stucked-resources'); } + private function cleanup_unused_network_from_coolify_proxy() + { + ray()->clearAll(); + $servers = Server::all(); + foreach ($servers as $server) { + if (! $server->isFunctional()) { + continue; + } + if (! $server->isProxyShouldRun()) { + continue; + } + ['networks' => $networks, 'allNetworks' => $allNetworks] = collectDockerNetworksByServer($server); + $removeNetworks = $allNetworks->diff($networks); + $commands = collect(); + foreach ($removeNetworks as $network) { + $out = instant_remote_process(["docker network inspect -f json $network | jq '.[].Containers | if . == {} then null else . end'"], $server, false); + if (empty($out)) { + $commands->push("docker network disconnect $network coolify-proxy >/dev/null 2>&1 || true"); + $commands->push("docker network rm $network >/dev/null 2>&1 || true"); + } + } + if ($commands->isNotEmpty()) { + echo "Cleaning up unused networks from coolify proxy\n"; + instant_remote_process($commands, $server, false); + } + } + } + private function restore_coolify_db_backup() { try { diff --git a/bootstrap/helpers/proxy.php b/bootstrap/helpers/proxy.php index dccfaeb38..c8202af2d 100644 --- a/bootstrap/helpers/proxy.php +++ b/bootstrap/helpers/proxy.php @@ -24,6 +24,7 @@ function collectProxyDockerNetworksByServer(Server $server) } function collectDockerNetworksByServer(Server $server) { + $allNetworks = collect([]); if ($server->isSwarm()) { $networks = collect($server->swarmDockers)->map(function ($docker) { return $docker['network']; @@ -34,11 +35,13 @@ function collectDockerNetworksByServer(Server $server) return $docker['network']; }); } + $allNetworks = $allNetworks->merge($networks); // Service networks foreach ($server->services()->get() as $service) { if ($service->isRunning()) { $networks->push($service->networks()); } + $allNetworks->push($service->networks()); } // Docker compose based apps $docker_compose_apps = $server->dockerComposeBasedApplications(); @@ -46,6 +49,7 @@ function collectDockerNetworksByServer(Server $server) if ($app->isRunning()) { $networks->push($app->uuid); } + $allNetworks->push($app->uuid); } // Docker compose based preview deployments $docker_compose_previews = $server->dockerComposeBasedPreviewDeployments(); @@ -61,23 +65,30 @@ function collectDockerNetworksByServer(Server $server) } $network = "{$application->uuid}-{$pullRequestId}"; $networks->push($network); + $allNetworks->push($network); } $networks = collect($networks)->flatten()->unique(); + $allNetworks = $allNetworks->flatten()->unique(); if ($server->isSwarm()) { if ($networks->count() === 0) { $networks = collect(['coolify-overlay']); + $allNetworks = collect(['coolify-overlay']); } } else { if ($networks->count() === 0) { $networks = collect(['coolify']); + $allNetworks = collect(['coolify']); } } - return $networks; + return [ + 'networks' => $networks, + 'allNetworks' => $allNetworks, + ]; } function connectProxyToNetworks(Server $server) { - $networks = collectDockerNetworksByServer($server); + ['networks' => $networks] = collectDockerNetworksByServer($server); if ($server->isSwarm()) { $commands = $networks->map(function ($network) { return [