This page builds Stellar Control from source and starts everything needed to operate simulated targets on one machine: a NATS server with JetStream, the services of the core, two simulated targets and the web console. Your First Procedure then walks through using them.
Prerequisites#
| Tool | Why |
|---|---|
rustup | The Rust toolchain is pinned by rust-toolchain.toml and installed on the first build |
| Docker or Podman | To run the NATS server (or a nats-server 2.12 binary) |
nats-server binary | Only for dry runs (stellar run --dry), which start an ephemeral server |
| Node.js and npm | Only to build the web console |
uv | Only for the Python SDK and the Python examples |
Build#
From the root of the repository:
cargo build --releaseThe binaries land in target/release/:
| Binary | Role |
|---|---|
stellar | The command line: configuration repositories, telecommands, runs, alarms, passes, files, identity |
stellar-mcs | Every service of the core in one process, for small cells, development and demonstrations |
stellar-api | HTTP/WebSocket API, and the web console when configured |
stellar-reconciler | Desired vs observed state, bindings, credentials |
stellar-executor | Direct telecommands and runs of procedures |
stellar-compute | Calibration, derived measures, current value table |
stellar-alarms | Alarm service |
stellar-scheduler | Passes and scheduled runs |
stellar-transfers | File transfer manager and stream quality |
stellar-editor | Web editor of the configuration repository |
stellar-lsp | Language server, for editors |
stellar-simulator | A simulated target (driver and gateway) |
The example drivers, transports and gateways (platform-v3-ccsds, ccsds-tc, obc-csp,
csp1-kiss, bench-can…) are built too; see Extending Stellar Control.
To install the CLI and the language server in ~/.cargo/bin:
cargo install --path tooling/cli
cargo install --path tooling/lspA NATS server#
Stellar Control needs NATS 2.12 with JetStream enabled. Two options.
Plain server, no authentication#
The simplest, for a first trial:
docker run -d --name nats -p 4222:4222 docker.io/library/nats:2.12.15-alpine -jsEvery component connects to nats://localhost:4222 by default.
Development server with decentralized authentication#
The repository ships a development setup close to production: an operator, an account
stellar, users with restricted permissions and TLS material, all generated locally by nsc.
dev/nats/setup.sh # once: identities in dev/nats/secrets/ (git-ignored)
docker compose up -d nats # or: podman compose up -d nats
dev/nats/smoke-test.sh # checks JetStream and permissions (needs the nats CLI)setup.sh writes:
| File | Content |
|---|---|
secrets/creds/dev.creds | User dev of account stellar: full access, for developers and tests |
secrets/creds/bootstrap.creds | User bootstrap: may only publish registrations and heartbeats (stellar.ctl.register, stellar.ctl.hb.>) and answer control requests |
secrets/stellar-account-signing.nk | Seed of the signing key of the account stellar, with which the reconciler signs the JWTs of the components it binds |
secrets/resolver.conf | Operator, system account and memory resolver with the account JWTs, included by dev/nats/nats-server.conf |
secrets/tls/ | A development CA, server and client certificates |
Point a component at the server with its credentials:
export STELLAR__NATS__CREDENTIALS=dev/nats/secrets/creds/dev.credsTo require TLS, start the server with the TLS configuration:
NATS_CONF=nats-server-tls.conf docker compose up -d natsAfter setup.sh --force, restart the server so that it loads the new operator. The compose file
also defines a timescaledb service, the database of the reference output connector
(see Output Connectors).
The security model behind these files is described in NATS Accounts and Credentials.
The services of the core#
Every service reads the same global configuration file (--config or STELLAR_CONFIG); without
one, the defaults of Global Configuration apply, which
target nats://localhost:4222 and serve the API on 0.0.0.0:8080.
All in one process#
stellar-mcs runs the reconciler, the compute stage, the executor, the API, the alarm service,
the scheduler and the transfer manager in one process, plus the editor when
editor.repository is set:
stellar-mcs --config stellar.yaml| Option | Environment | Meaning |
|---|---|---|
--config <file> | STELLAR_CONFIG | Global configuration (YAML) |
--instance <suffix> | STELLAR_INSTANCE | Suffix of the instance names (api-<suffix>…); random by default |
--without <services> | STELLAR_WITHOUT | Services not to run, comma-separated: reconciler, compute, executor, api, alarms, scheduler, transfers, editor |
It uses about a quarter of the memory of the separate services, and each service behaves as if it ran alone. For production layouts, see Running the Services.
One process per service#
Each service has its own binary with the same command line (--config, --instance). On one
host, give each its own metrics port:
STELLAR__OBSERVABILITY__METRICS_ADDR=127.0.0.1:9101 stellar-reconciler &
STELLAR__OBSERVABILITY__METRICS_ADDR=127.0.0.1:9102 stellar-compute &
STELLAR__OBSERVABILITY__METRICS_ADDR=127.0.0.1:9103 stellar-executor &
STELLAR__OBSERVABILITY__METRICS_ADDR=127.0.0.1:9104 stellar-api &Publish a configuration#
The services work on the compiled snapshot of a configuration repository. Compile the example repository and make it the current configuration:
stellar compile examples/config --publish nats://localhost:4222The command prints the hash of the snapshot and also writes it to <hash>.ir in the current
directory (--output chooses the file). With an authenticated server, add
--nats-credentials dev/nats/secrets/creds/dev.creds. See
Compilation, Snapshots and Locks.
Simulated targets#
The example topology declares two simulated targets, sim-1 (a platform-v3 satellite) and
psu-sim-1 (a laboratory power supply). Each is played by a stellar-simulator process that
registers as their driver and gateway:
stellar-simulator --repository examples/config --simulation platform-v3-sim \
--target sim-1 --gateway sim-gw-1 &
stellar-simulator --repository examples/config --simulation lab-psu-sim \
--target psu-sim-1 --gateway psu-sim-gw-1 &| Option | Meaning |
|---|---|
--repository <dir> | Configuration repository holding simulations/<name>.yaml (STELLAR_REPOSITORY, default .) |
--simulation <name> | Simulation to play |
--target <name> | Target served, as in the topology |
--gateway <name> | Instance name of the gateway, as in the topology |
--driver <name> | Instance name of the driver (default <simulation>-1) |
--transport <name> | Instance name of the sim-cop1 transport, when the simulation sequences its telecommands with COP-1 |
Within seconds the reconciler binds them and the targets become ready. Check with:
curl -s http://localhost:8080/v1/topologyThe web console#
The web console is a Svelte application in core/frontend, served by the API when
api.web_dir points at its build:
cd core/frontend
npm ci
npm run build # writes core/frontend/dist# stellar.yaml
api:
listen: 0.0.0.0:8080
web_dir: core/frontend/distStart stellar-mcs --config stellar.yaml (or stellar-api) and open http://localhost:8080/.
Every path under /v1/ stays the API; any other path serves the application. See
Web Console.
A complete local demonstration#
The whole flow, on a plain NATS server:
docker run -d --name nats -p 4222:4222 docker.io/library/nats:2.12.15-alpine -js
cargo build --release
export PATH="$PWD/target/release:$PATH"
stellar compile examples/config --publish nats://localhost:4222
cat > stellar.yaml <<'YAML'
api:
web_dir: core/frontend/dist
passes:
feeders: {fds-feeder: fds, station-feeder: provider}
observability:
log_format: text
YAML
stellar-mcs --config stellar.yaml &
stellar-simulator --repository examples/config --simulation platform-v3-sim \
--target sim-1 --gateway sim-gw-1 &
stellar-simulator --repository examples/config --simulation lab-psu-sim \
--target psu-sim-1 --gateway psu-sim-gw-1 &
stellar send sim-1 'tcu[TCU1].ping'Stop the processes with Ctrl-C (SIGINT) or SIGTERM: every component shuts down cleanly.
Next steps#
- Your First Procedure: the tutorial on these simulated targets.
- Global Configuration: every configuration key.
- Nomad: the whole stack on a Nomad agent.