added roadrunner support and dockerfile

This commit is contained in:
pushrbx 2022-07-14 16:44:45 +01:00
parent 16560d3634
commit e47ad20f04
16 changed files with 1116 additions and 9 deletions

20
.dockerignore Normal file
View File

@ -0,0 +1,20 @@
.dockerignore
Makefile
docker*.yml
Dockerfile
bootstrap/cache/*
storage/logs/*
storage/framework/cache/data/*
storage/framework/sessions/*
storage/framework/testing/*
storage/framework/views/*
storage/*.cache
vendor
node_modules
*.log
.gitignore
.editorconfig
.idea
.vscode
.github
.git

241
.rr.local.unix.yaml Normal file
View File

@ -0,0 +1,241 @@
# ---------------------------------------------------------------------------------------------------
# WARNING! This file should be used ONLY for local application development. NOT for production usage!
# ---------------------------------------------------------------------------------------------------
# Hint: RR will replace any config options using reference to environment variables,
# eg.: `option_key: ${ENVIRONMENT_VARIABLE_NAME}`.
# RR configuration version
version: "2.7"
# Remote Procedures Calling (docs: https://roadrunner.dev/docs/beep-beep-rpc)
# Is used for connecting to RoadRunner server from your PHP workers.
rpc:
# TCP address:port for listening.
#
# Default: "tcp://127.0.0.1:6001"
listen: tcp://127.0.0.1:6001
# Application server settings (docs: https://roadrunner.dev/docs/php-worker)
server:
# Worker starting command, with any required arguments.
#
# This option is required.
command: "php ./vendor/bin/rr-worker start --relay-dsn unix:///var/run/rr/rr-relay.sock"
env:
- scout_driver: typesense
## Environment variables for the worker processes.
##
## Default: <empty map>
#env:
# - SOME_KEY: "SOME_VALUE"
# - SOME_KEY2: "SOME_VALUE2"
# Worker relay can be: "pipes", TCP (eg.: tcp://127.0.0.1:6001), or socket (eg.: unix:///var/run/rr-relay.sock).
#
# Default: "pipes"
relay: "unix:///var/run/rr/rr-relay.sock"
# Timeout for relay connection establishing (only for socket and TCP port relay).
#
# Default: 60s
relay_timeout: 60s
# HTTP plugin settings.
http:
# Host and port to listen on (eg.: `127.0.0.1:8080`).
#
# This option is required.
address: 0.0.0.0:8080
# HTTP access logs
#
# Default: false
access_logs: true
# Maximal incoming request size in megabytes. Zero means no limit.
#
# Default: 0
max_request_size: 256
# Middlewares for the http plugin, order is important. Allowed values is: "headers", "gzip".
#
# Default value: []
middleware: ["static", "headers", "gzip"]
# File uploading settings.
uploads:
# Directory for file uploads. Empty value means to use $TEMP based on your OS.
#
# Default: ""
dir: "/tmp"
# Deny files with the following extensions to upload.
#
# Default: [".php", ".exe", ".bat"]
forbid: [".php", ".exe", ".bat", ".sh"]
# Settings for "headers" middleware (docs: https://roadrunner.dev/docs/http-headers).
headers:
# Automatically add headers to every response.
#
# Default: <empty map>
response:
X-Powered-By: "RoadRunner"
# Settings for serving static content (docs: https://roadrunner.dev/docs/http-static).
static:
# Path to the directory with static assets.
#
# This option is required.
dir: "./public"
# File extensions to forbid.
#
# Default: []
forbid: [".htaccess", ".php"]
# Automatically add headers to every response.
#
# Default: <empty map>
response:
X-Powered-By: "RoadRunner"
# Workers pool settings.
pool:
# How many worker processes will be started. Zero (or nothing) means the number of logical CPUs.
#
# Default: 0
num_workers: 4
# Maximal count of worker executions. Zero (or nothing) means no limit.
#
# Default: 0
max_jobs: 64
# Timeout for worker allocation. Zero means no limit.
#
# Default: 60s
allocate_timeout: 10s
# Timeout for worker destroying before process killing. Zero means no limit.
#
# Default: 60s
destroy_timeout: 10s
# Supervisor is used to control http workers (previous name was "limit", docs:
# https://roadrunner.dev/docs/php-limit). "Soft" limits will not interrupt current request processing. "Hard"
# limit on the contrary - interrupts the execution of the request.
supervisor:
# Maximal worker memory usage in megabytes (soft limit). Zero means no limit.
#
# Default: 0
max_worker_memory: 128
# Maximal job lifetime (hard limit). Zero means no limit.
#
# Default: 0s
exec_ttl: 60s
# SSL (Secure Sockets Layer) settings (docs: https://roadrunner.dev/docs/http-https).
# ssl:
# # Host and port to listen on (eg.: `127.0.0.1:443`).
# #
# # Default: ":443"
# address: 0.0.0.0:8443
#
# # Automatic redirect from http:// to https:// schema.
# #
# # Default: false
# redirect: false
#
# # Path to the cert file. This option is required for SSL working.
# #
# # This option is required.
# cert: /etc/ssl/certs/selfsigned.crt
#
# # Path to the cert key file.
# #
# # This option is required.
# key: /etc/ssl/private/selfsigned.key
# HTTP/2 settings.
http2:
# HTTP/2 over non-encrypted TCP connection using H2C.
#
# Default: false
h2c: false
# Maximal concurrent streams count.
#
# Default: 128
max_concurrent_streams: 128
## Application metrics in Prometheus format (docs: https://roadrunner.dev/docs/beep-beep-metrics). Drop this section
## for this feature disabling.
#metrics:
# # Prometheus client address (path /metrics added automatically).
# #
# # Default: "127.0.0.1:2112"
# address: 127.0.0.1:8081
# Health check endpoint (docs: https://roadrunner.dev/docs/beep-beep-health). If response code is 200 - it means at
# least one worker ready to serve requests. 500 - there are no workers ready to service requests.
# Drop this section for this feature disabling.
status:
# Host and port to listen on (eg.: `127.0.0.1:2114`). Use the following URL: http://127.0.0.1:2114/health?plugin=http
# Multiple plugins must be separated using "&" - http://127.0.0.1:2114/health?plugin=http&plugin=rpc where "http" and
# "rpc" are active (connected) plugins.
#
# This option is required.
address: 127.0.0.1:8082
# Response status code if a requested plugin not ready to handle requests
# Valid for both /health and /ready endpoints
#
# Default: 503
unavailable_status_code: 503
# Automatically detect PHP file changes and reload connected services (docs:
# https://roadrunner.dev/docs/beep-beep-reload). Drop this section for this feature disabling.
reload:
# Sync interval.
#
# Default: "1s"
interval: 1s
# Global patterns to sync.
#
# Default: [".php"]
patterns: [".php"]
# List of included for sync services (this is a map, where key name is a plugin name).
#
# Default: <empty map>
services:
http:
# Directories to sync. If recursive is set to true, recursive sync will be applied only to the directories in
# "dirs" section. Dot (.) means "current working directory".
#
# Default: []
dirs: ["."]
# Recursive search for file patterns to add.
#
# Default: false
recursive: true
# Ignored folders.
#
# Default: []
ignore: ["vendor"]
# RoadRunner internal container configuration (docs: https://github.com/spiral/endure).
endure:
# Logging level. Possible values: "debug", "info", "warning", "error", "panic", "fatal".
#
# Default: "error"
log_level: error
app:
debug: true

241
.rr.local.yaml Normal file
View File

@ -0,0 +1,241 @@
# ---------------------------------------------------------------------------------------------------
# WARNING! This file should be used ONLY for local application development. NOT for production usage!
# ---------------------------------------------------------------------------------------------------
# Hint: RR will replace any config options using reference to environment variables,
# eg.: `option_key: ${ENVIRONMENT_VARIABLE_NAME}`.
# RR configuration version
version: "2.7"
# Remote Procedures Calling (docs: https://roadrunner.dev/docs/beep-beep-rpc)
# Is used for connecting to RoadRunner server from your PHP workers.
rpc:
# TCP address:port for listening.
#
# Default: "tcp://127.0.0.1:6001"
listen: tcp://127.0.0.1:6001
# Application server settings (docs: https://roadrunner.dev/docs/php-worker)
server:
# Worker starting command, with any required arguments.
#
# This option is required.
command: "php ./vendor/bin/rr-worker start"
env:
- scout_driver: typesense
## Environment variables for the worker processes.
##
## Default: <empty map>
#env:
# - SOME_KEY: "SOME_VALUE"
# - SOME_KEY2: "SOME_VALUE2"
# Worker relay can be: "pipes", TCP (eg.: tcp://127.0.0.1:6001), or socket (eg.: unix:///var/run/rr-relay.sock).
#
# Default: "pipes"
relay: "pipes"
# Timeout for relay connection establishing (only for socket and TCP port relay).
#
# Default: 60s
relay_timeout: 60s
# HTTP plugin settings.
http:
# Host and port to listen on (eg.: `127.0.0.1:8080`).
#
# This option is required.
address: 0.0.0.0:8080
# HTTP access logs
#
# Default: false
access_logs: true
# Maximal incoming request size in megabytes. Zero means no limit.
#
# Default: 0
max_request_size: 256
# Middlewares for the http plugin, order is important. Allowed values is: "headers", "gzip".
#
# Default value: []
middleware: ["static", "headers", "gzip"]
# File uploading settings.
uploads:
# Directory for file uploads. Empty value means to use $TEMP based on your OS.
#
# Default: ""
dir: "/tmp"
# Deny files with the following extensions to upload.
#
# Default: [".php", ".exe", ".bat"]
forbid: [".php", ".exe", ".bat", ".sh"]
# Settings for "headers" middleware (docs: https://roadrunner.dev/docs/http-headers).
headers:
# Automatically add headers to every response.
#
# Default: <empty map>
response:
X-Powered-By: "RoadRunner"
# Settings for serving static content (docs: https://roadrunner.dev/docs/http-static).
static:
# Path to the directory with static assets.
#
# This option is required.
dir: "./public"
# File extensions to forbid.
#
# Default: []
forbid: [".htaccess", ".php"]
# Automatically add headers to every response.
#
# Default: <empty map>
response:
X-Powered-By: "RoadRunner"
# Workers pool settings.
pool:
# How many worker processes will be started. Zero (or nothing) means the number of logical CPUs.
#
# Default: 0
num_workers: 4
# Maximal count of worker executions. Zero (or nothing) means no limit.
#
# Default: 0
max_jobs: 64
# Timeout for worker allocation. Zero means no limit.
#
# Default: 60s
allocate_timeout: 10s
# Timeout for worker destroying before process killing. Zero means no limit.
#
# Default: 60s
destroy_timeout: 10s
# Supervisor is used to control http workers (previous name was "limit", docs:
# https://roadrunner.dev/docs/php-limit). "Soft" limits will not interrupt current request processing. "Hard"
# limit on the contrary - interrupts the execution of the request.
supervisor:
# Maximal worker memory usage in megabytes (soft limit). Zero means no limit.
#
# Default: 0
max_worker_memory: 128
# Maximal job lifetime (hard limit). Zero means no limit.
#
# Default: 0s
exec_ttl: 60s
# SSL (Secure Sockets Layer) settings (docs: https://roadrunner.dev/docs/http-https).
# ssl:
# # Host and port to listen on (eg.: `127.0.0.1:443`).
# #
# # Default: ":443"
# address: 0.0.0.0:8443
#
# # Automatic redirect from http:// to https:// schema.
# #
# # Default: false
# redirect: false
#
# # Path to the cert file. This option is required for SSL working.
# #
# # This option is required.
# cert: /etc/ssl/certs/selfsigned.crt
#
# # Path to the cert key file.
# #
# # This option is required.
# key: /etc/ssl/private/selfsigned.key
# HTTP/2 settings.
http2:
# HTTP/2 over non-encrypted TCP connection using H2C.
#
# Default: false
h2c: false
# Maximal concurrent streams count.
#
# Default: 128
max_concurrent_streams: 128
## Application metrics in Prometheus format (docs: https://roadrunner.dev/docs/beep-beep-metrics). Drop this section
## for this feature disabling.
#metrics:
# # Prometheus client address (path /metrics added automatically).
# #
# # Default: "127.0.0.1:2112"
# address: 127.0.0.1:8081
# Health check endpoint (docs: https://roadrunner.dev/docs/beep-beep-health). If response code is 200 - it means at
# least one worker ready to serve requests. 500 - there are no workers ready to service requests.
# Drop this section for this feature disabling.
status:
# Host and port to listen on (eg.: `127.0.0.1:2114`). Use the following URL: http://127.0.0.1:2114/health?plugin=http
# Multiple plugins must be separated using "&" - http://127.0.0.1:2114/health?plugin=http&plugin=rpc where "http" and
# "rpc" are active (connected) plugins.
#
# This option is required.
address: 127.0.0.1:8082
# Response status code if a requested plugin not ready to handle requests
# Valid for both /health and /ready endpoints
#
# Default: 503
unavailable_status_code: 503
# Automatically detect PHP file changes and reload connected services (docs:
# https://roadrunner.dev/docs/beep-beep-reload). Drop this section for this feature disabling.
reload:
# Sync interval.
#
# Default: "1s"
interval: 1s
# Global patterns to sync.
#
# Default: [".php"]
patterns: [".php"]
# List of included for sync services (this is a map, where key name is a plugin name).
#
# Default: <empty map>
services:
http:
# Directories to sync. If recursive is set to true, recursive sync will be applied only to the directories in
# "dirs" section. Dot (.) means "current working directory".
#
# Default: []
dirs: ["."]
# Recursive search for file patterns to add.
#
# Default: false
recursive: true
# Ignored folders.
#
# Default: []
ignore: ["vendor"]
# RoadRunner internal container configuration (docs: https://github.com/spiral/endure).
endure:
# Logging level. Possible values: "debug", "info", "warning", "error", "panic", "fatal".
#
# Default: "error"
log_level: error
app:
debug: true

216
.rr.yaml Normal file
View File

@ -0,0 +1,216 @@
Production usage guide: https://roadrunner.dev/docs/beep-beep-production
# Hint: RR will replace any config options using reference to environment variables,
# eg.: `option_key: ${ENVIRONMENT_VARIABLE_NAME}`.
# RR configuration version
version: "2.7"
# Remote Procedures Calling (docs: https://roadrunner.dev/docs/beep-beep-rpc)
# Is used for connecting to RoadRunner server from your PHP workers.
rpc:
# TCP address:port for listening.
#
# Default: "tcp://127.0.0.1:6001"
listen: tcp://127.0.0.1:6001
# Application server settings (docs: https://roadrunner.dev/docs/php-worker)
server:
# Worker starting command, with any required arguments.
#
# This option is required.
command: "php ./vendor/bin/rr-worker start --relay-dsn unix:///var/run/rr/rr-relay.sock"
## Environment variables for the worker processes.
##
## Default: <empty map>
#env:
# - SOME_KEY: "SOME_VALUE"
# - SOME_KEY2: "SOME_VALUE2"
# Worker relay can be: "pipes", TCP (eg.: tcp://127.0.0.1:6001), or socket (eg.: unix:///var/run/rr-relay.sock).
#
# Default: "pipes"
relay: "unix:///var/run/rr/rr-relay.sock"
# Timeout for relay connection establishing (only for socket and TCP port relay).
#
# Default: 60s
relay_timeout: 60s
# Logging settings (docs: https://roadrunner.dev/docs/beep-beep-logging)
logs:
# Logging mode can be "development" or "production". Do not forget to change this value for production environment.
#
# Development mode (which makes DPanicLevel logs panic), uses a console encoder, writes to standard error, and
# disables sampling. Stacktraces are automatically included on logs of WarnLevel and above.
#
# Default: "development"
mode: production
# Logging level can be "panic", "error", "warning", "info", "debug".
#
# Default: "debug"
level: debug
# Encoding format can be "console" or "json" (last is preferred for production usage).
#
# Default: "console"
encoding: json
# HTTP plugin settings.
http:
# Host and port to listen on (eg.: `127.0.0.1:8080`).
#
# This option is required.
address: 0.0.0.0:8080
# Maximal incoming request size in megabytes. Zero means no limit.
#
# Default: 0
max_request_size: 256
# Middlewares for the http plugin, order is important. Allowed values is: "headers", "gzip".
#
# Default value: []
middleware: ["static", "headers", "gzip"]
# File uploading settings.
uploads:
# Directory for file uploads. Empty value means to use $TEMP based on your OS.
#
# Default: ""
dir: "/tmp"
# Deny files with the following extensions to upload.
#
# Default: [".php", ".exe", ".bat"]
forbid: [".php", ".exe", ".bat", ".sh"]
# Settings for "headers" middleware (docs: https://roadrunner.dev/docs/http-headers).
headers:
# Automatically add headers to every response.
#
# Default: <empty map>
response:
X-Powered-By: "RoadRunner"
# Settings for serving static content (docs: https://roadrunner.dev/docs/http-static).
static:
# Path to the directory with static assets.
#
# This option is required.
dir: "/app/public"
# File extensions to forbid.
#
# Default: []
forbid: [".htaccess", ".php"]
# Automatically add headers to every response.
#
# Default: <empty map>
response:
X-Powered-By: "RoadRunner"
# Workers pool settings.
pool:
# How many worker processes will be started. Zero (or nothing) means the number of logical CPUs.
#
# Default: 0
num_workers: 0
# Maximal count of worker executions. Zero (or nothing) means no limit.
#
# Default: 0
max_jobs: 64
# Timeout for worker allocation. Zero means no limit.
#
# Default: 60s
allocate_timeout: 10s
# Timeout for worker destroying before process killing. Zero means no limit.
#
# Default: 60s
destroy_timeout: 10s
# Supervisor is used to control http workers (previous name was "limit", docs:
# https://roadrunner.dev/docs/php-limit). "Soft" limits will not interrupt current request processing. "Hard"
# limit on the contrary - interrupts the execution of the request.
supervisor:
# Maximal worker memory usage in megabytes (soft limit). Zero means no limit.
#
# Default: 0
max_worker_memory: 128
# Maximal job lifetime (hard limit). Zero means no limit.
#
# Default: 0s
exec_ttl: 60s
# SSL (Secure Sockets Layer) settings (docs: https://roadrunner.dev/docs/http-https).
ssl:
# Host and port to listen on (eg.: `127.0.0.1:443`).
#
# Default: ":443"
address: 0.0.0.0:8443
# Automatic redirect from http:// to https:// schema.
#
# Default: false
redirect: false
# Path to the cert file. This option is required for SSL working.
#
# This option is required.
cert: /etc/ssl/certs/selfsigned.crt
# Path to the cert key file.
#
# This option is required.
key: /etc/ssl/private/selfsigned.key
# HTTP/2 settings.
http2:
# HTTP/2 over non-encrypted TCP connection using H2C.
#
# Default: false
h2c: false
# Maximal concurrent streams count.
#
# Default: 128
max_concurrent_streams: 128
## Application metrics in Prometheus format (docs: https://roadrunner.dev/docs/beep-beep-metrics). Drop this section
## for this feature disabling.
#metrics:
# # Prometheus client address (path /metrics added automatically).
# #
# # Default: "127.0.0.1:2112"
# address: 127.0.0.1:8081
# Health check endpoint (docs: https://roadrunner.dev/docs/beep-beep-health). If response code is 200 - it means at
# least one worker ready to serve requests. 500 - there are no workers ready to service requests.
# Drop this section for this feature disabling.
status:
# Host and port to listen on (eg.: `127.0.0.1:2114`). Use the following URL: http://127.0.0.1:2114/health?plugin=http
# Multiple plugins must be separated using "&" - http://127.0.0.1:2114/health?plugin=http&plugin=rpc where "http" and
# "rpc" are active (connected) plugins.
#
# This option is required.
address: 127.0.0.1:8082
# Response status code if a requested plugin not ready to handle requests
# Valid for both /health and /ready endpoints
#
# Default: 503
unavailable_status_code: 503
# RoadRunner internal container configuration (docs: https://github.com/spiral/endure).
endure:
# Logging level. Possible values: "debug", "info", "warning", "error", "panic", "fatal".
#
# Default: "error"
log_level: error

58
Dockerfile Normal file
View File

@ -0,0 +1,58 @@
FROM spiralscout/roadrunner:2.10.6 as roadrunner
FROM composer:2.3.9 as composer
FROM mlocati/php-extension-installer:1.5.29 as php-ext-installer
FROM php:8.0-bullseye as runtime
COPY --from=composer /usr/bin/composer /usr/bin/composer
COPY --from=php-ext-installer /usr/bin/install-php-extensions /usr/local/bin/
ENV COMPOSER_HOME="/tmp/composer"
RUN install-php-extensions gd exif intl bz2 gettext mongodb-stable redis curl mbstring redis opcache sockets pcntl
RUN set -ex \
&& apt-get update && apt-get install -y --no-install-recommends \
openssl \
git \
dos2unix \
unzip; \
# install supercronic (for laravel task scheduling), project page: <https://github.com/aptible/supercronic>
&& wget -q "https://github.com/aptible/supercronic/releases/download/v0.1.12/supercronic-linux-amd64" \
-O /usr/bin/supercronic \
&& chmod +x /usr/bin/supercronic \
&& mkdir /etc/supercronic \
&& echo '*/1 * * * * php /app/artisan schedule:run' > /etc/supercronic/laravel \
&& rm -rf /var/lib/apt/lists/* \
# enable opcache for CLI and JIT, docs: <https://www.php.net/manual/en/opcache.configuration.php#ini.opcache.jit>
&& echo -e "\nopcache.enable=1\nopcache.enable_cli=1\nopcache.jit_buffer_size=32M\nopcache.jit=1235\n" >> \
${PHP_INI_DIR}/conf.d/docker-php-ext-opcache.ini \
# show installed modules
&& php -m \
# create unpriviliged user
&& adduser --disabled-password --shell "/sbin/nologin" --home "/nonexistent" --no-create-home --uid "10001" --gecos "" "jikanapi" \
&& mkdir /app /var/run/rr \
&& chown -R jikanapi:jikanapi /app /var/run/rr \
&& chmod -R 777 /var/run/rr
# install roadrunner
COPY --from=roadrunner /usr/bin/rr /usr/bin/rr
USER jikanapi:jikanapi
WORKDIR /app
# copy composer (json|lock) files for dependencies layer caching
COPY --chown=jikanapi:jikanapi ./composer.* /app/
# install composer dependencies (autoloader MUST be generated later!)
RUN composer install -n --no-dev --no-cache --no-ansi --no-autoloader --no-scripts --prefer-dist
# copy application sources into image (completely)
COPY --chown=jikanapi:jikanapi . /app/
RUN set -ex \
&& composer update jikan-me/jikan \
&& composer dump-autoload -n --optimize \
&& chmod -R 777 ${COMPOSER_HOME}/cache \
&& chmod -R a+w storage/ \
&& chown -R jikanapi:jikanapi /app
# unset default image entrypoint
ENTRYPOINT []

