RoadRunner
What is RoadRunner?
RoadRunner is a high-performance PHP application server written in Go, an alternative to PHP-FPM for keeping long-running PHP worker processes alive between requests instead of bootstrapping your app from scratch every time. It's a supported driver for Laravel Octane. The Laradock image pulls the official rr binary and layers it on a PHP-CLI Alpine image with the sockets and opcache extensions installed, then serves your mounted app via its .rr.yaml config (CMD ["rr", "serve"]).
Start RoadRunner
- Laradock CLI
- Docker Compose
./laradock start roadrunner
docker compose up -d roadrunner
RoadRunner is self-contained: it doesn't declare a dependency on php-fpm or a web server, it serves your app directly via the rr binary.
Stop RoadRunner
- Laradock CLI
- Docker Compose
./laradock stop roadrunner
docker compose stop roadrunner
Configuration
All settings live in roadrunner/defaults.env and can be overridden by adding the same line to your own .env:
| Variable | Default | What it does |
|---|---|---|
ROADRUNNER_VERSION | 2025.1.15 | Version of the official RoadRunner image the rr binary is pulled from (build arg). |
ROADRUNNER_HTTP_PORT | 8090 | Host-side port mapped to container port 8080. |
The container also builds against LARADOCK_PHP_VERSION (Laradock's shared PHP_VERSION) and CHANGE_SOURCE, and adds an extra_hosts entry for dockerhost pointing at DOCKER_HOST_IP.
Set up Octane with RoadRunner
- In your Laravel app, install Octane with the RoadRunner driver:
This generates acomposer require laravel/octane spiral/roadrunner-cliphp artisan octane:install --server=roadrunner
.rr.yamlfile. Set its HTTP address to0.0.0.0:8080so it's reachable from outside the container. - Start the container:
- Laradock CLI
- Docker Compose
./laradock start roadrunner
docker compose up -d roadrunner
- Your app is served on the host at
ROADRUNNER_HTTP_PORT(8090by default), mapped to container port8080.
Change the exposed port
Set the new host-side port in your .env:
ROADRUNNER_HTTP_PORT=8095
Then recreate the container so the new port mapping takes effect:
- Laradock CLI
- Docker Compose
./laradock start roadrunner
docker compose up -d roadrunner
Reload workers after a code change
RoadRunner boots your app once per worker and keeps it in memory between requests (that's the entire point of Octane workers), so unlike PHP-FPM it does not pick up code changes on the next request automatically. Reset the worker pool from inside the container instead of restarting it:
- Laradock CLI
- Docker Compose
./laradock enter roadrunner
rr reset
docker compose exec roadrunner bash
rr reset
This restarts the worker pool in place (no dropped connections, no container restart), so freshly deployed code is picked up on the next request. It needs an rpc: listen: block in your .rr.yaml (added automatically by php artisan octane:install --server=roadrunner); without it rr reset has nothing to connect to.
Common issues
- Container starts but nothing responds.
.rr.yamlneeds its HTTP address set to0.0.0.0:8080, not127.0.0.1:8080, otherwise it only listens inside its own network namespace. .rr.yamlnot found. It's generated byphp artisan octane:install --server=roadrunnerinside your Laravel app; run that first, and confirm your app code is mounted correctly viaAPP_CODE_PATH_HOST.- Code changes don't show up. Workers keep your app booted in memory; reset the worker pool after deploying, don't expect a plain page refresh to pick up new code.
- Extension-related errors. The image only installs
socketsandopcacheby default; additional extensions need to be added toroadrunner/Dockerfileand the image rebuilt with./laradock rebuild roadrunner. - Port already in use on your host. Another service is already bound to
8090. ChangeROADRUNNER_HTTP_PORTand restart with./laradock start roadrunner.
Want another Octane-compatible runtime? See FrankenPHP. Looking for the classic Nginx + PHP-FPM setup instead? See Nginx. New to Laradock? Start with Getting Started.