mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-29 21:17:05 +02:00
Raise eligible Linux child processes own oom_score_adj from a child-side /bin/sh exec shim so cgroup memory pressure prefers transient workers over the long-lived gateway. Cover supervisor children, PTY shells, MCP stdio servers, and OpenClaw-launched browser processes through the shared process runtime seam. Harden the wrapper for distroless images, shell startup env, per-child and process-level opt-outs, dash-compatible exec, and leading-dash command names. Document Linux verification and OOM behavior. Fixes #70404. Co-authored-by: Neerav Makwana <261249544+neeravmakwana@users.noreply.github.com>
138 lines
3.8 KiB
Markdown
138 lines
3.8 KiB
Markdown
---
|
|
summary: "Linux support + companion app status"
|
|
read_when:
|
|
- Looking for Linux companion app status
|
|
- Planning platform coverage or contributions
|
|
- Debugging Linux OOM kills or exit 137 on a VPS or container
|
|
title: "Linux App"
|
|
---
|
|
|
|
# Linux App
|
|
|
|
The Gateway is fully supported on Linux. **Node is the recommended runtime**.
|
|
Bun is not recommended for the Gateway (WhatsApp/Telegram bugs).
|
|
|
|
Native Linux companion apps are planned. Contributions are welcome if you want to help build one.
|
|
|
|
## Beginner quick path (VPS)
|
|
|
|
1. Install Node 24 (recommended; Node 22 LTS, currently `22.14+`, still works for compatibility)
|
|
2. `npm i -g openclaw@latest`
|
|
3. `openclaw onboard --install-daemon`
|
|
4. From your laptop: `ssh -N -L 18789:127.0.0.1:18789 <user>@<host>`
|
|
5. Open `http://127.0.0.1:18789/` and authenticate with the configured shared secret (token by default; password if you set `gateway.auth.mode: "password"`)
|
|
|
|
Full Linux server guide: [Linux Server](/vps). Step-by-step VPS example: [exe.dev](/install/exe-dev)
|
|
|
|
## Install
|
|
|
|
- [Getting Started](/start/getting-started)
|
|
- [Install & updates](/install/updating)
|
|
- Optional flows: [Bun (experimental)](/install/bun), [Nix](/install/nix), [Docker](/install/docker)
|
|
|
|
## Gateway
|
|
|
|
- [Gateway runbook](/gateway)
|
|
- [Configuration](/gateway/configuration)
|
|
|
|
## Gateway service install (CLI)
|
|
|
|
Use one of these:
|
|
|
|
```
|
|
openclaw onboard --install-daemon
|
|
```
|
|
|
|
Or:
|
|
|
|
```
|
|
openclaw gateway install
|
|
```
|
|
|
|
Or:
|
|
|
|
```
|
|
openclaw configure
|
|
```
|
|
|
|
Select **Gateway service** when prompted.
|
|
|
|
Repair/migrate:
|
|
|
|
```
|
|
openclaw doctor
|
|
```
|
|
|
|
## System control (systemd user unit)
|
|
|
|
OpenClaw installs a systemd **user** service by default. Use a **system**
|
|
service for shared or always-on servers. `openclaw gateway install` and
|
|
`openclaw onboard --install-daemon` already render the current canonical unit
|
|
for you; write one by hand only when you need a custom system/service-manager
|
|
setup. The full service guidance lives in the [Gateway runbook](/gateway).
|
|
|
|
Minimal setup:
|
|
|
|
Create `~/.config/systemd/user/openclaw-gateway[-<profile>].service`:
|
|
|
|
```
|
|
[Unit]
|
|
Description=OpenClaw Gateway (profile: <profile>, v<version>)
|
|
After=network-online.target
|
|
Wants=network-online.target
|
|
|
|
[Service]
|
|
ExecStart=/usr/local/bin/openclaw gateway --port 18789
|
|
Restart=always
|
|
RestartSec=5
|
|
TimeoutStopSec=30
|
|
TimeoutStartSec=30
|
|
SuccessExitStatus=0 143
|
|
KillMode=control-group
|
|
|
|
[Install]
|
|
WantedBy=default.target
|
|
```
|
|
|
|
Enable it:
|
|
|
|
```
|
|
systemctl --user enable --now openclaw-gateway[-<profile>].service
|
|
```
|
|
|
|
## Memory pressure and OOM kills
|
|
|
|
On Linux, the kernel chooses an OOM victim when a host, VM, or container cgroup
|
|
runs out of memory. The Gateway can be a poor victim because it owns long-lived
|
|
sessions and channel connections. OpenClaw therefore biases transient child
|
|
processes to be killed before the Gateway when possible.
|
|
|
|
For eligible Linux child spawns, OpenClaw starts the child through a short
|
|
`/bin/sh` wrapper that raises the child's own `oom_score_adj` to `1000`, then
|
|
`exec`s the real command. This is an unprivileged operation because the child is
|
|
only increasing its own OOM kill likelihood.
|
|
|
|
Covered child process surfaces include:
|
|
|
|
- supervisor-managed command children,
|
|
- PTY shell children,
|
|
- MCP stdio server children,
|
|
- OpenClaw-launched browser/Chrome processes.
|
|
|
|
The wrapper is Linux-only and is skipped when `/bin/sh` is unavailable. It is
|
|
also skipped if the child env sets `OPENCLAW_CHILD_OOM_SCORE_ADJ=0`, `false`,
|
|
`no`, or `off`.
|
|
|
|
To verify a child process:
|
|
|
|
```bash
|
|
cat /proc/<child-pid>/oom_score_adj
|
|
```
|
|
|
|
Expected value for covered children is `1000`. The Gateway process should keep
|
|
its normal score, usually `0`.
|
|
|
|
This does not replace normal memory tuning. If a VPS or container repeatedly
|
|
kills children, increase the memory limit, reduce concurrency, or add stronger
|
|
resource controls such as systemd `MemoryMax=` or container-level memory limits.
|