Setting Up Laravel Octane with Swoole on MacOS
Swoole or Open Swoole allow for concurrency with Laravel Octane, while RoadRunner does not. This article will cover my experience installing Laravel Octane with Swoole.
Table of Contents
- Prerequisites
- Installing Swoole
- Creating Project
- Configuring Environment
- Hot Reloading
- Troubleshooting
Prerequisites
- Homebrew https://brew.sh/
- PHP via brew https://formulae.brew.sh/formula/php#default (as of 04 Dec, 2023 PHP 8.1+ is required for Laravel Octane as per Server Prerequisites https://laravel.com/docs/10.x/octane#server-prerequisites)
- PECL (comes with PHP via brew)
- Composer for PHP dependencies https://getcomposer.org/doc/00-intro.md#installation-linux-unix-macos
- Laravel https://laravel.com/docs/10.x/installation#creating-a-laravel-project
- Swoole https://github.com/swoole/swoole-src
Additional prerequisites for production-like environment including HTTPS and custom domain support:
- NGINX via brew https://formulae.brew.sh/formula/nginx#default
- dnsmasq via brew https://formulae.brew.sh/formula/dnsmasq#default
- mkcert via brew https://formulae.brew.sh/formula/mkcert#default
Installing Swoole
To use Laravel Octane with Swoole, you need to install Swoole before installing Octane.
To install Swoole, just run pecl install swoole
. If you run in any trouble, please refer to troubleshooting. Installation will prompt you with some of the options, select those that you need, here is what I used for my project:
pecl install swoole
# enable sockets supports? [no] : yes
#
# enable openssl support? [no] : yes
#
# enable mysqlnd support? [no] : yes
#
# enable curl support? [no] : yes
#
# enable cares support? [no] : no
#
# enable brotli support? [yes] : yes
#
# enable PostgreSQL database support? [no] : yes
#
# enable ODBC database support? [no] : no
#
# enable Oracle database support? [no] : no
#
# enable Sqlite database support? [no] : yes
Creating Project
Create Laravel project as usual:
composer create-project laravel/laravel lara-octane
Then, install Laravel Octane:
cd lara-octane
composer require laravel/octane
php artisan octane:install
# follow terminal prompts to choose between RoadRunner and Swoole
Now, you can start Octane server:
php artisan octane:start --port=8001
Although PHP has built-in web server, and Laravel as well as Laravel Octane supports it out-of-the-box, I wouldn’t recommend using it even for local development. In case of using Laravel Octane, please read Configuring Environment next. Without Octane, I recommend to use Laravel Herd for basic needs.
Configuring Environment
We will configure our local environment to access website via domain (eg lara-octane.test) instead of IP.
dnsmasq
After installing dnsmasq with brew install dnsmasq
, locate dnsmasq.conf
(should be in /opt/homebrew/etc/
), and update address=
and listen-address=
fields:
# dnsmasq.conf
# ...
address=/.test/127.0.0.1
listen-address=127.0.0.1
# ...
You can also create separate config file for this:
# dnsmasq.conf
# ...
conf-dir=/opt/homebrew/etc/dnsmasq.d # uncomment this
# ...
# dnsmasq.d/test
address=/.test/127.0.0.1
listen-address=127.0.0.1
You might also need to setup DNS resolving:
mkdir -p /etc/resolver
nano /etc/resolver/test
# test
nameserver 127.0.0.1
domain test
search_order 1
Now, when setting up Nginx config for Laravel Octane, you should do a proxy pass:
# lara-octane.test
listen 80;
server_name lara-octane.test;
proxy_pass http://127.0.0.1:$lara_octane_port;
mkcert
To setup https, we need mkcert.
brew install mkcert
mkdir -p /opt/homebrew/Cellar/mkcert/$MKCERT_VER/certificates
cd /opt/homebrew/Cellar/mkcert/$MKCERT_VER/certificates
Then we install local authority and issue as many certificates as we need, you can also issue certificate for multiple domains as well as wildcard subdomains:
mkcert -install
mkcert lara-octane.test
Then, enable https and link to those certificates in Nginx config (notice we change 80 to 443 in listen
and http to https in proxy_pass
):
# lara-octane.test
listen 443 ssl;
server_name lara-octane.test;
ssl_certificate /opt/homebrew/Cellar/mkcert/$MKCERT_VER/certificates/lara-octane.test.pem;
ssl_certificate_key /opt/homebrew/Cellar/mkcert/$MKCERT_VER/certificates/lara-octane.test-key.pem;
proxy_pass https://127.0.0.1:$lara_octane_port;
Hot Reloading
If you’re using Vite and have dev server running, pages will still detect filechanges like a normal vite dev server would do.
To enable hot reloading of server files, you must install chokidar with npm locally, and then start Octane server:
npm install --save-dev chokidar
php artisan octane:start --watch
You may configure the directories and files that should be watched using the watch
configuration option within your application’s config/octane.php
configuration file.
Troubleshooting
Libraries or Extensions Will not Load or Wrong PHP Version Used
If you have Laravel Herd installed, it uses its’ own php binary, which can be found under PathToHerd/bin
. There should be symlink of php
to Herd’s binary, and path to Herd should be added to your $PATH variable. To use Laravel Octane, we must use PHP installed with homebrew, so the safest option would be to remove symlink:
whereis herd
cd PathToHerd/bin
ln -al
# look for php symlink
rm php
Then, when you need your Laravel Herd server, you can run
herd use 8.3 # or whatever version you use
Can not Load libpq
Locate libpq.pc
and extend PKG_CONFIG_PATH
:
cd /opt/homebrew && find ./* -name "*libpq.pc*"
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:${FOLDER_WITH_LIBPQ.PC}
If it is not installed, install one of the options described in output.
# this would be libpq if installed via brew, or you can install postgresql
brew install pibpq
brew install postgresq
Fatal Error: pcre2.h
Not Found
This might be pcre2.h
, ares.h
, or any other library headers depending on your selections during Swoole setup. Example message is as follows:
In file included from /private/tmp/pear/temp/swoole/ext-src/php_swoole.cc:21:
/opt/homebrew/Cellar/php/8.3.0/include/php/ext/pcre/php_pcre.h:23:10: fatal error: 'pcre2.h' file not found
#include "pcre2.h"
^~~~~~~~~
Search for libname.h
in /opt/homebrew/
:
cd /opt/homebrew && find ./ -name "*libname.h*"
If libname.h
exists, but not in /opt/homebrew/include
, try to brew link
parent library. If it does exist in /opt/homebrew/include/
, try to extend link:
sudo ln -s /opt/homebrew/include/libname.h /usr/local/include/
Otherwise, install target package with brew:
# install
brew install libname
# link to /opt/homebrew/include/
brew link libname
# link to /usr/local/include
ln -s /opt/homebrew/iclude/libname.h /usr/local/include/
You might need to link included header files multiple times, for example when one header file includes others. You can grep for includes inside those:
cat /opt/homeberew/include/libname.h | grep '#include'
ld: library not found for -lssl
Check for/install openssl
with brew, then adjust LIBRARY_PATH
:
# openssl should be located in /opt/homebrew/opt/
export LIBRARY_PATH=$LIBRARY_PATH:/opt/homebrew/opt/openssl@1.1/lib/
How to Use C-Ares?
I did not figure this one out. It was not necessary for my project at the moment, so I left this out. You can help with this one via comments below or by contacting me directly. Credit where credit’s due.
Composer segfault
Remove swoole.so
extension in php.ini
:
php --ini
nano path/to/php.ini
# remove extension=swoole.so, usually first line