Belajar RoadRunner - Framework Integration (Laravel Octane & Symfony)
Episode 6 of 26

Belajar RoadRunner - Framework Integration (Laravel Octane & Symfony)

Mengintegrasikan RoadRunner ke framework populer: menjalankan Laravel dengan Octane server roadrunner, memahami worker count dan warm-up untuk mengurangi cold start, lalu mengatur Symfony Runtime sebagai app server untuk aplikasi Symfony.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Setelah di episode 4-5 kita menulis worker PSR-7 manual, pada episode kali ini kita berhenti menulis dari nol: mengintegrasikan RoadRunner ke framework — Laravel lewat Octane dan Symfony lewat Runtime. Di produksi nyata, hampir tidak ada yang menulis worker manual; mereka memakai framework yang sudah menyediakan abstraksi worker dan koneksi ke RoadRunner.

Mengapa episode ini penting? Karena inilah jalur adopsi paling realistis: kalian punya aplikasi Laravel/Symfony yang sudah berjalan di PHP-FPM, lalu ingin pindah ke long-running tanpa menulis ulang seluruh aplikasi. Framework integration adalah jembatannya.

Laravel Octane dengan RoadRunner

Laravel Octane adalah package resmi Laravel untuk menjalankan aplikasi di app server modern — RoadRunner adalah salah satu servernya, selain Swoole dan FrankenPHP. Install dan aktifkan:

Install Laravel Octane
composer require laravel/octane
php artisan octane:install --server=roadrunner

Perintah ini melakukan tiga hal: menyalin vendor binary RoadRunner ke proyek (via vendor/bin/rr), mempublikasikan file config/octane.php, dan menempatkan file worker rr-worker.php di direktori proyek. Konfigurasi .rr.yaml Laravel biasanya seperti ini:

.rr.yaml untuk Laravel Octane
version: "3"
 
server:
  command: "php vendor/bin/octane"
  relay: pipes
 
http:
  address: 0.0.0.0:8000
  pool:
    num_workers: 8
    max_worker_memory: 128
    max_jobs: 500
  middleware: ["gzip"]
 
logs:
  mode: production
  level: info

Jalankan dengan:

Jalankan Octane RoadRunner
php artisan octane:start --server=roadrunner --host=0.0.0.0 --port=8000

Bagaimana Octane Bekerja

Octane meng-bootstrap aplikasi Laravel sekali di awal worker (membangun kernel, service provider, koneksi DB), lalu setiap request memakai kernel yang sama. Ini perbedaan kunci dengan FPM:

  • Bootstrap sekali: register dan boot service provider terjadi saat worker lahir, bukan per-request.
  • Request lifecycle: setiap request "membersihkan" state yang bisa bocor (via RequestSaw listeners) — misalnya me-reset singleton yang menyimpan data request.
  • Warm-up: daftar code yang dipanaskan di awal sehingga bytecode sudah di-opcache.

Worker Count dan Warm-Up

Kalian bisa mengatur berapa worker dan kapan mereka direstart lewat config/octane.php:

config/octane.php - pengaturan inti
'warm' => [
    'App\Http\Controllers\WelcomeController::class',
    'App\Services\MetricsService::class',
],

Nilai warm berisi class yang "dipanaskan" saat worker start — class di-load ke opcache sehingga request pertama tidak harus me-load-nya. Kombinasi num_workers, max_jobs, dan warm menentukan trade-off memory vs latensi cold start; kita eksperimen lebih jauh di episode 20.

Warning

Saat pindah ke Octane, ada kelas/singleton yang tidak boleh menyimpan state request (misalnya menyimpan user di property class). State harus selalu berbasis request, session, atau store eksternal. Daftar lengkap concern ini dibahas di episode 14.

Symfony dengan RoadRunner Runtime

Untuk Symfony, ada Symfony Runtime — mekanisme alternatif index.php yang memakai RoadRunner sebagai runner. Install:

Install Symfony Runtime untuk RoadRunner
composer require symfony/runtime spirals/roadrunner-bundle

Package spirals/roadrunner-bundle (dari Spiral) menyediakan integrasi penuh: otomatis membuat worker, mengatur kernel, dan menghubungkan plugin ekosistem (KV, queue, dll) ke service Symfony. Entry point-nya bukan index.php biasa:

rr-worker.php - entry Symfony
<?php
 
use App\Kernel;
use Spiral\RoadRunner\Worker;
use Spiral\RoadRunner\Http\PSR7Worker;
use Nyholm\Psr7\Factory\Psr17Factory;
use Symfony\Bridge\PsrHttpMessage\Factory\PsrHttpFactory;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\KernelInterface;
 
require __DIR__ . '/vendor/autoload.php';
 
$kernel = new Kernel('prod', false);
$kernel->boot();
 
$psr7 = new PSR7Worker(
    Worker::create(),
    new Psr17Factory(),
    new Psr17Factory(),
    new Psr17Factory()
);
 
while ($request = $psr7->waitRequest()) {
    try {
        $httpFactory = new PsrHttpFactory($psr17, $psr17, $psr17, $psr17);
        $sfRequest = $httpFactory->createRequest($request);
        $response = $kernel->handle($sfRequest);
        $psr7->respond($httpFactory->createResponse($response));
        $kernel->terminate($sfRequest, $response);
    } catch (\Throwable $e) {
        $psr7->getWorker()->error((string) $e);
    }
}

Perhatikan polanya: kernel di-boot sekali di luar loop, lalu setiap request diproses dengan handle()/terminate() — sama seperti pola Octane. Config .rr.yaml cukup mengarahkan server.command ke php rr-worker.php.

Memilih Antara Keduanya

AspekLaravel OctaneSymfony Runtime
Package kuncilaravel/octanesymfony/runtime + spirals/roadrunner-bundle
Entry workerOtomatis (php vendor/bin/octane)Manual rr-worker.php
Integrasi plugin RRVia Octane + facadeVia bundle (DI)
Kalibrasiphp artisan octane:statusLog runtime
Cocok untukTim LaravelTim Symfony / Spiral

Kedua jalur memberi hasil yang sama: aplikasi framework berjalan sebagai worker persistent di bawah RoadRunner, dengan kontrol pool yang sama dari .rr.yaml.

Penutup

Pada episode 6 ini, kalian telah mengintegrasikan RoadRunner ke kedua framework mainstream PHP.

Inti yang harus dibawa pulang:

  • Laravel: php artisan octane:install --server=roadrunner lalu octane:start.
  • Symfony: symfony/runtime + spirals/roadrunner-bundle, boot kernel sekali di luar loop.
  • Bootstrap sekali, request lifecycle per-request — itulah model long-running.
  • config/octane.php dan blok pool mengatur worker count dan warm-up.
  • Waspadai state request-scoped yang bocor antar request.

Di episode 7 selanjutnya, kita membuka "jalur belakang" RoadRunner: RPC & Goridge — protokol komunikasi Go↔PHP yang dipakai semua plugin, dengan praktik memanggil method dari Go ke PHP dan sebaliknya. Sampai jumpa di episode 7!

Belajar RoadRunner - Framework Integration (Laravel Octane & Symfony) | Belajar RoadRunner