Configuration
Environment variables, database, cache, queue, storage, and the admin prefix.
Cogeze is a Laravel application. Everything Laravel configures with .env and config/
works unchanged. This page covers what Cogeze adds or constrains.
Environment#
APP_NAME=Cogeze
APP_ENV=local
APP_KEY= # php artisan key:generate
APP_DEBUG=true # false in production, always
APP_URL=http://localhost:8000
APP_LOCALE=en
APP_FALLBACK_LOCALE=en
DB_CONNECTION=mariadb
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=cmsadmin
DB_USERNAME=cmsadmin
DB_PASSWORD=
SESSION_DRIVER=database
CACHE_STORE=database
QUEUE_CONNECTION=database
FILESYSTEM_DISK=local
SANCTUM_STATEFUL_DOMAINS=localhost:8000,127.0.0.1:8000
APP_DEBUG#
APP_DEBUG changes behaviour beyond error pages. In the Router Hub, a failing optional
need falls back and logs when debug is off, and rethrows when debug is on — so a
developer sees the real failure instead of an empty block. The same applies to storefront
sections.
Never enable it in production: it turns a degraded block into a 500.
APP_LOCALE vs the language plugin#
config('app.locale') is Laravel's default. The site's own default language lives in the
languages table, owned by the language plugin, and the two can disagree.
The Router Hub asks the plugin first through the language.default command, and falls back
to config only when the plugin is absent. Do not assume config('app.locale') reflects what
visitors see — see Internationalisation.
SANCTUM_STATEFUL_DOMAINS#
The admin SPA authenticates with cookies over Sanctum. Any host serving the admin must be listed here, including the port. A missing entry produces a 419 on login with no other symptom.
Database#
MariaDB 12+ or MySQL 8+. A docker-compose.yml ships with the repository:
services:
mariadb:
image: mariadb:12.3
environment:
MARIADB_DATABASE: cmsadmin
MARIADB_USER: cmsadmin
MARIADB_PASSWORD: 1234
MARIADB_ROOT_PASSWORD: 1234
ports:
- "${DB_FORWARD_PORT:-3306}:3306"
volumes:
- mariadb_data:/var/lib/mysql
docker compose up -d
php artisan migrate --seed
DB_FORWARD_PORT remaps the host port when 3306 is already taken; the container port never
changes, so DB_PORT in .env follows the host value.
What migrate --seed does#
Core migrations create only infrastructure tables — users, cache, jobs, tokens,
route_map, plugins, plugin_settings, command logs, dashboard layouts. Every content
table belongs to a plugin and is created when that plugin is installed.
The seeder then installs every plugin found on disk, in dependency order. There is no
hard-coded list: order comes from a topological sort over dependencies() and
optionalDependencies(), with installPriority() breaking ties. Adding a plugin requires no
change to the seeder.
Cache#
CACHE_STORE=database is the default and works out of the box. Redis is faster and is
worth it once traffic justifies it:
CACHE_STORE=redis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379
Two Cogeze subsystems depend on the cache:
| Subsystem | Key | Invalidation |
|---|---|---|
| Route map | router:map:s{shape}:v{version} |
Version counter bumps on install/enable/disable and URL edits |
| Page needs | hub:need:{command}:{hash} |
TTL only, per the page's cache value |
Both degrade to a direct query if the cache is unavailable. A broken cache costs speed, not correctness.
Queue#
QUEUE_CONNECTION=database is the default. Run a worker in production:
php artisan queue:work --tries=3
Plugins that send mail or process media dispatch jobs. Without a worker they queue silently and nothing happens.
Storage#
php artisan storage:link
Uploads go to storage/app/public and are served from public/storage. For S3, set
FILESYSTEM_DISK=s3 and the AWS_* variables — the media plugin uses the configured disk
and needs no further changes.
Admin prefix#
The admin shell is at /admin by default. It is configurable, with a deliberate fallback
chain:
system_config('router.admin_prefix') → env('ADMIN_PATH') → 'admin'
Every layer is optional and the last one is hard-coded, so a bad database value cannot lock you out of the admin.
/api/admin/* is fixed and never changes. The prefix only affects the URL of the HTML
shell; the SPA calls the API at a stable path. Changing the prefix therefore cannot lock the
application out of its own API.
The prefix is also a reserved segment: no plugin page may claim a URL under it — see Pages.
System configuration#
Values administrators edit live in system_configurations, read through a helper:
system_config('contact') // whole group as an array
system_config('contact', 'email') // one field
system_config('contact.email') // dot form
system_config('contact.email', null, '—') // with a default
Values are cached. This is site-wide configuration, distinct from per-plugin settings — see Settings.