systemg

Search docs

/
Install

How It Works

Projects

A project is a durable namespace that groups a set of services. Its identity is its id — the key under the projects: map in your manifest. Because a single resident supervisor can host many projects at once — and a single config file can declare many projects — projects are how systemg keeps unrelated (or related) workloads cleanly separated inside one running daemon.

Info

One supervisor, many projects. You can run a database stack, a web API, and a batch of cron units as three independent projects under the same systemg process. They share the runtime but keep separate state, logs, and status — and you target each one by id with -p/--project.

Declaring a project

Projects live under the projects: map, keyed by id. One file can declare many:

version: "2"
projects:
  arbitration:
    name: Arbitration
    services:
      worker:
        command: "python worker.py"
  gamecast:
    services:
      api:
        command: "python api.py"

Each key is the project id. Start the whole file and all its projects boot; the first project becomes the primary and the rest register behind it. See Configuration for the full schema.

Warning

Treat the project id as durable runtime identity. Changing it does not rename a project — it creates a new namespace, and the old one's running services become orphaned state (visible under sysg status --all). Rename freely with name; never rename by editing the id.

Note

Top-level services: with no project form a loose bundle — they still run, and their state persists under projects/__loose__/. The older singular project: block still parses (with a deprecation warning) for existing single-project manifests; convert them with sysg migrate. Prefer the projects: map once more than one project shares a supervisor.

-p/--project vs -c/--config

These two flags answer different questions, and knowing which to reach for is the single most useful thing about projects.

FlagWhat it does
-c / --configLoads and registers the config file on disk — every project it declares, plus any loose bundle. Use it the first time you start, or when you want to reload the manifest from a specific path.
-p / --projectTargets a single project already registered with the running supervisor, by its id. No file path required.

The mental model: -c is bring this file's projects into the supervisor from disk; -p is act on one project the supervisor already knows about.

Info

-c <file> operates on the file as a whole. sysg status -c stack.yaml shows every project the file declares, not just the first — the file identifies "everything here," and -p narrows to one.

# First start: register the project from its config
$ sysg start -c services/arbitration.yaml

# From now on, target it by id — no config path needed
$ sysg status -p arbitration
$ sysg logs -p arbitration -s worker
$ sysg restart -p arbitration
$ sysg stop -p arbitration

Info

Every registered project stores the config path it was started from. That's why -p alone is enough for later commands — systemg looks up the project's recorded manifest for you. This is what makes multi-project workflows ergonomic: you register once with -c, then drive everything by -p.

How -p relates to sysg restart

restart -p <id> is where the stored config path pays off:

$ sysg restart -p arbitration

When --config is omitted, restart --project reuses the config path the supervisor already recorded for that project and reloads it from disk. Manifest changes are applied on reload:

  • services added since the last load start
  • services removed from the manifest stop
  • changed commands take effect

You do not need to pass -c again once the project has a known config path. Pass -c explicitly only when you want to reload from a different file.

Warning

If the config you point at declares a different project.id than the one you target, systemg refuses the operation rather than silently switching namespaces. The flag, the config, and any service selector prefix must all agree on the project.

Qualified service selectors

Anywhere you name a service, you can qualify it with its project using project_id/service_name:

$ sysg restart -s arbitration/worker
$ sysg logs -s gamecast-dev/api

This is equivalent to passing -p plus the bare service name. If you supply both a selector prefix and -p, they must match.

Warning

A mismatch is an error, not a best-effort guess:

project flag 'arbitration' does not match service selector project 'gamecast-dev'

systemg would rather stop than act on the wrong project.

Info

When a service name is unambiguous — it exists in exactly one registered project — you can drop the project qualifier entirely and systemg resolves it for you. If the same service name lives in multiple projects, systemg refuses and asks you to disambiguate with -p.

-p per command

-p/--project is accepted across the commands that act on running projects:

CommandEffect of -p <id>
startStart (or start a single service within) the named project.
stopStop the named project's services. Use --supervisor to shut everything down.
restartReload the project's stored manifest and restart its services.
statusScope the status table to one project.
logsFilter tailed logs to one project.
inspectInspect a service within a specific project.
ConfigurationCron