Installation & Setup Linux Install

OpenClaw on Alpine Linux: Minimal Footprint Deployment Guide

Alpine Linux runs OpenClaw in under 150 MB total image size. That's why it's the base of choice for containerized OpenClaw deployments. The musl libc difference from glibc systems trips people up once — here's how to avoid it entirely.

SR
S. Rivera
AI Infrastructure Lead
Feb 22, 2025 14 min read Linux Install
Updated Feb 2025
Key Takeaways
Alpine 3.19+ includes Node.js 20 LTS in the community repository — apk add nodejs npm is all you need.
Alpine uses musl libc, not glibc. Install build-base python3 before npm install to satisfy native module compilation.
Alpine uses OpenRC, not systemd. Create an init script at /etc/init.d/openclaw and enable it with rc-update add openclaw default.
For Docker deployments, start from node:20-alpine — this is the smallest production-ready Node.js base image available.
Mount a named volume to /var/lib/openclaw to persist gateway config and memory data across container restarts.

Alpine Linux ships at 5 MB. A full OpenClaw deployment on Alpine — Node.js runtime, the gateway binary, and all dependencies — fits comfortably under 200 MB. On Ubuntu or Debian, the same stack runs 500 MB or more. For teams running 10 or 20 container instances, that difference compounds fast. Alpine is not a compromise. It's a deliberate engineering choice that saves real money on storage and bandwidth.

Why Alpine Works Well for OpenClaw

Alpine's minimalism is its main feature: fewer packages installed means fewer CVEs exposed, smaller images, and faster cold starts. For OpenClaw specifically, this matters in three situations:

  • Docker deployments — smaller image means faster pull times, lower registry storage costs, faster CI/CD pipelines
  • VPS or edge nodes — low RAM and disk overhead leaves more resources for the OpenClaw gateway itself
  • Security-conscious setups — Alpine's minimal package surface reduces what's available to an attacker if something is compromised

The one tradeoff is musl libc. Alpine uses musl instead of glibc. Most Node.js packages work fine with musl, but packages that include native C++ bindings need a compiler toolchain at build time. We'll handle this with two extra packages.

Install Node.js on Alpine

Enable the community repository if not already active. Open /etc/apk/repositories and ensure the community line is uncommented:

# /etc/apk/repositories
https://dl-cdn.alpinelinux.org/alpine/v3.19/main
https://dl-cdn.alpinelinux.org/alpine/v3.19/community

Update and install Node.js:

apk update
apk add nodejs npm

Verify:

node --version   # v20.x.x on Alpine 3.19+
npm --version
⚠️
Alpine Version Matters
Alpine 3.18 ships Node.js 18 in community repos. Alpine 3.17 and older have Node.js 16 or 14 — too old for OpenClaw. Always check your Alpine version with cat /etc/alpine-release before proceeding. Upgrade Alpine or use the node:20-alpine Docker image for guaranteed version control.

Handling Musl Libc and Native Modules

Some npm packages that OpenClaw depends on include native Node.js addons — C++ code that gets compiled at install time. On Alpine, this compilation requires the musl-compatible build toolchain. Install it before running npm:

apk add build-base python3

build-base includes gcc, g++, make, and the musl development headers. python3 is needed by node-gyp, the native module build tool. Without these, some npm install commands produce cryptic errors like ENOENT python or make: not found.

Sound familiar? This is the #1 issue Alpine users hit with OpenClaw. Install these two packages first and you'll never see those errors.

Install OpenClaw on Alpine

With Node.js and build tools in place:

npm install -g openclaw

If the install triggers native module compilation, you'll see output from node-gyp. This is expected — let it complete. The build typically takes 30–90 seconds depending on hardware.

Verify and initialize:

openclaw --version
mkdir -p /var/lib/openclaw /etc/openclaw
openclaw gateway init --config /etc/openclaw/gateway.yaml

Edit your gateway config with the API keys and channels you need:

vi /etc/openclaw/gateway.yaml
💡
System User for Security
Create a dedicated user: adduser -S -D -H -s /sbin/nologin openclaw. Run the gateway under this user. Alpine's adduser syntax differs from Debian/Ubuntu — the -S flag creates a system user, -D skips password, -H skips home directory creation.

Set Up OpenRC Service

Alpine uses OpenRC for service management, not systemd. Create the init script:

cat > /etc/init.d/openclaw << 'EOF'
#!/sbin/openrc-run

