PHP Probe with Docker

Enabling the PHP Probe

Before being able to profile, you need to add the Probe to your Docker PHP image. Here is an example of a Dockerfile based on the official Docker PHP image:

Caution

Choose the snippet corresponding to the base system you are using (Linux or Alpine).

FROM php:7.3-fpm

RUN version=$(php -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION;") \
    && curl -A "Docker" -o /tmp/blackfire-probe.tar.gz -D - -L -s https://blackfire.io/api/v1/releases/probe/php/linux/amd64/$version \
    && mkdir -p /tmp/blackfire \
    && tar zxpf /tmp/blackfire-probe.tar.gz -C /tmp/blackfire \
    && mv /tmp/blackfire/blackfire-*.so $(php -r "echo ini_get ('extension_dir');")/blackfire.so \
    && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://blackfire:8707\n" > $PHP_INI_DIR/conf.d/blackfire.ini \
    && rm -rf /tmp/blackfire /tmp/blackfire-probe.tar.gz

# Please note that the Blackfire Probe is dependent on the session module.
# If it isn't present in your install, you will need to enable it yourself.
FROM php:7.3-fpm-alpine

RUN version=$(php -r "echo PHP_MAJOR_VERSION.PHP_MINOR_VERSION;") \
    && curl -A "Docker" -o /tmp/blackfire-probe.tar.gz -D - -L -s https://blackfire.io/api/v1/releases/probe/php/alpine/amd64/$version \
    && mkdir -p /tmp/blackfire \
    && tar zxpf /tmp/blackfire-probe.tar.gz -C /tmp/blackfire \
    && mv /tmp/blackfire/blackfire-*.so $(php -r "echo ini_get ('extension_dir');")/blackfire.so \
    && printf "extension=blackfire.so\nblackfire.agent_socket=tcp://blackfire:8707\n" > $PHP_INI_DIR/conf.d/blackfire.ini \
    && rm -rf /tmp/blackfire /tmp/blackfire-probe.tar.gz

# Please note that the Blackfire Probe is dependent on the session module.
# If it isn't present in your install, you will need to enable it yourself.

Caution

If you are using a zts (Zend Thread Safety) version of PHP, please add -zts to the version name.

Build your container as usual:

1
docker build -t php-blackfire .

Docker Compose

Within a docker-compose context, you may take inspiration of the following snippet to connect your PHP container and the agent together:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
version: '3'
services:
  app:
    build: .
    ports:
      - "8080:80"

  blackfire:
    image: blackfire/blackfire
    environment:
        # Exposes BLACKFIRE_SERVER_* environment variables from the host
        BLACKFIRE_SERVER_ID: ~
        BLACKFIRE_SERVER_TOKEN: ~

Using the Client for CLI Profiling

When profiling command line scripts, the process is slightly different than for HTTP requests. You execute blackfire run which in the end runs an embedded agent and wraps your PHP script with the required environment variables. Therefore, in this configuration you do not need to (and cannot) use the blackfire/blackfire image. Instead, you need to fetch and use the blackfire client binary inside your PHP container.

Here is an example of a Dockerfile based on the official Docker PHP image that retrieves the client at build time:

1
2
3
4
5
6
FROM php:7.4-fpm

RUN mkdir -p /tmp/blackfire \
    && curl -A "Docker" -L https://blackfire.io/api/v1/releases/client/linux_static/amd64 | tar zxp -C /tmp/blackfire \
    && mv /tmp/blackfire/blackfire /usr/bin/blackfire \
    && rm -Rf /tmp/blackfire

Build your container as usual:

1
docker build -t php-blackfire .

When running the PHP container, you need to expose a BLACKFIRE_CLIENT_ID and a BLACKFIRE_CLIENT_TOKEN environment variables to allow the client to communicate with Blackfire’s API.

You can now directly execute blackfire run php myscript.php within your PHP container.

Debugging the PHP Probe

By default, the Probe is quiet and does not produce logs. To debug issues, pass -e BLACKFIRE_LOG_LEVEL=4 to the docker run command, and tail the logs via Docker:

1
docker logs -f PHP_CONTAINER_ID