TutorialGatewayFebruary 27, 2026·9 min read

OpenClaw Gateway: Run as Background Service, Daemon & Headless Mode

A common question from new OpenClaw users: can I run the gateway in headless mode so it stays alive when I close the terminal? Yes, and there are six ways to do it. This guide covers nohup, tmux, pm2, launchd on macOS, systemd on Linux, and Docker — with copy-paste commands for each, plus auto-restart configuration, health monitoring, and log access.

What Is the OpenClaw Gateway and Why It Must Stay Running

The OpenClaw gateway is the central process that routes messages between your agents and the outside world. It listens on port 18789 by default and handles all inbound requests from Telegram, Slack, scheduled heartbeat tasks, and the CLI. Every agent you run depends on the gateway being online. If the gateway stops, your agents stop.

When you run openclaw gateway start directly in a terminal, the process is tied to that terminal session. Close the terminal, disconnect from SSH, or let your Mac go to sleep, and the gateway dies with it. This is fine for local testing. It is not acceptable for any agent you actually want to rely on.

The solution is to detach the gateway process from the terminal entirely, or hand it off to a process manager that keeps it alive independently. There are multiple ways to do this, ranging from a one-line quick fix to production-grade system service configuration.

The Problem: Closing the Terminal Kills the Gateway

When a terminal session ends, the operating system sends a SIGHUP (hangup) signal to the foreground process. The default behavior for most programs, including the OpenClaw gateway, is to exit immediately on SIGHUP. This is why agents that work perfectly in testing suddenly go silent overnight or whenever you close your laptop.

Symptom: Telegram bot stops responding after a few hours

You or your Mac closed the terminal or went to sleep. The gateway exited and took your bot with it.

Symptom: SSH session times out, agents go offline

A dropped SSH connection sends SIGHUP to all processes started in that session that are not explicitly detached.

Symptom: Gateway does not start after system reboot

Without a startup service configured, you have to manually run openclaw gateway start every time the machine restarts.

Every method below solves at least the first two problems. The pm2, launchd, systemd, and Docker methods also solve the third by configuring automatic startup on boot.

Method 1: nohup and & (Quick and Dirty)

The fastest way to detach the gateway from your terminal is nohup. It tells the operating system to ignore the SIGHUP signal so the process keeps running after you close the terminal. The trailing & sends it to the background immediately.

# Start gateway in background, immune to terminal close
nohup openclaw gateway start &

# Output goes to nohup.out in current directory
# Check it with:
tail -f nohup.out

# Find the process ID (PID) to stop it later
ps aux | grep "openclaw gateway"

# Stop the gateway
kill $(ps aux | grep "openclaw gateway" | grep -v grep | awk '{print $2}')

When to use it: Quick testing on a machine you control. You do not want to install anything extra. You are fine manually restarting it after reboots.

Limitations: No auto-restart if the gateway crashes. No auto-start on reboot. Log management is manual. Not suitable for production.

Method 2: screen or tmux Sessions

Terminal multiplexers like tmux and screen create persistent terminal sessions that survive SSH disconnection and terminal close. You start the gateway inside one of these sessions, detach, and the session (and your gateway) keeps running on the server.

Using tmux

# Install tmux if not already installed
# macOS:
brew install tmux
# Ubuntu/Debian:
sudo apt install tmux -y

# Create a new tmux session named "openclaw"
tmux new -s openclaw

# Inside the tmux session, start the gateway
openclaw gateway start

# Detach from the session without stopping it
# Press Ctrl+B, then D

# Later, reattach to check on it
tmux attach -t openclaw

# List all running sessions
tmux ls

# Kill the session (stops the gateway)
tmux kill-session -t openclaw

Using screen

# Install screen if not already installed
# Ubuntu/Debian:
sudo apt install screen -y

# Create a named screen session
screen -S openclaw

# Inside the screen session, start the gateway
openclaw gateway start

# Detach from the session
# Press Ctrl+A, then D

# Reattach to the session
screen -r openclaw

# List running sessions
screen -ls

When to use it: Remote SSH sessions where you want a persistent terminal you can reattach to. Useful for debugging since you see live output.

