Principle:Openclaw Openclaw Daemon Installation
| Knowledge Sources | |
|---|---|
| Domains | Daemon, Service_Management, Configuration |
| Last Updated | 2026-02-06 12:00 GMT |
Overview
Daemon installation is the process of detecting the operating system init system, generating the appropriate service descriptor, and registering a long-running gateway process as a system-managed background service.
Description
An AI gateway must run continuously to receive and respond to messages across all connected channels. While users can start the gateway manually in a terminal session, this is fragile: the process dies when the terminal closes, and there is no automatic restart on crash. The daemon installation concept solves this by registering the gateway with the OS-level service manager so it starts automatically, restarts on failure, and can be controlled with standard system commands.
The challenge is that each major operating system uses a completely different service management system. macOS uses launchd with XML plist files registered via launchctl. Linux uses systemd with INI-style unit files managed by systemctl. Windows uses the Task Scheduler with tasks registered via schtasks. Despite these differences, the operations a user needs are identical: install, uninstall, start, stop, restart, check status, and read the service command.
The daemon installation principle addresses this through a strategy pattern: a factory function inspects process.platform and returns a GatewayService object that implements a uniform interface. Each platform-specific implementation translates the generic operations into the native system calls. This abstraction means the rest of the codebase (onboarding wizard, CLI commands, status checks) never needs to know which init system is in use.
Usage
Apply this pattern when:
- A server-side process needs to survive terminal disconnection and persist across reboots.
- The application must run on macOS, Linux, and Windows with consistent behavior.
- Users need simple install/uninstall/restart commands without learning platform-specific service management.
- The service descriptor needs to include environment variables, working directories, and specific binary arguments.
Theoretical Basis
The daemon installation uses a platform-discriminated strategy pattern:
resolveGatewayService()
|
|-- process.platform === "darwin"
| \-> LaunchAgent strategy
| install: write plist to ~/Library/LaunchAgents/, launchctl load
| uninstall: launchctl unload, delete plist
| stop: launchctl stop <label>
| restart: launchctl stop + start
| isLoaded: launchctl list | grep <label>
| readCommand: parse plist ProgramArguments
|
|-- process.platform === "linux"
| \-> systemd strategy
| install: write unit file to ~/.config/systemd/user/, systemctl enable
| uninstall: systemctl disable, delete unit file
| stop: systemctl --user stop <service>
| restart: systemctl --user restart <service>
| isLoaded: systemctl --user is-enabled <service>
| readCommand: parse ExecStart from unit file
|
|-- process.platform === "win32"
| \-> Scheduled Task strategy
| install: schtasks /Create with trigger AtLogon
| uninstall: schtasks /Delete
| stop: schtasks /End
| restart: schtasks /End + /Run
| isLoaded: schtasks /Query for task name
| readCommand: parse task XML
|
\-- other -> throw Error("not supported")
Uniform GatewayService interface:
| Method | Description |
|---|---|
| install(args) | Generates and registers the service descriptor with the specified program arguments, environment, and working directory. |
| uninstall(args) | Stops and deregisters the service, removing descriptor files. |
| stop(args) | Stops the running service without deregistering. |
| restart(args) | Stops and immediately restarts the service. |
| isLoaded(args) | Returns true if the service is currently registered and active. |
| readCommand(env) | Reads back the program arguments from the installed descriptor. |
| readRuntime(env) | Returns runtime status (PID, exit status, state). |
Key design decisions:
- User-level services only: All three platform implementations install user-level (not system-level) services. This avoids requiring root/admin privileges and scopes the gateway to the current user.
- No process manager dependency: The implementation uses native OS facilities (launchd, systemd, schtasks) rather than third-party process managers like PM2 or forever, keeping the install footprint minimal.
- Descriptive labels: Each platform adapter provides human-readable label, loadedText, and notLoadedText strings so that status output can describe the service state naturally (e.g., "LaunchAgent: loaded" vs "systemd: enabled").