zinit
A lightweight process supervisor with dependency management, similar to systemd but simpler.
Features
- Dependency Graph: Services declare dependencies (
requires,after,wants,conflicts) - State Machine: 7 explicit states (Inactive, Blocked, Starting, Running, Stopping, Exited, Failed)
- Process Groups: Signals sent to process groups, handling
sh -cchild processes correctly - Health Checks: TCP, HTTP, and exec-based health checks with retries
- Ordered Shutdown: Dependents stop before their dependencies
- Hot Reload: Reload configuration without full restart
- Multi-Environment: Works in containers, VMs, and bare-metal
Deployment Modes
zinit adapts its behavior based on deployment environment:
Container Mode
Use zinit-pid1 as your container entrypoint:
ENTRYPOINT ["/usr/bin/zinit-pid1", "--container"]
Or set the environment variable:
ZINIT_CONTAINER=1
Behavior:
- Loads services from
/etc/zinit/services/ - Clean exit on shutdown (no reboot syscall)
- No system services directory
VM / Bare-Metal Mode
Use zinit-pid1 as your init system (PID 1):
# In /sbin/init or kernel cmdline: init=/usr/bin/zinit-pid1
Behavior:
- Loads system services from
/etc/zinit/system/first (auto-assignedclass=system) - Loads user services from
/etc/zinit/services/second - Handles reboot/poweroff via syscalls (SIGINT=reboot, SIGTERM=poweroff)
- Never exits (kernel panic prevention)
Standalone Mode
Run zinit-server directly (not as PID 1):
Optionally enable system services directory:
Quick Start
# Build all binaries
# Or build specific components
# Run the server
# Use the CLI
Architecture
zinit-pid1 (PID 1 shim)
| spawns/monitors
v
zinit-server (daemon)
| unix socket
v
zinit (CLI/TUI)
Crate Structure
zinit is a single crate with feature flags:
src/
lib.rs # Library entry point
bin/
zinit.rs # CLI binary
zinit-server.rs # Server binary
zinit-pid1.rs # PID 1 binary (Linux only)
sdk/ # Shared types, config, protocol, clients
server/ # Supervisor, dependency graph, process management
client/ # CLI interface
Features
| Feature | Description |
|---|---|
sdk |
Shared types, config, protocol (always included) |
client |
CLI interface |
server |
Supervisor daemon |
pid1 |
PID 1 init shim (Linux only) |
tui |
Terminal UI for client |
repl |
Interactive REPL for client |
async |
Async client support |
full |
Build everything |
Default features: client, server
Configuration
Service configs are TOML files in the config directory (default: /etc/zinit/services/):
[]
= "my-app"
= "/usr/bin/my-app --daemon"
= "/var/lib/my-app" # optional working directory
= false # exit after success (default: false)
= "start" # start | stop | ignore (default: start)
= "user" # user | system (default: user)
[]
= ["database"] # must be running
= ["logger"] # start order only
= ["metrics"] # soft dependency
= ["legacy-app"] # mutual exclusion
[]
= "on-failure" # always | on-failure | never
= "SIGTERM"
= 30000
= 10000
= 1000
= 60000
= 0 # 0 = unlimited
[]
= "http"
= "http://localhost:8080/health"
= 10000
= 3
[]
= 1000
Targets
Virtual services for grouping:
[]
= "multi-user"
[]
= ["network", "logger", "database"]
Service Status
The status field controls supervisor behavior:
start(default): Automatically start and keep runningstop: Keep stopped (won't auto-start)ignore: Supervisor ignores this service
Service Class
The class field protects critical services from bulk operations:
user(default): Normal service, affected by*_allcommandssystem: Protected service, skipped by bulk operations
System-class services are immune to start_all, stop_all, and delete_all commands.
CLI Commands
# Debug commands
Path Configuration
zinit uses platform-specific default paths:
Linux (System/PID1 mode)
- Config directory:
/etc/zinit/services - System services:
/etc/zinit/system(PID1 mode only) - Socket:
/run/zinit.sock
macOS / Windows (Standalone mode)
- Config directory:
$HOME/hero/cfg/zinit - Socket:
$HOME/hero/var/zinit.sock
You can override these with environment variables (see below).
See PATHS.md for detailed path configuration documentation.
Environment Variables
| Variable | Default | Description |
|---|---|---|
ZINIT_LOG_LEVEL |
info |
Log level: trace, debug, info, warn, error |
ZINIT_CONFIG_DIR |
Platform-specific (see above) | Service config directory |
ZINIT_SOCKET |
Platform-specific (see above) | Unix socket path |
ZINIT_CONTAINER |
unset | If set, zinit-pid1 runs in container mode |
Example: Custom Paths
# Use custom config and socket directories
# Start server
# Connect with CLI
Library Usage
zinit can be used as a library:
use ;
// Blocking client
let mut client = connect_unix?;
let services = client.list?;
// Async client (requires "async" feature)
use AsyncZinitClient;
let mut client = connect_unix.await?;
let status = client.status.await?;
Docker Usage
# Build test image
# Run (uses container mode automatically)
# With debug logging
# Explicit container mode
Shutdown Ordering
Services are stopped in reverse dependency order:
Example: database <- app <- worker
Startup order: database -> app -> worker
Shutdown order: worker -> app -> database
When stopping a single service, dependents are stopped first:
zinit stop databasestops worker, then app, then database- Dependencies are NOT auto-stopped (other services may need them)
Development
# Run integration tests
License
See LICENSE file.