Configuration
The app is configured through:
.envconfig/*.php- provider registration in
config/app.php
ApplicationFactory loads all files under config/ and resolves environment values through env(...).
Config Files
Current project config files:
config/app.php: app identity, bootstrap defaults, base URL, timezone, log path, and provider registration.config/auth.php: authentication, session storage, token storage, guards, and auth infrastructure defaults.config/cache.php: application cache stores, cache prefixes, and route cache settings.config/database.php: database connections for MySQL, PostgreSQL, SQLite, and SQL Server.config/maintenance.php: maintenance-mode state handling, wait behavior, and command allowlists.config/migrations.php: migration paths, schema snapshots, repository table names, and model-generation paths.config/queue.php: queue driver, named stores, worker behavior, retry defaults, visibility timeout, and Redis queue options.config/rate_limit.php: rate-limit stores and reusable presets such asapi,login, anduploads.config/services.php: infrastructure-style service connections, mainly Redis by default.config/storage.php: default storage disk and named local, public, database-backed, or S3-backed disks.config/version.php: version metadata source, sync behavior, and generated version file location.
As a rule:
- put defaults and structure in
config/*.php - put environment-specific values in
.env
Service Providers
The app boots providers from config/app.php.
Important providers include:
FrameworkServiceProvider: registers core framework services such as requests, responses, routing, and validation.AppServiceProvider: registers app-level services such as HTML rendering, exception handling, logging, and timezone setup.EventServiceProvider: registers the event bus and the application's event-to-listener map.CacheServiceProvider: builds configured file or Redis cache stores and selects the default cache store.RoutesServiceProvider: loads cached routes when enabled, otherwise loads route files from source.DatabaseServiceProvider: registers configured PDO database connections and the default connection.StorageServiceProvider: registers configured local, database-backed, and S3-backed storage disks.RateLimitServiceProvider: registers the rate limiter store and framework rate-limiting services.AuthServiceProvider: registers auth config, password hashing, users, tokens, sessions, guards, and token resolvers.RedisServiceProvider: registers configured Redis connections and the default Redis connection.QueueServiceProvider: registers queue storage, retry policy, and worker services.
If you create a new provider, register it in config/app.php.
Main Environment Variables
The sections below cover the environment variables you are most likely to change in a fresh app.
App and HTTP
APP_NAME="Myxa App"
APP_ENV=local
APP_DEBUG=true
APP_URL=https://myxa.localhost
APP_TIMEZONE=UTC
APP_HOST=myxa.localhost
APP_PORT=80
APP_SSL_PORT=443
Variable notes:
APP_NAME: display name for the application.APP_ENV: current runtime environment, such aslocal,staging, orproduction.APP_DEBUG: enables detailed error output when set totrue.APP_URL: canonical base URL used when the app needs to build absolute links.APP_TIMEZONE: default PHP timezone used by the application.APP_HOST: local hostname used by the Docker nginx configuration.APP_PORT: host HTTP port published by Docker.APP_SSL_PORT: host HTTPS port published by Docker.
Cache
CACHE_STORE=local
CACHE_REDIS_CONNECTION=default
CACHE_REDIS_PREFIX=cache:
ROUTE_CACHE=false
Variable notes:
CACHE_STORE: default application cache store, usuallylocalorredis.CACHE_REDIS_CONNECTION: Redis connection name to use whenCACHE_STORE=redis.CACHE_REDIS_PREFIX: key prefix used for Redis-backed cache entries.ROUTE_CACHE: tells the app to prefer the compiled route manifest when it exists.
config/cache.php defines these stores:
local: file cacheredis: Redis-backed cache
If you want shared cache across multiple app nodes, switch:
CACHE_STORE=redis
Important note:
- routes are not cached until you run
./myxa route:cache
Database
DB_CONNECTION=mysql
DB_HOST=db
DB_PORT=3306
DB_DATABASE=myxa
DB_USERNAME=myxa
DB_PASSWORD=secret
DB_ROOT_PASSWORD=root
DB_FORWARD_PORT=3306
Variable notes:
DB_CONNECTION: default database connection name.DB_HOST: database host for the default MySQL connection.DB_PORT: database port for the default MySQL connection.DB_DATABASE: database name for the default MySQL connection.DB_USERNAME: database username for the default MySQL connection.DB_PASSWORD: database password for the default MySQL connection.DB_ROOT_PASSWORD: root password used by the local Docker MySQL service.DB_FORWARD_PORT: host port published by Docker for MySQL.
config/database.php includes named connection templates for:
mysqlpgsqlsqlitesqlsrv
mysql remains the default because the local Docker stack already boots MySQL out of the box.
If you prefer another engine, switch DB_CONNECTION and fill in the matching env values.
Redis
REDIS_CONNECTION=default
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_DB=0
REDIS_FORWARD_PORT=6379
Variable notes:
REDIS_CONNECTION: default Redis connection name.REDIS_HOST: Redis host for the default connection.REDIS_PORT: Redis port for the default connection.REDIS_DB: Redis database index for the default connection.REDIS_FORWARD_PORT: host port published by Docker for Redis.
These map into config/services.php. The default connection alias is default.
If you want separate Redis connections for cache, queues, sessions, or rate limiting, add them in config/services.php.
Queue
QUEUE_CONNECTION=file
QUEUE_NAME=default
QUEUE_VISIBILITY_TIMEOUT=60
QUEUE_REDIS_CONNECTION=default
QUEUE_REDIS_PREFIX=queue:
QUEUE_WORKER_SLEEP=3
QUEUE_WORKER_MAX_IDLE=0
QUEUE_WORKER_MAX_ATTEMPTS=3
QUEUE_WORKER_BACKOFF=30
Variable notes:
QUEUE_CONNECTION: default queue store, usuallyfileorredis.QUEUE_NAME: default queue name used when a job does not specify one.QUEUE_VISIBILITY_TIMEOUT: seconds a reserved job may stay hidden before being released back to the queue.QUEUE_REDIS_CONNECTION: Redis connection name to use whenQUEUE_CONNECTION=redis.QUEUE_REDIS_PREFIX: key prefix used for Redis-backed queues.QUEUE_WORKER_SLEEP: seconds to sleep after an empty queue poll.QUEUE_WORKER_MAX_IDLE: empty-poll limit before the worker exits;0means keep running.QUEUE_WORKER_MAX_ATTEMPTS: default retry limit when a job does not declare its ownmaxAttempts().QUEUE_WORKER_BACKOFF: base retry delay in seconds for the default retry policy.
config/queue.php defines:
file: local filesystem queue understorage/queueredis: shared Redis-backed queue- a visibility-timeout based reservation recovery path for crashed workers
For local development or a single-node app, file is a good default.
For scaled or multi-node deployments, switch to:
QUEUE_CONNECTION=redis
The queue:work command can override loop behavior such as --sleep, --max-jobs, --max-idle, and --once, while retry defaults still come from config.
Storage
STORAGE_DISK=local
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
AWS_ENDPOINT=
AWS_SESSION_TOKEN=
AWS_USE_PATH_STYLE_ENDPOINT=false
Variable notes:
STORAGE_DISK: default storage disk, usuallylocal,public,db, ors3.AWS_ACCESS_KEY_ID: access key for S3-compatible storage.AWS_SECRET_ACCESS_KEY: secret key for S3-compatible storage.AWS_DEFAULT_REGION: region used by the S3-compatible storage client.AWS_BUCKET: bucket name used by thes3disk.AWS_ENDPOINT: optional custom endpoint for S3-compatible providers.AWS_SESSION_TOKEN: optional temporary session token for S3 credentials.AWS_USE_PATH_STYLE_ENDPOINT: enables path-style S3 URLs for providers that require them.
config/storage.php defines:
local:storage/apppublic:storage/app/publicdb: database-backed storages3: S3-compatible object storage
Choose disks by use case:
localfor private/internal filespublicfor web-exposed filess3for shared or cloud-backed files across multiple nodes
Use App\Storage\StorageArea when you want consistent public/... and private/... path prefixes. The helper can be used with any disk; for S3-backed apps, a common pattern is one s3 disk plus those prefixes.
Rate Limiting
RATE_LIMIT_STORE=file
RATE_LIMIT_REDIS_CONNECTION=default
RATE_LIMIT_REDIS_PREFIX=rate-limit:
RATE_LIMIT_API_MAX_ATTEMPTS=60
RATE_LIMIT_API_DECAY_SECONDS=60
RATE_LIMIT_LOGIN_MAX_ATTEMPTS=5
RATE_LIMIT_LOGIN_DECAY_SECONDS=60
RATE_LIMIT_UPLOADS_MAX_ATTEMPTS=20
RATE_LIMIT_UPLOADS_DECAY_SECONDS=60
Variable notes:
RATE_LIMIT_STORE: default rate-limit store, usuallyfilefor local use orredisfor shared deployments.RATE_LIMIT_REDIS_CONNECTION: Redis connection name to use whenRATE_LIMIT_STORE=redis.RATE_LIMIT_REDIS_PREFIX: key prefix used for Redis-backed rate-limit counters.RATE_LIMIT_API_MAX_ATTEMPTS: maximum attempts allowed for theapipreset.RATE_LIMIT_API_DECAY_SECONDS: time window, in seconds, for theapipreset.RATE_LIMIT_LOGIN_MAX_ATTEMPTS: maximum attempts allowed for theloginpreset.RATE_LIMIT_LOGIN_DECAY_SECONDS: time window, in seconds, for theloginpreset.RATE_LIMIT_UPLOADS_MAX_ATTEMPTS: maximum attempts allowed for theuploadspreset.RATE_LIMIT_UPLOADS_DECAY_SECONDS: time window, in seconds, for theuploadspreset.
config/rate_limit.php defines:
- named stores, such as
fileandredis - named presets, such as
api,login, anduploads
For a single-server local setup, file is fine.
For multi-node or scaled setups, the simplest switch is:
RATE_LIMIT_STORE=redis
The extra RATE_LIMIT_* values shown above are optional overrides. The app already has sensible defaults in config/rate_limit.php.
Auth
Common auth-related environment variables:
AUTH_SESSION_DRIVER=file
AUTH_SESSION_COOKIE=myxa_session
AUTH_SESSION_LIFETIME=1209600
AUTH_SESSION_SAME_SITE=Lax
AUTH_SESSION_SECURE=false
AUTH_SESSION_LENGTH=64
AUTH_SESSION_REDIS_CONNECTION=default
AUTH_SESSION_REDIS_PREFIX=session:
AUTH_TOKEN_LENGTH=40
AUTH_TOKEN_NAME=cli
AUTH_TOKEN_SCOPES=*
Variable notes:
AUTH_SESSION_DRIVER: session storage driver, usuallyfile,redis, ordatabase.AUTH_SESSION_COOKIE: cookie name used for the web session.AUTH_SESSION_LIFETIME: session lifetime in seconds.AUTH_SESSION_SAME_SITE: controls when browsers send the session cookie on cross-site requests.Laxis a good default for normal apps,Strictis more restrictive and may block cookies after cross-site navigation, andNoneallows cross-site cookie use but requiresAUTH_SESSION_SECURE=true.AUTH_SESSION_SECURE: sends the session cookie only over HTTPS when set totrue.AUTH_SESSION_LENGTH: generated session token length.AUTH_SESSION_REDIS_CONNECTION: Redis connection name to use whenAUTH_SESSION_DRIVER=redis.AUTH_SESSION_REDIS_PREFIX: key prefix used for Redis-backed sessions.AUTH_TOKEN_LENGTH: generated bearer token length.AUTH_TOKEN_NAME: default token name used by token-related CLI commands.AUTH_TOKEN_SCOPES: default token scopes used by token-related CLI commands.
These live in config/auth.php. They are optional overrides rather than required .env entries.
The app provides:
- session-based
webauth - bearer-token
apiauth - CLI commands for users and tokens
Versioning
The app reads version metadata from version.json.
That file is generated with:
./myxa version:sync
The manifest is runtime-friendly and does not require .git to be present in production.
How to Add New Config
- Add a new
config/*.phpfile or extend an existing one. - Read values with
env(...)there. - Resolve config through
ConfigRepositoryin your services.
Example:
use App\Config\ConfigRepository;
final class ReportService
{
public function __construct(private readonly ConfigRepository $config)
{
}
public function timezone(): string
{
return (string) $this->config->get('app.timezone', 'UTC');
}
}
When to Use .env vs Config Files
Use .env for:
- secrets
- hostnames
- ports
- environment-specific values
Use config/*.php for:
- structure
- defaults
- named presets
- feature-level organization