Deploying BookStack was the easy part. Understanding what was happening inside the application wasn't. Without visibility into incoming requests, database queries, or Laravel operations, troubleshooting performance issues felt like guesswork. In this tutorial, you'll instrument BookStack with OpenTelemetry, connect it to SigNoz, and build an end-to-end observability pipeline, all without modifying the application's source code.
BookStack is an open-source platform for creating and managing documentation, but it doesn't provide built-in distributed tracing or deep application observability. In this tutorial, you'll instrument BookStack with OpenTelemetry and export traces to SigNoz, enabling you to monitor requests, analyse Laravel application behaviour, and troubleshoot issues more effectively.
Prerequisites
Before you begin, make sure you have the following:
A Linux server (Ubuntu 22.04 or later) with at least 4 vCPUs and 8 GB RAM
Docker Engine and Docker Compose installed
Solution Overview
BookStack is instrumented with OpenTelemetry, which exports traces to the OpenTelemetry Collector. The collector forwards the telemetry to SigNoz, where you can visualise requests and analyse distributed traces.
HTTP Requests
│
▼
┌─────────────┐
│ BookStack │
│ (Laravel) │
└──────┬──────┘
│
OpenTelemetry SDK
│
OTLP (HTTP:4318)
│
▼
┌────────────────────────┐
│ OpenTelemetry Collector│
│ (SigNoz Collector) │
└───────────┬────────────┘
│
▼
┌───────────┐
│ SigNoz │
│ Dashboard │
└───────────┘
Step 1: Install SigNoz
Before instrumenting BookStack, you need a backend to collect, store, and visualise telemetry data. In this step, you'll install SigNoz using the foundryctl CLI and verify that it's ready to receive traces from BookStack.
-
Install the Foundry CLI, which simplifies the deployment of SigNoz by generating and managing the required Docker Compose configuration.
curl -fsSL https://signoz.io/foundry.sh | bash export PATH="/root/.local/bin:$PATH"Verify that the installation completed successfully:
foundryctl version -
Create a file named
casting.yamlwith the following configuration. This file instructsfoundryctlto deploy SigNoz using Docker Compose.
apiVersion: v1alpha1 kind: Installation metadata: name: signoz spec: deployment: flavor: compose mode: docker -
Deploy SigNoz using the installation configuration.
foundryctl cast -f casting.yamlThe installer validates your Docker environment, generates the required Docker Compose resources, and starts the SigNoz services.
-
Verify that the deployment completed successfully.
docker psYou should see containers such as
signoz-frontend,signoz-query-service,signoz-otel-collector, andclickhouse. Then open
http://<SERVER-IP>:8080in your browser. If the installation completed successfully, the SigNoz dashboard should load. Replace<SERVER_IP>with your Server IP.
Enter the email and password to create the initial admin account for SigNoz.
Step 2: Build a Custom BookStack Image
The official LinuxServer BookStack image doesn't include the OpenTelemetry components required to export traces. In this step, you'll build a custom image that installs the OpenTelemetry PHP extension and Laravel auto-instrumentation packages during the image build, making the deployment reproducible and eliminating the need to modify a running container.
-
Create a project directory for the deployment and navigate into it.
mkdir bookstack-otel cd bookstack-otel -
Generate a Laravel application key. BookStack uses this key to encrypt sensitive application data, and you'll reference it later when creating the Docker Compose configuration.
echo "base64:$(openssl rand -base64 32)"Save the generated value—you'll use it when configuring the BookStack container.
-
Create a file named
Dockerfilewith the following configuration.
FROM lscr.io/linuxserver/bookstack:version-v26.03.3 COPY scripts/install-opentelemetry.sh /tmp/install-opentelemetry.sh RUN chmod +x /tmp/install-opentelemetry.sh \ && /tmp/install-opentelemetry.sh \ && rm /tmp/install-opentelemetry.sh \ && rm -rf /root/.composer/cache WORKDIR /app/wwwThis Dockerfile extends the official BookStack image, runs the installation script during the image build.
-
Create a file named
install-opentelemetry.shwith the following installation script.
#!/bin/sh set -e echo "==========================================" echo "Installing OpenTelemetry PHP Extension" echo "==========================================" # Add Alpine edge testing repository if missing if ! grep -q "edge/testing" /etc/apk/repositories; then echo "https://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories fi apk update apk add --no-cache php85-pecl-opentelemetry echo "==========================================" echo "Installing OpenTelemetry Laravel Packages" echo "==========================================" cd /app/www composer config --no-interaction allow-plugins.php-http/discovery false composer config --no-interaction allow-plugins.tbachert/spi true composer require \ open-telemetry/sdk \ open-telemetry/exporter-otlp \ open-telemetry/opentelemetry-auto-laravel \ php-http/guzzle7-adapter \ --no-interaction \ --prefer-dist \ --optimize-autoloader \ --no-scripts echo "==========================================" echo "Verifying installation..." echo "==========================================" php -m | grep opentelemetry composer show open-telemetry/sdk composer show open-telemetry/opentelemetry-auto-laravel echo "==========================================" echo "OpenTelemetry installation completed!" echo "=========================================="This script installs the OpenTelemetry PHP extension together with the Composer packages required for Laravel auto-instrumentation. It also performs basic validation during the image build to confirm that the required components were installed successfully.
Step 3: Deploy BookStack with OpenTelemetry
With the custom image prepared, you're ready to deploy BookStack and its MariaDB database. In this step, you'll create a single Docker Compose configuration that builds the custom image, configures OpenTelemetry, and connects BookStack to the SigNoz OpenTelemetry Collector.
-
Create a
docker-compose.ymlfile with the following configuration.
services: bookstack: build: context: . dockerfile: Dockerfile image: bookstack-otel:latest container_name: bookstack environment: - PUID=1000 - PGID=1000 - TZ=Asia/Kolkata - APP_URL=http://<SERVER-IP>:6875 - APP_KEY=<APP_KEY> - DB_HOST=bookstack_db - DB_PORT=3306 - DB_DATABASE=bookstackapp - DB_USERNAME=bookstack - DB_PASSWORD=bookstack # OpenTelemetry - OTEL_SERVICE_NAME=bookstack - OTEL_TRACES_EXPORTER=otlp - OTEL_METRICS_EXPORTER=none - OTEL_LOGS_EXPORTER=none - OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf - OTEL_EXPORTER_OTLP_ENDPOINT=http://signoz-ingester-1:4318 - OTEL_PHP_AUTOLOAD_ENABLED=true volumes: - ./bookstack_data:/config ports: - "6875:80" depends_on: - bookstack_db restart: unless-stopped bookstack_db: image: lscr.io/linuxserver/mariadb:latest container_name: bookstack_db environment: - PUID=1000 - PGID=1000 - TZ=Asia/Kolkata - MYSQL_ROOT_PASSWORD=<ROOT_PASSWORD> - MYSQL_DATABASE=bookstackapp - MYSQL_USER=bookstack - MYSQL_PASSWORD=bookstack volumes: - ./bookstack_db_data:/config restart: unless-stopped networks: default: external: true name: signoz-networkBefore starting the deployment, replace the following placeholders:
* `<SERVER-IP>` with your server's IP address or domain.
* `<APP_KEY>` with the Laravel application key generated in the previous step.
* `<ROOT_PASSWORD>` with a secure MariaDB root password.
* `signoz-network` with the Docker network created by your SigNoz installation if it uses a different name.
-
Build the custom image and start the BookStack and MariaDB containers.
docker compose up -d --buildDocker builds the custom BookStack image, installs the OpenTelemetry components, and starts both containers.
-
Verify that the deployment completed successfully.
docker psThe
bookstackandbookstack_dbcontainers should both be in the Up state. -
Open BookStack in your browser.
http://<SERVER-IP>:6875Replace
<SERVER-IP>with your Server IP.
The BookStack login page should load successfully, confirming that the application is running with the custom OpenTelemetry-enabled image.
Enter email asadmin@admin.comand password aspassword.
Step 4: Verify the OpenTelemetry Installation
Before generating application traffic, verify that the OpenTelemetry components were installed correctly and that BookStack is configured to export traces. In this step, you'll confirm that the PHP extension, Composer packages, Laravel package discovery, and OpenTelemetry environment variables are all working as expected.
-
Verify that the OpenTelemetry PHP extension is loaded inside the BookStack container.
docker exec bookstack php -m | grep opentelemetryIf the installation was successful, the command should return:
opentelemetry -
Confirm that the required OpenTelemetry Composer packages were installed.
docker exec bookstack composer show | grep opentelemetryYou should see packages similar to:
open-telemetry/api open-telemetry/sdk open-telemetry/exporter-otlp open-telemetry/opentelemetry-auto-laravel -
Verify that the OpenTelemetry environment variables are available inside the running container.
docker exec bookstack printenv | grep OTELYou should see output similar to:
OTEL_SERVICE_NAME=bookstack OTEL_TRACES_EXPORTER=otlp OTEL_EXPORTER_OTLP_ENDPOINT=http://signoz-ingester-1:4318 OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf OTEL_PHP_AUTOLOAD_ENABLED=true -
Verify that Laravel can discover the installed packages without errors.
docker exec bookstack php artisan package:discoverThe command should complete successfully without reporting missing dependencies or package discovery errors.
-
Open BookStack in your browser to confirm that the application is still running.
http://<SERVER-IP>:6875Replace
<SERVER-IP>with your Server IP.
The login page should load normally, confirming that the custom image is running correctly and is ready to export traces.
Step 5: Generate Application Traffic
With BookStack configured and the OpenTelemetry installation verified, the next step is to generate application traffic. As users interact with BookStack, OpenTelemetry automatically captures each request and exports the resulting traces to the SigNoz OpenTelemetry Collector.
-
Open BookStack in your browser.
http://<SERVER-IP>:6875Replace
<SERVER-IP>with your Server IP. Log in using the default BookStack administrator credentials or an existing user account.
Perform a few common actions to generate application traffic, such as:
* Browse books and shelves.
* Open and view existing pages.
* Create a new page.
* Edit and save content.
* Navigate between different sections of the application.
Each of these actions generates HTTP requests that are automatically instrumented by OpenTelemetry and exported to SigNoz.
- Repeat a few of these actions over the next minute to generate multiple traces. This provides enough telemetry data to inspect different requests in the SigNoz dashboard.
Step 6: View Traces in SigNoz
After generating application traffic, verify that BookStack is exporting traces to SigNoz. In this step, you'll inspect the collected traces and explore the request details captured by OpenTelemetry.
-
Open the SigNoz dashboard in your browser.
http://<SERVER-IP>:8080Replace
<SERVER-IP>with your Server IP. -
From the left navigation menu, select Traces.
After a few seconds, you should see traces from the bookstack service.
If no traces appear immediately, wait a few seconds, refresh the page, perform another action in BookStack, and check again.
-
Click any trace from the bookstack service to inspect its details.
The trace view displays the sequence of operations performed while processing a request. Depending on the action you performed, you'll typically see spans representing the incoming HTTP request, Laravel middleware, route handling, controller execution, and database operations.
-
Verify that the trace was recorded successfully.
Confirm that:
* The **Service Name** is `bookstack`.
* The trace completed successfully.
* Multiple spans are displayed for the request.
* The request duration and execution timeline are visible.
Congratulations! You've successfully instrumented BookStack with OpenTelemetry and configured it to export traces to SigNoz. You now have end-to-end visibility into your application's requests, making it easier to understand application behaviour and troubleshoot performance issues.
What I Learned
Building this setup highlighted a few practical lessons:
Use a custom Docker image. Installing the OpenTelemetry components during the image build makes the deployment reproducible and prevents changes from being lost when containers are recreated.
Verify each step as you go. Checking the PHP extension, Composer packages, and environment variables helped identify configuration issues early.
Ensure the containers share the same network. BookStack can only export traces if it can reach the SigNoz OpenTelemetry Collector.
Generate application traffic before checking SigNoz. Traces are created only when BookStack processes requests.
Conclusion
You've successfully instrumented BookStack with OpenTelemetry and configured it to export traces to SigNoz, giving you end-to-end visibility into application requests with a reproducible Docker-based deployment.
To continue exploring application observability, check out the following resources:
OpenTelemetry Documentation: https://opentelemetry.io/docs/
SigNoz Documentation: https://signoz.io/docs/introduction/
SigNoz Distributed Tracing: https://signoz.io/docs/userguide/traces/





Top comments (0)