Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Roadrunner Laravel Package

spiral/roadrunner

RoadRunner is a high-performance PHP application server and process manager written in Go. Runs long-lived PHP workers and replaces Nginx+FPM setups. Extensible via plugins (HTTP/2/3, HTTPS, FastCGI), PSR-7/17 compatible, service-friendly.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require spiral/roadrunner-cli
   ./vendor/bin/rr get-binary

Ensure PHP extensions php-curl, php-zip, and php-sockets are enabled.

  1. Configure .rr.yaml:

    version: '3'
    server:
      command: "php worker.php"
    http:
      address: "0.0.0.0:8080"
    
  2. Create a Worker (worker.php):

    use Spiral\RoadRunner;
    use Nyholm\Psr7;
    
    $worker = RoadRunner\Worker::create();
    $psrFactory = new Psr7\Factory\Psr17Factory();
    $httpWorker = new RoadRunner\Http\PSR7Worker($worker, $psrFactory, $psrFactory, $psrFactory);
    
    while ($req = $httpWorker->waitRequest()) {
        $rsp = new Psr7\Response();
        $rsp->getBody()->write('Hello RoadRunner!');
        $httpWorker->respond($rsp);
    }
    
  3. Run:

    ./rr serve -c .rr.yaml
    

First Use Case: Replacing PHP-FPM

Replace your existing Nginx+PHP-FPM setup with RoadRunner’s HTTP server. Configure Nginx to proxy requests to 127.0.0.1:8080 (or your .rr.yaml port). Test with:

curl http://localhost:8080

Implementation Patterns

1. HTTP Server Integration

  • PSR-7 Middleware: Use Laravel’s built-in middleware (e.g., App\Http\Middleware) by wrapping them in PSR-7 adapters.
    use Spiral\RoadRunner\Http\PSR7Worker;
    use Nyholm\Psr7\Factory\Psr17Factory;
    
    $worker = RoadRunner\Worker::create();
    $psrFactory = new Psr17Factory();
    $httpWorker = new PSR7Worker($worker, $psrFactory, $psrFactory, $psrFactory);
    
    while ($req = $httpWorker->waitRequest()) {
        $response = app()->handle($req); // Laravel's PSR-7 handler
        $httpWorker->respond($response);
    }
    
  • Static Files: Leverage RoadRunner’s built-in static middleware in .rr.yaml:
    http:
      address: "0.0.0.0:8080"
      middleware: ["static"]
    

2. Queue Workers

  • Job Processing: Use RoadRunner’s job plugin for Laravel queues (e.g., Redis, Database).
    jobs:
      pool:
        num_workers: 4
        max_jobs: 0
        supervisor: true
    
    use Spiral\RoadRunner\Jobs\JobsWorker;
    
    $jobsWorker = new JobsWorker($worker);
    while ($job = $jobsWorker->wait()) {
        $job->perform(); // Laravel's job handler
    }
    

3. gRPC Services

  • Protobuf Integration: Define gRPC services in .proto files and mount them in .rr.yaml:
    grpc:
      proto: "proto/*.proto"
      listen: "tcp://0.0.0.0:50051"
    
    Generate PHP stubs with protoc and implement handlers in Laravel.

4. Observability

  • OpenTelemetry: Enable metrics/tracing in .rr.yaml:
    otel:
      endpoint: "http://localhost:4317"
      service_name: "laravel-app"
    
    Use Laravel’s spatie/laravel-observability package for integration.

5. Worker Lifecycle

  • Graceful Shutdown: Handle SIGTERM in your worker:
    declare(ticks=1);
    pcntl_signal(SIGTERM, function() {
        $worker->getWorker()->stop();
    });
    

Gotchas and Tips

Configuration Quirks

  1. YAML Syntax:

    • Use quotes for strings with special characters (e.g., "tcp://127.0.0.1:6001").
    • Indentation must be spaces (no tabs). Example:
      http:
        address: "0.0.0.0:8080"
        middleware: ["static", "headers"]
      
  2. Plugin Conflicts:

    • Avoid mixing fileserver and static middleware in the same HTTP config.
    • Ensure jobs and http workers don’t share the same pool unless explicitly configured.
  3. TLS Management:

    • RoadRunner auto-manages TLS certificates if paths are set in .rr.yaml:
      http:
        address: "0.0.0.0:443"
        tls:
          cert: "/path/to/cert.pem"
          key: "/path/to/key.pem"
      

Debugging

  1. Logs:

    • Set logs.level: debug in .rr.yaml for verbose output.
    • Check RoadRunner logs at stderr or via rr logs.
  2. Worker Crashes:

    • Use supervisor: true in job/worker pools to auto-restart failed workers.
    • Check PHP errors with rr logs --worker.
  3. Port Conflicts:

    • Ensure ports in .rr.yaml (e.g., 8080, 6001) aren’t occupied by other services. Use lsof -i :8080 to check.

Performance Tips

  1. Worker Pool Tuning:

    • Adjust num_workers in job/worker pools based on CPU cores (e.g., num_workers: 4 for 4 cores).
    • Set max_jobs: 0 for unlimited concurrency (default) or limit with max_jobs: 100.
  2. HTTP Middleware:

    • Disable unused middleware (e.g., gzip) if not needed to reduce overhead.
    • Order matters: Place headers before static to avoid double-processing.
  3. gRPC Optimization:

    • Use protobuf PHP extension for faster serialization:
      pecl install protobuf
      
    • Enable connection pooling in .rr.yaml:
      grpc:
        pool:
          max_connections: 100
      

Extension Points

  1. Custom Plugins:

    • Write Go plugins using RoadRunner’s plugin SDK. Example: A custom KV store plugin.
    • Load plugins via .rr.yaml:
      plugins:
        my_plugin:
          config: "path/to/config.json"
      
  2. Laravel Service Providers:

    • Bind RoadRunner workers to Laravel’s container:
      $this->app->singleton(RoadRunner\Worker::class, function() {
          return RoadRunner\Worker::create();
      });
      
  3. Dynamic Configuration:

    • Use SIGUSR2 to reload .rr.yaml without restarting:
      kill -USR2 <rr_pid>
      
    • Requires symlinking .rr.yaml to a target file (e.g., ln -s config/rr.yaml .rr.yaml).

Common Pitfalls

  1. EOF Errors:

    • Cause: Missing php-sockets extension or misconfigured worker command.
    • Fix: Verify php --modules | grep sockets and ensure server.command in .rr.yaml matches your worker script.
  2. Queue Stuck Jobs:

    • Cause: Unhandled exceptions in job workers.
    • Fix: Wrap job execution in try-catch and log errors:
      try {
          $job->perform();
      } catch (\Throwable $e) {
          $worker->getWorker()->error($e->getMessage());
          throw $e; // Requeue or mark as failed
      }
      
  3. Temporal Workflows:

    • Ensure NO_PROXY is set if using Temporal behind a proxy:
      temporal:
        env:
          NO_PROXY: "localhost,127.0.0.1"
      
  4. Docker Gotchas:

    • Bind-mount .rr.yaml and ensure volumes are writable.
    • Use user: "www-data" in Dockerfile if running as non-root.

Pro Tips

  • Hot Reloading: Use rr watch to auto-reload workers on file changes (experimental).
  • Metrics: Expose Prometheus metrics via:
    metrics:
      address: "0.0.0.0:2112"
    
    Scrape with http://localhost:2112/metrics.
  • **
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope
anil/file-picker
broqit/fields-ai