VI Shipping

The CLI

toa is the one command-line tool for running, inspecting, building and deploying an application. Its commands are grouped by what you are doing; the first few are met in Run It and Make a Change.

§Installing

The toa binary comes with the runtime. What a command needs beyond it depends on the command:

$ npm i -D @toa.io/runtime @toa.io/operations

An application toa create wrote lists both, and @toa.io/userland, in its devDependencies: npm install is all it takes. toa is installed with the project, so in a shell it is run as npx toa, and by its name in a script of package.json.

NeedsCommands
@toa.io/userlandcreate
@toa.io/runtimecompose, mono, serve, call
@toa.io/operationsenv, build, push, deploy, conceal, reveal, export deployment, export images, export secrets, export tags, compose --dock, key --public, key --format paseto
neithermap, types, npm, export manifest, export convergence, shell, key

A command whose package is missing says so:

`toa deploy` needs @toa.io/operations, which is not installed

A machine that only deploys needs no runtime:

$ npm i @toa.io/cli @toa.io/operations
$ npx toa deploy production -p application

build, push and deploy use docker; deploy, conceal, reveal and shell use kubectl and, for deploy, helm. They act on the current docker and kubectl contexts.

§Creating an application

§toa create

$ npx -p @toa.io/cli -p @toa.io/userland toa create <name>

Writes an application into the working directory; name is the application’s name, which is what its Context is called. Create an Application starts from it.

$ mkdir store && cd store
$ npx -p @toa.io/cli -p @toa.io/userland toa create store
package.json
tsconfig.json
docker-compose.yaml
ecosystem.config.js
context.toa.yaml
cucumber.js
components/
  hello/
    manifest.toa.yaml
    operations/greet.ts
  notes/
    manifest.toa.yaml
features/
  hello.feature
  notes.feature
  steps/
    application.ts
    http.ts
FileIs
context.toa.yamlThe Context: the application’s name and where its infrastructure is.
docker-compose.yamlRabbitMQ, MongoDB as a replica set of one member, and Redis, on their usual ports, with the credentials toa env --dev writes.
ecosystem.config.jsThe two processes PM2 keeps: sys, what Toa serves beside an application, and app, the components.
components/helloA component with code and no state.
components/notesA component with state and no code.
featuresA scenario for each component, and the steps they are written with; see Write a Test.
package.jsonThe packages of Toa at the version that created the application, and the scripts.
tsconfig.jsonWhat tsc checks the components and the steps with.
  • The directory has to be empty; .git may be there. Otherwise nothing is written: The directory is not empty: it holds README.md.
  • A name a Context cannot have is refused the same way: 'my store' is not a name an application can have.
  • The files come from @toa.io/userland, which is why the command is run with both packages.
  • Nothing is installed or started. The command prints what to run next; running the application takes Docker and PM2 on the machine.

§The scripts

The generated package.json wraps the commands of every day:

ScriptRunsDoes
npm installtoa npm, as postinstallInstalls the packages, then what the declarations require beyond them.
npm run dockdocker compose up -d --waitStarts RabbitMQ, MongoDB and Redis from docker-compose.yaml and waits until they are ready.
npm run envtoa types --quiet && toa env --dev && toa mapWrites the types, .env and .map.json.
npm run syspm2 start ecosystem.config.js --only sysStarts sys alone: toa serve configuration exposition introspection. It is what the scenarios need, since they start the components themselves.
npm startpm2 start ecosystem.config.jsStarts sys and app; app is toa compose with every directory under components. The gateway is on http://localhost:8000.
npm run restartnpm run env && pm2 restart ecosystem.config.jsGenerates again and restarts both processes. Run it after any change.
npm stoppm2 delete ecosystem.config.jsStops both processes, and PM2 forgets them.
npm run featurescucumber-jsRuns the scenarios; see Write a Test.
npm run typechecktscChecks the types of the components and the steps; see Use TypeScript.

pm2 logs shows what the two processes write, and pm2 ls whether they run.

§Options every command takes

OptionMeaning
--env <path>read variables from this .env file
--map <path>read the component map from this file
--log <level>log level; info by default
-h, --helphelp for the program or for one command
-v, --versionthe version

Without --env, a .env file is looked for from the working directory upwards. Without --map, .map.json is looked for the same way by the commands that need one: compose, mono, serve and call.

Most commands that read a Context take -p, --path: where the Context is, . by default. The directory given, or one of its parents, must contain context.toa.yaml. With the application in a subdirectory, commands are run from the repository root as toa env -p application.

Unknown options are refused.

§Preparing to run

§toa env

$ npx toa env [environment]

Writes the variables of an environment to a .env file beside the Context.

OptionDefaultMeaning
environmentlocalthe environment, or a chain such as staging:production
-p, --path.path to the Context
--as.envoutput file, relative to the Context
-d, --devofffill secrets with local development defaults
-i, --interactiveoffask for each secret that has no value
-c, --componentallonly what this component needs; repeat for several
-s, --serviceallonly what this service needs, by shortcut or package; repeat