View File

@ -25,7 +25,16 @@ Please read the [manual installation guide](https://github.com/jikan-me/jikan-re
For any additional help, join our [Discord server](http://discord.jikan.moe/).
### 🐳 Docker Installation
If you don't want to install it manually, you can use the [docker image](https://github.com/jikan-me/jikan-docker)
We distribute the app as a container image so you can just run it:
```bash
docker run -d --name=jikan-rest -p 8080:8080 -p 8443:8443 -v ./.env:/app/.env jikan-rest:latest rr serve -c .rr.local.unix.yaml
```
Additionally, there is a `Dockerfile` in the repo which you can use to build the container image and startup the app in a container:
```bash
docker build -t jikan-rest:nightly .
docker run -d --name=jikan-rest -p 8080:8080 -p 8443:8443 -v ./.env:/app/.env jikan-rest:nightly rr serve -c .rr.local.unix.yaml
```
## Public REST API
If you don't want to host your instance, there's a public API available.

View File

@ -52,7 +52,7 @@ class GithubReport
/**
* @var string|bool
*/
private string|bool $redisRunning;
private string|bool $redisRunning = false;
/**
* @var string
@ -94,7 +94,12 @@ class GithubReport
$report->instanceType = 'UNKNOWN';
if (env('APP_ENV') !== 'testing') {
$report->instanceType = $_SERVER['SERVER_NAME'] === 'api.jikan.moe' ? 'OFFICIAL' : 'HOSTED';
if (array_key_exists('SERVER_NAME', $_SERVER)) {
$report->instanceType = $_SERVER['SERVER_NAME'] === 'api.jikan.moe' ? 'OFFICIAL' : 'HOSTED';
}
else {
$report->instanceType = 'HOSTED-RR';
}
}
return $report;

View File

@ -45,7 +45,7 @@ class Insights
->insert([
'timestamp' => time(),
'url' => $request->getRequestUri(),
'type' =>
'type' => ""
]);
}

View File

@ -0,0 +1,37 @@
<?php
namespace App\Listeners;
use pushrbx\LumenRoadRunner\Events\Contracts\WithApplication;
use pushrbx\LumenRoadRunner\Listeners\ListenerInterface;
class PsrWorkerBeforeRequestHandlingListener implements ListenerInterface
{
public function handle($event): void
{
if ($event instanceof WithApplication) {
$app = $event->application();
$serviceProviderClass = "";
if (env("SCOUT_DRIVER") === "typesense") {
$serviceProviderClass = \Typesense\LaravelTypesense\TypesenseServiceProvider::class;
}
if (env("SCOUT_DRIVER") === "Matchish\ScoutElasticSearch\Engines\ElasticSearchEngine") {
$serviceProviderClass = \Matchish\ScoutElasticSearch\ElasticSearchServiceProvider::class;
}
if ($serviceProviderClass !== "") {
$provider = new $serviceProviderClass($app);
$provider->register();
if (\method_exists($provider, $boot_method = 'boot')) {
$app->call([$provider, $boot_method]);
}
}
}
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Listeners;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use pushrbx\LumenRoadRunner\Events\LoopErrorOccurredEvent;
class PsrWorkerErrorListener
{
private \App\Exceptions\Handler $exceptionHandler;
private Logger $logger;
public function __construct()
{
$this->exceptionHandler = new \App\Exceptions\Handler;
$this->logger = new Logger('psr-worker');
$this->logger->pushHandler(new StreamHandler(storage_path().'/logs/psr-worker.log'), env('APP_DEBUG') ? Logger::DEBUG : Logger::WARNING);
}
public function handle(LoopErrorOccurredEvent $event): void
{
$this->logger->info("error logging...");
try {
$this->exceptionHandler->report($event->exception());
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
}
}
}

View File

@ -23,6 +23,7 @@ use App\Services\TypeSenseScoutSearchService;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Collection;
use Laravel\Scout\Builder as ScoutBuilder;
use Typesense\LaravelTypesense\Typesense;
class AppServiceProvider extends ServiceProvider
{
@ -161,4 +162,27 @@ class AppServiceProvider extends ServiceProvider
{
return $app["config"]->get("scout.driver");
}
public static function servicesToWarm(): array
{
$services = [
ScoutSearchService::class,
AnimeSearchQueryBuilder::class,
MangaSearchQueryBuilder::class,
ClubSearchQueryBuilder::class,
CharacterSearchQueryBuilder::class,
PeopleSearchQueryBuilder::class,
TopAnimeQueryBuilder::class,
TopMangaQueryBuilder::class
];
if (env("SCOUT_DRIVER") === "typesense") {
$services[] = Typesense::class;
}
if (env("SCOUT_DRIVER") === "Matchish\ScoutElasticSearch\Engines\ElasticSearchEngine") {
$services[] = \Elastic\Elasticsearch\Client::class;
}
return $services;
}
}

View File

@ -3,6 +3,7 @@
namespace App\Providers;
use Laravel\Lumen\Providers\EventServiceProvider as ServiceProvider;
use pushrbx\LumenRoadRunner\Events\LoopErrorOccurredEvent;
class EventServiceProvider extends ServiceProvider
{
@ -12,8 +13,8 @@ class EventServiceProvider extends ServiceProvider
* @var array
*/
protected $listen = [
'App\Events\SomeEvent' => [
'App\Listeners\EventListener',
],
LoopErrorOccurredEvent::class => [
\App\Listeners\PsrWorkerErrorListener::class
]
];
}

View File

@ -112,10 +112,13 @@ $app->configure('database');
$app->configure('queue');
$app->configure('controller-to-table-mapping');
$app->configure('controller');
$app->configure('roadrunner');
$app->register(\pushrbx\LumenRoadRunner\ServiceProvider::class);
$app->register(\SwaggerLume\ServiceProvider::class);
$app->register(Flipbox\LumenGenerator\LumenGeneratorServiceProvider::class);
$app->register(\App\Providers\SourceHeartbeatProvider::class);
$app->register(\App\Providers\EventServiceProvider::class);
$app->register(Illuminate\Database\Eloquent\LegacyFactoryServiceProvider::class);
$app->register(\App\Providers\AppServiceProvider::class);
@ -153,7 +156,7 @@ $app->register(Laravel\Scout\ScoutServiceProvider::class);
// we support TypeSense and ElasticSearch as search indexes.
if (env("SCOUT_DRIVER") === "typesense") {
// in this case the TYPESENSE_HOST env var should be set too
$app->register(Typesense\LaravelTypesense\TypesenseServiceProvider::class);
$app->register(\Typesense\LaravelTypesense\TypesenseServiceProvider::class);
}
if (env("SCOUT_DRIVER") === "Matchish\ScoutElasticSearch\Engines\ElasticSearchEngine") {
// in this case the ELASTICSEARCH_HOST env var should be set too

View File

@ -4,6 +4,12 @@
"keywords": ["framework", "laravel", "lumen"],
"license": "MIT",
"type": "project",
"repositories": [
{
"type": "vcs",
"url": "https://github.com/pushrbx/lumen-roadrunner"
}
],
"require": {
"php": "^8.0",
"ext-json": "*",
@ -28,7 +34,8 @@
"symfony/yaml": "^4.1",
"typesense/laravel-scout-typesense-driver": "^5.0",
"vlucas/phpdotenv": "^5",
"zircote/swagger-php": "3.*"
"zircote/swagger-php": "3.*",
"pushrbx/lumen-roadrunner": "dev-master"
},
"require-dev": {
"mockery/mockery": "^1.3.1",

125
config/roadrunner.php Normal file
View File

@ -0,0 +1,125 @@
<?php
use pushrbx\LumenRoadRunner\Events;
use pushrbx\LumenRoadRunner\Defaults;
use pushrbx\LumenRoadRunner\Listeners;
use Spiral\RoadRunner\Environment\Mode;
return [
/*
|--------------------------------------------------------------------------
| Force HTTPS Schema Usage
|--------------------------------------------------------------------------
|
| Set this value to `true` if your application uses HTTPS (required for
| correct links generation, for example).
|
*/
'force_https' => (bool)env('APP_FORCE_HTTPS', false),
/*
|--------------------------------------------------------------------------
| Event Listeners
|--------------------------------------------------------------------------
|
| Worker provided by this package allows to interacts with request
| processing loop using application events.
|
| Feel free to add your own event listeners.
|
*/
'listeners' => [
Events\BeforeLoopStartedEvent::class => [
...Defaults::beforeLoopStarted(),
],
Events\BeforeLoopIterationEvent::class => [
...Defaults::beforeLoopIteration(),
],
Events\BeforeRequestHandlingEvent::class => [
...Defaults::beforeRequestHandling(),
Listeners\InjectStatsIntoRequestListener::class,
\App\Listeners\PsrWorkerBeforeRequestHandlingListener::class
],
Events\AfterRequestHandlingEvent::class => [
...Defaults::afterRequestHandling(),
],
Events\AfterLoopIterationEvent::class => [
...Defaults::afterLoopIteration(),
Listeners\RunGarbageCollectorListener::class, // keep the memory usage low
// Listeners\CleanupUploadedFilesListener::class, // remove temporary files
],
Events\AfterLoopStoppedEvent::class => [
...Defaults::afterLoopStopped(),
],
Events\LoopErrorOccurredEvent::class => [
...Defaults::loopErrorOccurred(),
Listeners\SendExceptionToStderrListener::class,
Listeners\StopWorkerListener::class,
\App\Listeners\PsrWorkerErrorListener::class,
],
],
/*
|--------------------------------------------------------------------------
| Containers Pre Resolving / Clearing
|--------------------------------------------------------------------------
|
| The bindings listed below will be resolved before the events loop
| starting. Clearing a binding will force the container to resolve that
| binding again when asked.
|
| Feel free to add your own bindings here.
|
*/
'warm' => [
...Defaults::servicesToWarm(),
...\App\Providers\AppServiceProvider::servicesToWarm(),
],
'clear' => [
...Defaults::servicesToClear(),
'auth', // is not required for Laravel >= v8.35
],
/*
|--------------------------------------------------------------------------
| Reset Providers
|--------------------------------------------------------------------------
|
| Providers that will be registered on every request.
|
| Feel free to add your service-providers here.
|
*/
'reset_providers' => [
...Defaults::providersToReset(),
Illuminate\Auth\AuthServiceProvider::class, // is not required for Laravel >= v8.35
Illuminate\Pagination\PaginationServiceProvider::class, // is not required for Laravel >= v8.35
],
/*
|--------------------------------------------------------------------------
| Worker Classes
|--------------------------------------------------------------------------
|
| Here you can override the worker class for processing different kinds of
| jobs, that received from the RoadRunner daemon. The key is a worker mode.
|
*/
'workers' => [
Mode::MODE_HTTP => \pushrbx\LumenRoadRunner\Worker::class,
// Mode::MODE_JOBS => ...,
// Mode::MODE_TEMPORAL => ...,
],
];

90
docker-compose.yml Normal file
View File

@ -0,0 +1,90 @@
# For now this is just for local development. This is not production ready.
version: '3.8'
volumes:
mongo-data: {}
redis-data: {}
tmp-data: {}
typesense-data: {}
services:
jikan_rest: &jikan_rest
build:
context: .
dockerfile: Dockerfile
user: "${APP_UID:-10001}:${APP_GID:-10001}"
environment:
PS1: '\[\033[1;32m\]\[\033[1;36m\][\u@\h] \[\033[1;34m\]\w\[\033[0;35m\] \[\033[1;36m\]# \[\033[0m\]'
HOME: /tmp
APP_DEBUG: 'true'
APP_ENV: local
REDIS_HOST: redis
REDIS_PASSWORD: redis_password
DB_CONNECTION: mongodb
DB_HOST: mongodb
DB_DATABASE: jikan
DB_PORT: 27017
DB_ADMIN: jikan
DB_USERNAME: jikan_user
DB_PASSWORD: forge
volumes:
- /etc/passwd:/etc/passwd:ro
- /etc/group:/etc/group:ro
- tmp-data:/tmp:rw
- .:/app:rw
depends_on:
mongodb: {condition: service_healthy}
redis: {condition: service_healthy}
typesense: {condition: service_healthy}
web:
<<: *jikan_rest
command: rr serve -c .rr.local.unix.yaml
ports:
- '8080:8080/tcp'
- '8443:8443/tcp'
healthcheck:
test: [ 'CMD-SHELL', 'wget --spider -q "http://127.0.0.1:8082/health?plugin=http&plugin=rpc"' ]
interval: 2s
timeout: 2s
# todo: integrate this in a worker class and configure road runner to allocate it when the web container starts
queue:
<<: *jikan_rest
command: php /app/artisan queue:work --memory=256 --sleep=1
cron:
<<: *jikan_rest
command: supercronic /etc/supercronic/laravel # it runs artisan schedule:run
mongodb:
image: mongo:focal
volumes:
- mongo-data:/data/db
ports:
- '27017/tcp'
command: --wiredTigerCacheSizeGB 1
healthcheck:
test: echo 'db.runCommand("ping").ok' | mongo mongodb://localhost:27017 --quiet
interval: 30s
timeout: 10s
retries: 5
redis:
image: redis:7-alpine
command: redis-server --requirepass redis_password
volumes:
- redis-data:/data:rw
ports:
- '6379/tcp'
healthcheck:
test: [ 'CMD', 'redis-cli', 'ping' ]
interval: 500ms
timeout: 1s
typesense:
image: typesense/typesense:0.23.1
command: -data-dir /data --api-key "typesenseapikeycomeshere"
restart: no
volumes:
- typesense-data:/data
ports:
- "8108/tcp"