- new setup/upgrading.md: version rule, the two 0.2 boot refusals with their fixes, behaviour changes, and what 0.2 adds since 0.1 - architecture module table lists all 28 modules - WinterCMS map: cache and reorder are provided; rows for field types, sanitizing, singletons, API tokens, CORS, Turnstile, menu item types - configuration keys for CORS profiles, api_docs, auth.cookie, turnstile - index, setup intro and frontend page link the new topics
8.3 KiB
title, description, section, order
| title | description | section | order |
|---|---|---|---|
| Configuration | Configure an application with YAML files, per-environment directories, plugin defaults and SUMMER_ environment variables, and set the keys it needs. | setup | 30 |
Configuration
WinterCMS keeps configuration in config/*.php files, per-environment directories and .env. SummerCMS keeps the same shape with YAML files, merged by compass into one tree that you read with dot paths such as app.name.
The config directory
Each YAML file in the application's config/ directory is a section named after the file, so config/app.yaml provides the app.* keys and config/http.yaml provides http.*:
# config/app.yaml
name: Acme
url: http://127.0.0.1:8080
timezone: Europe/Warsaw
Files for one environment go in config/env/<environment>/ with the same naming, and override the base files. The environment comes from SUMMER_ENV and defaults to production, so a development setup sets SUMMER_ENV=development and keeps its overrides in config/env/development/.
Plugin defaults
A plugin ships its own defaults embedded in the binary through pact.HasConfig. Its config/config.yaml becomes <plugin id>.<key>, so the posts_per_page key of acme.blog is read as acme.blog.posts_per_page. WinterCMS writes the same key as acme.blog::posts_per_page. The application overrides a plugin default like any other key: put posts_per_page under blog: in config/acme.yaml.
Environment variables
Any key can be overridden with an environment variable. Take the dot path, replace each dot with a double underscore, upper-case it and prefix SUMMER_:
| Key | Variable |
|---|---|
database.dsn |
SUMMER_DATABASE__DSN |
app.key |
SUMMER_APP__KEY |
admin.jwt.secret |
SUMMER_ADMIN__JWT__SECRET |
A .env file next to the config/ directory supplies KEY=VALUE lines for variables that are not already set in the real environment. Keep secrets in the environment or in .env, never in committed YAML.
Environment values are strings. Keys that must be numbers, such as http.body_limits.default_bytes, belong in a YAML file.
The layers merge in this order, each overriding the ones before it: plugin defaults, config/*.yaml, config/env/<environment>/*.yaml, SUMMER_ variables, then runtime overrides that a command saved to config/env/<environment>/overrides.yaml.
Keys an application sets
These are the keys most applications set. Each module's reference page lists all of its keys and their defaults.
| Key | Purpose | Reference |
|---|---|---|
database.dsn |
PostgreSQL connection string. Required by every command that opens the database. | lagoon |
app.key |
Base64 encoding of 32 random bytes, used to encrypt columns. Generate it with key:generate. |
lagoon |
app.timezone |
Timezone of scheduled commands. Defaults to UTC. | conga |
app.locale, app.fallback_locale |
Default and fallback translation locales. | phrasebook |
http.body_limits.default_bytes, http.body_limits.upload_bytes |
Request body limits. Required by serve and route:list. |
surf |
http.cors.*, http.trusted_proxies |
CORS and the proxies whose forwarded client IP is trusted. With supports_credentials: true, a wildcard host other than the whole leftmost label and an origin pattern not anchored with ^ and $ fail the start-up. |
surf |
http.cors_profiles.* |
Named CORS profiles with the http.cors keys except paths, applied to a route or group with the cors:<profile> middleware; checked like http.cors. |
surf |
http.api_docs.enabled, http.api_docs.path, http.api_docs.title |
The opt-in Swagger UI page for the public API (off by default; path /api-docs, title API documentation). |
surf |
http.rate_limit.store |
Where throttle counters live: memory (per instance, the default) or redis (shared by every instance). |
cooler |
cache.driver, cache.prefix, cache.memory.max_entries |
The cache driver (memory, the default, or redis), the key prefix (default from app.name) and the memory driver's size bound (default 10000). |
cooler |
site_cache.purge_url, site_cache.purge_token |
The host site's page-cache purge route and its bearer token (at least 32 characters). Set both or neither; http only to a loopback host. Keep the token in SUMMER_SITE_CACHE__PURGE_TOKEN. |
cooler |
redis.url |
Redis URL (redis://, rediss:// or unix://), required when a Redis cache or rate-limit store is selected. Keep it in SUMMER_REDIS__URL when it carries a password. |
cooler |
http.access_log |
Logs one record per request with method, matched route pattern, status and duration. Defaults to false. |
surf |
storage.uploads.bucket_url |
Uploads bucket, file://, mem:// or s3:// (the last only in a binary built with the summercms_s3 tag from build.tags in summer.yaml; credentials from the AWS environment). Required by serve. |
lagoon |
storage.uploads.public_url |
Absolute http or https base of a public bucket or CDN; file and thumbnail URLs become that base plus the partition path. Unset keeps storage.uploads.public_path_prefix. Only for a bucket holding public files alone. |
lagoon |
storage.uploads.serve |
Mounts attach.StaticHandlerPublic under storage.uploads.public_path_prefix with X-Content-Type-Options: nosniff, a sandboxing CSP and Content-Disposition: attachment for anything but a raster image. Defaults to false. |
surf |
auth.cookie.name, auth.cookie.domain, auth.cookie.path, auth.cookie.secure, auth.cookie.same_site |
The httpOnly token cookie for a browser frontend (defaults token, host-only, /, Secure when app.url is https, lax). In production a cookie that is not Secure fails the start-up. |
bouncer |
turnstile.secret, turnstile.field |
The Cloudflare Turnstile secret behind the turnstile:open and turnstile:closed middleware (keep it in SUMMER_TURNSTILE__SECRET) and the request field carrying the token (default turnstile_token). |
surf |
admin.jwt.secret |
Secret for admin tokens. Required as soon as a plugin registers an admin controller. | cabana |
backend.uri |
Path the admin is served under. Defaults to /backend. |
cabana |
mail.driver, mail.from, mail.smtp.* |
Mail delivery: memory, log or smtp. |
postcard |
queue.work_in_serve, queue.queues.* |
Whether serve runs the job worker, and workers per queue. |
conga |
realtime.driver, realtime.centrifugo.* |
The realtime driver and its Centrifugo settings. | lighthouse |
search.driver, search.typesense.* |
The search engine and its Typesense settings. | beachcomber |
push.enabled, push.public_key, push.private_key |
Web Push with VAPID keys. | flare |
Some keys are checked more strictly from 0.2 on, so a value that started an older release can stop the start-up; Upgrading lists them and their fixes.
Note
The documentation checks every identifier, link and command name it shows against the code, but not configuration keys. The keys on this page are reviewed by hand; the module reference pages are the authority.
Reading configuration in a plugin
Plugins read configuration from backpack.App.Config, a compass.Config. Use compass.Config.String, compass.Config.Int and compass.Config.Bool for single values, which return the zero value for a missing key, compass.Config.Has to tell a missing key from a zero value, and compass.Config.LoadSection to decode a whole section into a struct.