Limitations: Still no auto-restart on crash or auto-start on reboot without additional configuration. If the machine reboots, the tmux session is gone.

Method 3: pm2 Process Manager (Recommended for Most Users)

pm2 is a production process manager for Node.js applications. It runs the gateway as a background daemon, automatically restarts it on crash, survives terminal close and SSH disconnection, and can be configured to start automatically on system boot. It works the same way on macOS and Linux, which makes it the most portable option.

# Install pm2 globally
npm install -g pm2

# Start the OpenClaw gateway with pm2
pm2 start "openclaw gateway start" --name openclaw

# Check status
pm2 status

# View live logs
pm2 logs openclaw

# View last 100 log lines
pm2 logs openclaw --lines 100

# Restart the gateway
pm2 restart openclaw

# Stop the gateway
pm2 stop openclaw

# Remove from pm2
pm2 delete openclaw

Auto-Start on Boot with pm2

After confirming the gateway runs correctly with pm2, save the process list and generate a startup script so it survives reboots.

# Save current pm2 process list
pm2 save

# Generate the startup command for your OS
pm2 startup

# pm2 will print a command — copy and run it
# Example output:
# sudo env PATH=$PATH:/usr/bin pm2 startup systemd -u youruser --hp /home/youruser

# Run the printed command, then verify with:
pm2 status

pm2 supports exponential backoff restart delays, max restart limits, and memory threshold restarts. These are configurable via a pm2 ecosystem file if you need fine-grained control.

Method 4: launchd on macOS (Native Daemon)

launchd is macOS's native service manager. A launchd plist file gives you automatic startup on login, auto-restart on crash, and proper system integration without installing any third-party tools. This is the cleanest option for Mac users who want to keep their stack minimal.

Create the launchd Plist

First, find the full path to the openclaw binary:

which openclaw
# Example output: /usr/local/bin/openclaw

Create the plist file at ~/Library/LaunchAgents/com.openclaw.gateway.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.openclaw.gateway</string>

  <key>ProgramArguments</key>
  <array>
    <string>/usr/local/bin/openclaw</string>
    <string>gateway</string>
    <string>start</string>
  </array>

  <key>RunAtLoad</key>
  <true/>

  <key>KeepAlive</key>
  <true/>

  <key>StandardOutPath</key>
  <string>/tmp/openclaw-gateway.log</string>

  <key>StandardErrorPath</key>
  <string>/tmp/openclaw-gateway-error.log</string>
</dict>
</plist>

Load and Manage the launchd Service

# Load the service (starts it immediately and on every login)
launchctl load ~/Library/LaunchAgents/com.openclaw.gateway.plist

# Check if it is running
launchctl list | grep openclaw

# View logs
tail -f /tmp/openclaw-gateway.log
tail -f /tmp/openclaw-gateway-error.log

# Stop the service
launchctl unload ~/Library/LaunchAgents/com.openclaw.gateway.plist

# Reload after editing the plist
launchctl unload ~/Library/LaunchAgents/com.openclaw.gateway.plist
launchctl load ~/Library/LaunchAgents/com.openclaw.gateway.plist

The KeepAlive key tells launchd to restart the gateway automatically if it crashes or exits for any reason. The RunAtLoad key starts it immediately when loaded and on every user login.

Method 5: systemd on Linux (Native Service)

On any modern Linux system (Ubuntu, Debian, Fedora, Arch), systemd is the standard way to manage background services. A systemd unit file gives you automatic startup on boot, auto-restart on crash, log integration with journald, and clean start/stop/status commands. This is the recommended method for any Linux VPS.

Find Your openclaw Path and User

# Find openclaw binary path
which openclaw
# Example: /usr/local/bin/openclaw or /home/youruser/.nvm/versions/node/v20.0.0/bin/openclaw

# Find your username
whoami
# Example: ubuntu

Create the systemd Unit File

Create the file /etc/systemd/system/openclaw.service:

sudo nano /etc/systemd/system/openclaw.service

Paste the following content, replacing youruser with your actual username and adjusting the ExecStart path if needed:

[Unit]
Description=OpenClaw Gateway
After=network.target

