Overview
NanoClaw Pro runs as a systemd user service that starts on login and restarts on failure. The service manages the main Node.js process, which handles channel connections, message polling, and spawning containerized agents using Docker.Prerequisites
Node.js 20 or later
Claude Code CLI authenticated
Docker or Docker Desktop installed and running
Build tools (gcc, make, python3)
Installation
Clone and set up the project
Install and configure Docker
Docker Desktop (recommended for desktop Linux):Docker Engine (for servers):Verify Docker is running:
Build the agent container image
nanoclaw-agent:latest image with Node.js 20, Claude Code CLI, Chromium (for browser automation), and the agent-runner code.Configure authentication
Create a Extract from Only authentication variables are extracted and mounted into containers.
.env file in the project root:Option 1: Claude Subscription (OAuth)~/.claude/.credentials.json if logged into Claude Code.Option 2: Pay-per-use API KeyCreate systemd user service
Create Replace
~/.config/systemd/user/nanoclaw.service:/home/yourusername with your actual home directory path.Service Management
Check Service Status
Start/Stop/Restart
Service Logs
Systemd captures stdout/stderr to journald. You can also access file logs:| File | Contents |
|---|---|
logs/nanoclaw.log | Main process stdout (redirected by service) |
logs/nanoclaw.error.log | Main process stderr |
groups/{name}/logs/container-*.log | Per-agent execution logs |
container-20260307-143022.log
Debugging
Docker vs Podman
NanoClaw Pro uses Docker by default. To switch to Podman:Podman is daemonless and rootless by default, making it more secure than Docker. It’s API-compatible but has subtle differences in networking and volume mounts.
Container Runtime Setup
NanoClaw requires a container runtime to isolate agent execution. The service automatically:- Checks if runtime is running (
docker info) - Kills orphaned
nanoclaw-*containers from previous runs - Spawns fresh containers for each agent invocation with
--rm(auto-cleanup)
nanoclaw-{groupFolder}-{timestamp} and runs with:
- Working directory:
/workspace/group(mounted fromgroups/{name}/) - Non-root user:
node(uid 1000) - Network: bridge (default)
- Auto-remove: Yes (
--rmflag)
Volume Mounts
Default mounts for all groups:containerConfig in SQLite:
/workspace/extra/webapp in container.
Environment Variables
Configure in systemd service file’s[Service] section:
| Variable | Default | Purpose |
|---|---|---|
ASSISTANT_NAME | Andy | Trigger word for messages (@Andy) |
CONTAINER_IMAGE | nanoclaw-agent:latest | Agent container image |
CONTAINER_TIMEOUT | 1800000 (30 min) | Max container runtime (ms) |
IDLE_TIMEOUT | 1800000 (30 min) | Keep container alive after last result |
MAX_CONCURRENT_CONTAINERS | 5 | Max parallel agent containers |
PATH | Standard + ~/.local/bin | Include Claude Code CLI path |
Startup Sequence
When the service starts:- Ensures Docker is running (
docker info, exits if failed) - Cleans up orphaned
nanoclaw-*containers - Initializes SQLite database (
store/messages.db) - Loads registered groups, sessions, router state
- Connects channels (self-registration pattern)
- Starts scheduler loop (60s interval)
- Starts IPC watcher (monitors
data/ipc/) - Recovers unprocessed messages from before restart
- Starts message polling loop (2s interval)
Security
The service runs as your user (not root). All agents execute in Docker containers with:- Process isolation: cgroups and namespaces
- Filesystem isolation: Only mounted directories visible
- Network isolation: Bridge network (can be configured per-group)
- Non-root user: Runs as
node(uid 1000) inside container - No privileged mode: Standard container security
- Mount allowlist:
src/mount-security.tsvalidates paths before mounting
.env file is shadowed with /dev/null when mounting project root for main group.
Firewall Configuration
If using a firewall, allow Docker’s bridge network:WSL2 Considerations
If running on Windows Subsystem for Linux:- Use Docker Desktop for Windows with WSL2 backend (recommended)
- Or install Docker Engine inside WSL2 (more complex networking)
- Ensure WSL2 has enough memory allocated (default 50% of host RAM)
.wslconfig in Windows home directory:
Next Steps
macOS Deployment
Deploy with launchd on macOS
Troubleshooting
Common issues and solutions