Browse Source

Add roadrunner for laravel (#6539)

* Add roadrunner for laravel (./deploy/roadrunner/*, ./laravel-roadrunner.dockerfile)
update swoole to parallel laravel-s and roadrunner (./deploy/swoole, ./laravel-swoole.dockerfile) 

Disable Laravel emergency disk logging on errors (./config/logging.php, .env)
Make php-fpm console error logging viewable in docker logs (./laravel.dockerfile)
add option in dockerfile to view Laravel console error logging in docker logs (disabled by default) (./laravel.dockerfile)

Update faker to new repository home, fakerphp/faker (./composer.json, ./deploy/*/composer.json)

* Update README.md

* remove extraneous development file composer-rr.json
Brion Finlay 4 years ago
parent
commit
a518bd57c4

+ 1 - 1
frameworks/PHP/laravel/.env

@@ -4,7 +4,7 @@ APP_KEY=base64:JRW3D/imCqern1eNGYaRTmP8wixsi3gWRXTSIT1LGTQ=
 APP_DEBUG=false
 APP_DEBUG=false
 APP_URL=http://localhost
 APP_URL=http://localhost
 
 
-LOG_CHANNEL=stack
+LOG_CHANNEL=stdout
 
 
 DB_CONNECTION=mysql
 DB_CONNECTION=mysql
 DB_HOST=tfb-database
 DB_HOST=tfb-database

+ 17 - 1
frameworks/PHP/laravel/README.md

@@ -74,7 +74,21 @@ Laravel-swoole is an adapter layer between Swoole and Laravel/Lumen.  It provide
 Also because Laravel was written under php-fpm environment where the framework is reset between each request, sometimes state changes are not re-initialized between requests since it isn't necessary in an environment where the framework is terminated after each request.
 Also because Laravel was written under php-fpm environment where the framework is reset between each request, sometimes state changes are not re-initialized between requests since it isn't necessary in an environment where the framework is terminated after each request.
 To handle this, Laravel-swoole creates a sandbox for each request with a copy of initial framework state so that any changes made by the request do not impact the state of other incoming requests.
 To handle this, Laravel-swoole creates a sandbox for each request with a copy of initial framework state so that any changes made by the request do not impact the state of other incoming requests.
 
 
-Brion Finlay 10/3/2018  
+benchmark support: [Brion Finlay](https://github.com/bfinlay) 10/3/2018
+
+# laravel-roadrunner Benchmarking Test
+
+The laravel-roadrunner test is a benchmark test of Laravel running on [Roadrunner](https://github.com/spiral/roadrunner).
+
+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.
+
+RoadRunner includes PSR-7/PSR-17 compatible HTTP and HTTP/2 server and can be used to replace classic Nginx+FPM setup with much greater performance and flexibility.
+
+RoadRunner achieves performance improvements by reusing PHP instances so that the framework is not bootstrapped on each request.
+
+RoadRunner uses a synchronous model of execution rather than asynchronous for broader compatibility with libraries.
+
+benchmark support: [Brion Finlay](https://github.com/bfinlay) 4/16/2021
 
 
 ### Test Type Implementation Source Code
 ### Test Type Implementation Source Code
 
 
@@ -89,6 +103,8 @@ Brion Finlay 10/3/2018
 The tests were run with:
 The tests were run with:
 * [Swoole](https://www.swoole.co.uk/)
 * [Swoole](https://www.swoole.co.uk/)
 * [laravel-swoole](https://github.com/swooletw/laravel-swoole/wiki)
 * [laravel-swoole](https://github.com/swooletw/laravel-swoole/wiki)
+* [Roadrunner](https://github.com/spiral/roadrunner)
+* [Roadrunner Laravel Bridge](https://github.com/spiral/roadrunner-laravel)
 * [Laravel](https://laravel.com/)
 * [Laravel](https://laravel.com/)
 
 
 ## Test URLs
 ## Test URLs

+ 23 - 0
frameworks/PHP/laravel/benchmark_config.json

@@ -69,6 +69,29 @@
 			"display_name": "laravel-laravel-s",
 			"display_name": "laravel-laravel-s",
 			"notes": "",
 			"notes": "",
 			"versus": "swoole"
 			"versus": "swoole"
+		},
+		"roadrunner": {
+			"json_url": "/json",
+			"db_url": "/db",
+			"query_url": "/queries/",
+			"fortune_url": "/fortunes",
+			"update_url": "/updates/",
+			"plaintext_url": "/plaintext",
+			"port": 8080,
+			"approach": "Realistic",
+			"classification": "Fullstack",
+			"database": "MySQL",
+			"framework": "laravel",
+			"language": "PHP",
+			"flavor": "None",
+			"orm": "Full",
+			"platform": "roadrunner",
+			"webserver": "none",
+			"os": "Linux",
+			"database_os": "Linux",
+			"display_name": "laravel-roadrunner",
+			"notes": "",
+			"versus": "swoole"
 		}
 		}
 	}]
 	}]
 }
 }

+ 1 - 1
frameworks/PHP/laravel/composer.json

@@ -12,7 +12,7 @@
     },
     },
     "require-dev": {
     "require-dev": {
         "facade/ignition": "^2.3.6",
         "facade/ignition": "^2.3.6",
-        "fzaninotto/faker": "^1.9.1",
+        "fakerphp/faker": "^1.9.1",
         "mockery/mockery": "^1.3.1",
         "mockery/mockery": "^1.3.1",
         "nunomaduro/collision": "^5.0",
         "nunomaduro/collision": "^5.0",
         "phpunit/phpunit": "^9.3"
         "phpunit/phpunit": "^9.3"

+ 55 - 0
frameworks/PHP/laravel/config/logging.php

@@ -0,0 +1,55 @@
+<?php
+
+use Monolog\Handler\StreamHandler;
+use Monolog\Handler\SyslogUdpHandler;
+
+return [
+    /*
+     * Benchmark note:
+     *
+     * If Laravel does not have a log defined it will open an emergency log file and log
+     * errors to the filesystem.   This configuration sends logs to stdout instead.
+     * php-fpm directs these to /dev/null unless "catch_workers_output = yes" is set in php-fpm.conf
+     *
+     */
+
+    /*
+    |--------------------------------------------------------------------------
+    | Default Log Channel
+    |--------------------------------------------------------------------------
+    |
+    | This option defines the default log channel that gets used when writing
+    | messages to the logs. The name specified in this option should match
+    | one of the channels defined in the "channels" configuration array.
+    |
+    */
+
+    'default' => env('LOG_CHANNEL', 'stdout'),
+
+    /*
+    |--------------------------------------------------------------------------
+    | Log Channels
+    |--------------------------------------------------------------------------
+    |
+    | Here you may configure the log channels for your application. Out of
+    | the box, Laravel uses the Monolog PHP logging library. This gives
+    | you a variety of powerful log handlers / formatters to utilize.
+    |
+    | Available Drivers: "single", "daily", "slack", "syslog",
+    |                    "errorlog", "monolog",
+    |                    "custom", "stack"
+    |
+    */
+
+    'channels' => [
+        'stdout' => [
+            'driver' => 'monolog',
+            'handler' => StreamHandler::class,
+            'formatter' => env('LOG_STDERR_FORMATTER'),
+            'with' => [
+                'stream' => 'php://stdout',
+            ],
+        ],
+    ],
+
+];

+ 6 - 3
frameworks/PHP/laravel/deploy/conf/php-fpm.conf

@@ -22,7 +22,8 @@ pid = /run/php/php-fpm.pid
 ; Note: the default prefix is /var
 ; Note: the default prefix is /var
 ; Default Value: log/php-fpm.log
 ; Default Value: log/php-fpm.log
 ;error_log = /var/log/php7.3-fpm.log
 ;error_log = /var/log/php7.3-fpm.log
-error_log = /dev/stderr
+;error_log = /dev/stderr
+error_log = /proc/self/fd/2
 
 
 
 
 ; syslog_facility is used to specify what type of program is logging the
 ; syslog_facility is used to specify what type of program is logging the
@@ -385,6 +386,7 @@ pm.max_spare_servers = 512
 ; The access log file
 ; The access log file
 ; Default: not set
 ; Default: not set
 ;access.log = log/$pool.access.log
 ;access.log = log/$pool.access.log
+;access.log = /proc/self/fd/2
 
 
 ; The access log format.
 ; The access log format.
 ; The following syntax is allowed
 ; The following syntax is allowed
@@ -497,7 +499,7 @@ pm.max_spare_servers = 512
 ; Note: on highloaded environement, this can cause some delay in the page
 ; Note: on highloaded environement, this can cause some delay in the page
 ; process time (several ms).
 ; process time (several ms).
 ; Default Value: no
 ; Default Value: no
-;catch_workers_output = yes
+; catch_workers_output = yes
 
 
 ; Clear environment in FPM workers
 ; Clear environment in FPM workers
 ; Prevents arbitrary environment variables from reaching FPM worker processes
 ; Prevents arbitrary environment variables from reaching FPM worker processes
@@ -548,4 +550,5 @@ pm.max_spare_servers = 512
 ;php_flag[display_errors] = off
 ;php_flag[display_errors] = off
 ;php_admin_value[error_log] = /var/log/fpm-php.www.log
 ;php_admin_value[error_log] = /var/log/fpm-php.www.log
 ;php_admin_flag[log_errors] = on
 ;php_admin_flag[log_errors] = on
-;php_admin_value[memory_limit] = 32M
+;php_admin_value[memory_limit] = 32M
+

+ 22 - 0
frameworks/PHP/laravel/deploy/roadrunner/.rr.yaml

@@ -0,0 +1,22 @@
+# see https://roadrunner.dev/docs/intro-config
+server:
+  command: "php ./vendor/bin/rr-worker start --relay-dsn unix:///usr/local/var/run/rr-rpc.sock"
+  relay: "unix:///usr/local/var/run/rr-rpc.sock"
+logs:
+  mode: production
+  level: error
+http:
+  address: 0.0.0.0:8080
+  middleware: ["headers", "static", "gzip"]
+  pool:
+    max_jobs: 64 # feel free to change this
+    supervisor:
+      exec_ttl: 60s
+  headers:
+    response:
+      Server: "RoadRunner"
+  static:
+    dir: "public"
+    forbid: [".php"]
+
+

+ 57 - 0
frameworks/PHP/laravel/deploy/roadrunner/composer.json

@@ -0,0 +1,57 @@
+{
+    "name": "laravel/laravel",
+    "type": "project",
+    "description": "The Laravel Framework.",
+    "keywords": [
+        "framework",
+        "laravel"
+    ],
+    "license": "MIT",
+    "require": {
+        "laravel/framework": "^8.16",
+        "nyholm/psr7": "*",
+        "spiral/roadrunner": "^2.0",
+        "spiral/roadrunner-laravel": "^4.0"
+    },
+    "require-dev": {
+        "facade/ignition": "^2.3.6",
+        "fakerphp/faker": "^1.9.1",
+        "mockery/mockery": "^1.3.1",
+        "nunomaduro/collision": "^5.0",
+        "phpunit/phpunit": "^9.3"
+    },
+    "config": {
+        "optimize-autoloader": true,
+        "preferred-install": "dist",
+        "sort-packages": true
+    },
+    "extra": {
+        "laravel": {
+            "dont-discover": []
+        }
+    },
+    "autoload": {
+        "psr-4": {
+            "App\\": "app/"
+        }
+    },
+    "autoload-dev": {
+        "psr-4": {
+            "Tests\\": "tests/"
+        }
+    },
+    "minimum-stability": "dev",
+    "prefer-stable": true,
+    "scripts": {
+        "post-autoload-dump": [
+            "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
+            "@php artisan package:discover --ansi"
+        ],
+        "post-root-package-install": [
+            "@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
+        ],
+        "post-create-project-cmd": [
+            "@php artisan key:generate --ansi"
+        ]
+    }
+}

BIN
frameworks/PHP/laravel/deploy/roadrunner/roadrunner-2.0.4-linux-amd64.tar.gz


+ 1 - 2
frameworks/PHP/laravel/deploy/swoole/composer.json

@@ -8,13 +8,12 @@
     ],
     ],
     "license": "MIT",
     "license": "MIT",
     "require": {
     "require": {
-        "php": "^7.3",
         "laravel/framework": "^8.0",
         "laravel/framework": "^8.0",
         "swooletw/laravel-swoole": "^v2.6"
         "swooletw/laravel-swoole": "^v2.6"
     },
     },
     "require-dev": {
     "require-dev": {
         "facade/ignition": "^2.3.6",
         "facade/ignition": "^2.3.6",
-        "fzaninotto/faker": "^1.9.1",
+        "fakerphp/faker": "^1.9.1",
         "mockery/mockery": "^1.3.1",
         "mockery/mockery": "^1.3.1",
         "nunomaduro/collision": "^5.0",
         "nunomaduro/collision": "^5.0",
         "phpunit/phpunit": "^9.3"
         "phpunit/phpunit": "^9.3"

+ 0 - 17
frameworks/PHP/laravel/deploy/swoole/install-composer.sh

@@ -1,17 +0,0 @@
-#!/bin/sh
-
-EXPECTED_SIGNATURE="$(curl -s https://composer.github.io/installer.sig)"
-php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
-ACTUAL_SIGNATURE="$(php -r "echo hash_file('SHA384', 'composer-setup.php');")"
-
-if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
-then
-    >&2 echo 'ERROR: Invalid installer signature'
-    rm composer-setup.php
-    exit 1
-fi
-
-php composer-setup.php --quiet
-RESULT=$?
-rm composer-setup.php
-exit $RESULT

+ 0 - 2
frameworks/PHP/laravel/deploy/swoole/php.ini

@@ -1,2 +0,0 @@
-opcache.enable_cli=1
-opcache.validate_timestamps=0

+ 1 - 1
frameworks/PHP/laravel/laravel-laravel-s.dockerfile

@@ -16,7 +16,7 @@ RUN chmod -R 777 /laravel
 
 
 RUN apt-get update > /dev/null && \
 RUN apt-get update > /dev/null && \
     apt-get install -yqq git unzip > /dev/null
     apt-get install -yqq git unzip > /dev/null
-RUN php -r "copy('https://install.phpcomposer.com/installer', 'composer-setup.php');" && php composer-setup.php && php -r "unlink('composer-setup.php');"
+RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && php composer-setup.php && php -r "unlink('composer-setup.php');"
 RUN mv composer.phar /usr/local/bin/composer
 RUN mv composer.phar /usr/local/bin/composer
 
 
 COPY deploy/laravel-s/composer.json ./
 COPY deploy/laravel-s/composer.json ./

+ 34 - 0
frameworks/PHP/laravel/laravel-roadrunner.dockerfile

@@ -0,0 +1,34 @@
+FROM php:8.0-cli
+
+RUN docker-php-ext-install pdo_mysql pcntl opcache sockets > /dev/null
+
+RUN echo "opcache.enable_cli=1" >> /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini
+#RUN echo "opcache.jit=1205" >> /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini
+#RUN echo "opcache.jit_buffer_size=128M" >> /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini
+
+ADD ./ /laravel
+WORKDIR /laravel
+
+RUN mkdir -p /laravel/bootstrap/cache /laravel/storage/logs /laravel/storage/framework/sessions /laravel/storage/framework/views /laravel/storage/framework/cache
+RUN chmod -R 777 /laravel
+
+RUN apt-get update > /dev/null && \
+    apt-get install -yqq git unzip > /dev/null
+RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && php composer-setup.php && php -r "unlink('composer-setup.php');"
+RUN mv composer.phar /usr/local/bin/composer
+
+COPY deploy/roadrunner/composer.json ./
+COPY deploy/roadrunner/.rr.yaml ./
+
+RUN composer install -a --no-dev --quiet
+RUN php artisan optimize
+
+# `./vendor/bin/rr get-binary` is github rate-limited
+RUN tar xzf deploy/roadrunner/roadrunner-*.tar.gz && mv roadrunner-*/rr . && chmod +x ./rr
+RUN php artisan vendor:publish --provider='Spiral\RoadRunnerLaravel\ServiceProvider' --tag=config
+
+EXPOSE 8080
+
+# CMD bash
+CMD ./rr serve -c ./.rr.yaml
+

+ 14 - 19
frameworks/PHP/laravel/laravel-swoole.dockerfile

@@ -1,37 +1,32 @@
-FROM php:7.4
+FROM php:8.0-cli
 
 
 RUN pecl install swoole > /dev/null && \
 RUN pecl install swoole > /dev/null && \
     docker-php-ext-enable swoole
     docker-php-ext-enable swoole
+RUN docker-php-ext-install pdo_mysql pcntl opcache > /dev/null
 
 
-RUN docker-php-ext-install pdo_mysql > /dev/null
+RUN echo "opcache.enable_cli=1" >> /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini
+#RUN echo "opcache.jit=1205" >> /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini
+#RUN echo "opcache.jit_buffer_size=128M" >> /usr/local/etc/php/conf.d/docker-php-ext-opcache.ini
 
 
 ADD ./ /laravel
 ADD ./ /laravel
 WORKDIR /laravel
 WORKDIR /laravel
-COPY deploy/swoole/php.ini /usr/local/etc/php/
-
-RUN mkdir -p /laravel/bootstrap/cache
-RUN mkdir -p /laravel/storage/framework/sessions
-RUN mkdir -p /laravel/storage/framework/views
-RUN mkdir -p /laravel/storage/framework/cache
 
 
+RUN mkdir -p /laravel/bootstrap/cache  /laravel/storage/framework/sessions /laravel/storage/framework/views /laravel/storage/framework/cache
 RUN chmod -R 777 /laravel
 RUN chmod -R 777 /laravel
 
 
-RUN echo "APP_SWOOLE=true" >> .env
-
-# Install composer using the installation method documented at https://getcomposer.org/doc/faqs/how-to-install-composer-programmatically.md
-# This method was chosen because composer is not part of the apt repositories that are in the default PHP 7.4 docker image
-# Adding alternate apt php repos can potentially cause problems with extension compatibility between the php build from the docker image and the alternate php build
-# An additional benefit of this method is that the correct version of composer will be used for the environment and version of the php system in the docker image
-RUN deploy/swoole/install-composer.sh
-
 RUN apt-get update -yqq > /dev/null && \
 RUN apt-get update -yqq > /dev/null && \
     apt-get install -yqq git unzip > /dev/null
     apt-get install -yqq git unzip > /dev/null
-COPY deploy/swoole/composer* ./
-RUN php composer.phar install -a --no-dev --quiet
 
 
+RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && php composer-setup.php && php -r "unlink('composer-setup.php');"
+RUN mv composer.phar /usr/local/bin/composer
+
+COPY deploy/swoole/composer.json ./
+
+RUN echo "APP_SWOOLE=true" >> .env
+
+RUN composer install -a --no-dev --quiet
 RUN php artisan optimize
 RUN php artisan optimize
 
 
-RUN chmod -R 777 /laravel
 
 
 EXPOSE 8080
 EXPOSE 8080
 
 

+ 7 - 10
frameworks/PHP/laravel/laravel.dockerfile

@@ -18,20 +18,17 @@ WORKDIR /laravel
 
 
 RUN if [ $(nproc) = 2 ]; then sed -i "s|pm.max_children = 1024|pm.max_children = 512|g" /etc/php/8.0/fpm/php-fpm.conf ; fi;
 RUN if [ $(nproc) = 2 ]; then sed -i "s|pm.max_children = 1024|pm.max_children = 512|g" /etc/php/8.0/fpm/php-fpm.conf ; fi;
 
 
-RUN mkdir -p /laravel/bootstrap/cache
-RUN mkdir -p /laravel/storage/framework/sessions
-RUN mkdir -p /laravel/storage/framework/views
-RUN mkdir -p /laravel/storage/framework/cache
-
+RUN mkdir -p /laravel/bootstrap/cache /laravel/storage/logs /laravel/storage/framework/sessions /laravel/storage/framework/views /laravel/storage/framework/cache
 RUN chmod -R 777 /laravel
 RUN chmod -R 777 /laravel
 
 
 RUN composer install --optimize-autoloader --classmap-authoritative --no-dev --quiet
 RUN composer install --optimize-autoloader --classmap-authoritative --no-dev --quiet
-
 RUN php artisan optimize
 RUN php artisan optimize
 
 
-RUN chmod -R 777 /laravel
-
 EXPOSE 8080
 EXPOSE 8080
 
 
-CMD service php8.0-fpm start && \
-    nginx -c /laravel/deploy/nginx.conf
+# Uncomment next line for Laravel console error logging to be viewable in docker logs
+# RUN echo "catch_workers_output = yes" >> /etc/php/8.0/fpm/php-fpm.conf
+
+RUN mkdir -p /run/php
+CMD /usr/sbin/php-fpm8.0 --fpm-config /etc/php/8.0/fpm/php-fpm.conf && nginx -c /laravel/deploy/nginx.conf
+