name="openclaw"
description="OpenClaw AI Agent Gateway"
command="/usr/bin/openclaw"
command_args="gateway start --config /etc/openclaw/gateway.yaml"
command_user="openclaw"
command_background=true
pidfile="/run/openclaw.pid"
output_log="/var/log/openclaw.log"
error_log="/var/log/openclaw.log"

depend() {
    need net
    after firewall
}
EOF
chmod +x /etc/init.d/openclaw

Enable and start the service:

rc-update add openclaw default
rc-service openclaw start
rc-service openclaw status

Check logs: tail -f /var/log/openclaw.log

Docker Deployment on Alpine

The Dockerfile for a containerized OpenClaw on Alpine:

FROM node:20-alpine

RUN apk add --no-cache build-base python3 \
    && npm install -g openclaw \
    && apk del build-base python3 \
    && adduser -S -D -H -s /sbin/nologin openclaw

RUN mkdir -p /var/lib/openclaw /etc/openclaw \
    && chown openclaw:nogroup /var/lib/openclaw

COPY gateway.yaml /etc/openclaw/gateway.yaml
RUN chmod 640 /etc/openclaw/gateway.yaml

USER openclaw
WORKDIR /var/lib/openclaw
EXPOSE 8080

CMD ["openclaw", "gateway", "start", "--config", "/etc/openclaw/gateway.yaml"]

Build and run:

docker build -t openclaw-alpine .
docker run -d \
  --name openclaw \
  -p 8080:8080 \
  -v openclaw-data:/var/lib/openclaw \
  --restart unless-stopped \
  openclaw-alpine

The --restart unless-stopped flag ensures the container comes back up after a host reboot or Docker daemon restart. The named volume persists all OpenClaw data between container updates.

Common Mistakes on Alpine

  • Missing build-base and python3 — native npm module compilation fails with confusing errors; always install these before npm install
  • Using Alpine 3.17 or older — Node.js version in those repos is too old; upgrade to Alpine 3.19 or use node:20-alpine
  • Expecting systemd commands to work — Alpine uses OpenRC; use rc-service and rc-update, not systemctl
  • No volume mount in Docker — gateway config and memory data are lost every time the container is removed or updated
  • Not deleting build tools in Dockerfile — leaving build-base in the final image adds 150+ MB unnecessarily; delete after npm install

Frequently Asked Questions

Does OpenClaw work on Alpine Linux with musl libc?

Yes, with caveats. OpenClaw's Node.js runtime works with musl libc, but some npm packages that include native bindings may fail to compile. If you hit build errors during npm install, add the build-base and python3 packages via apk first — they provide the compiler toolchain needed for native modules.

How do I install Node.js on Alpine Linux for OpenClaw?

Run: apk add nodejs npm. Alpine's community repository includes Node.js 20 LTS on Alpine 3.19 and newer. On older Alpine versions, the packaged Node.js may be older — check with node --version after install and consider upgrading Alpine if the version is below 18.

Does Alpine Linux use systemd? How do I run OpenClaw as a service?

Alpine uses OpenRC, not systemd. Create an init script at /etc/init.d/openclaw, mark it executable, then run rc-update add openclaw default to enable it. Use rc-service openclaw start to start the service. Logs go to /var/log/openclaw.log by default.

Why is Alpine Linux popular for containerized OpenClaw deployments?

Alpine's base image is under 10 MB compared to Ubuntu's 80+ MB. For Docker-based OpenClaw deployments, this means faster image pulls, smaller attack surface, and lower storage costs. The tradeoff is musl libc compatibility issues with some native npm modules.

How do I persist OpenClaw data across Alpine container restarts?

Mount a Docker volume to /var/lib/openclaw where OpenClaw writes its gateway config, memory files, and logs. Without a volume, all data is lost when the container stops. Use: docker run -v openclaw-data:/var/lib/openclaw your-openclaw-image.

What firewall does Alpine Linux use with OpenClaw?

Alpine uses iptables directly, or you can install ufw via apk. For basic setups, install iptables-dev and add rules to allow port 8080. For production, install and configure ufw with: apk add ufw && ufw allow 8080/tcp && ufw enable.

SR
S. Rivera
AI Infrastructure Lead
S. Rivera manages OpenClaw infrastructure deployments across containerized and bare-metal environments. Specializes in minimal-footprint AI agent setups on Alpine, Container Linux, and edge hardware where resource efficiency is critical.
Stay Current
New OpenClaw guides every week — straight to your inbox.