Zaher Ghaibeh
PHP Backend developer
I've experience in a few PHP Frameworks, such as Laravel, Lumen and Slim (The last two are used for building Microservices/API services).
Using Swoole PHP 7.2 Docker image
Published at Wednesday, May 23, 2018

We all read about Swoole in Laravel-news article, and the results they provided looks nice, this pushed me to create a new Docker image which has PHP 7.2 CLI and Swoole complied with it directly.

In this article am going to show you how you can use it with a simple lumen application, and show you the results I got from using Swoole comparing to using nginx.

1. Creating Lumen Project

First of all, let's create a simple Lumen project

$ composer create-project laravel/lumen

2. Install Required Packages

Secondly, we need to install the lumen package for Swoole, and made small change

$ cd lumen
$ composer require swooletw/laravel-swoole

3. Register the Service Provider

Then we need to edit our bootstrap/app.php file and register Swoole service provider, just add the following line within Register Service Providers section

$app->register(SwooleTW\Http\LumenServiceProvider::class);

4. Prepare Our Dockerfile

Lastly, we need to prepare our simple Dockerfile which should live within our lumen project directory

FROM zaherg/php72-swoole:latest

LABEL Maintainer="Zaher Ghaibeh <z@zah.me>"

ENV APP_ENV ${APP_ENV:-production}
ENV APP_DEBUG ${APP_DEBUG:-false}
ENV APP_TIMEZONE ${APP_TIMEZONE:-UTC}
ENV SWOOLE_HTTP_PORT ${SWOOLE_HTTP_PORT:-80}
ENV SWOOLE_HTTP_HOST ${SWOOLE_HTTP_HOST:-"0.0.0.0"}

USER root

ADD ./ /var/www

CMD "php", "artisan","swoole:http","start"

5. Build the Docker image

Now we are ready to build our docker image

$ docker build -t lumen-swoole .

6. Run our Docker image

Once it's finished you can run it with the command

$ docker run --rm --name swoole -p 80:80 -d lumen-swoole:latest

Open your browser to localhost and you will be greeted with lumen default route.

Some tests with real data:

I did a small test with real data, to return 500 records at once from MySQL, and I tried hard to make the environment equal in both, but the only difference is that the nginx box is running PHP 7.1 which comes with alpine by default, meanwhile Swoole is running PHP 7.2

And this is what I got

Nginx:

wrk -t4 -c100 http://api.test/v1/all
Running 10s test @ http://api.test/v1/all
  4 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency     1.48s   245.72ms   1.73s    66.67%
    Req/Sec     1.50      2.22    10.00     82.14%
  32 requests in 10.05s, 13.84KB read
  Socket errors: connect 0, read 124, write 5, timeout 29
Requests/sec:      3.18
Transfer/sec:      1.38KB

Swoole:

$ wrk -t4 -c100 http://api.test/v1/all
Running 10s test @ http://api.test/v1/all
  4 threads and 100 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency   603.12ms  104.12ms   1.05s    81.77%
    Req/Sec    40.21     17.70   101.00     59.08%
  1607 requests in 10.05s, 627.73KB read
  Socket errors: connect 0, read 59, write 0, timeout 0
Requests/sec:    159.82
Transfer/sec:     62.43KB

Basically with Swoole, I was able to execute 160 requests per second, meanwhile, with Nginx, I was able to execute 3.18 requests per second.

Now it is up to you which one to use.