Implement Roadrunner PHP application server for high-performance PHP and Centrifugo event hooks.
This commit is contained in:
parent
f4b54c3eb6
commit
e890106010
|
@ -27,6 +27,11 @@ FROM ghcr.io/azuracast/azuracast.com:builtin AS docs
|
|||
#
|
||||
FROM ghcr.io/azuracast/icecast-kh-ac:latest AS icecast
|
||||
|
||||
#
|
||||
# Roadrunner build step
|
||||
#
|
||||
FROM ghcr.io/roadrunner-server/roadrunner:2023.3.8 AS roadrunner
|
||||
|
||||
#
|
||||
# Final build image
|
||||
#
|
||||
|
@ -49,6 +54,9 @@ COPY --from=mariadb /etc/apt/trusted.gpg.d/mariadb.gpg /etc/apt/trusted.gpg.d/ma
|
|||
COPY --from=icecast /usr/local/bin/icecast /usr/local/bin/icecast
|
||||
COPY --from=icecast /usr/local/share/icecast /usr/local/share/icecast
|
||||
|
||||
# Add Roadrunner
|
||||
COPY --from=roadrunner /usr/bin/rr /usr/local/bin/rr
|
||||
|
||||
# Run base build process
|
||||
COPY ./util/docker/common /bd_build/
|
||||
|
||||
|
|
|
@ -66,10 +66,12 @@
|
|||
"psr/simple-cache": "^3.0",
|
||||
"ramsey/uuid": "^4.0",
|
||||
"rlanvin/php-ip": "dev-master",
|
||||
"roadrunner-php/centrifugo": "^2.0",
|
||||
"skoerfgen/acmecert": "^3.2",
|
||||
"slim/http": "^1.1",
|
||||
"slim/slim": "^4.2",
|
||||
"spatie/flysystem-dropbox": "^3",
|
||||
"spiral/roadrunner-http": "^3.3",
|
||||
"spomky-labs/otphp": "^11",
|
||||
"supervisorphp/supervisor": "dev-main",
|
||||
"symfony/cache": "^6",
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "937d84fd61dbb782e05b56a7d49ee79e",
|
||||
"content-hash": "4613de83e017a7053418e8b1903b34d2",
|
||||
"packages": [
|
||||
{
|
||||
"name": "aws/aws-crt-php",
|
||||
|
@ -2192,6 +2192,50 @@
|
|||
],
|
||||
"time": "2023-11-06T15:42:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "google/protobuf",
|
||||
"version": "v3.25.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/protocolbuffers/protobuf-php.git",
|
||||
"reference": "1fb247e72df401c863ed239c1660f981644af5db"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/1fb247e72df401c863ed239c1660f981644af5db",
|
||||
"reference": "1fb247e72df401c863ed239c1660f981644af5db",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": ">=5.0.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-bcmath": "Need to support JSON deserialization"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Google\\Protobuf\\": "src/Google/Protobuf",
|
||||
"GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"description": "proto library for PHP",
|
||||
"homepage": "https://developers.google.com/protocol-buffers/",
|
||||
"keywords": [
|
||||
"proto"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v3.25.1"
|
||||
},
|
||||
"time": "2023-11-15T21:36:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "graham-campbell/guzzle-factory",
|
||||
"version": "v7.0.1",
|
||||
|
@ -5932,6 +5976,151 @@
|
|||
},
|
||||
"time": "2022-03-02T08:51:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "roadrunner-php/centrifugo",
|
||||
"version": "2.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/roadrunner-php/centrifugo.git",
|
||||
"reference": "9b48bfa1d6aee0c889ea77bb2afe8f733e0ad8e7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/roadrunner-php/centrifugo/zipball/9b48bfa1d6aee0c889ea77bb2afe8f733e0ad8e7",
|
||||
"reference": "9b48bfa1d6aee0c889ea77bb2afe8f733e0ad8e7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"google/protobuf": "^3.7",
|
||||
"php": ">=8.1",
|
||||
"roadrunner-php/roadrunner-api-dto": "^1.0",
|
||||
"spiral/goridge": "^4.0",
|
||||
"spiral/roadrunner": "^2023.1",
|
||||
"spiral/roadrunner-worker": "^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"mockery/mockery": "^1.5",
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"vimeo/psalm": ">= 5.8"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"RoadRunner\\Centrifugo\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Anton Titov (wolfy-j)",
|
||||
"email": "wolfy-j@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "Pavel Buchnev (butschster)",
|
||||
"email": "pavel.buchnev@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "Aleksei Gagarin (roxblnfk)",
|
||||
"email": "alexey.gagarin@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "Maksim Smakouz (msmakouz)",
|
||||
"email": "maksim.smakouz@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "Kirill Nesmeyanov (SerafimArts)",
|
||||
"email": "kirill.nesmeyanov@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "RoadRunner Community",
|
||||
"homepage": "https://github.com/spiral/roadrunner/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "RoadRunner: Centrifugo bridge",
|
||||
"homepage": "https://roadrunner.dev/",
|
||||
"support": {
|
||||
"chat": "https://discord.gg/V6EK4he",
|
||||
"docs": "https://roadrunner.dev/docs",
|
||||
"forum": "https://forum.roadrunner.dev/",
|
||||
"issues": "https://github.com/roadrunner-server/roadrunner/issues",
|
||||
"source": "https://github.com/roadrunner-php/centrifugo/tree/2.0.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sponsors/roadrunner-server",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-04-13T11:38:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "roadrunner-php/roadrunner-api-dto",
|
||||
"version": "1.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/roadrunner-php/roadrunner-api-dto.git",
|
||||
"reference": "82e0889171086b485bd4c31a3575b8ffa531e6d1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/roadrunner-php/roadrunner-api-dto/zipball/82e0889171086b485bd4c31a3575b8ffa531e6d1",
|
||||
"reference": "82e0889171086b485bd4c31a3575b8ffa531e6d1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"google/protobuf": "^v3.22",
|
||||
"php": "^8.1"
|
||||
},
|
||||
"conflict": {
|
||||
"temporal/sdk": "<2.6.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Temporal\\": "generated/Temporal",
|
||||
"RoadRunner\\": "generated/RoadRunner",
|
||||
"GPBMetadata\\": "generated/GPBMetadata"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Pavel Butchnev (butschster)",
|
||||
"email": "pavel.buchnev@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "Aleksei Gagarin (roxblnfk)",
|
||||
"email": "alexey.gagarin@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "RoadRunner Community",
|
||||
"homepage": "https://github.com/roadrunner-server/roadrunner/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "RoadRunner PHP API",
|
||||
"homepage": "https://roadrunner.dev/",
|
||||
"support": {
|
||||
"chat": "https://discord.gg/V6EK4he",
|
||||
"docs": "https://roadrunner.dev/docs",
|
||||
"forum": "https://forum.roadrunner.dev/",
|
||||
"issues": "https://github.com/roadrunner-server/roadrunner/issues",
|
||||
"source": "https://github.com/roadrunner-php/roadrunner-api-dto/tree/1.4.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sponsors/roadrunner-server",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-10-11T13:36:31+00:00"
|
||||
},
|
||||
{
|
||||
"name": "skoerfgen/acmecert",
|
||||
"version": "3.3.1",
|
||||
|
@ -6371,6 +6560,314 @@
|
|||
],
|
||||
"time": "2023-09-25T07:13:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spiral/goridge",
|
||||
"version": "4.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/roadrunner-php/goridge.git",
|
||||
"reference": "d955f58be1c51daa1eb94a5ddaf4c2daf64ee14e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/roadrunner-php/goridge/zipball/d955f58be1c51daa1eb94a5ddaf4c2daf64ee14e",
|
||||
"reference": "d955f58be1c51daa1eb94a5ddaf4c2daf64ee14e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-sockets": "*",
|
||||
"php": ">=8.1",
|
||||
"spiral/roadrunner": "^2023"
|
||||
},
|
||||
"require-dev": {
|
||||
"google/protobuf": "^3.22",
|
||||
"infection/infection": "^0.26.1",
|
||||
"jetbrains/phpstorm-attributes": "^1.0",
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"rybakit/msgpack": "^0.7",
|
||||
"vimeo/psalm": "^5.9"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-msgpack": "MessagePack codec support",
|
||||
"ext-protobuf": "Protobuf codec support",
|
||||
"google/protobuf": "(^3.0) Protobuf codec support",
|
||||
"rybakit/msgpack": "(^0.7) MessagePack codec support"
|
||||
},
|
||||
"type": "goridge",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spiral\\Goridge\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Anton Titov (wolfy-j)",
|
||||
"email": "wolfy-j@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "Valery Piashchynski",
|
||||
"homepage": "https://github.com/rustatian"
|
||||
},
|
||||
{
|
||||
"name": "Aleksei Gagarin (roxblnfk)",
|
||||
"homepage": "https://github.com/roxblnfk"
|
||||
},
|
||||
{
|
||||
"name": "Pavel Buchnev (butschster)",
|
||||
"email": "pavel.buchnev@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "Maksim Smakouz (msmakouz)",
|
||||
"email": "maksim.smakouz@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "RoadRunner Community",
|
||||
"homepage": "https://github.com/roadrunner-server/roadrunner/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "High-performance PHP-to-Golang RPC bridge",
|
||||
"homepage": "https://spiral.dev/",
|
||||
"support": {
|
||||
"chat": "https://discord.gg/V6EK4he",
|
||||
"docs": "https://roadrunner.dev/docs",
|
||||
"forum": "https://forum.roadrunner.dev/",
|
||||
"issues": "https://github.com/roadrunner-server/roadrunner/issues",
|
||||
"source": "https://github.com/roadrunner-php/goridge/tree/4.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sponsors/roadrunner-server",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-10-03T18:40:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spiral/roadrunner",
|
||||
"version": "v2023.3.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/roadrunner-server/roadrunner.git",
|
||||
"reference": "80eff8aa42c59bc2d2cc9a2fab4e02398fd94994"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/roadrunner-server/roadrunner/zipball/80eff8aa42c59bc2d2cc9a2fab4e02398fd94994",
|
||||
"reference": "80eff8aa42c59bc2d2cc9a2fab4e02398fd94994",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "metapackage",
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Anton Titov / Wolfy-J",
|
||||
"email": "wolfy.jd@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Valery Piashchynski",
|
||||
"homepage": "https://github.com/rustatian"
|
||||
},
|
||||
{
|
||||
"name": "RoadRunner Community",
|
||||
"homepage": "https://github.com/roadrunner-server/roadrunner/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "RoadRunner: High-performance PHP application server and process manager written in Go and powered with plugins",
|
||||
"homepage": "https://roadrunner.dev/",
|
||||
"support": {
|
||||
"chat": "https://discord.gg/V6EK4he",
|
||||
"docs": "https://roadrunner.dev/docs",
|
||||
"forum": "https://forum.roadrunner.dev/",
|
||||
"issues": "https://github.com/roadrunner-server/roadrunner/issues",
|
||||
"source": "https://github.com/roadrunner-server/roadrunner/tree/v2023.3.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sponsors/roadrunner-server",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-12-14T15:48:20+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spiral/roadrunner-http",
|
||||
"version": "3.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/roadrunner-php/http.git",
|
||||
"reference": "7a1f7d0729ad483e9c637ee276f6e910def33f4d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/roadrunner-php/http/zipball/7a1f7d0729ad483e9c637ee276f6e910def33f4d",
|
||||
"reference": "7a1f7d0729ad483e9c637ee276f6e910def33f4d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": ">=8.1",
|
||||
"psr/http-factory": "^1.0.1",
|
||||
"psr/http-message": "^1.0.1 || ^2.0",
|
||||
"spiral/roadrunner": "^2023.3",
|
||||
"spiral/roadrunner-worker": "^3.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"buggregator/trap": "^1.0",
|
||||
"jetbrains/phpstorm-attributes": "^1.0",
|
||||
"nyholm/psr7": "^1.3",
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"symfony/process": "^6.2 || ^7.0",
|
||||
"vimeo/psalm": "^5.9"
|
||||
},
|
||||
"suggest": {
|
||||
"spiral/roadrunner-cli": "Provides RoadRunner installation and management CLI tools"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spiral\\RoadRunner\\Http\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Anton Titov (wolfy-j)",
|
||||
"email": "wolfy-j@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "Valery Piashchynski",
|
||||
"homepage": "https://github.com/rustatian"
|
||||
},
|
||||
{
|
||||
"name": "Aleksei Gagarin (roxblnfk)",
|
||||
"homepage": "https://github.com/roxblnfk"
|
||||
},
|
||||
{
|
||||
"name": "Pavel Buchnev (butschster)",
|
||||
"email": "pavel.buchnev@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "Maksim Smakouz (msmakouz)",
|
||||
"email": "maksim.smakouz@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "RoadRunner Community",
|
||||
"homepage": "https://github.com/roadrunner-server/roadrunner/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "RoadRunner: HTTP and PSR-7 worker",
|
||||
"homepage": "https://spiral.dev/",
|
||||
"support": {
|
||||
"chat": "https://discord.gg/V6EK4he",
|
||||
"docs": "https://roadrunner.dev/docs",
|
||||
"forum": "https://forum.roadrunner.dev/",
|
||||
"issues": "https://github.com/roadrunner-server/roadrunner/issues",
|
||||
"source": "https://github.com/roadrunner-php/http/tree/3.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sponsors/roadrunner-server",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-12-05T20:45:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spiral/roadrunner-worker",
|
||||
"version": "3.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/roadrunner-php/worker.git",
|
||||
"reference": "53f81c3e138a650c4605fcd60cae7c89ef24061f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/roadrunner-php/worker/zipball/53f81c3e138a650c4605fcd60cae7c89ef24061f",
|
||||
"reference": "53f81c3e138a650c4605fcd60cae7c89ef24061f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer-runtime-api": "^2.0",
|
||||
"ext-json": "*",
|
||||
"ext-sockets": "*",
|
||||
"php": ">=8.1",
|
||||
"psr/log": "^2.0|^3.0",
|
||||
"spiral/goridge": "^4.1.0",
|
||||
"spiral/roadrunner": "^2023.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"jetbrains/phpstorm-attributes": "^1.0",
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"symfony/var-dumper": "^6.3 || ^7.0",
|
||||
"vimeo/psalm": "^5.9"
|
||||
},
|
||||
"suggest": {
|
||||
"spiral/roadrunner-cli": "Provides RoadRunner installation and management CLI tools"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spiral\\RoadRunner\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Anton Titov (wolfy-j)",
|
||||
"email": "wolfy-j@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "Valery Piashchynski",
|
||||
"homepage": "https://github.com/rustatian"
|
||||
},
|
||||
{
|
||||
"name": "Aleksei Gagarin (roxblnfk)",
|
||||
"homepage": "https://github.com/roxblnfk"
|
||||
},
|
||||
{
|
||||
"name": "Pavel Buchnev (butschster)",
|
||||
"email": "pavel.buchnev@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "Maksim Smakouz (msmakouz)",
|
||||
"email": "maksim.smakouz@spiralscout.com"
|
||||
},
|
||||
{
|
||||
"name": "RoadRunner Community",
|
||||
"homepage": "https://github.com/roadrunner-server/roadrunner/graphs/contributors"
|
||||
}
|
||||
],
|
||||
"description": "RoadRunner: PHP worker",
|
||||
"homepage": "https://spiral.dev/",
|
||||
"support": {
|
||||
"chat": "https://discord.gg/V6EK4he",
|
||||
"docs": "https://roadrunner.dev/docs",
|
||||
"forum": "https://forum.roadrunner.dev/",
|
||||
"issues": "https://github.com/roadrunner-server/roadrunner/issues",
|
||||
"source": "https://github.com/roadrunner-php/worker/tree/3.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sponsors/roadrunner-server",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2023-12-05T19:53:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spomky-labs/otphp",
|
||||
"version": "11.2.0",
|
||||
|
|
|
@ -69,9 +69,6 @@ return static function (RouteCollectorProxy $app) {
|
|||
$group->post('/sftp-event', Controller\Api\Internal\SftpEventAction::class)
|
||||
->setName('api:internal:sftp-event');
|
||||
|
||||
$group->post('/centrifugo', Controller\Api\Internal\CentrifugoAction::class)
|
||||
->setName('api:internal:centrifugo');
|
||||
|
||||
$group->get('/relays', Controller\Api\Internal\RelaysController::class)
|
||||
->setName('api:internal:relays')
|
||||
->add(Middleware\RequireLogin::class);
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Controller\Api\Internal;
|
||||
|
||||
use App\Cache\NowPlayingCache;
|
||||
use App\Container\LoggerAwareTrait;
|
||||
use App\Controller\SingleActionInterface;
|
||||
use App\Entity\Api\NowPlaying\NowPlaying;
|
||||
use App\Http\Response;
|
||||
use App\Http\ServerRequest;
|
||||
use App\Service\Centrifugo;
|
||||
use App\Utilities\Types;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
|
||||
final class CentrifugoAction implements SingleActionInterface
|
||||
{
|
||||
use LoggerAwareTrait;
|
||||
|
||||
public function __construct(
|
||||
private readonly NowPlayingCache $npCache
|
||||
) {
|
||||
}
|
||||
|
||||
public function __invoke(ServerRequest $request, Response $response, array $params): ResponseInterface
|
||||
{
|
||||
$parsedBody = Types::array($request->getParsedBody());
|
||||
$this->logger->debug('Centrifugo connection body', $parsedBody);
|
||||
|
||||
$channels = array_filter(
|
||||
$parsedBody['channels'] ?? [],
|
||||
fn($channel) => str_starts_with($channel, 'station:') || $channel === Centrifugo::GLOBAL_TIME_CHANNEL
|
||||
);
|
||||
|
||||
$allInitialData = [];
|
||||
|
||||
$router = $request->getRouter();
|
||||
$router->buildBaseUrl(false);
|
||||
|
||||
foreach ($channels as $channel) {
|
||||
$initialData = [];
|
||||
|
||||
if ($channel === Centrifugo::GLOBAL_TIME_CHANNEL) {
|
||||
$initialData['time'] = time();
|
||||
} elseif (str_starts_with($channel, 'station:')) {
|
||||
$stationName = substr($channel, 8);
|
||||
$np = $this->npCache->getForStation($stationName);
|
||||
if (!($np instanceof NowPlaying)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$np->resolveUrls($router->getBaseUrl());
|
||||
$np->update();
|
||||
|
||||
$initialData['np'] = $np;
|
||||
$initialData['triggers'] = [];
|
||||
}
|
||||
|
||||
$allInitialData[] = [
|
||||
'channel' => $channel,
|
||||
'pub' => [
|
||||
'data' => $initialData,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return $response->withJson([
|
||||
'result' => [
|
||||
'user' => '',
|
||||
'channels' => $channels,
|
||||
'data' => $allInitialData,
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -30,27 +30,37 @@ final class Centrifugo
|
|||
'method' => 'publish',
|
||||
'params' => [
|
||||
'channel' => self::GLOBAL_TIME_CHANNEL,
|
||||
'data' => [
|
||||
'time' => time(),
|
||||
],
|
||||
'data' => $this->buildTimeMessage(),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function buildTimeMessage(): array
|
||||
{
|
||||
return [
|
||||
'time' => time(),
|
||||
];
|
||||
}
|
||||
|
||||
public function publishToStation(Station $station, mixed $message, array $triggers): void
|
||||
{
|
||||
$this->send([
|
||||
'method' => 'publish',
|
||||
'params' => [
|
||||
'channel' => $this->getChannelName($station),
|
||||
'data' => [
|
||||
'np' => $message,
|
||||
'triggers' => $triggers,
|
||||
],
|
||||
'data' => $this->buildStationMessage($message, $triggers),
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function buildStationMessage(mixed $message, array $triggers = []): array
|
||||
{
|
||||
return [
|
||||
'np' => $message,
|
||||
'triggers' => $triggers,
|
||||
];
|
||||
}
|
||||
|
||||
private function send(array $body): void
|
||||
{
|
||||
$this->client->post(
|
||||
|
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service\Centrifugo;
|
||||
|
||||
use App\Cache\NowPlayingCache;
|
||||
use App\Container\LoggerAwareTrait;
|
||||
use App\Entity\Api\NowPlaying\NowPlaying;
|
||||
use App\Http\RouterInterface;
|
||||
use App\Service\Centrifugo;
|
||||
use RoadRunner\Centrifugo\Payload\ConnectResponse;
|
||||
use RoadRunner\Centrifugo\Payload\ResponseInterface;
|
||||
use RoadRunner\Centrifugo\Request\Connect;
|
||||
use RoadRunner\Centrifugo\Request\Invalid;
|
||||
use RoadRunner\Centrifugo\Request\RequestInterface;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
final class EventHandler
|
||||
{
|
||||
use LoggerAwareTrait;
|
||||
|
||||
public function __construct(
|
||||
private readonly NowPlayingCache $npCache,
|
||||
private readonly Centrifugo $centrifugo,
|
||||
private readonly RouterInterface $router
|
||||
) {
|
||||
if (!$this->centrifugo->isSupported()) {
|
||||
throw new RuntimeException('Centrifugo is not supported.');
|
||||
}
|
||||
|
||||
$this->router->buildBaseUrl(false);
|
||||
}
|
||||
|
||||
public function __invoke(RequestInterface $request): ?ResponseInterface
|
||||
{
|
||||
if ($request instanceof Invalid) {
|
||||
$e = $request->getException();
|
||||
$this->logger->error(
|
||||
sprintf('Centrifugo error: %s', $e->getMessage()),
|
||||
[
|
||||
'exception' => $e,
|
||||
]
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
if ($request instanceof Connect) {
|
||||
return $this->onConnect($request);
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
$request->error($e->getCode(), $e->getMessage());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function onConnect(Connect $request): ?ResponseInterface
|
||||
{
|
||||
$channels = array_filter(
|
||||
$request->channels,
|
||||
fn($channel) => str_starts_with($channel, 'station:') || $channel === Centrifugo::GLOBAL_TIME_CHANNEL
|
||||
);
|
||||
|
||||
if (empty($channels)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$allInitialData = [];
|
||||
|
||||
foreach ($channels as $channel) {
|
||||
if ($channel === Centrifugo::GLOBAL_TIME_CHANNEL) {
|
||||
$initialData = $this->centrifugo->buildTimeMessage();
|
||||
} elseif (str_starts_with($channel, 'station:')) {
|
||||
$stationName = substr($channel, 8);
|
||||
$np = $this->npCache->getForStation($stationName);
|
||||
if (!($np instanceof NowPlaying)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$np->resolveUrls($this->router->getBaseUrl());
|
||||
$np->update();
|
||||
|
||||
$initialData = $this->centrifugo->buildStationMessage($np);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
$allInitialData[] = [
|
||||
'channel' => $channel,
|
||||
'pub' => [
|
||||
'data' => $initialData,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return new ConnectResponse(
|
||||
user: '',
|
||||
data: $allInitialData,
|
||||
channels: $channels
|
||||
);
|
||||
}
|
||||
}
|
|
@ -80,7 +80,7 @@ final class ServiceControl
|
|||
'cron' => __('Runs routine synchronized tasks'),
|
||||
'mariadb' => __('Database'),
|
||||
'nginx' => __('Web server'),
|
||||
'php-fpm' => __('PHP FastCGI Process Manager'),
|
||||
'roadrunner' => __('Roadrunner PHP Server'),
|
||||
'php-nowplaying' => __('Now Playing manager service'),
|
||||
'php-worker' => __('PHP queue processing worker'),
|
||||
'redis' => __('Cache'),
|
||||
|
|
|
@ -20,4 +20,3 @@ apt-get remove --purge -y php${PHP_VERSION}-dev zlib1g-dev build-essential
|
|||
|
||||
echo "extension=spx.so" > /etc/php/${PHP_VERSION}/mods-available/30-spx.ini
|
||||
ln -s /etc/php/${PHP_VERSION}/mods-available/30-spx.ini /etc/php/${PHP_VERSION}/cli/conf.d/30-spx.ini
|
||||
ln -s /etc/php/${PHP_VERSION}/mods-available/30-spx.ini /etc/php/${PHP_VERSION}/fpm/conf.d/30-spx.ini
|
||||
|
|
|
@ -8,8 +8,10 @@ websocket_disable: true
|
|||
uni_websocket: true
|
||||
uni_sse: true
|
||||
uni_http_stream: true
|
||||
proxy_connect_endpoint: http://localhost:6010/api/internal/centrifugo
|
||||
proxy_connect_endpoint: grpc://127.0.0.1:6300
|
||||
proxy_connect_timeout: 10s
|
||||
grpc_api: true
|
||||
grpc_api_port: 6301
|
||||
allowed_origins:
|
||||
- "*"
|
||||
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
upstream php-fpm-internal {
|
||||
server unix:/var/run/php-fpm-internal.sock;
|
||||
}
|
||||
|
||||
upstream php-fpm-www {
|
||||
server unix:/var/run/php-fpm-www.sock;
|
||||
upstream roadrunner {
|
||||
server 127.0.0.1:6090;
|
||||
}
|
||||
|
||||
upstream centrifugo {
|
||||
|
@ -16,40 +12,6 @@ upstream vite {
|
|||
}
|
||||
{{end}}
|
||||
|
||||
# Internal connection handler for PubSub and internal API calls
|
||||
server {
|
||||
listen 127.0.0.1:6010;
|
||||
|
||||
root /var/azuracast/www/web;
|
||||
index index.php;
|
||||
|
||||
server_name localhost;
|
||||
|
||||
# Default clean URL routing
|
||||
location / {
|
||||
try_files $uri @clean_url;
|
||||
}
|
||||
|
||||
location @clean_url {
|
||||
rewrite ^(.*)$ /index.php last;
|
||||
}
|
||||
|
||||
location ~ ^/index\.php(/|$) {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
|
||||
fastcgi_pass php-fpm-internal;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
fastcgi_param DOCUMENT_ROOT $realpath_root;
|
||||
include fastcgi_params;
|
||||
|
||||
fastcgi_read_timeout 600;
|
||||
fastcgi_buffering off;
|
||||
|
||||
internal;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen {{ default .Env.AZURACAST_HTTP_PORT "80" }};
|
||||
listen {{ default .Env.AZURACAST_HTTPS_PORT "443" }} default_server http2 ssl;
|
||||
|
@ -134,18 +96,10 @@ server {
|
|||
{{end}}
|
||||
|
||||
location ~ ^/index\.php(/|$) {
|
||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||
|
||||
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
|
||||
fastcgi_pass php-fpm-www;
|
||||
fastcgi_index index.php;
|
||||
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
|
||||
fastcgi_param DOCUMENT_ROOT $realpath_root;
|
||||
include fastcgi_params;
|
||||
|
||||
fastcgi_pass roadrunner;
|
||||
fastcgi_read_timeout {{ default .Env.NGINX_TIMEOUT "1800" }};
|
||||
fastcgi_buffering off;
|
||||
|
||||
internal;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
[global]
|
||||
error_log = /dev/stderr
|
||||
daemonize = no
|
||||
|
||||
[www]
|
||||
user = azuracast
|
||||
group = azuracast
|
||||
|
||||
listen = /var/run/php-fpm-www.sock
|
||||
listen.owner = azuracast
|
||||
listen.group = www-data
|
||||
listen.mode = 0660
|
||||
|
||||
pm = ondemand
|
||||
pm.max_children = {{ default .Env.PHP_FPM_MAX_CHILDREN "20" }}
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 2
|
||||
pm.max_spare_servers = 4
|
||||
pm.max_requests = 200
|
||||
pm.status_path = /status
|
||||
pm.process_idle_timeout = 60s
|
||||
|
||||
chdir = /
|
||||
clear_env=No
|
||||
catch_workers_output = yes
|
||||
decorate_workers_output = no
|
||||
|
||||
{{if eq .Env.PROFILING_EXTENSION_ENABLED "1"}}
|
||||
process.dumpable = yes
|
||||
{{end}}
|
||||
|
||||
[internal]
|
||||
user = azuracast
|
||||
group = azuracast
|
||||
|
||||
listen = /var/run/php-fpm-internal.sock
|
||||
listen.owner = azuracast
|
||||
listen.group = www-data
|
||||
listen.mode = 0660
|
||||
|
||||
pm = ondemand
|
||||
pm.max_children = 10
|
||||
pm.start_servers = 2
|
||||
pm.min_spare_servers = 2
|
||||
pm.max_spare_servers = 4
|
||||
pm.max_requests = 50
|
||||
pm.process_idle_timeout = 60s
|
||||
|
||||
chdir = /
|
||||
|
||||
clear_env=No
|
||||
catch_workers_output = yes
|
||||
decorate_workers_output = no
|
|
@ -0,0 +1,30 @@
|
|||
version: '3'
|
||||
|
||||
rpc:
|
||||
listen: tcp://127.0.0.1:6401
|
||||
|
||||
server:
|
||||
relay: pipes
|
||||
command: "php util/rr_http_worker.php"
|
||||
|
||||
logs:
|
||||
mode: {{if eq .Env.APPLICATION_ENV "development"}}development{{else}}production{{end}}
|
||||
|
||||
http:
|
||||
address: 0.0.0.0:6010
|
||||
fcgi:
|
||||
address: tcp://127.0.0.1:6090
|
||||
pool:
|
||||
debug: {{if eq .Env.APPLICATION_ENV "development"}}true{{else}}false{{end}}
|
||||
max_jobs: 50
|
||||
|
||||
centrifuge:
|
||||
proxy_address: tcp://127.0.0.1:6300
|
||||
grpc_api_address: tcp://127.0.0.1:6301
|
||||
use_compressor: true
|
||||
name: "azuracast"
|
||||
pool:
|
||||
debug: {{if eq .Env.APPLICATION_ENV "development"}}true{{else}}false{{end}}
|
||||
command: "php util/rr_centrifugo_worker.php"
|
||||
num_workers: 1
|
||||
max_jobs: 250
|
|
@ -1,20 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
source /etc/php/.version
|
||||
|
||||
# Set up PHP config
|
||||
dockerize -template "/etc/php/${PHP_VERSION}/fpm/05-azuracast.ini.tmpl:/etc/php/${PHP_VERSION}/fpm/conf.d/05-azuracast.ini" \
|
||||
-template "/etc/php/${PHP_VERSION}/fpm/www.conf.tmpl:/etc/php/${PHP_VERSION}/fpm/pool.d/www.conf" \
|
||||
cp /etc/php/${PHP_VERSION}/fpm/conf.d/05-azuracast.ini /etc/php/${PHP_VERSION}/cli/conf.d/05-azuracast.ini
|
||||
|
||||
# Wait for services to spin up.
|
||||
gosu azuracast php /var/azuracast/www/bin/uptime_wait || exit 1
|
||||
|
||||
# Initialize before running FPM
|
||||
gosu azuracast azuracast_cli azuracast:setup --init || exit 1
|
||||
|
||||
# Run initial Acme check
|
||||
gosu azuracast azuracast_cli azuracast:acme:get-certificate || true
|
||||
|
||||
# Run PHP-FPM
|
||||
exec /usr/sbin/php-fpm${PHP_VERSION} -F --fpm-config /etc/php/${PHP_VERSION}/fpm/php-fpm.conf -c /etc/php/${PHP_VERSION}/fpm/
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ $(whoami) != 'azuracast' ]; then
|
||||
echo 'This script must be run as the "azuracast" user. Rerunning...'
|
||||
exec gosu azuracast run_roadrunner "$@"
|
||||
fi
|
||||
|
||||
dockerize -template "/var/azuracast/rr.yaml.tmpl:/var/azuracast/rr.yaml"
|
||||
|
||||
# Wait for services to spin up.
|
||||
php /var/azuracast/www/bin/uptime_wait || exit 1
|
||||
|
||||
# Initialize before running FPM
|
||||
azuracast_cli azuracast:setup --init || exit 1
|
||||
|
||||
# Run initial Acme check
|
||||
azuracast_cli azuracast:acme:get-certificate || true
|
||||
|
||||
# Run PHP-FPM
|
||||
exec rr serve -c /var/azuracast/rr.yaml -w /var/azuracast/www
|
|
@ -1,5 +1,5 @@
|
|||
[program:php-fpm]
|
||||
command=run_php_fpm
|
||||
[program:roadrunner]
|
||||
command=run_roadrunner
|
||||
priority=300
|
||||
numprocs=1
|
||||
autostart=true
|
|
@ -12,7 +12,7 @@ echo "deb-src [signed-by=/etc/apt/keyrings/php.gpg] https://ppa.launchpadcontent
|
|||
|
||||
apt-get update
|
||||
|
||||
apt-get install -y --no-install-recommends php${PHP_VERSION}-fpm php${PHP_VERSION}-cli php${PHP_VERSION}-gd \
|
||||
apt-get install -y --no-install-recommends php${PHP_VERSION}-cli php${PHP_VERSION}-gd \
|
||||
php${PHP_VERSION}-curl php${PHP_VERSION}-xml php${PHP_VERSION}-zip \
|
||||
php${PHP_VERSION}-gmp php${PHP_VERSION}-mysqlnd php${PHP_VERSION}-mbstring php${PHP_VERSION}-intl \
|
||||
php${PHP_VERSION}-redis php${PHP_VERSION}-maxminddb
|
||||
|
@ -20,11 +20,7 @@ apt-get install -y --no-install-recommends php${PHP_VERSION}-fpm php${PHP_VERSIO
|
|||
# Copy PHP configuration
|
||||
echo "PHP_VERSION=$PHP_VERSION" >> /etc/php/.version
|
||||
|
||||
mkdir -p /run/php
|
||||
touch /run/php/php${PHP_VERSION}-fpm.pid
|
||||
|
||||
cp /bd_build/web/php/php.ini.tmpl /etc/php/${PHP_VERSION}/fpm/05-azuracast.ini.tmpl
|
||||
cp /bd_build/web/php/www.conf.tmpl /etc/php/${PHP_VERSION}/fpm/www.conf.tmpl
|
||||
cp /bd_build/web/php/php.ini.tmpl /etc/php/${PHP_VERSION}/cli/05-azuracast.ini.tmpl
|
||||
|
||||
# Enable FFI (for StereoTool inspection)
|
||||
echo 'ffi.enable="true"' >> /etc/php/${PHP_VERSION}/mods-available/ffi.ini
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
set -e
|
||||
set -x
|
||||
|
||||
cp /bd_build/web/roadrunner/rr.yaml.tmpl /var/azuracast/rr.yaml.tmpl
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
source /etc/php/.version
|
||||
|
||||
dockerize -template "/etc/php/${PHP_VERSION}/cli/05-azuracast.ini.tmpl:/etc/php/${PHP_VERSION}/cli/conf.d/05-azuracast.ini"
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\AppFactory;
|
||||
|
||||
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT);
|
||||
ini_set('display_errors', '1');
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
$app = AppFactory::createApp();
|
||||
$di = $app->getContainer();
|
||||
|
||||
/** @var App\Service\Centrifugo\EventHandler $centrifugo */
|
||||
$centrifugo = $di->get(App\Service\Centrifugo\EventHandler::class);
|
||||
|
||||
$worker = Spiral\RoadRunner\Worker::create();
|
||||
$requestFactory = new RoadRunner\Centrifugo\Request\RequestFactory($worker);
|
||||
$centrifugoWorker = new RoadRunner\Centrifugo\CentrifugoWorker($worker, $requestFactory);
|
||||
|
||||
while ($request = $centrifugoWorker->waitRequest()) {
|
||||
$response = $centrifugo->__invoke($request);
|
||||
if (null !== $response) {
|
||||
$request->respond($response);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use App\AppFactory;
|
||||
|
||||
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT);
|
||||
ini_set('display_errors', '1');
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
$environment = AppFactory::buildEnvironment([
|
||||
App\Environment::IS_CLI => false,
|
||||
]);
|
||||
$diBuilder = AppFactory::createContainerBuilder($environment);
|
||||
|
||||
$httpFactory = new App\Http\HttpFactory();
|
||||
$worker = \Spiral\RoadRunner\Worker::create();
|
||||
$psr7Worker = new Spiral\RoadRunner\Http\PSR7Worker($worker, $httpFactory, $httpFactory, $httpFactory);
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
$request = $psr7Worker->waitRequest();
|
||||
if ($request === null) {
|
||||
break;
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$psr7Worker->respond($httpFactory->createResponse(400));
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
$di = AppFactory::buildContainer($diBuilder);
|
||||
$app = AppFactory::buildAppFromContainer($di);
|
||||
|
||||
$response = $app->handle($request);
|
||||
$psr7Worker->respond($response);
|
||||
} catch (\Throwable $e) {
|
||||
$psr7Worker->respond($httpFactory->createResponse(500, 'Critical error'));
|
||||
$psr7Worker->getWorker()->error((string)$e);
|
||||
}
|
||||
|
||||
gc_collect_cycles();
|
||||
}
|
Loading…
Reference in New Issue