Skip to content

Instantly share code, notes, and snippets.

@pascalbaljet
Last active July 8, 2024 18:12
Show Gist options
  • Save pascalbaljet/ccc2c3c5b8cda91fa20b0ced588067e4 to your computer and use it in GitHub Desktop.
Save pascalbaljet/ccc2c3c5b8cda91fa20b0ced588067e4 to your computer and use it in GitHub Desktop.

Revisions

  1. pascalbaljet revised this gist Aug 24, 2022. 1 changed file with 1 addition and 0 deletions.
    1 change: 1 addition & 0 deletions SwapOctaneServer.php
    Original file line number Diff line number Diff line change
    @@ -71,6 +71,7 @@ private function start($server)
    {
    $this->info('Start server: ' . $server);

    // make sure there's no dangling daemon
    $this->stop($server);

    $this->forgeApi->createDaemon($this->serverId, [
  2. pascalbaljet revised this gist Aug 24, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion SwapOctaneServer.php
    Original file line number Diff line number Diff line change
    @@ -76,7 +76,7 @@ private function start($server)
    $this->forgeApi->createDaemon($this->serverId, [
    "command" => "bash start-{$server}-server.sh",
    "user" => "forge",
    "directory" => "/home/forge/website.com/current",
    "directory" => "/home/forge/website.com/current", // symbolic link
    ]);

    $port = $server === static::BLUE ? $this->bluePort : $this->greenPort;
  3. pascalbaljet created this gist Aug 24, 2022.
    127 changes: 127 additions & 0 deletions SwapOctaneServer.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,127 @@
    <?php

    namespace App\Console\Commands;

    use Illuminate\Console\Command;
    use Illuminate\Console\Concerns\CallsCommands;
    use Illuminate\Support\Facades\Http;
    use Laravel\Forge\Forge;
    use Laravel\Forge\Resources\Daemon;

    class SwapOctaneServer extends Command
    {
    use CallsCommands;

    private Forge $forgeApi;
    private $serverId;
    private $siteId;
    private $bluePort;
    private $greenPort;

    const BLUE = 'blue';
    const GREEN = 'green';

    /**
    * The name and signature of the console command.
    *
    * @var string
    */
    protected $signature = 'octane:swap-server';

    /**
    * The console command description.
    *
    * @var string
    */
    protected $description = 'Start a new Octane daemon and swap the port in the nginx config';

    /**
    * Execute the console command.
    *
    * @return int
    */
    public function handle(Forge $forge)
    {
    $this->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);

    $this->stop($server);

    $this->forgeApi->createDaemon($this->serverId, [
    "command" => "bash start-{$server}-server.sh",
    "user" => "forge",
    "directory" => "/home/forge/website.com/current",
    ]);

    $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));
    }
    }
    }
    2 changes: 2 additions & 0 deletions start-blue-server.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    export OCTANE_STATE_FILE=/home/forge/website.com/shared/storage/logs/octane-server-state-blue.json
    php8.0 artisan octane:start --port=8001
    2 changes: 2 additions & 0 deletions start-green-server.sh
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,2 @@
    export OCTANE_STATE_FILE=/home/forge/website.com/shared/storage/logs/octane-server-state-green.json
    php8.0 artisan octane:start --port=8002