From 766b227e475a2eb6e30d7bc56b275f572ec7d441 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Fri, 22 Aug 2025 08:21:44 +0200 Subject: [PATCH] Add a development FrankenPHP server --- bin/frankenphp-worker.php | 36 ++++++++++++ config/params/shlink_dev_env.php.dist | 4 +- data/infra/frankenphp.Dockerfile | 55 +++++++++++++++++++ data/infra/frankenphp_caddy_config/.gitignore | 2 + data/infra/frankenphp_caddy_data/.gitignore | 2 + docker-compose.yml | 31 +++++++++++ 6 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 bin/frankenphp-worker.php create mode 100644 data/infra/frankenphp.Dockerfile create mode 100755 data/infra/frankenphp_caddy_config/.gitignore create mode 100755 data/infra/frankenphp_caddy_data/.gitignore diff --git a/bin/frankenphp-worker.php b/bin/frankenphp-worker.php new file mode 100644 index 00000000..61740b4d --- /dev/null +++ b/bin/frankenphp-worker.php @@ -0,0 +1,36 @@ +get(Application::class); + $responseEmitter = $container->get(EmitterInterface::class); + $handler = static function () use ($app, $responseEmitter): void { + $response = $app->handle(ServerRequestFactory::fromGlobals()); + $responseEmitter->emit($response); + }; + + $maxRequests = (int) ($_SERVER['MAX_REQUESTS'] ?? 0); + for ($nbRequests = 0; !$maxRequests || $nbRequests < $maxRequests; ++$nbRequests) { + $keepRunning = frankenphp_handle_request($handler); + + // Call the garbage collector to reduce the chances of it being triggered in the middle of a page generation + gc_collect_cycles(); + + if (! $keepRunning) { + break; + } + } +})(); diff --git a/config/params/shlink_dev_env.php.dist b/config/params/shlink_dev_env.php.dist index d9de7022..e5dddf35 100644 --- a/config/params/shlink_dev_env.php.dist +++ b/config/params/shlink_dev_env.php.dist @@ -4,13 +4,15 @@ declare(strict_types=1); use Shlinkio\Shlink\Core\Config\EnvVars; +use function Shlinkio\Shlink\Config\runningInRoadRunner; + return [ EnvVars::APP_ENV->value => 'dev', // EnvVars::GEOLITE_LICENSE_KEY->value => '', // URL shortener - EnvVars::DEFAULT_DOMAIN->value => 'localhost:8800', + EnvVars::DEFAULT_DOMAIN->value => runningInRoadRunner() ? 'localhost:8800' : 'localhost:8008', EnvVars::IS_HTTPS_ENABLED->value => false, // Database - MySQL diff --git a/data/infra/frankenphp.Dockerfile b/data/infra/frankenphp.Dockerfile new file mode 100644 index 00000000..22e3e580 --- /dev/null +++ b/data/infra/frankenphp.Dockerfile @@ -0,0 +1,55 @@ +FROM dunglas/frankenphp:1-php8.4-alpine +MAINTAINER Alejandro Celaya + +ENV PDO_SQLSRV_VERSION='5.12.0' +ENV MS_ODBC_DOWNLOAD='7/6/d/76de322a-d860-4894-9945-f0cc5d6a45f8' +ENV MS_ODBC_SQL_VERSION='18_18.4.1.1' + +RUN apk update + +# Install common php extensions +RUN docker-php-ext-install pdo_mysql +RUN docker-php-ext-install calendar + +RUN apk add --no-cache oniguruma-dev +RUN docker-php-ext-install mbstring + +RUN apk add --no-cache sqlite-libs +RUN apk add --no-cache sqlite-dev +RUN docker-php-ext-install pdo_sqlite + +RUN apk add --no-cache icu-dev +RUN docker-php-ext-install intl + +RUN apk add --no-cache libzip-dev zlib-dev +RUN docker-php-ext-install zip + +RUN apk add --no-cache libpng-dev +RUN docker-php-ext-install gd + +RUN apk add --no-cache postgresql-dev +RUN docker-php-ext-install pdo_pgsql + +RUN apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS linux-headers && \ + docker-php-ext-install sockets && \ + apk del .phpize-deps +RUN docker-php-ext-install bcmath + +# Install xdebug and sqlsrv driver +RUN apk add --update linux-headers && \ + wget https://download.microsoft.com/download/${MS_ODBC_DOWNLOAD}/msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk && \ + apk add --allow-untrusted msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk && \ + apk add --no-cache --virtual .phpize-deps $PHPIZE_DEPS unixodbc-dev && \ + pecl install pdo_sqlsrv-${PDO_SQLSRV_VERSION} xdebug && \ + docker-php-ext-enable pdo_sqlsrv xdebug && \ + apk del .phpize-deps && \ + rm msodbcsql${MS_ODBC_SQL_VERSION}-1_amd64.apk + +# Install composer +COPY --from=composer:2 /usr/bin/composer /usr/local/bin/composer + +# Make home directory writable by anyone +RUN chmod 777 /home + +VOLUME /home/shlink +WORKDIR /home/shlink diff --git a/data/infra/frankenphp_caddy_config/.gitignore b/data/infra/frankenphp_caddy_config/.gitignore new file mode 100755 index 00000000..d6b7ef32 --- /dev/null +++ b/data/infra/frankenphp_caddy_config/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/data/infra/frankenphp_caddy_data/.gitignore b/data/infra/frankenphp_caddy_data/.gitignore new file mode 100755 index 00000000..d6b7ef32 --- /dev/null +++ b/data/infra/frankenphp_caddy_data/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/docker-compose.yml b/docker-compose.yml index cc6966f0..847c257e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -66,6 +66,37 @@ services: extra_hosts: - 'host.docker.internal:host-gateway' + shlink_frankenphp: + container_name: shlink_frankenphp + user: 1000:1000 + build: + context: . + dockerfile: ./data/infra/frankenphp.Dockerfile + ports: + - "8008:8008" + volumes: + - ./:/home/shlink + - ./data/infra/php.ini:/usr/local/etc/php/php.ini + - ./data/infra/frankenphp_caddy_data:/data + - ./data/infra/frankenphp_caddy_config:/config + links: + - shlink_db_mysql + - shlink_db_postgres + - shlink_db_maria + - shlink_db_ms + - shlink_redis + - shlink_redis_acl + - shlink_mercure + - shlink_mercure_proxy + - shlink_rabbitmq + - shlink_matomo + environment: + FRANKENPHP_CONFIG: 'worker /home/shlink/bin/frankenphp-worker.php' + SERVER_NAME: ':8008 https:8009' + extra_hosts: + - 'host.docker.internal:host-gateway' + tty: true + shlink_db_mysql: container_name: shlink_db_mysql user: 1000:1000