Appearance
Scaffolds
A scaffold is a named recipe for creating an application. dqx init --scaffold laravel creates the project and the application in it.
Recipes are data, not code: dqx ships some, and a machine or a project can add its own without waiting for a release.
What ships with dqx
| recipe | extends | proposes | creates |
|---|---|---|---|
laravel:13 | none | db, mailpit | 2 step(s) |
qore-cms | laravel:13 → qore-works-business | db, mailpit, redis | 15 step(s) |
qore-works-business | laravel:13 | db, mailpit, redis | 9 step(s) |
laravel:13
- laravel 13 · php 8.5 · mysql 8.4 · node 22
- services: db, mailpit
Proposes, every one of these is overridden by anything you state:
| key | value |
|---|---|
php | 8.5 |
node | 22 |
services | db, mailpit |
database | mysql 8.4 |
install | gitHooks, env, composer, npm, ssl |
Creates the application
bash
composer create-project laravel/laravel:^13 .Sets it up
bash
php artisan key:generateRuns on every install
bash
php artisan migrateqore-cms
- laravel 13 · php 8.5 · mysql 8.4 · node 22
- services: db, mailpit, redis
- installs: qore-admin-base, dq-sonar, qore-cms, qore-frontend · needs Flux credentials
Extends laravel:13 → qore-works-business.
Proposes, every one of these is overridden by anything you state:
| key | value |
|---|---|
php | 8.5 |
node | 22 |
services | db, mailpit, redis |
database | mysql 8.4 |
install | gitHooks, env, composer, npm, ssl, flux |
Sets it up
bash
composer require qore-works-business/qore-cms -W
php artisan qore-cms:install
php artisan tinker --execute='\Illuminate\Support\ServiceProvider::addProviderToBootstrapFile(\App\Application\Cms\Providers\ApplicationServiceProvider::class);'
composer require qore-works-business/qore-frontend -W
php artisan scaffold:application StatamicSite statamic --create --no-interaction
php -r '$f="routes/web.php";if(!is_file($f))exit;$s=file_get_contents($f);$t=preg_replace("~^[ \t]*Route::get\(\s*[\x27\x22]/[\x27\x22]\s*,\s*(?:function\s*\(\s*\)\s*\{\s*return\s+view\(\s*[\x27\x22]welcome[\x27\x22]\s*\)\s*;?\s*\}|fn\s*\(\s*\)\s*=>\s*view\(\s*[\x27\x22]welcome[\x27\x22]\s*\))\s*\)\s*;\s*~m","",$s);if($t!==$s)file_put_contents($f,rtrim($t).PHP_EOL);'Runs on every install
bash
php artisan vendor:publish --tag=qore-cms-migrations
php artisan vendor:publish --tag=statamic-cp --force
php artisan tinker --execute='\Statamic\Facades\User::findByEmail("admin@dolphiq.nl") ?? \Statamic\Facades\User::make()->email("admin@dolphiq.nl")->password("password")->set("name", "Admin")->makeSuper()->save();'
npm run buildAfterwards
The homepage shows the CMS home entry. Log in at /cp with admin@dolphiq.nl / password - local development only: change or remove that user before the project runs anywhere else. To render more CMS content, see https://docs.qore.works/packages/qore-cms/#show-cms-content-in-a-website.
Afterwards
The Control Panel shows a Statamic licensing alert on a .dqx domain: qore-cms enables Statamic Pro, and Statamic only counts localhost, IP addresses, ports other than 80/443, subdomains such as local. or dev., and the TLDs .test, .local, .localhost, .invalid, .example and .wip as development domains. It is harmless locally and needs no licence; for trial mode instead, open the site on a .test alias (dqx suffix add test). See https://statamic.dev/licensing#public-domains.
qore-works-business
- laravel 13 · php 8.5 · mysql 8.4 · node 22
- services: db, mailpit, redis
- installs: qore-admin-base, dq-sonar · needs Flux credentials
Extends laravel:13.
Proposes, every one of these is overridden by anything you state:
| key | value |
|---|---|
php | 8.5 |
node | 22 |
services | db, mailpit, redis |
database | mysql 8.4 |
install | gitHooks, env, composer, npm, ssl, flux |
Creates the application
bash
composer config repositories.filament composer https://packages.filamentphp.com/composer
composer config repositories.dolphiq composer https://dolphiq.repo.packagist.com/packages/Sets it up
bash
composer require qore-works-business/qore-admin-base:^v2.0 --with-all-dependencies
php artisan qore-admin-base:install --dev-packages
php artisan tinker --execute='\Illuminate\Support\ServiceProvider::addProviderToBootstrapFile(\App\Providers\QoreServiceProvider::class);'
php artisan tinker --execute='\Illuminate\Support\ServiceProvider::addProviderToBootstrapFile(\App\Application\Admin\Providers\QorePanelServiceProvider::class);'
composer require dolphiq/dq-sonarRuns on every install
bash
php artisan migrate --seedAfterwards
dq-sonar reports PHP, Laravel, database and package versions to My Dolphiq once a server has DQ_SONAR_DSN in its .env; it stays off locally. Generate the DSN in My Dolphiq on the application's installation, keep it out of the repository, and check it on the server with php artisan sonar:test.
Where these come from
This section is generated from the registry itself on every docs build, so it cannot drift from what dqx_scaffolds and dqx init --scaffold actually do. A machine or a project can add more - see where they live.
qore-cms creates a login everybody knows
So that the site works the moment the install ends - the homepage shows the CMS home entry and /cp has somebody to log in with - its postInstall creates a Statamic super user, admin@dolphiq.nl / password. That is for local development only: change or remove that user before the project runs anywhere else.
qore-cms shows a licensing alert on .dqx
qore-cms enables Statamic Pro, and Statamic's licence server decides from the domain whether a site is in development ("trial mode") or public. Its rules are a fixed list - localhost, an IP address, a port other than 80 or 443, a subdomain such as local. or dev., or one of the TLDs .test, .local, .localhost, .invalid, .example and .wip - and no setting adds to it. A .dqx domain is none of those, so the Control Panel warns that Pro runs unlicensed on a public domain. Locally that is harmless. For the trial-mode notice instead, open the site on a .test alias (dqx suffix add test). See Statamic's public domains.
What a recipe looks like
yaml
laravel:13:
defaults: # proposed, never forced
php: '8.4'
services: [db, mailpit]
install: { env: true, composer: true, npm: true, ssl: true }
create: # before dqx writes .env - the app does not exist yet
- composer create-project laravel/laravel:^13 .
setup: # after .env, with the database reachable
- php artisan key:generate
postInstall: # written into .dq/config.yml, run by every install
- php artisan migrate
notes: # shown when init finishes, and kept in INSTALL.md
- Laravel is installed.The three lists, and why there are three
The order is a dependency, and only the recipe knows it. A package that migrates during its own installer needs a .env with a working database before it runs, and a composer create-project needs to happen before there is one.
createruns once, at init, before dqx writes.env.setupruns once, after.env, with the stack up and the database reachable.postInstallis written into the project's config and runs on every install - including the one your colleague does after cloning.
Getting that last one wrong is the mistake that breaks somebody else: a create-project in postInstall fails on their machine with an error that mentions nothing about a recipe. dqx refuses those at load time.
Inheritance
yaml
my-house-recipe:
extends: laravel:13
defaults:
services: [redis] # unioned with the parent's → db, mailpit, redis
setup:
- composer require acme/thingOne parent each - which keeps "who wins" answerable - but the chain can be as deep as you like, and every layer runs, root first, per list. Maps merge with the child winning; lists union across the whole chain; a flag or a --from key replaces the resolved list outright, because that is somebody stating what they want rather than adding to it.
Cycles, missing parents and chains deeper than eight fail when the registry loads, not halfway through somebody's new project.
Versions
laravel means the newest registered version, and the answer records which: the created .dq/config.yml says scaffold: laravel:13. Six months later that is the only thing that can still say whether a project was made with 13 or 14.
laravel:13 pins it. An unregistered name fails with the list of what is registered.
Where they live
| built in | ships with dqx |
~/.config/dqx/scaffolds.yml | this machine's |
<project>/.dq/scaffolds.yml | this project's |
Later files win, entry by entry - so a house recipe lands the day somebody writes it, and pinning one locally while you develop it is how it gets written in the first place.
Rules a recipe follows
- Commands run without a TTY. Anything that prompts hangs a container nobody can see, so installers need their non-interactive flag.
- A recipe never carries a credential. Package names and repository URLs only; credentials are discovered from the machine, and a missing one is reported before anything is written.
- Defaults are proposals. Anything stated explicitly wins, and every applied default is reported with the layer that set it.