Secret values already in the output file are kept. With --dev alone, a secret that has no default and is not set in the shell’s environment is written empty. -d -i together fills what can be filled and asks for the rest. npm run env runs toa env --dev.

-c writes the variables of a component even when it is evicted. An unknown name is refused: Component 'store.order' is not in the context.

§toa map

$ npx toa map [environment]

Writes the component map to .map.json beside the Context. Run it again whenever component sources change; npm run env and npm run restart do.

OptionDefaultMeaning
environmentlocalas for toa env
-p, --path.path to the Context
--as.map.jsonoutput file, relative to the Context

§toa npm

$ npx toa npm [environment]

Installs the packages the application’s declarations require and Toa does not bundle: for example, the SDK of a storage provider a component’s storage uses. A deployment installs the same set into its images; this command installs it into your workspace, as devDependencies of the nearest package.json above the Context.

OptionDefaultMeaning
environmentlocalas for toa env
-p, --path.path to the Context
-n, --dry-runoffprint what is missing instead of installing it

Prints Nothing to install when the workspace already declares everything. Run it after upgrading Toa and after declaring a new storage provider. In a generated application it is the postinstall script, so npm install runs it.

§Running

Tests start components themselves; see Write a Test.

§toa compose

$ npx toa compose [paths...]

Runs components as one composition.

