Quick Start

The official OxPHP image bundles the server, PHP, the OxPHP extension, and every runtime dependency, so you can go from an empty directory to a running app in a handful of commands.

One command

If you already have a PHP project with a public/ directory:

bash
docker run -p 80:80 -v .:/var/www/html ghcr.io/oxphp/oxphp:0.10.0

Open http://localhost/. Your application is running.

To enable the internal server (health, metrics, config):

bash
docker run -p 80:80 -p 9090:9090 -e INTERNAL_ADDR=0.0.0.0:9090 -v .:/var/www/html ghcr.io/oxphp/oxphp:0.10.0

Step-by-step setup with Docker Compose

A more detailed walkthrough, from an empty directory to a working PHP application with health checks and structured logging.

  1. Create the project directory.

    bash
    mkdir my-oxphp-app && cd my-oxphp-app
  2. Create a Dockerfile.

    Dockerfile
    FROM ghcr.io/oxphp/oxphp:0.10.0 COPY --chown=www-data:www-data . /var/www/html

    The official image includes the server binary, PHP 8.4 or 8.5 ZTS (8.5 by default; pull 8.4 with :0.10.0-php8.4 or any *-php8.4* tag), the OxPHP PHP extension, and all runtime dependencies.

  3. Add a compose.yaml.

    compose.yaml
    services: oxphp: build: . ports: - "80:80" - "9090:9090" environment: - LISTEN_ADDR=0.0.0.0:80 - DOCUMENT_ROOT=/var/www/html/public - INTERNAL_ADDR=0.0.0.0:9090 - LOG_LEVEL=info - ACCESS_LOG=all

    Port 80 serves your application. Port 9090 exposes the internal server for health checks, Prometheus metrics, and the active configuration snapshot.

  4. Create a PHP application.

    bash
    mkdir -p public

    Create public/index.php:

    public/index.php
    <?php $requestId = oxphp_request_id(); $info = oxphp_server_info(); echo "<h1>OxPHP</h1>\n"; echo "<p>Request ID: {$requestId}</p>\n"; echo "<p>Worker: {$info['worker_id']}</p>\n"; echo "<p>SAPI: " . php_sapi_name() . "</p>\n"; echo "<p>Version: {$info['version']}</p>\n"; echo "<p>Time: " . date('c') . "</p>\n";

    oxphp_request_id() returns the unique ID assigned to each request. oxphp_server_info() returns details about the running server including version, worker_id, request_time, and worker_mode.

  5. Build and start.

    bash
    docker compose up -d --build
  6. Test your application.

    bash
    curl http://localhost/

    Expected output:

    html
    <h1>OxPHP</h1> <p>Request ID: 67a4b3c11a2b00000001</p> <p>Worker: 0</p> <p>SAPI: cli-server</p> <p>Version: 0.10.0</p> <p>Time: 2026-03-23T12:00:00+00:00</p>

    Each request gets a unique ID. The worker ID shows which PHP worker thread handled it.

  7. Check the internal endpoints.

    bash
    # Health check — 200 when healthy, 503 when degraded curl http://localhost:9090/health # Prometheus-compatible metrics curl http://localhost:9090/metrics # Active configuration (TLS paths redacted) curl http://localhost:9090/config
  8. View the logs.

    bash
    docker compose logs -f oxphp

    Because ACCESS_LOG=all is set, every request appears as a structured JSON log line with method, path, status, response time, and request ID.

Tip

If your application needs custom PHP extensions (pdo_pgsql, intl, xdebug, etc.), see examples/dockerfile/Dockerfile in the repository. It's a ready-to-use multi-stage Dockerfile with separate dev and prod targets.

Why does `php_sapi_name()` report `cli-server` instead of `oxphp`?

OxPHP deliberately registers under one of the SAPI names OPcache recognises. OPcache disables itself for unknown SAPIs; without this rename PHP execution would skip the OPcache layer entirely and run several times slower. The trade-off is that php_sapi_name() cannot be used to detect OxPHP — use function_exists('oxphp_request_id') or OxPHP\Http\Request::current() instead.

What's next

  • Docker Guide — development and production Dockerfiles, Compose configuration, PHP ini mounts, and health check setup
  • Configuration — full environment variable reference
  • Routing — Traditional, Framework, SPA, and Worker routing modes
  • Worker Mode — persistent PHP processes that bootstrap once and handle multiple requests
  • PHP Functions — all OxPHP built-in PHP functions