This guide provides an Ansible playbook to deploy OpenClaw natively (without Docker) on Debian 10+, Ubuntu 20.04+, and RHEL 9+ compatible hosts using npm global installation.
Important: OpenClaw uses file-based storage (no external database required). Configuration is stored in ~/.openclaw/openclaw.json.
- name: Deploy OpenClaw (Native npm Installation)
hosts: openclaw
become: true
vars:
# Application settings
openclaw_user: openclaw
openclaw_home: /home/openclaw
gateway_port: 18789
gateway_bind: lan # Use "loopback" for localhost-only access
# Node.js settings
nodejs_version: "22.x"
# Gateway token (auto-generated if not provided)
openclaw_gateway_token: "{{ vault_openclaw_gateway_token | default(lookup('password', '/dev/null length=64 chars=hexdigits')) }}"
tasks:
- name: Include OS-specific variables
include_vars: "{{ item }}"
with_first_found:
- "{{ ansible_distribution | lower }}-{{ ansible_distribution_major_version }}.yml"
- "{{ ansible_distribution | lower }}.yml"
- "{{ ansible_os_family | lower }}.yml"
- "default.yml"
ignore_errors: true
- name: Install Node.js prerequisites (Debian/Ubuntu)
apt:
name:
- curl
- ca-certificates
- gnupg
state: present
update_cache: true
when: ansible_os_family == "Debian"
- name: Install Node.js prerequisites (RHEL)
dnf:
name:
- curl
- ca-certificates
state: present
when: ansible_os_family == "RedHat"
- name: Add NodeSource repository (Debian/Ubuntu)
block:
- name: Download NodeSource setup script
get_url:
url: https://deb.nodesource.com/setup_{{ nodejs_version }}
dest: /tmp/nodesource_setup.sh
mode: "0755"
- name: Run NodeSource setup script
command: /tmp/nodesource_setup.sh
when: ansible_os_family == "Debian"
- name: Add NodeSource repository (RHEL)
block:
- name: Download NodeSource setup script
get_url:
url: https://rpm.nodesource.com/setup_{{ nodejs_version }}
dest: /tmp/nodesource_setup.sh
mode: "0755"
- name: Run NodeSource setup script
command: /tmp/nodesource_setup.sh
when: ansible_os_family == "RedHat"
- name: Install Node.js (Debian/Ubuntu)
apt:
name: nodejs
state: present
update_cache: true
when: ansible_os_family == "Debian"
- name: Install Node.js (RHEL)
dnf:
name: nodejs
state: present
when: ansible_os_family == "RedHat"
- name: Verify Node.js version
command: node -v
register: node_version
changed_when: false
- name: Create OpenClaw system user
user:
name: "{{ openclaw_user }}"
home: "{{ openclaw_home }}"
shell: /bin/bash
system: true
create_home: true
comment: "OpenClaw AI Assistant Service"
- name: Install OpenClaw globally via npm
become: true
become_user: "{{ openclaw_user }}"
npm:
name: openclaw
global: true
state: present
- name: Create .openclaw directory
become: true
become_user: "{{ openclaw_user }}"
file:
path: "{{ openclaw_home }}/.openclaw"
state: directory
mode: "0700"
owner: "{{ openclaw_user }}"
group: "{{ openclaw_user }}"
- name: Create workspace directory
become: true
become_user: "{{ openclaw_user }}"
file:
path: "{{ openclaw_home }}/.openclaw/workspace"
state: directory
mode: "0700"
owner: "{{ openclaw_user }}"
group: "{{ openclaw_user }}"
- name: Generate gateway token if not provided
set_fact:
openclaw_gateway_token: "{{ lookup('password', '/dev/null length=64 chars=hexdigits') }}"
when: openclaw_gateway_token is not defined
- name: Write OpenClaw configuration file
become: true
become_user: "{{ openclaw_user }}"
copy:
dest: "{{ openclaw_home }}/.openclaw/openclaw.json"
mode: "0600"
owner: "{{ openclaw_user }}"
group: "{{ openclaw_user }}"
content: |
{
"gateway": {
"mode": "{{ gateway_bind }}",
"port": {{ gateway_port }},
"auth": {
"mode": "token",
"token": "{{ openclaw_gateway_token }}"
}
},
"agents": {
"defaults": {
"sandbox": {
"mode": "all"
}
}
}
}
- name: Create systemd service file
copy:
dest: /etc/systemd/system/openclaw.service
mode: "0644"
content: |
[Unit]
Description=OpenClaw AI Assistant Gateway
After=network.target
Documentation=https://docs.openclaw.ai
[Service]
Type=simple
User={{ openclaw_user }}
Group={{ openclaw_user }}
WorkingDirectory={{ openclaw_home }}
Environment=HOME={{ openclaw_home }}
Environment=OPENCLAW_GATEWAY_PORT={{ gateway_port }}
ExecStart=/usr/bin/openclaw gateway --port {{ gateway_port }}
Restart=on-failure
RestartSec=10
LimitNOFILE=65536
# Security hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=read-only
ReadWritePaths={{ openclaw_home }}/.openclaw
[Install]
WantedBy=multi-user.target
- name: Reload systemd daemon
systemd:
daemon_reload: true
- name: Enable OpenClaw service
systemd:
name: openclaw
enabled: true
daemon_reload: true
- name: Start OpenClaw service
systemd:
name: openclaw
state: started
- name: Wait for OpenClaw to be ready
uri:
url: "http://localhost:{{ gateway_port }}"
method: GET
status_code:
- 200
- 301
- 302
- 401
retries: 30
delay: 10
until: result is succeeded
register: result
ignore_errors: true
- name: Display deployment information
debug:
msg: |
OpenClaw deployment complete!
Service Status: {{ 'running' if result is succeeded else 'check manually' }}
Gateway Port: {{ gateway_port }}
Gateway Bind: {{ gateway_bind }}
Access the Web UI at: http://{{ inventory_hostname }}:{{ gateway_port }}/?token={{ openclaw_gateway_token }}
IMPORTANT:
- Store the gateway token securely
- Do not expose port {{ gateway_port }} to the public internet
- Use a reverse proxy with authentication for remote access
- Run 'openclaw doctor' for security audit
Save the playbook as deploy-openclaw-native.yml.
Create an inventory file (inventory.ini):
[openclaw]
server1.example.com
server2.example.com
Use Ansible Vault to store sensitive values:
# Create vault file
ansible-vault create group_vars/openclaw/vault.yml
Add your gateway token:
vault_openclaw_gateway_token: your-secure-random-token-here
# Basic run
ansible-playbook -i inventory.ini deploy-openclaw-native.yml
# With vault
ansible-playbook -i inventory.ini deploy-openclaw-native.yml --ask-vault-pass
After deployment, access OpenClaw at:
http://YOUR_SERVER_IP:18789/?token=<your-gateway-token>
If you need to retrieve the gateway token:
# SSH to the server
ssh user@server
# Switch to openclaw user
sudo su - openclaw
# View the configuration
cat ~/.openclaw/openclaw.json | grep token
Access the Web UI and complete the onboarding wizard to configure:
Or configure via SSH:
sudo su - openclaw
openclaw onboard
# Check systemd status
systemctl status openclaw
# View logs
journalctl -u openclaw -f
# View recent errors
journalctl -u openclaw -p err
systemctl restart openclaw
systemctl stop openclaw
# Switch to openclaw user
sudo su - openclaw
# Update npm package
npm update -g openclaw
# Restart service
sudo systemctl restart openclaw
systemctl status openclaw
# Full logs
journalctl -u openclaw -f
# Last 100 lines
journalctl -u openclaw -n 100
# Since boot
journalctl -u openclaw -b
sudo su - openclaw
openclaw doctor
The doctor command performs health checks and security audits, surfacing risky or misconfigured DM policies.
sudo su - openclaw
openclaw gateway --port 18789
sudo su - openclaw
openclaw onboard
openclaw doctor regularly for security auditsjournalctl -u openclawFor detailed security guidance, see OpenClaw Security.
We develop tailored automation solutions for:
Let’s discuss your requirements: office@linux-server-admin.com | Contact