All docsStellar ControlMission control · by Stellar Systems v1.1.0

Deployment

Docker

A minimal deployment of Stellar Control with Docker: NATS with JetStream, the configuration published, the core in one container, a simulated target and the web console.

The quickest way to run Stellar Control: a NATS server with JetStream, the services of the core in one container (stellar-control), and a simulated target, on one host. It suits a trial, a demonstration or a check of a new delivery; for an installation that lasts, see Docker Compose. Podman works the same way, with podman for docker.

The image#

Stellar Systems delivers the image stellar-control from the registry given with the delivery (here <registry>/stellar-control:<version>). To host a platform of your own, contact us (contact@stellar-systems.eu).

ContentWhere
The services of the core (stellar-reconciler, stellar-compute, stellar-executor, stellar-api, stellar-alarms, stellar-scheduler, stellar-transfers), the all-in-one stellar-control, stellar-editor, stellar-lsp, the CLI stellar, stellar-simulator/usr/local/bin
The web console/usr/share/stellar/web
An example configuration repository (targets sim-1 and psu-sim-1, with their simulations)/usr/share/stellar/examples/config
Every key of the global configuration with its default/usr/share/stellar/stellar.example.yaml
  • It runs stellar-control by default; another command chooses a service (stellar-api, stellar-reconciler…), the CLI or the simulator.
  • It runs as the user stellar (uid 10001), under tini, in /var/lib/stellar, and works with a read-only root file system and no capability (--read-only --tmpfs /tmp --cap-drop ALL).
  • The services read the global configuration from STELLAR_CONFIG, and any key from a STELLAR__<SECTION>__<KEY> variable (see Global Configuration). The simulator and the components of the SDKs read STELLAR_NATS_URL and the other variables of the SDK instead.
  • The API listens on 8080 (api.listen); every service serves /metrics and /healthz on 9100 (observability.metrics_addr).

NATS runs from its official image (nats:2.12).

A minimal deployment#

1. A network and NATS#

Shell
docker network create stellar
docker volume create stellar-jetstream
docker run -d --name nats --network stellar -v stellar-jetstream:/data \
    docker.io/library/nats:2.12.15-alpine -js -sd /data -m 8222

-js enables JetStream, -sd stores it in the volume, -m serves the monitoring endpoint (/healthz) on 8222. NATS is reached as nats://nats:4222 on the network stellar only; nothing is published on the host. This server has no authentication: keep it for a trial, and see NATS and JetStream for a server with accounts and TLS.

2. The global configuration#

Shell
cat > stellar.yaml <<'YAML'
nats:
  url: nats://nats:4222
api:
  listen: 0.0.0.0:8080
  web_dir: /usr/share/stellar/web
observability:
  log_format: text
YAML
chmod 644 stellar.yaml

3. Publish the configuration#

The services work on a compiled configuration. Compile and publish one, here the example of the image, with the CLI of the image:

Shell
docker run --rm --network stellar --read-only --tmpfs /tmp -e HOME=/tmp \
    <registry>/stellar-control:<version> \
    stellar compile /usr/share/stellar/examples/config --publish nats://nats:4222 \
    --output /tmp/snapshot.ir

For a configuration repository of your own, mount it:

Shell
docker run --rm --network stellar --read-only --tmpfs /tmp -e HOME=/tmp \
    -v "$PWD/config:/srv/stellar/config:ro" <registry>/stellar-control:<version> \
    stellar compile /srv/stellar/config --publish nats://nats:4222 --output /tmp/snapshot.ir

HOME=/tmp gives the CLI a writable cache for the external packages of a repository, in a read-only container. Or with the CLI installed on the host, once NATS is published there (-p 127.0.0.1:4222:4222 on the NATS container): stellar compile ./config --publish nats://127.0.0.1:4222.

Publish again after each change of the repository; the services pick the new revision up at the next safe point of each target. Until a configuration is published, the API answers 503 on what needs it and the web console shows no configuration. See Compilation, Snapshots and Locks.

4. The core in one container#

Shell
docker run -d --name control --network stellar -p 127.0.0.1:8080:8080 \
    -v "$PWD/stellar.yaml:/etc/stellar/stellar.yaml:ro" -e STELLAR_CONFIG=/etc/stellar/stellar.yaml \
    --read-only --tmpfs /tmp --cap-drop ALL \
    <registry>/stellar-control:<version>

On a host with SELinux enforced, add ,z to the options of the mounted files (stellar.yaml:ro,z).

5. A simulated target#

The target sim-1 of the example is played by its simulation platform-v3-sim, through the gateway sim-gw-1:

Shell
docker run -d --name sim-1 --network stellar --read-only --tmpfs /tmp --cap-drop ALL \
    -e STELLAR_NATS_URL=nats://nats:4222 \
    -e STELLAR_REPOSITORY=/usr/share/stellar/examples/config \
    -e RUST_LOG=info \
    <registry>/stellar-control:<version> \
    stellar-simulator --simulation platform-v3-sim --target sim-1 \
    --gateway sim-gw-1 --driver platform-v3-sim-1

The second target of the example, psu-sim-1, is played the same way with --simulation lab-psu-sim --target psu-sim-1 --gateway psu-sim-gw-1 --driver lab-psu-sim-1. See Simulated Targets.

6. The console#

The API and the web console answer on http://127.0.0.1:8080/:

Shell
curl -fsS http://127.0.0.1:8080/v1/topology        # the targets of the configuration
stellar alarms --api http://127.0.0.1:8080          # with the CLI on the host

Open http://127.0.0.1:8080/ in a browser: sim-1 shows its telemetry once the simulator has registered and the reconciler has bound it.

One container per service#

The same image runs each service of the core in a container of its own: give each its command, with the same configuration and a distinct instance name.

Shell
for service in reconciler compute executor api alarms scheduler transfers; do
    docker run -d --name "$service" --network stellar \
        -v "$PWD/stellar.yaml:/etc/stellar/stellar.yaml:ro" -e STELLAR_CONFIG=/etc/stellar/stellar.yaml \
        -e STELLAR_INSTANCE="$service-1" \
        --read-only --tmpfs /tmp --cap-drop ALL \
        $([ "$service" = api ] && echo -p 127.0.0.1:8080:8080) \
        <registry>/stellar-control:<version> "stellar-$service"
done

The services can start in any order once NATS is up, and a service started before NATS retries its connection. See Running the Services for what each one does and how they scale.

Logs and stop#

Shell
docker logs -f control                 # one JSON object per line, or text (log_format: text)
docker stop sim-1 control nats         # SIGTERM: each service stops cleanly
docker rm sim-1 control nats && docker network rm stellar

The volume stellar-jetstream keeps the streams, the published configuration and the state of the targets across restarts; docker volume rm stellar-jetstream starts from scratch.

Going further#

↑↓ to moveEnter to open