Files
php-qml/docs/configuration.md
magdev beb4e3ab9d docs: refresh README + docs/ for v0.2.0
The README still framed the project as "Phase 5 / pre-v0.1.0" and the
docs predated the v0.2.0 surface (typed BridgeOp, public service
interfaces, port negotiation, pre-migration auto-backup, bridge:export,
periodic auto-update, two new makers, qmltestrunner). Bring them in line
with what's actually shipped, and add badges (release, license, PHP,
Symfony, Qt, FrankenPHP, CI, platform) to the README so the status is
legible at a glance.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 22:27:52 +02:00

8.8 KiB

Configuration reference

Exhaustive lookup for env vars and CLI flags. For what the framework does with these, see the linked concept docs.

Environment variables

Read by the Qt host (BackendConnection)

Var Default Effect
BRIDGE_URL unset If set, host runs in dev mode and connects to this URL. If unset, host runs in bundled mode.
BRIDGE_TOKEN unset Bearer token for Authorization headers. Dev mode reads this from env (typically set in .env); bundled mode generates a per-session value and ignores env.
BRIDGE_PORT (negotiated) Bundled mode: pin a specific TCP port instead of negotiating one. Set by test harnesses (bundled-supervisor.sh, perfsmoke.sh) for reproducibility. Dev mode ignores it (the Caddyfile still reads {$PORT:8765}).
BRIDGE_FRANKENPHP_BIN <bin>/bin/frankenphp Bundled mode: override the FrankenPHP binary path.
BRIDGE_SYMFONY_DIR candidate list Bundled mode: override the Symfony app directory. Candidates: <bin>/symfony, <bin>/../symfony, <bin>/../share/<app>/symfony, <bin>/../usr/share/<app>/symfony.
BRIDGE_CADDYFILE candidate list Bundled mode: override the Caddyfile path. Same candidate prefixes as BRIDGE_SYMFONY_DIR.
BRIDGE_APPIMAGEUPDATE_BIN <bin>/AppImageUpdate.AppImage Override the auto-update sidecar path.
BRIDGE_AUTO_UPDATE_DISABLE unset Bundled mode: set to 1 to disable the periodic auto-update poll. The QML checkForUpdates() / applyUpdate() Q_INVOKABLEs still work.
BRIDGE_AUTO_UPDATE_PERIOD_MIN 360 Bundled mode: override the periodic auto-update interval in minutes (default 6 h).
APPIMAGE set by AppImage runtime Bundled-mode auto-update reads this to know which AppImage to update.

Read by the bundled Symfony app

These come from framework/skeleton/symfony/.env in dev mode and from environment passed by BackendConnection::spawnChild() in bundled mode.

Var Notes
APP_ENV dev (dev mode) or prod (bundled mode).
APP_DEBUG 1 / 0 to match.
APP_SECRET Symfony framework secret. Static in dev; per-session random in bundled mode.
BRIDGE_TOKEN Bearer token the SessionAuthenticator checks against.
DATABASE_URL sqlite:///%kernel.project_dir%/var/data.sqlite (dev) or sqlite:///<userdata>/var/data.sqlite (bundled). Override to switch to PostgreSQL/MySQL.
MERCURE_URL http://127.0.0.1:8765/.well-known/mercure.
MERCURE_PUBLIC_URL Same as MERCURE_URL for local-only deployment.
MERCURE_JWT_SECRET HMAC secret for minting publisher JWTs. ≥256 bits.
MERCURE_PUBLISHER_JWT_KEY Same value as MERCURE_JWT_SECRET.
MERCURE_SUBSCRIBER_JWT_KEY Same value as MERCURE_JWT_SECRET.
PORT 8765 in dev. In bundled mode the host sets this to the negotiated port (or to BRIDGE_PORT if pinned). The Caddyfile reads {$PORT:8765}.

Read by make dev / scripts/dev.sh

Var Default Effect
FRANKENPHP frankenphp (PATH lookup) Path to the FrankenPHP binary.

Read by make appimage / build-appimage.sh

Var Default Effect
FRANKENPHP frankenphp (PATH lookup) Path to the FrankenPHP binary to bundle.
APPIMAGE_UPDATE_INFO unset If set, embedded into the AppImage's .upd_info ELF section so AppImageUpdate finds the appcast. Format: zsync|<url-to-.zsync>.
APPIMAGE_EXTRACT_AND_RUN unset If 1, the AppImage runtime extracts to a temp dir before running. CI sets this so the AppImage works on systems without FUSE.

Read by tests/perfsmoke.sh

