Skip to content

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, hop3 and kubernetes refuse a layout with several processes and none named web.
  • 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's url and bind must read MYXO_URL_<PROCESS> and MYXO_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.