[Service]
Type=simple
User=youruser
WorkingDirectory=/home/youruser
ExecStart=/usr/local/bin/openclaw gateway start
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Enable and Start the Service

# Reload systemd to pick up the new unit file
sudo systemctl daemon-reload

# Enable the service to start on boot
sudo systemctl enable openclaw

# Start the service now
sudo systemctl start openclaw

# Check status
sudo systemctl status openclaw

# View live logs
sudo journalctl -u openclaw -f

# View logs since today
sudo journalctl -u openclaw --since today

# Restart the gateway
sudo systemctl restart openclaw

# Stop the gateway
sudo systemctl stop openclaw

The Restart=on-failure directive tells systemd to restart the gateway if it exits with a non-zero status code. The RestartSec=5 adds a 5-second delay between restart attempts to avoid tight crash loops.

Method 6: Docker Container (Production)

Docker is the most isolated and portable way to run the OpenClaw gateway. The container encapsulates the Node.js runtime, OpenClaw installation, and your configuration. Docker handles auto-restart, and the container runs completely independently of your shell sessions.

Dockerfile

FROM node:20-slim

# Install OpenClaw globally
RUN npm install -g openclaw

# Set working directory
WORKDIR /root

# Copy your OpenClaw config into the image
# (or mount it as a volume at runtime)
COPY .openclaw/ /root/.openclaw/

# Expose the gateway port
EXPOSE 18789

# Start the gateway
CMD ["openclaw", "gateway", "start"]

Build and Run the Container

# Build the image
docker build -t openclaw-gateway .

# Run with auto-restart and port mapping
docker run -d   --name openclaw-gateway   --restart unless-stopped   -p 18789:18789   openclaw-gateway

# Or mount your local config directory instead of copying it
docker run -d   --name openclaw-gateway   --restart unless-stopped   -p 18789:18789   -v ~/.openclaw:/root/.openclaw   openclaw-gateway

# Check container status
docker ps

# View live logs
docker logs -f openclaw-gateway

# Stop the container
docker stop openclaw-gateway

# Remove the container
docker rm openclaw-gateway

The --restart unless-stopped policy tells Docker to automatically restart the container on crash and on system reboot, unless you explicitly stop it with docker stop.

Monitoring Gateway Health

Regardless of which method you use, the quickest health check is a direct HTTP request to the gateway:

# Basic health check
curl http://localhost:18789/health

# Check what is bound to port 18789
lsof -i :18789

# With pm2
pm2 status
pm2 monit

# With systemd
sudo systemctl status openclaw

# With Docker
docker ps --filter name=openclaw-gateway

For automated monitoring, you can add a simple cron job that pings the health endpoint and sends a Telegram alert if it fails:

# Add to crontab (crontab -e)
# Check every 5 minutes, alert via Telegram if gateway is down
*/5 * * * * curl -sf http://localhost:18789/health ||   curl -s "https://api.telegram.org/botYOUR_TOKEN/sendMessage"   -d "chat_id=YOUR_CHAT_ID&text=OpenClaw+gateway+is+DOWN"

Checking Gateway Logs

Log location depends on which method you use. Here is a quick reference:

nohup

tail -f nohup.out in the directory where you ran the command.

tmux / screen

Reattach to the session with tmux attach -t openclaw or screen -r openclaw to see live output directly.

pm2

pm2 logs openclaw or files at ~/.pm2/logs/openclaw-out.log and ~/.pm2/logs/openclaw-error.log.

launchd

tail -f /tmp/openclaw-gateway.log (or the path you set in the plist).

systemd

sudo journalctl -u openclaw -f for live streaming, sudo journalctl -u openclaw --since "1 hour ago" for recent history.

Docker

docker logs -f openclaw-gateway for live output, docker logs --tail 100 openclaw-gateway for recent history.

Common Errors and Fixes

Error: EADDRINUSE — port 18789 already in use

A previous gateway process is still running. Kill it before starting a new one:

kill $(lsof -ti:18789)

If using pm2, run pm2 delete openclaw first. For systemd, use sudo systemctl restart openclaw, which handles this automatically.

