Skip to main content
The bundle ships two demo applications — one per supported Symfony version — in demo/symfony7 and demo/symfony8. Each demo has its own docker-compose.yml and Makefile and can be run independently.
The demo/ folder is not shipped when you install the bundle via composer require. It exists only in the bundle source repository and is excluded from the Composer package via archive.exclude. To run the demos, clone the bundle repository.

Quick start

1

Start the container

Run from the bundle root:
make -C demo/symfony8 up
2

Install and set up the database

make -C demo/symfony8 install
This runs composer install, creates the database, runs migrations, and loads fixtures (menus and menu items).
3

Open the demo

Open http://localhost:8011 in your browser (or the port set in demo/symfony8/.env).
  • Home page — rendered menus (sidebar, context resolution examples)
  • /admin/menus — dashboard: list, create, edit, copy menu, manage items
Alternatively, run both from the demo/ directory:
make -C demo/symfony7 setup
make -C demo/symfony8 setup
(setup is an alias for up + install combined.)

What each demo includes

  • Independent docker-compose.yml and Makefile (up, down, install, setup, test, test-coverage, update-bundle, verify, and more)
  • FrankenPHP with Caddy serving HTTP on port 80 inside the container; the host port is mapped via Docker Compose (8010:80 for Symfony 7, 8011:80 for Symfony 8)
  • Data fixtures: menus (sidebar, footer) and multilingual menu items; examples of context resolution (same code, different JSON context)
  • Symfony Web Profiler and debug toolbar enabled in dev mode
  • Translations for the demo UI (en, es, fr)

Ports

Each demo reads its host port from the PORT variable in its .env file (default: 8010 for Symfony 7, 8011 for Symfony 8). To run both demos simultaneously, ensure each uses a different port.

FrankenPHP and Caddy

The demos use FrankenPHP (a Caddy + PHP single binary) as the web server.

Development vs production mode

AspectDevelopmentProduction
FrankenPHP worker modeOff (one PHP process per request)On (workers keep app in memory)
Twig cacheOff (config/packages/dev/twig.yaml)On (default)
OPcache revalidationEvery request (docker/php-dev.ini)Default (e.g. 2 seconds)
HTTP cache headersno-store, no-cache (Caddyfile.dev)Cache-friendly
APP_ENV / APP_DEBUGdev / 1prod / 0
Each demo ships two Caddyfiles:
  • docker/frankenphp/Caddyfile — production (worker mode enabled)
  • docker/frankenphp/Caddyfile.dev — development (no worker, no-cache headers)
The Docker entrypoint copies Caddyfile.dev over the default when APP_ENV=dev.

Worker mode (production Caddyfile)

The production Caddyfile uses FrankenPHP worker mode, which keeps the Symfony application in memory between requests for maximum performance:
:80 {
    php_server {
        worker /app/public/index.php 2
    }
}

Switching between development and production

After changing APP_ENV or the Caddyfile, restart the container:
docker-compose restart
# or:
make -C demo/symfony8 restart

Running demo tests

make -C demo/symfony8 test
make -C demo/symfony8 test-coverage

# Or from the demo directory:
cd demo/symfony8 && make test

Release verification

From the bundle root, make release-check runs the root QA suite and then make -C demo release-verify, which starts each demo, runs its verify target (HTTP health check), and stops it. This confirms the demos start and respond correctly before a release is tagged.

Troubleshooting

In development mode, check that:
  • The container is running with APP_ENV=dev and APP_DEBUG=1
  • Caddyfile.dev (no worker) is active — the entrypoint copies it automatically when APP_ENV=dev
  • docker/php-dev.ini is mounted (opcache.revalidate_freq=0)
  • config/packages/dev/twig.yaml has twig.cache: false
  • You have hard-refreshed the browser
Verify APP_ENV=dev and APP_DEBUG=1 are set, and that WebProfilerBundle is enabled for the dev environment in config/bundles.php.
  • Check the host port is free (default 8010 / 8011)
  • Inspect container logs: docker-compose logs php
  • Ensure required env vars are set (e.g. APP_SECRET)
  • For DashboardMenuBundle demos, confirm MySQL is healthy before running install