Skip to content

The layout file

A layout is a TOML file. Every string may read the environment: ${NAME}, which must be set, or ${NAME:-default}. A value from the environment fills a number or a boolean as well: instances = "${WEB_INSTANCES:-1}".

Top-level keys

Key Default What it sets
database none the installation's database, SQLite or PostgreSQL, where the framework's services keep their tables; it must be the database the services that publish events write to
call_timeout 30.0 seconds for every call between services, in a process or across processes
[supervisor] how each process restarts its services, below
[processes.NAME] a process and its settings, below
[services.NAME] a service's configuration, given to its Config

Each of sqlite:// and postgresql:// works in database, and postgres:// too. An unknown key is an error.

[processes.NAME]

Key Default What it sets
services (required) the services the process runs; each service is placed once in the layout
url none where other processes reach this one: http://host:port, or unix:PATH on one host; required if others call its services
bind 127.0.0.1 the address its listener binds, for an HTTP url
port the url's the listener's port, if it differs from the url's, as behind a proxy
instances 1 replicas, on a platform that runs them (Kubernetes); refused on one host, and with SQLite
privileges "full" "reduced" for a process that parses untrusted files: systemd's sandbox, or a restricted security context on Kubernetes; Hop3 refuses it unless --without-sandbox
free_threaded false refuse to start with the GIL, on a build without one, or after an import turns it back on
copy_messages false copy every message of a call within the process, as the network would, to find code that shares one
loopback false call this process's own services through its listener, as if they were remote
http_client "httpx2" the HTTP client for calls to other processes: httpx2, or aiohttp with the myxo[aiohttp] extra

The process named web, or the only process, serves the public port, $PORT, on the platforms. On Kubernetes, a process's url and bind must read MYXO_URL_<PROCESS> and MYXO_BIND, which the manifests set. SQLite serves one host: a layout that runs a process using it as replicas, or shares it between processes on several hosts, is refused, with the next step named.

[supervisor]

Key Default What it sets
initial_delay 0.5 seconds before the first restart
max_delay 30.0 the longest delay; each restart doubles the delay up to this
healthy_after 60.0 a run this long, in seconds, resets the delay
max_failures 5 the process stops after more failures than this within window
window 60.0 the period, in seconds, that max_failures counts over

myxo up applies the same policy to the processes it runs.

[services.NAME]

The keys are the fields of the service's Config, a msgspec.Struct. A section for a service that the layout doesn't place is an error, and so is a service that no installed package declares.

An example

database = "${DATABASE_URL:-sqlite:///guestbook.db}"
call_timeout = 10.0

[supervisor]
max_failures = 10

[processes.web]
services = ["web", "book"]
url = "${MYXO_URL_WEB:-unix:run/web.sock}"
bind = "${MYXO_BIND:-127.0.0.1}"
instances = "${WEB_INSTANCES:-1}"

[processes.worker]
services = ["moderation"]

[services.web]
host = "${MYXO_BIND:-127.0.0.1}"
port = "${PORT:-8000}"

[services.book]
database = "${DATABASE_URL:-sqlite:///guestbook.db}"