start
Overview
The start command launches the systemg process manager and begins managing services defined in your configuration file. It supports both foreground and daemonized modes, automatically handles service dependencies, and monitors services for crashes.
Usage
Basic Usage
Start the process manager with the default configuration file (systemg.yaml or sysg.yaml):
$ sysg start
Start the process manager with a specific configuration file:
$ sysg start --config systemg.yaml
Daemon Mode
Start the long-lived supervisor that persists after you log out:
$ sysg start --config systemg.yaml --daemonize
When daemonized, systemg runs in the background and subsequent commands (status, restart, logs, stop) communicate with the same background process via a Unix domain socket rather than re-spawning services.
Logging Verbosity
Adjust logging verbosity for the current invocation. Named levels are case-insensitive and numbers map to TRACE=5 down to OFF=0:
$ sysg start --log-level debug
$ sysg start --log-level 4
The same --log-level flag works with every sysg subcommand if you need different verbosity elsewhere.
How It Works
Configuration Loading
-
File Resolution: Systemg first attempts to resolve the configuration file path:
- If an absolute path is provided, it's used as-is
- If a relative path is provided, it's resolved relative to the current working directory
- If no path is specified, systemg looks for
systemg.yamlorsysg.yamlin the current directory
-
Configuration Parsing: The YAML file is parsed and validated:
- Environment variables in the config are expanded using
${VAR_NAME}syntax - Service dependencies are validated to ensure no circular dependencies exist
- Environment files specified in
env.fileare loaded and applied
- Environment variables in the config are expanded using
Service Startup Process
Dependency Resolution
When configuration files declare depends_on entries, sysg start bootstraps services in dependency order using a topological sort:
- Dependency Graph Construction: Systemg builds a dependency graph from the
depends_onfields - Topological Ordering: Services are ordered so that every dependency starts before its dependents
- Validation: The graph is checked for:
- Circular dependencies (which cause an error)
- Unknown dependencies (services that don't exist in the config)
Service Launch Sequence
For each service in dependency order:
-
Dependency Check: Before starting a service, systemg verifies all its dependencies are running:
- If a dependency failed to start, the service is skipped
- If a dependency is not yet running, the service waits (this shouldn't happen due to topological ordering)
- Failed services are tracked to prevent dependent services from starting
-
Process Launch: The service command is executed:
- Commands are executed via
sh -cto support shell features - Each service runs in its own process group (on Linux, uses
setpgid(0, 0)) - On Linux, services are configured to receive
SIGTERMwhen systemg exits usingprctl(PR_SET_PDEATHSIG) - On macOS, services share the same process group for coordinated termination
- Commands are executed via
-
Environment Setup:
- Environment variables from
env.varsare set - Environment files from
env.fileare loaded - The working directory is set to the project root (config file's parent directory)
- Environment variables from
-
Log Capture:
- Standard output and standard error are captured via pipes
- Separate threads write logs to files in
~/.local/share/systemg/logs/followed by the service name and_stdout.logor_stderr.log - Logs are written asynchronously to avoid blocking the service
-
Lifecycle Hooks: If configured,
on_start.successhooks fire once the service survives the initial readiness probe (or exits successfully immediately), whileon_start.errorhooks run if the spawn fails or the process dies before reaching that state. Learn more in the Webhooks guide. -
Readiness Verification: Systemg polls the service to confirm it's running:
- Polls every 50ms for up to 5 seconds
- Confirms the process is still alive across consecutive polls
- For one-shot services (that exit immediately), success is determined by exit code
-
PID Tracking: The service's PID is recorded in
~/.local/share/systemg/pid.jsonfor later commands
Foreground vs Daemon Mode
Foreground Mode (default)
When started without --daemonize:
- Systemg runs in the foreground and blocks until services exit
- A signal handler is registered for
SIGINT/SIGTERMto gracefully shut down services - Services are terminated by sending
SIGTERMto their process groups, thenSIGKILLif needed - The process exits after all services are stopped
Daemon Mode (--daemonize)
When started with --daemonize:
-
Duplicate Check: Systemg first checks if a supervisor is already running:
- Reads the supervisor PID from
~/.local/share/systemg/supervisor.pid - Sends a null signal to verify the process exists
- If running, aborts with a warning
- Reads the supervisor PID from
-
Daemonization Process:
- Forks twice to detach from the terminal (double-fork pattern)
- Creates a new session with
setsid() - Changes working directory to
/ - Redirects stdin, stdout, and stderr to
/dev/null
-
Supervisor Initialization:
- Creates a Unix domain socket at
~/.local/share/systemg/supervisor.sock - Writes the supervisor PID to the PID file
- Starts only non-cron services (cron services are managed separately)
- Spawns a background thread to check for due cron jobs every second
- Creates a Unix domain socket at
-
Event Loop: The supervisor enters an event loop:
- Listens for commands on the Unix socket
- Handles
Stop,Restart, andShutdowncommands from CLI invocations - Manages service lifecycle and responds to crashes
Service Monitoring
After services are started, systemg spawns a monitoring thread that:
- Periodic Checks: Polls all running services every 2 seconds
- Crash Detection: Detects when services exit unexpectedly
- Restart Handling: For services with
restart_policy: "always"orrestart_policy: "on-failure":- Waits for the configured
backoffduration (default: 5 seconds) - Runs any
on_stop.errorwebhooks to report the crash - Restarts the service if the policy allows and fires
on_restart.successwebhooks on success (oron_restart.errorif the restart attempt fails)
- Waits for the configured
- Dependency Cascading: When a service crashes, all services that depend on it are automatically stopped to prevent workloads from running against unhealthy backends
Cron Services
Services with cron configuration are handled specially:
- They are not started during the initial service launch
- A background thread checks for due cron jobs every second
- When a cron job is due, it's executed in a separate thread
- The job is monitored until completion (up to 1 hour)
- Completion status is tracked for overlap detection
Error Handling
Dependency Failures
If a prerequisite service fails to start:
- All dependent services are skipped
- The command exits with a dependency error
- The system is not left in a half-running state
Service Start Failures
If a service fails to start:
- The error is logged
on_start.errorwebhooks are executed if configured- Dependent services are skipped
- The first error encountered is returned
Configuration Errors
Invalid configuration files result in:
- Clear error messages indicating the problem
- No services are started
- The process exits with an error code
Command Options
$ sysg start --help
Start the process manager with the given configuration
Usage: sysg start [OPTIONS]
Options:
-c, --config <CONFIG> Path to the configuration file (defaults to `systemg.yaml`) [default: systemg.yaml]
--log-level <LEVEL> Override the logging verbosity for this invocation only
--daemonize Whether to daemonize systemg
-h, --help Print help