Error: Permission denied on port 18789

Port numbers below 1024 require root. Port 18789 is in the safe range and should not require elevated permissions. If you see this error, check that you are running as the correct user and that no firewall rule is blocking the bind. On Linux, verify with sudo ufw status.

Error: openclaw: command not found (in systemd or launchd)

System services do not inherit your shell's PATH environment. You must use the full absolute path to the openclaw binary in your unit file or plist. Find it with which openclaw and use that exact path in ExecStart or ProgramArguments. If you installed via nvm, the path will be inside the nvm directory, for example /home/youruser/.nvm/versions/node/v20.0.0/bin/openclaw.

Gateway starts but agents do not respond

The gateway may be running as a different user than the one that owns the OpenClaw config files. Check that the user specified in your systemd User= directive or launchd plist matches the user who owns ~/.openclaw/. Also verify the gateway is reading the correct config with openclaw config show from the same user context.

Which Method Should You Use?

MethodAuto-restartBoot startInstall neededBest for
nohupNoNoNoneQuick testing
tmux / screenNoNotmux or screenRemote SSH sessions
pm2YesYesnpm installMost users (recommended)
launchdYesYesNone (macOS built-in)Mac, minimal tooling
systemdYesYesNone (Linux built-in)Linux VPS (production)
DockerYesYesDockerFull isolation, portability

Related Guides

Frequently Asked Questions

Can I run the OpenClaw gateway in headless mode?

Yes. The OpenClaw gateway is a standard Node.js process, so you can run it headlessly using any process management method. The simplest approach is nohup openclaw gateway start & which detaches the process from your terminal session. For reliable long-term operation, pm2 or a native system service (launchd on macOS, systemd on Linux) is recommended because they handle auto-restart on crash and auto-start on boot.

What happens to the OpenClaw gateway when I close my terminal?

By default, the gateway process receives a SIGHUP signal when the terminal closes and stops running. This means your agents go offline, Telegram bots stop responding, and scheduled heartbeat tasks no longer fire. To prevent this, you must either detach the process from the terminal using nohup, run it inside a tmux or screen session, or configure it as a system service with pm2, launchd, or systemd.

Which method should I use to run the OpenClaw gateway as a daemon?

For most users, pm2 is the best option. It installs via npm, works identically on macOS and Linux, handles auto-restart on crash, persists across reboots, and provides built-in log management. If you are on macOS and prefer native tools, launchd is the most reliable choice. On a Linux VPS, systemd is the production standard. Docker is the best option if you want full isolation and portability.

How do I check if the OpenClaw gateway is running in the background?

Run 'curl http://localhost:18789/health' to test if the gateway is responding. If using pm2, run 'pm2 status' or 'pm2 logs openclaw' to see the process state and recent output. For systemd, use 'sudo systemctl status openclaw'. For launchd on macOS, use 'launchctl list | grep openclaw'. You can also check 'lsof -i :18789' to confirm something is bound to the gateway port.

What causes the 'port 18789 already in use' error?

This error means a previous gateway process is still running. Find it with 'lsof -ti:18789' and kill it with 'kill $(lsof -ti:18789)'. This commonly happens when you try to start the gateway a second time after the terminal closed but the process did not actually stop. If you are using pm2, run 'pm2 delete openclaw' before starting fresh. For systemd, 'sudo systemctl restart openclaw' handles this automatically.

How do I view OpenClaw gateway logs when running as a background service?

The log location depends on your method. With pm2, run 'pm2 logs openclaw' or find log files at ~/.pm2/logs/openclaw-out.log and ~/.pm2/logs/openclaw-error.log. With systemd, use 'sudo journalctl -u openclaw -f' for live log streaming or 'sudo journalctl -u openclaw --since today' for today's output. With nohup, logs go to nohup.out in the directory where you ran the command. With Docker, use 'docker logs -f openclaw-gateway'.

Get Your Agent Config Files Ready to Deploy

Generate your SOUL.md, config.json, and all supporting files at crewclaw.com. Download a deploy-ready package and get your gateway running in minutes, not hours.

Build Your Agent Config

Free to generate. $9 one-time to download the full package.