## 1. Project Overview & Quickstart (roadrunner-server/roadrunner)

## File: README.md

<a href="https://roadrunner.dev" target="_blank">
  
    
    
  
</a>


RoadRunner is an open-source (MIT licensed) high-performance PHP application server, process manager written in Go and powered with plugins ❤️.
It supports running as a service with the ability to extend its functionality on a per-project basis with plugins.


# Features

**RoadRunner** features a range of plugins, including `HTTP(S)/2/3` and `fCGI` servers that are compatible with PSR-7/PSR-17 standards. This is just one of its many capabilities. It serves as an effective alternative to the traditional Nginx+FPM setup, providing improved performance and more flexibility. Its extensive plugin options go far beyond just `HTTP(S)/2/3` and `fCGI` servers, offering a broad range of functionalities:
- Queue drivers: RabbitMQ, Kafka, SQS, Beanstalk, NATS, In-Memory.
- KV drivers: Redis, Memcached, BoltDB, In-Memory.
- OpenTelemetry protocol support (`gRPC`, `http`, `jaeger`).
- [Workflow engine](https://github.com/temporalio/sdk-php) via [Temporal](https://temporal.io).
- `gRPC` server. For increased speed, the `protobuf` extension can be used.
- `HTTP(S)/2/3` and `fCGI` servers features **automatic TLS management**, **103 Early Hints** support and middleware like: Static, Headers, gzip, prometheus (metrics), send (x-sendfile), OTEL, proxy_ip_parser, etc.
- Embedded distribute lock plugin which manages access to shared resources.
- Metrics server (you might easily expose your own).
- WebSockets and Broadcast via [Centrifugo](https://centrifugal.dev) server.
- Systemd-like services manager with auto-restarts, execution time limiter, etc.
- Production-ready.
- And more 😉

# Join our discord server: [Link](https://discord.gg/TFeEmCs)



# Installation

The easiest way to get the latest RoadRunner version is to use one of the pre-built release binaries, which are available for
OSX, Linux, FreeBSD, and Windows. Instructions for using these binaries are on the GitHub [releases page](https://github.com/roadrunner-server/roadrunner/releases).

## Docker:

To get the roadrunner binary file you can use our docker image: `ghcr.io/roadrunner-server/roadrunner:2025.X.X` (more information about
image and tags can be found [here](https://github.com/roadrunner-server/roadrunner/pkgs/container/roadrunner)).

```dockerfile
FROM ghcr.io/roadrunner-server/roadrunner:2025.X.X AS roadrunner
FROM php:8.3-cli

COPY --from=roadrunner /usr/bin/rr /usr/local/bin/rr

# USE THE RR
```

Configuration located in the `.rr.yaml` file ([full sample](https://github.com/roadrunner-server/roadrunner/blob/master/.rr.yaml)):


## Installation via Composer
You can also install RoadRunner automatically using the command shipped with the composer package, run:

```bash
composer require spiral/roadrunner-cli
./vendor/bin/rr get-binary
```

Server binary will be available at the root of your project.

> **Note**
>
> PHP's extensions `php-curl` and `php-zip` are required to download RoadRunner automatically.
> PHP's extensions `php-sockets` need to be installed to run roadrunner.
> Check with `php --modules` your installed extensions.


## Installation option for the Debian-derivatives (Ubuntu, Mint, MX, etc)

```bash
wget https://github.com/roadrunner-server/roadrunner/releases/download/v2025.X.X/roadrunner-2025.X.X-linux-amd64.deb
sudo dpkg -i roadrunner-2025.X.X-linux-amd64.deb
```

## Download the latest release via curl:
```bash
curl --proto '=https' --tlsv1.2 -sSf  https://raw.githubusercontent.com/roadrunner-server/roadrunner/master/download-latest.sh | sh
```

## MacOS using [Homebrew](https://brew.sh/):
```bash
brew install roadrunner
```

## Windows using [Chocolatey](https://community.chocolatey.org/):
```bash
choco install roadrunner
```

---

Configuration can be located in `.rr.yaml` file ([full sample](https://github.com/roadrunner-server/roadrunner/blob/master/.rr.yaml)):

```yaml
version: '3'

rpc:
  listen: tcp://127.0.0.1:6001

server:
  command: "php worker.php"

http:
  address: "0.0.0.0:8080"

logs:
  level: error
```

> Read more in [Documentation](https://docs.roadrunner.dev).

Example Worker:
--------

```php
<?php

use Spiral\RoadRunner;
use Nyholm\Psr7;

include "vendor/autoload.php";

$worker = RoadRunner\Worker::create();
$psrFactory = new Psr7\Factory\Psr17Factory();

$worker = new RoadRunner\Http\PSR7Worker($worker, $psrFactory, $psrFactory, $psrFactory);

while ($req = $worker->waitRequest()) {
    try {
        $rsp = new Psr7\Response();
        $rsp->getBody()->write('Hello world!');

        $worker->respond($rsp);
    } catch (\Throwable $e) {
        $worker->getWorker()->error((string)$e);
    }
}
```

> [!IMPORTANT]
> If you see the `EOF` error, check that you have installed the PHP packages from [this step](https://github.com/roadrunner-server/roadrunner#installation-via-composer).
> If this does not help, try to execute the command `php worker.php` directly and check the output.

---

### Available Plugins: [link](https://docs.roadrunner.dev)

Run:
----
To run application server:

```
$ ./rr serve -c .rr.yaml
```

License:
--------
The MIT License (MIT). Please see [`LICENSE`](./LICENSE) for more information. Maintained
by [Spiral Scout](https://spiralscout.com).

## Contributors

Thanks to all the people who already contributed!

<a href="https://github.com/roadrunner-server/roadrunner/graphs/contributors">
  
</a>

---

## File: schemas/readme.md

# Schemas

This directory contains public schemas for the most important parts of application.

**Do not rename or remove this directory or any file or directory inside.**

- You can validate existing config file using the following command from the project root.

 ```bash
docker run --rm -v "$(pwd):/src" -w "/src" node:22-alpine sh -c \
     "cd schemas && npm install && node test.js"
 ```

## 2. Official Technical Reference & Guides (roadrunner-server/roadrunner-docs)

## File: README.md

# NEW DOCS ARE HERE: [LINK](https://github.com/roadrunner-server/docs)




RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager.
It supports running as a service with the ability to extend its functionality on a per-project basis.

## Contributors

Thanks to all the people who already contributed!

<a href="https://github.com/roadrunner-server/roadrunner-docs/graphs/contributors">
  
</a>

---

## File: docs/en/lab/dashboards/dashboards.md

# RoadRunner Dashboards

Grafana's dashboards for the RR (including temporal) installations. More info about the available metrics is here: [link](../metrics.md)

## gRPC dashboard

This dashboard contains gRPC plugin metrics: [link](grpc.md)

## HTTP dashboard

This dashboard contains http plugin metrics: [link](http.md)

## JOBS dashboard

This dashboard contains jobs plugin metrics: [link](jobs.md)

## Temporal dashboard

[This](temporal.md) dashboard contains temporal (RR part) plugin metrics.
Official repo with the temporal metrics available here: https://github.com/temporalio/dashboards

---

## File: docs/en/lab/dashboards/grpc.md

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

## File: docs/en/lab/dashboards/http.md

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

## File: docs/en/lab/dashboards/jobs.md

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

## File: docs/en/lab/dashboards/temporal.md

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

## File: docs/en/lab/access-logs.md

# Logging — HTTP Access logs

RoadRunner has the HTTP access logs support, which provides detailed information about incoming HTTP requests and
responses.

> **Note**
> This feature is disabled by default, but it can be easily enabled by configuring the HTTP server.

## Enabling HTTP Access Logs

To enable HTTP access logs in RoadRunner, you need to modify the configuration file of the HTTP server.

**Here's an example configuration file:**

```yaml .rr.yaml
version: "3"

http:
  address: 127.0.0.1:8000
  access_logs: true
  # ...
```

Once enabled, RoadRunner will log the following information for each incoming HTTP request:

- `method` - HTTP method of the request
- `remote_addr` - Remote address of the client
- `bytes_sent` - Content length of the response
- `http_host` - Host name of the server
- `request` - Query string of the request
- `time_local` - Local time of the server in Common Log Format
- `request_length` - Request body size including headers in bytes (content-len + size of all headers) in bytes. Max allowed headers
  size for the RR is 1MB.
- `request_time` - Request processing time in seconds with a milliseconds' resolution
- `status` - HTTP response status
- `http_user_agent` - HTTP user [agent](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/User-Agent) string of the client
- `http_referer` - HTTP [referer](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referer) string of the client

---

## File: docs/en/lab/applogger.md

# Logging — Application logger

The RoadRunner server has a useful `app-logger` plugin that allows users to send logs from their applications to the
RoadRunner server using an RPC interface. This plugin is enabled by default and does not require any additional
configurations. It can be used to observe all application and server logs in one place. This is especially useful when
debugging and monitoring applications.

> **Note**
> It will send raw messages to the RoadRunner `STDERR`

## Configuration

The `logs` section in the RoadRunner configuration file allows you to configure logging behavior for their application.

```yaml .rr.yaml
rpc:
  listen: tcp://127.0.0.1:6001

logs:
  channels:
    app:
      level: info
```

> **Warning**
> To interact with the RoadRunner app-logger plugin, you will need to have the RPC defined in the rpc configuration
> section. You can refer to the documentation page [here](../php/rpc.md) to learn more about the configuration.

The `level` key is used to specify the logging level for this channel. This means that only log messages with a severity
level of info or higher will be sent to this channel.

> **Note**
> Read more about logging in the [Logging — Logger](./logger.md) section.

## PHP client

The RoadRunner `app-logger` plugin comes with a convenient PHP package that simplifies the process of integrating the
plugin with your PHP application.

### Installation

To get started, you can install the package via Composer using the following command:

```terminal
composer require roadrunner-php/app-logger
```

### Usage

After the installation, you can create an instance of the `RoadRunner\Logger\Logger` class, which will allow you to use
the available class methods.

**Here is an example:**

```php
use Spiral\Goridge\RPC\RPC;
use RoadRunner\Logger\Logger;

$rpc = RPC::create('tcp://127.0.0.1:6001');

$logger = new Logger($rpc);

$logger->info('Hello, RoadRunner!');
$logger->warning('Something might be wrong...');
$logger->error('Houston, we have a problem!');
```

> **Note**
> You can refer to the documentation page [here](../php/rpc.md) to learn more about creating the RPC connection.

### Available methods

- `debug(string): void`: Sends a debug log message to the server
- `error(string): void`: Sends an error log message to the server
- `info(string): void`: Sends an info log message to the server
- `warning(string): void`: Sends a warning log message to the server
- `log(string): void`: Sends a log message directly to the `STDERR` of the server

## API

### RPC API

RoadRunner provides an RPC API, which allows you to manage app-logger in your applications using remote
procedure calls. The RPC API provides a set of methods that map to the available methods of
the `RoadRunner\Logger\Logger`class in PHP.

> **Note**
> All methods accept a `string` (which will be log message) as a first argument and a `bool` placeholder for the second
> arg.

#### Error

Method sends an `error` log message with the specified message to the RoadRunner server.

```go
func (r *RPC) Error(in string, _ *bool) error {}
```

#### Info

Method sends an `info` log message with the specified message to the RoadRunner server.

```go
func (r *RPC) Info(in string, _ *bool) error {}
```

#### Warning

Method sends a `warning` log message with the specified message to the RoadRunner server.

```go
func (r *RPC) Warning(in string, _ *bool) error {}
```

#### Debug

Method sends a `debug` log message with the specified message to the RoadRunner server.

```go
func (r *RPC) Debug(in string, _ *bool) error {}
```

#### Log

Method sends a log message with the specified message directly to the `STDERR` of the RoadRunner server.

```go
func (r *RPC) Log(in string, _ *bool) error {}
```

---

## File: docs/en/lab/health.md

# Observability — Health and Readiness checks

The RoadRunner Status Plugin provides a healthcheck status for various plugins such
as `http`, `grpc`, `temporal`, `jobs` and `centrifuge`. This plugin provides an easy way to check the condition of the
workers and ensure that they are ready to serve requests.

## Activation of the Status Plugin

To activate the health/readiness checks endpoint, include a `status` section in your configuration file.

Here is an example:

```yaml .rr.yaml
version: "3"

status:
  address: 127.0.0.1:2114
```

The above configuration sets the address to `127.0.0.1:2114`. This is the address that the plugin will listen to. You
can change the address to any IP address and port number of your choice.

To access the health check, you need to use the following URL: http://127.0.0.1:2114/health?plugin=http. This URL will
return the health status of the http plugin.

> **Note**
> You can specify multiple plugins by separating them with a comma. For example, to check the health status of both the
> http and grpc plugins, you can use the following URL: http://127.0.0.1:2114/health?plugin=http&plugin=grpc.

The health check endpoint will return `HTTP 200` if there is at least one worker ready to serve requests. If there are
no workers ready to service requests, the endpoint will return `HTTP 500`. If there are any other errors, the endpoint
will also return `HTTP 500`.

The readiness check endpoint will return `HTTP 200` if there is at least one worker ready to take the request (i.e., not
currently busy with another request). If there is no worker ready or all workers are busy, the endpoint will return 
`HTTP 500` status code (you can override this too).

## Customizing the Not-Ready Status Code

By default, Status Plugin uses a `500` status code. However, you can replace this status code with a custom one.

To achieve this, utilize the `unavailable_status_code` option:

```yaml .rr.yaml
version: "3"

status:
  address: 127.0.0.1:2114
  unavailable_status_code: 501
```

## Jobs plugin pipelines check

In addition to checking the health status of the workers, you can also examine the pipelines in the Jobs plugin using
the following URL: http://127.0.0.1:2114/jobs

This URL will return the status of the pipelines in the Jobs plugin. The output will be in the following format:

```
plugin: jobs: pipeline: test-1 | priority: 13 | ready: true | queue: test-1 | active: 0 | delayed: 0 | reserved: 0 | driver: memory | error:  
```

## Use cases

The health check endpoint serves the following purposes:

### Kubernetes Readiness and Liveness Probes

In Kubernetes, you can use readiness and liveness probes to check the health of your application. It can be used as a
readiness or liveness probe to ensure that your application is ready to serve requests. You can configure Kubernetes to
check the health check endpoint and take appropriate action if the endpoint returns an error.

**Read more [here](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/)**

### AWS Target Group Health Checks

If you are using AWS Elastic Load Balancer, you can use it as a health check for your target group. You can configure
the target group to check the health check endpoint and take appropriate action if the endpoint returns an error.

**Read more [here](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/target-group-health-checks.html)**

### GCE Load Balancing Health Checks

If you are using Google Cloud Platform, you can use it as a health check for your load balancer. You can configure the
load balancer to check the health check endpoint and take appropriate action if the endpoint returns an error.

**Read more [here](https://cloud.google.com/load-balancing/docs/health-checks)**

---

## File: docs/en/lab/logger.md

# Logging — Logger

Logger Plugin is responsible for collecting logs from server plugins and PHP application workers' `STDERR` and
displaying them in the RoadRunner `STDERR`/`STDOUT`. It comes with a variety of options that allow you to customize the
way your application logs are collected and displayed.

### Configuration

### Modes

```yaml
logs:
  mode: production
```

There are three available modes:

1. `production` - This mode uses logger settings that are optimized for production usage.
2. `development` - This mode is enabled by default and is designed for use during application development. In
   development mode, DPanicLevel logs panic, console colors are used, and logs are written to standard error. Sampling
   is disabled, and stack traces are automatically included on logs of WarnLevel and above.
3. `raw` - This mode displays messages as raw output without any formatting. This mode is useful in production
   environments where you need to parse logs programmatically.

> **Note**
> Use `production` mode in production environments. It is optimized for production usage.

### Encoding

Logger supports two types of encoding, `console` and `json`. By default, `console` encoding is used, which outputs logs
in a friendly format. JSON encoding, on the other hand, returns messages in a JSON Structured logging format. This
format presents log messages as JSON objects with key-value pairs representing each log message field, making them more
machine-readable and easier to process programmatically. JSON encoding is also better suited for production usage.

```yaml
logs:
  encoding: console
```

### Level

The level is used to specify the logging level. This means that only log messages with a severity level will be sent to
this channel. Available levels include `panic`, `error`, `warn`, `info`, and `debug`.

```yaml
logs:
  level: info
```

> **Note**
> The default level is `debug`.

### Output

By default, RoadRunner sends logs to `STDERR`. However, you can configure RoadRunner to send logs to `STDOUT` by using
the output key.

```yaml
logs:
  output: stdout
```

### Line Endings

It allows configuring custom line endings for the logger. By default, the plugin uses `\n` as the line ending. Note that the `\n` is a forced default. This means that if the value is empty, RoadRunner will still use `\n`. So no empty line endings are allowed.

```yaml
logs:
  line_ending: "\r\n"
```

### Channels

In addition, you can configure each plugin log messages individually using the `channels` section. It allows you to
customize the logger settings for each plugin independently. You can disable logging for a particular plugin or change
its log mode and output destination.

```yaml
version: "3"

logs:
  encoding: console # default value
  level: info
  mode: none # disable server logging. Also `off` can be used.
  channels:
    http:
      mode: production
      output: http.log
```

## File Logger

It is possible to redirect channels or the entire log output to a file. To use the file logger, you need to set
the `file_logger_options.log_output` option to the filename where you want to write the logs.

### Entire log

```yaml
logs:
  mode: development
  file_logger_options:
    log_output: "test.log"
    max_size: 10
    max_age: 24
    max_backups: 10
    compress: true
```

### Channel

You can also redirect a specific channel to a file. To do this, you need to specify the channel name in the `channels`

```yaml
logs:
  mode: development
  level: debug
  channels:
    http:
      file_logger_options:
        log_output: "test.log"
        max_size: 10
        max_age: 24
        max_backups: 10
        compress: true
```

### Available options

1. `log_output`: Filename is the file to write logs to in the same directory. It uses `processname-lumberjack.log` in
   `os.TempDir()` if empty.
2. `max_size`: is the maximum size in megabytes of the log file before it gets rotated. It defaults to 100 megabytes.
3. `max_age`: is the maximum number of days to retain old log files based on the timestamp encoded in their filename.
   Note that a day is defined as 24 hours and may not exactly correspond to calendar days due to daylight savings, leap
   seconds, etc. The default is not to remove old log files based on age.
4. `max_backups`: is the maximum number of old log files to retain. The default is to retain all old log files (though
   MaxAge may still cause them to get deleted.)
5. `compress`: determines if the rotated log files should be compressed using gzip. The default is not to perform
   compression.
6. `log_ending`: line ending to use in the logger. Default is new line - `\n`.

## ZapLogger

Feel free to register your own [ZapLogger](https://github.com/uber-go/zap) extensions.