How to Run OpenClaw as Non-Root in Docker
Running Docker containers as root is a major security risk. If an attacker escapes the container, they gain root access to your host system. OpenClaw's default Docker image runs as root for simplicity, but production deployments need proper privilege separation. This guide shows you how to create a non-root user, fix file permissions, handle volume mounts, and troubleshoot common issues when running OpenClaw securely.
Why This Is Hard to Do Yourself
These are the common pitfalls that trip people up.
Root by default
OpenClaw Docker images run as root (UID 0), giving container processes full privileges.
Permission errors
Non-root users can't write to volumes owned by root, breaking logs, data, and cache directories.
Build-time vs runtime
Creating users in Dockerfile is different from switching users in docker-compose. Both are needed.
Skill compatibility
Some ClawHub skills expect root access for package installation or system commands.
Step-by-Step Guide
Create a custom Dockerfile with non-root user
Extend the official OpenClaw image.
# Dockerfile.nonroot
FROM openclaw/openclaw:2.4.1
# Create openclaw user and group
RUN groupadd --system --gid 1000 openclaw && \
useradd --system --uid 1000 --gid openclaw --shell /bin/bash openclaw
# Create directories and set ownership
RUN mkdir -p /app/data /app/logs /app/.cache && \
chown -R openclaw:openclaw /app
# Switch to non-root user
USER openclaw
CMD ["npm", "start"]Build the custom image
docker build -f Dockerfile.nonroot -t openclaw-nonroot:latest .Update docker-compose.yml with proper user and volumes
Configure user ID and fix volume permissions.
# docker-compose.yml
services:
openclaw:
image: openclaw-nonroot:latest
user: "1000:1000"
volumes:
- ./data:/app/data
- ./logs:/app/logs
environment:
- NODE_ENV=productionFix volume mount ownership on host
Ensure host directories are owned by UID 1000.
# On the Docker host:
sudo chown -R 1000:1000 ./data ./logs
# Or let Docker create them with correct ownership:
mkdir -p data logs
sudo chown 1000:1000 data logsWarning: If you skip this step, the container will fail with "Permission denied" errors when trying to write to mounted volumes.
Test non-root operation
Verify OpenClaw starts and runs as non-root.
docker-compose up -d
# Check that process runs as UID 1000:
docker-compose exec openclaw id
# Output: uid=1000(openclaw) gid=1000(openclaw)
# Verify logs are written:
ls -la logs/
# Should show files owned by 1000:1000Handle skills that require elevated privileges
Identify and restrict skills needing root.
# In soul.md or gateway config:
skill_restrictions:
disabled_skills:
- system-package-installer # Requires apt/yum
- docker-in-docker # Requires socket access
allowed_skills:
- web-search
- file-analyzer
- code-reviewNon-Root Docker Is Tricky
Permission errors, broken skills, and subtle bugs are common when switching to non-root. We handle the migration, test your skills, and ensure everything works securely.
Get matched with a specialist who can help.
Sign Up for Expert Help โ