Var Default Effect
PERF_COLD_START_MS 2000 Cold-start budget. CI uses 4000 for shared runners.
PERF_IDLE_MEM_MB 200 Idle RSS budget (host + descendants).
PERF_BUNDLE_MB 200 Bundle size budget.
PERF_BACKEND_PORT 8765 Port the smoke probes for /healthz.
PERF_HEALTHZ_DEADLINE_MS 5000 How long to wait for the first 200 before failing. CI uses 8000.

Read by bin/php-qml-init

Var Default Effect
PHP_QML_FRAMEWORK unset → auto-detect Path to a php-qml checkout. Auto-detected when the script is run from a checkout (<repo>/bin/php-qml-init); pass explicitly when the script lives elsewhere.

CLI flags

bin/php-qml-init

php-qml-init [--framework <dir>] [--vendor] [--skip-install] [--git] <name>
Flag Default Effect
<name> required Project directory name. Lowercase, alphanumeric, _ or -, leading letter.
--framework <dir> auto-detect Override the php-qml checkout location. Equivalent to PHP_QML_FRAMEWORK.
--vendor off Copy framework/php and framework/qml into <name>/.bridge/ and <name>/.bridge-qml/. The new project is portable away from the checkout but won't pick up framework updates automatically.
--skip-install off Don't run composer install or migrations. Useful for offline scaffolding.
--git off git init and create an "Initial scaffold" commit.
-h, --help Print usage.

The script auto-validates that <name> doesn't already exist (or that the existing dir is empty). It rewrites every skeleton identifier to the project name (CMake project, Qt target, QML URI, app title, single-instance lock id, composer path-repo, CMake add_subdirectory(framework/qml), .vscode/launch.json).

bin/console bridge:export

bin/console bridge:export <destination>

Copies the active SQLite database (read from DATABASE_URL) to <destination>. Overwrites the destination if it exists. Works in both dev and bundled mode.

Arg Required Notes
<destination> yes Filesystem path. The QML side has the same operation as BackendConnection.exportDatabase(path).

Errors with exit code 1 if DATABASE_URL doesn't point at a SQLite file or if the source doesn't exist. See PHP API §bridge:export.

packaging/linux/build-appimage.sh

build-appimage.sh \
    --app-name <name> \
    --host-binary <path> \
    --symfony-dir <path> \
    --frankenphp <path> \
    --caddyfile <path> \
    --desktop <path> \
    --icon <path> \
    --output <path.AppImage> \
    [--update-info <zsync-url>]

All except --update-info are required. See Linux packaging §CLI for details.

make targets

Run from a project's root (skeleton, todo example, or a php-qml-init'd project).

Target What it does
make help Print available targets.
make install composer install in symfony/.
make build cmake -S qml -B build/qml && cmake --build build/qml.
make dev make build + scripts/dev.sh (FrankenPHP --watch + Qt host).
make doctor bin/console bridge:doctor.
make doctor-connect bin/console bridge:doctor --connect.
make qmltest Configure with -DBUILD_TESTING=ON, run the qmltestrunner Quick Test target via CTest. Skeleton + examples/todo.
make quality PHP quality + qmllint + qmltest + (todo example) integration test.
make integration (todo example only) HTTP+SSE round-trip + crash-recover smoke.
make integration-bundled (todo example only) bundled-mode supervisor smoke (cache redirect + auto-backup + clean shutdown).
make appimage Stage symfony --no-dev, run build-appimage.sh. (Skeleton + todo example.)
make perf (todo example only) Run tests/perfsmoke.sh against the built AppImage.
make clean Remove build/.

Default ports & paths

What Where
FrankenPHP HTTP / Mercure http://127.0.0.1:<port> (8765 in dev; negotiated in bundled mode)
Mercure SSE endpoint /.well-known/mercure
Health probe GET /healthz (returns 200 OK when ready; response carries name, bundle)
Bundled-mode user data ~/.local/share/<app>/var/ (Linux). XDG_DATA_HOME honoured.
Bundled-mode SQLite ~/.local/share/<app>/var/data.sqlite
Bundled-mode auto-backups ~/.local/share/<app>/var/data.sqlite.<timestamp>.bak (last 5 kept)
Bundled-mode runtime port ~/.local/share/<app>/var/bridge.port (written every launch)
Bundled-mode logs ~/.local/share/<app>/var/log/
Single-instance socket ~/.local/share/<app>/<app>.sock
AppImage AppDir layout usr/bin/<app>, usr/share/<app>/symfony/, usr/share/<app>/Caddyfile, usr/bin/AppImageUpdate.AppImage

See also