Yii3 on OxPHP

Yii3 is the leanest recipe here. The yiisoft/app template has a public/index.php front controller, needs no database, and, because most string handling is polyfilled, needs essentially no extra PHP extensions. It maps onto OxPHP's framework routing mode and runs as a single service.

Stack at a glance

  • OxPHP image: ghcr.io/oxphp/oxphp:0.13.0 (PHP 8.5)
  • Routing mode: Framework (ENTRY_FILE=index.php; DOCUMENT_ROOT left at the default /var/www/html/public)
  • Extensions added: mbstring (native, for speed; the runtime otherwise polyfills it)
  • Services: OxPHP only
  • URL: http://localhost:8094 · internal http://localhost:9095/health
Note

yiisoft/app declares "php": "8.2 - 8.5", so the default PHP 8.5 image fits.

Project layout

bash
mkdir -p yii3-oxphp/src docker run --rm -v "$PWD/yii3-oxphp/src":/app -w /app \ composer:2 create-project yiisoft/app . --prefer-dist cp yii3-oxphp/src/.env.example yii3-oxphp/src/.env

Dockerfile and Compose

src/Dockerfile
ARG OXPHP_VERSION=0.13.0 ARG PHP_VERSION=8.5 ARG ALPINE_VERSION=3.23 # ── PHP base: native mbstring ───────────────────────────────── FROM php:${PHP_VERSION}-zts-alpine${ALPINE_VERSION} AS php-base RUN apk add --no-cache oniguruma \ && apk add --no-cache --virtual .build-deps oniguruma-dev \ && docker-php-ext-install -j"$(nproc)" mbstring \ && apk del .build-deps # ── Composer ────────────────────────────────────────────────── FROM composer:2 AS composer # ── OxPHP artifacts (PHP 8.5 default image) ─────────────────── FROM ghcr.io/oxphp/oxphp:${OXPHP_VERSION} AS oxphp # ── dev: OxPHP server + PHP CLI + Composer ──────────────────── FROM php-base AS dev RUN apk add --no-cache libgcc git COPY --from=composer /usr/bin/composer /usr/local/bin/composer COPY --from=oxphp /usr/local/bin/oxphp /usr/local/bin/oxphp COPY --from=oxphp /usr/local/lib/liboxphp_bridge.so /usr/local/lib/ COPY --from=oxphp /usr/local/lib/php/extensions/ /tmp/oxphp-ext/ RUN cp /tmp/oxphp-ext/*/oxphp_sapi.so "$(php -r 'echo ini_get("extension_dir");')/" \ && rm -rf /tmp/oxphp-ext \ && echo "extension=oxphp_sapi.so" > /usr/local/etc/php/conf.d/oxphp-ext.ini RUN { \ echo "[opcache]"; echo "opcache.enable=1"; echo "opcache.enable_cli=1"; \ echo "opcache.validate_timestamps=1"; echo "opcache.revalidate_freq=0"; \ } > /usr/local/etc/php/conf.d/opcache-dev.ini RUN getent passwd www-data >/dev/null \ || adduser -D -H -u 82 -G www-data -s /sbin/nologin www-data RUN mkdir -p /var/www/html/public && chown -R www-data:www-data /var/www/html ENV LD_LIBRARY_PATH=/usr/local/lib WORKDIR /var/www/html COPY --chown=www-data:www-data . /var/www/html EXPOSE 80 9090 CMD ["oxphp"]
Note

The yiisoft/app template ships its own whitelist-style .dockerignore; keep it. With a bind-mounted src/, the COPY is only a fallback.

Install and first run

bash
docker compose up -d --build docker compose exec app php yii # the Yii console

OxPHP notes

Note
  • With no database and no extra services, this is the smallest possible OxPHP deployment: one image and one process.
  • yiisoft/assets publishes static files into public/assets/<hash>/. They are real files on disk, and framework mode serves them directly. No URL-rewrite gymnastics are needed (unlike some asset pipelines that embed a version segment in the URL).

Verify

bash
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8094/ # 200 curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8094/nonexistent # 404 (Yii router) curl -s -o /dev/null -w "%{http_code}\n" http://localhost:9095/health # 200

Prompts for your agent

These prompts assume an agent with the OxPHP documentation MCP server connected. The agent reads the pages it needs itself.

prompt
Run my Yii3 application on OxPHP locally. Read the `examples/framework/yii3` page through the OxPHP documentation MCP server. Write the Dockerfile and the Compose file for this repository — the recipe is a single service with no database, so add the services my `config/` actually wires up — and give me the first-run commands.
prompt
My Yii3 app runs on OxPHP but its published assets come back 404. Read the `examples/framework/yii3` page through the OxPHP documentation MCP server. Check my asset bundles and the template's whitelist `.dockerignore` against the document root my Compose file sets, and tell me which one is losing the files.

See also

Found a mistake? Report it →