OptionDefaultMeaning
paths.component directories, or glob patterns matching them
--servicenonean extension service to run in the same process; repeat
--killoffshut down as soon as it has started
--dockoffbuild the composition’s image and run it in Docker
--context.path to the Context, for --dock
$ npx toa compose                                   # the component in the current directory
$ npx toa compose ./components/store.orders
$ npx toa compose ./components/*
$ npx toa compose ./components/* --service exposition --service configuration

It prints Composition complete when every component is connected and serving, and stops on SIGINT or SIGTERM after finishing what is in progress. See Decide What Runs Together for running services in the same process.

--service names are exact; nothing is added to them. Without the option, the list comes from TOA_SERVICES, separated by spaces. An extension that runs no service is refused: Service is not implemented by '@toa.io/extensions.telemetry'.

--dock builds the image a deployment would build for these components and services, runs it with the current .env, and removes it. The exit code is the composition’s. Inside the container, your machine is host.docker.internal, so use an environment whose addresses say so; see Several local environments. The components must belong to the Context.

§toa mono

$ npx toa mono [paths...]

Runs components and every extension service they use in one process. Unlike compose, the services are discovered from what the components declare.

OptionDefaultMeaning
paths.component directories, or glob patterns
--killoffshut down as soon as it has started

§toa serve

$ npx toa serve [paths...]

Runs extension services, without components, in one process.

$ npx toa serve exposition
$ npx toa serve exposition configuration introspection

Each is named by shortcut, package name, or path. The list is exact. A named service that is off in this environment, because its variables are absent, is refused and nothing starts:

'introspection' has no service to run in this environment: its variables are absent.
Regenerate the environment file with `toa env`.

A usual local arrangement is two processes: toa serve for the services and toa compose for the components, both reading the same .env and .map.json. It is the one a generated application runs under PM2: sys is toa serve configuration exposition introspection, and app is toa compose with every component.

§toa call

$ npx toa call <endpoint> [request]

Calls an operation of a running component and prints the reply.

$ npx toa call hello.greet "{ input: { name: 'Toa' } }"
$ npx toa call notes.observe "{ query: { id: '7a1c...' } }"

hello and notes are the two components of a generated application.

endpoint is <namespace>.<component>.<operation>; with two segments the namespace is default. request is a request (Call Operations and Select State) written as YAML, which includes JSON; without it the request is empty.

The reply is printed to stdout. A streamed reply is printed chunk by chunk. An exception is printed to stderr and the command exits with 1.

The component must be running somewhere the broker reaches, and the call is validated against the map, so call needs .env and .map.json as compose does.

§Inspecting

§toa types

$ npx toa types

Generates TypeScript types for the Context and every component in it; see Use TypeScript.

OptionDefaultMeaning
-p, --path.path to the Context
-e, --environmentlocalthe environment the Context is read for
-c, --componentspaths to components that belong to no Context, instead of reading one
-q, --quietoffprint nothing

It writes types/ beside context.toa.yaml and a types directory in each component, and prints the files written. In each, toa.d.ts is rewritten on every run, and index.d.ts, which is where types of your own go, is kept. npm run env runs it with --quiet.

§toa export manifest

$ npx toa export manifest

Prints a component’s manifest as the runtime reads it: with the prototype merged in, shorthand expanded and defaults filled. toa export man is the same.

OptionDefaultMeaning
-p, --path.path to the component
-o, --outputyamlyaml or json
-e, --erroroffprint nothing unless the manifest is invalid

With --error it is a manifest validator: silent and 0 for a valid manifest, an error otherwise.

§toa export secrets

$ npx toa export secrets <environment>

Lists every secret a deployment of the environment needs, with its keys. See Supply Secrets. Takes -p, --path.

§toa export tags

$ npx toa export tags <environment>

Prints the image reference of every workload the environment deploys. Takes -p, --path, and --mono for the single-image form.

§toa export deployment

$ npx toa export deployment <environment> <target>

Writes the Helm chart of a deployment into the target directory without applying it, and prints the path. Takes -p, --path and --mono. toa export dep is the same.

§toa export images

$ npx toa export images <target>

Writes the build contexts of the images — Dockerfiles and sources — into target without building them. Takes -p, --path and --mono. toa export img is the same.

§toa export convergence

$ npx toa export convergence <environment>

Prints what a region’s convergence broker must hold before the region is deployed; see Adding a region.

OptionDefaultMeaning
-p, --path.path to the Context
--formatdefinitionsdefinitions for the broker’s import, or commands for rabbitmqadmin invocations

§Building and deploying

See Deploy and Build Images.

§toa build

$ npx toa build

Builds every image on the local Docker daemon. Takes -p, --path, and --mono to build the single image.

§toa push

$ npx toa push [environment]

Builds every image and pushes it to the registry. An image the registry already has is skipped. environment defaults to default. Takes -p, --path.

§toa deploy

$ npx toa deploy [environment]

Checks secrets, builds and pushes images, and applies the deployment to the current Kubernetes context.

OptionDefaultMeaning
environmentdefaultthe environment, or a chain
-p, --path.path to the Context
-n, --namespacecurrentKubernetes namespace to deploy into
-w, --waitoffwait until the rollout is complete
-t, --timeout5mhow long --wait may take, as a duration such as 15m0s
-d, --dryoffprint what would be applied; no cluster is read and nothing is applied
--monooffdeploy the single-image form

§Secrets

§toa conceal

$ npx toa conceal <secret> <key=value...>

Creates or updates a secret in the cluster. The name is prefixed with toa-.

$ npx toa conceal mongodb.default username=store password=secret
$ npx toa conceal -i -e production
OptionDefaultMeaning
-n, --namespacecurrentKubernetes namespace
-i, --interactiveoffask for every secret the Context needs, instead of naming one
-e, --environmentthe environment, for --interactive
-p, --path.path to the Context, for --interactive

Keys given to an existing secret are added to it; other keys stay.

§toa reveal

$ npx toa reveal <secret>

Prints the keys and values of a secret created by toa conceal, one key: value per line. The name is given without the toa- prefix. Prints nothing when there is no such secret.

§toa key

$ npx toa key

Generates a key for identity tokens, to store as a secret.

OptionDefaultMeaning
--formatjwejwe for a 256-bit encryption key, paseto for a legacy PASETO key
--publicoffprint a secret/public key pair instead, one per line

Where the keys go is shown in Tokens.

§In the cluster

§toa shell

$ npx toa shell [image]

Starts a disposable pod in the current Kubernetes context and opens an interactive shell in it. The pod is removed when the shell exits.

$ npx toa shell                    # alpine
$ npx toa shell mongo              # an image with the client you need
$ npx toa shell -- ping 10.0.0.7   # run a command instead of a shell

Use it to check, from inside the cluster, that the application’s infrastructure is reachable; see A pod does not become ready.

§Variables the CLI reads

VariableEffect
TOA_ENVthe environment types and npm read the Context for, when none is given
TOA_SERVICESservices compose runs when --service is absent
TOA_DEBUG=1sets the default log level to debug
TOA_BOOT_TRACE=1compose, mono and serve trace their own startup
TOA_OUTBOX_DEFER, TOA_OUTBOX_INTERVAL, TOA_OUTBOX_BATCHdevelopment settings of event publication; see Settings
TOA_SUFFIXruns an isolated copy; see a second copy

§Exit codes

A command exits with 0 on success and 1 on any failure, printing the error to stderr. A running process that fails — an uncaught exception, an unhandled rejection, a boot that cannot complete — prints the error, writes a Process failed log record with the reason, and exits with 1.

§Every command

CommandPurpose
toa create <name>create an application in the working directory
toa env [environment]write the environment’s variables to .env
toa map [environment]write the component map to .map.json
toa npm [environment]install packages the declarations require
toa compose [paths...]run components as one composition
toa mono [paths...]run components and their services in one process
toa serve [paths...]run extension services
toa call <endpoint> [request]call an operation
toa typesgenerate TypeScript types
toa export manifestprint a normalized manifest
toa export secrets <environment>list the secrets a deployment needs
toa export tags <environment>print image references
toa export deployment <environment> <target>write the chart
toa export images <target>write the image build contexts
toa export convergence <environment>print a region’s broker definitions
toa buildbuild images locally
toa push [environment]build and push images
toa deploy [environment]deploy
toa conceal <secret> <key=value...>write a cluster secret
toa reveal <secret>read a cluster secret
toa keygenerate a token key
toa shell [image]open a shell in the cluster
Search
Search the documentation