forgeApi = $forge; $this->serverId = config('services.forge.server_id'); $this->siteId = config('services.forge.site_id'); $this->bluePort = config('services.forge.blue_port'); // 8001 $this->greenPort = config('services.forge.green_port'); // 8002 $nginxPort = $this->getNginxPort(); $this->info('Current nginx port: ' . $nginxPort); $blueIsActive = $nginxPort === $this->bluePort; $this->start($blueIsActive ? static::GREEN : static::BLUE); $this->stop($blueIsActive ? static::BLUE : static::GREEN); } private function getNginxPort(): int { $config = $this->forgeApi->siteNginxFile($this->serverId, $this->siteId); preg_match('/(proxy_pass http:\/\/127.0.0.1:)(\d+)\$/', $config, $matches); return $matches[2]; } private function start($server) { $this->info('Start server: ' . $server); // make sure there's no dangling daemon $this->stop($server); $this->forgeApi->createDaemon($this->serverId, [ "command" => "bash start-{$server}-server.sh", "user" => "forge", "directory" => "/home/forge/website.com/current", // symbolic link ]); $port = $server === static::BLUE ? $this->bluePort : $this->greenPort; $this->info('Polling server on port: ' . $server); retry( 300, fn () => Http::timeout(1) ->connectTimeout(1) ->get("127.0.0.1:{$port}"), 100 ); $this->updateNginxConfig($port); } private function updateNginxConfig($newPort) { $this->info('Updating nginx config to port: ' . $newPort); $config = $this->forgeApi->siteNginxFile($this->serverId, $this->siteId); $config = preg_replace_callback('/(proxy_pass http:\/\/127.0.0.1:)(\d+)\$/', function ($matches) use ($newPort) { return $matches[1] . $newPort . '$'; }, $config); $this->forgeApi->updateSiteNginxFile($this->serverId, $this->siteId, $config); } private function stop($server) { $forge = $this->forgeApi; /** @var Daemon $daemon */ $daemon = collect($forge->daemons($this->serverId))->firstWhere('command', "bash start-{$server}-server.sh"); if ($daemon) { $this->info('Wait for pending requests on server: ' . $server); usleep(config('octane.max_execution_time') * 1000 * 1000); $this->info('Stop server: ' . $server); rescue(fn () => $forge->deleteDaemon($daemon->serverId, $daemon->id)); } } }