Environments and the two-layer config
shipped 1.0.0Two files, both YAML, both maintained by cwp init and
cwp config set rather than by hand.
The project — .cwp.yml, committed
version: 1
name: example
docroot: public
php: "8.3"
plugin_slug: example-site # the site plugin's directory
environments:
dev:
cloudron_app: dev.example.com
url: https://dev.example.com
package: managed # managed | developer
protected: false
prod:
cloudron_app: example.com
url: https://example.com
package: managed
protected: true # refuses upward writes without --force
vps:
provider: ssh # a plain host
ssh: deploy@example.com # what you would type after `ssh`
path: /var/www/example # the docroot on that host
url: https://example.com
protected: true
tracked: # the paths push and deploy send upward
- wp-content/plugins/example-site
pull:
uploads: proxy # sync | skip | proxy
scrub: true
keep_admin_email: you@example.com
keep_roles: [administrator, editor]
builder:
id: bricks # none | bricks
options:
child_theme: example-child
export_dir: bricks
wp_user: 1 # optional — who ability calls run as
hooks_dir: .cwp/hooks
The environment map describes your remotes. The local site is not in it, and
that is why omitting the environment on
cwp bricks,
cwp content,
cwp plugins,
cwp ability, cwp mcp and
cwp open means local rather than dev.
The machine — ~/.config/cwp/config.yml, never committed
version: 1
cloudron_host: my.example.com
defaults:
uploads: proxy
scrub: true
backup_before_push: true
snapshot_before_pull: true
snapshot_before_bricks_write: true
projects:
example: ~/Code/example/example.com
The projects registry is written by cwp init and read by
cwp projects.
Which layer wins, and how to find out
pull.uploads is project config and defaults.uploads is machine config. They
spell the same idea deliberately: one is the default the other starts from, and a
flag beats both.
The layer is never a guess. cwp knows which file each key lives in, and an
unknown key is refused with the near misses rather than written to whichever
file happened to be open. cwp config get <key> --explain prints the chain and
marks the winner:
✓ pull.uploads — proxy
pull.uploads resolves to proxy from the project layer:
flag —
→ project proxy
machine —
default proxy
Two things the config deliberately does not hold
Defaults you did not set. cwp config set writes back your file with one key
changed, never a serialised copy of the parsed config — otherwise every schema
default would freeze into the file the first time you set anything, and a default
cwp later corrects would never reach you. That is not hypothetical: it is exactly
how a set of table names that had never existed survived in real projects.
ssh settings. ssh: is passed through verbatim, so ports, identity files and
jump hosts live in ~/.ssh/config, where they cannot disagree with the rest of
your machine.