FrankenPHP

Starting from PHP extension 5.8.0, Tideways has official support for FrankenPHP including worker mode.

Worker Mode Support

To hook Tideways into worker mode request handling:

  1. PHP extension must be installed into the FrankenPHP docker container

  2. code changes must be made to the callback passed to frankenphp_handle_request

  3. Start container with Tideways environment variables

Follow the Docker & Compose docs for the steps to setup the tideways-daemon container.

FrankenPHP Container with Tideways Extension

A minimal Dockerfile that builds FrankenPHP including the Tideways PHP extension looks like this:

FROM dunglas/frankenphp

RUN export DEBIAN_FRONTEND="noninteractive"; \
    set -ex; \
    echo 'deb [signed-by=/usr/share/keyrings/tideways.asc] https://packages.tideways.com/apt-packages-main any-version main' | tee /etc/apt/sources.list.d/tideways.list; \
    curl -fsSL 'https://packages.tideways.com/key.gpg' -o /usr/share/keyrings/tideways.asc; \
    apt-get update; \
    apt-get install -y "tideways-php"; \
    echo "tideways.auto_start=0\n" > /usr/local/etc/php/conf.d/docker-php-ext-tideways.ini; \
    rm -rf /var/lib/apt/lists/*;

Code Changes to frankenphp_handle_request callback

Tideways does not automatically start and stop instrumentation for every FrankenPHP request. See the adapted worker.php script for the necessary code changes to integrate Tideways with FrankenPHP.

When using Laravel Octane, Tideways provides a Laravel Middleware that does this step for you.
<?php

ignore_user_abort(true);

$handler = static function () {
    echo "Hello World!"; // Your handler code here
};
$tidewaysMiddleware = static function () use ($handler) {
    \Tideways\Profiler::start();
    try {
        $handler();
    } catch (\Throwable $e) {
        \Tideways\Profiler::logException($e);
        throw $e;
    } finally {
        \Tideways\Profiler::stop();
    }
};

$_SERVER['MAX_REQUESTS'] ??= 1000;

// See https://frankenphp.dev/docs/worker/ for more information
for($nbRequests = 0, $running = true; isset($_SERVER['MAX_REQUESTS']) && ($nbRequests < ((int)$_SERVER['MAX_REQUESTS'])) && $running; ++$nbRequests) {
    $running = \frankenphp_handle_request($tidewaysMiddleware);

    gc_collect_cycles();
}

Start with Tideways Environment Variables

To enable Tideways, the worker mode script should be started with two environment variables:

  1. TIDEWAYS_APIKEY environment variable for Tideways project API Key

  2. TIDEWAYS_CONNECTION environment variable to point to the running tideways-daemon.

Example docker-compose.yml

When setting everything up with docker-compose, the following docker-compose.yml can serve as an example reference on how to integrate PHP container, Tideways configuration and daemon:

# See: https://frankenphp.dev/docs/docker/#using-a-volume-in-development
# For production see: https://frankenphp.dev/docs/production/
services:
  php:
    build:
      context: ./php
      dockerfile: Dockerfile
    environment:
      FRANKENPHP_CONFIG: "worker /app/public/index.php"
      TIDEWAYS_CONNECTION: "tcp://tideways-daemon:9135"
      TIDEWAYS_APIKEY: "<YOUR_API_KEY_HERE>"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./:/app
      - caddy_data:/data
      - caddy_config:/config
    tty: true

  tideways-daemon:
    image: ghcr.io/tideways/daemon

volumes:
  caddy_data:
  caddy_config:
Still need help? Email [email protected]