Commands¶
| Command | What it does |
|---|---|
myxo serve LAYOUT [PROCESS] |
runs one process of the layout; PROCESS may be left out if the layout has one |
myxo migrate LAYOUT |
runs each service's migrate, and creates the framework's tables, once, before any process starts |
myxo up LAYOUT |
runs the migrations, then every process of the layout on this machine; restarts a process that exits, and stops them all on SIGTERM or Ctrl-C |
myxo check LAYOUT |
finds what would stop the layout, without starting anything |
myxo export LAYOUT TARGET --name NAME |
writes a platform's files, with env.example |
A layout that a command refuses gives one line on stderr, myxo: ..., and status 1. A usage error gives status 2. The troubleshooting guide lists the messages.
myxo serve¶
Runs one process until SIGTERM or Ctrl-C, then exits with status 0. A process whose supervisor gives up exits with status 1, for whatever runs it to restart.
myxo migrate¶
Creates the tables of the framework's services that the layout's services use, then runs each service's migrate, by stage. It must run before any process starts, and is safe to run again. A database it cannot reach gives one line and status 1.
myxo up¶
This command suits development, and a box with no platform. It runs the migrations, then one myxo serve for each process. A process that exits restarts under the layout's [supervisor] policy. On SIGTERM or Ctrl-C, each process gets SIGTERM, and 10 s to stop before it is killed. A layout that asks for more than one instance of a process is refused.
myxo check¶
Prints LAYOUT: ok and exits with status 0, or prints each problem and exits with status 1. It reads the environment as serve does, and imports every service in the layout. It reports:
- the layout's placement and settings, and a missing environment variable;
- what SQLite cannot do;
- each interface's operations, and a mutable message;
- each event handler, with the event type and group;
- the GIL, for a process marked
free_threaded; - a client that a service asks for, when no service implements it or the implementer's process has no
url; - an import that bypasses an interface. Where services share a package, each one's code is the module holding the class; services in one module are not checked against each other.
It also warns about a process that listens on a port with a bind other than loopback, and still exits with status 0. Whoever reaches that port can call the process's services, since calls between processes are not authenticated. On Kubernetes, the pods listen on all interfaces, and the network policy is what keeps other pods out (Security).
It stops at the first problem in each process, so a second run may find more. It imports the services and creates none of them, since a service's __init__ may open a database. It reads clients from the source of each service's class and the classes it inherits, so it sees runtime.client(BookAPI) and runtime.client(api.BookAPI). An interface held in a variable escapes it. A client tested first with runtime.provides may go unimplemented. A target's own limits come from the command that runs it: up runs one instance of each process. Each export target refuses what it cannot run.
myxo export¶
Writes the files of a target, and prints their paths. It reads the environment for the settings that shape the files, such as an instance count, and writes no value from the environment into env.example, which lists the variables the layout reads, with their defaults. It refuses an unknown key at the top of the layout, in [supervisor] or in a process, and an instance count that is no number. It leaves the [services.NAME] sections and the other values to the commands that run on the target, since a value may wait for the environment.
| Option | Default | What it sets |
|---|---|---|
--name NAME |
(required) | the application's name, for units and Kubernetes objects |
--out DIR |
the current directory | where the files go |
--path PATH |
see below | where the layout file is on the target |
--command COMMAND |
see below | how the target runs myxo |
--image IMAGE |
none | the application's image; required for Kubernetes |
--package PACKAGE |
none | the uv workspace package to install in the Docker image |
--health PATH |
/healthz |
the web process's health path, which your web service must answer on the public port |
--without-sandbox |
off | on Hop3, runs a process with privileges = "reduced" with full privileges, which the export otherwise refuses |
| Target | Files | --path default |
--command default |
|---|---|---|---|
systemd |
NAME-migrate.service, NAME@.service, NAME.target, and a drop-in for each reduced process |
/etc/NAME/layout.toml |
/opt/NAME/bin/myxo |
procfile |
Procfile, with the migrations as its release phase |
the path given | myxo |
hop3 |
Procfile, hop3.toml |
the path given | myxo |
kubernetes |
migrate.json, app.json |
/etc/myxo/layout.toml |
myxo |
docker |
Dockerfile |
Every target also writes env.example.
The export follows these conventions:
- The process named
web, or the only process, serves the public port,$PORT.procfile,hop3andkubernetesrefuse a layout with several processes and none namedweb. - On systemd, every unit works in the application's state directory,
/var/lib/NAME, so relative paths in the layout name the same files for every unit. - On one host (
systemd,hop3), a layout that asks for more than one instance is refused. - On Kubernetes, the manifests read the environment from a secret named
NAME-env. A layout that would use SQLite is refused, since pods share no files. A process'surlandbindmust readMYXO_URL_<PROCESS>andMYXO_BIND, which the manifests set. The public port is 7480 inside the cluster, and listeners take the ports after it. A network policy per process admits only the application's own pods to a process's listener, while the public port stays open.
The deployment guides show each target in use.