Docker Deployment
The netclaw Docker image runs the daemon (netclawd) in a supervised container. The CLI stays on your host and connects over HTTP at 127.0.0.1:5199. Your interactive terminal stays outside the container; the daemon runs headless.
Before you begin
Section titled “Before you begin”- Docker Engine 20.10+ or Docker Desktop
- A provider API key (OpenRouter, Anthropic, OpenAI, etc.) or a reachable Ollama instance
- An initialized
~/.netclawdirectory — runnetclaw initon the host first, or bind-mount a pre-configured one. If you don’t have the CLI yet, see Installation.
Quick start
Section titled “Quick start”docker run -d \ --name netclaw \ -v ~/.netclaw:/root/.netclaw \ -p 127.0.0.1:5199:5199 \ ghcr.io/netclaw-dev/netclawThe port binding is loopback-only (127.0.0.1:5199) because the health check endpoint is unauthenticated — don’t expose it to the network. The volume mount persists identity, config, credentials, session state, and logs across restarts. Self-update is disabled in the image; the image tag is the version. Update availability checks still run, so you’ll know when a new release exists.
Tags: :latest tracks the most recent release. Pin to a version tag (e.g., :1.2.3) in production.
Verify from the host:
netclaw statusThe CLI defaults to http://127.0.0.1:5199, so no configuration is needed for local Docker. For remote daemons, see Exposure Modes.
First run with Docker only
Section titled “First run with Docker only”If you don’t have netclaw init on the host, run it inside the container:
docker exec -it netclaw netclaw initThe interactive wizard works the same way over docker exec -it.
Configuration via environment variables
Section titled “Configuration via environment variables”Pass provider credentials and model config as NETCLAW_-prefixed environment variables. Double underscores separate path segments, following the .NET configuration convention. Env vars take highest priority, overriding both netclaw.json and secrets.json.
docker run -d \ --name netclaw \ -v ~/.netclaw:/root/.netclaw \ -p 127.0.0.1:5199:5199 \ -e NETCLAW_Providers__openrouter__Type=openrouter \ -e NETCLAW_Providers__openrouter__ApiKey=sk-or-v1-... \ -e NETCLAW_Models__Main__Provider=openrouter \ -e NETCLAW_Models__Main__ModelId=anthropic/claude-sonnet-4 \ ghcr.io/netclaw-dev/netclawKeep secrets out of config files — inject them at runtime. The ModelId value must match a valid identifier from the provider API; see Models for the full schema and available model IDs.
Docker Compose
Section titled “Docker Compose”For anything beyond quick testing, use Compose. This example pairs netclaw with a local Ollama instance and uses named volumes (unlike the bind mount in the quick start) for easier lifecycle management:
services: netclaw: image: ghcr.io/netclaw-dev/netclaw container_name: netclaw restart: unless-stopped depends_on: - ollama ports: - "127.0.0.1:5199:5199" volumes: - netclaw-home:/root/.netclaw environment: NETCLAW_Providers__local-ollama__Type: ollama NETCLAW_Providers__local-ollama__Endpoint: http://ollama:11434 NETCLAW_Models__Main__Provider: local-ollama NETCLAW_Models__Main__ModelId: qwen3:30b
ollama: image: ollama/ollama:latest container_name: ollama ports: - "127.0.0.1:11434:11434" volumes: - ollama-data:/root/.ollama
volumes: netclaw-home: ollama-data:docker compose up -dPull the model into Ollama before netclaw can use it:
docker exec ollama ollama pull qwen3:30bNetclaw references Ollama by service name (http://ollama:11434) since Compose puts both containers on the same network.
Docker socket access
Section titled “Docker socket access”If you want the agent to manage Docker containers as part of its tool use, mount the socket:
-v /var/run/docker.sock:/var/run/docker.sockAdd this to the volumes section of the netclaw service in your Compose file or to the docker run command.
Volume layout
Section titled “Volume layout”Everything the daemon persists lives under /root/.netclaw:
/root/.netclaw/├── client/config.json # CLI endpoint state├── config/│ ├── netclaw.json # Daemon settings│ └── secrets.json # Credentials├── identity/ # Agent personality (SOUL.md, AGENTS.md, TOOLING.md)├── sessions/ # Conversation history├── keys/ # Key material├── projects/├── environment/├── schedules/└── logs/ # crash-*.log, session logsBack up this volume before upgrades. config/ and identity/ are the critical directories; everything else can be regenerated.
Health checks
Section titled “Health checks”The image has a built-in health check that polls every 15 seconds with a 30-second startup grace period:
HEALTHCHECK --interval=15s --timeout=5s --start-period=30s --retries=3 CMD curl -sf http://127.0.0.1:5199/api/health/ready || exit 1| Endpoint | Auth | Purpose |
|---|---|---|
GET /api/health/ready | None | Returns 200 OK when the daemon is ready. Use this for orchestrators and load balancers. |
GET /api/health/status | Required | Returns detailed runtime status. |
Check container health from the host:
docker inspect --format='{{.State.Health.Status}}' netclawProcess supervision
Section titled “Process supervision”The entrypoint script is a PID 1 supervisor. If the daemon exits (config-update restart, crash, netclaw init wizard completion), the entrypoint waits 2 seconds and restarts it. The container stays alive, so docker exec sessions survive daemon restarts.
docker stop sends SIGTERM, which the entrypoint forwards to the daemon for a clean shutdown. Docker’s default 10-second stop timeout is plenty.
Upgrading
Section titled “Upgrading”Self-update is disabled in the image (NETCLAW_Daemon__DisableSelfUpdate=true), so upgrades mean pulling a new image. Schema migrations are forward-only with no automatic rollback.
# Pull the new versiondocker pull ghcr.io/netclaw-dev/netclaw:latest
# Stop the old container (volume stays)docker stop netclaw && docker rm netclaw
# Start with the new imagedocker run -d \ --name netclaw \ -v ~/.netclaw:/root/.netclaw \ -p 127.0.0.1:5199:5199 \ ghcr.io/netclaw-dev/netclaw:latest
# Wait for readinessuntil curl -sf http://127.0.0.1:5199/api/health/ready; do sleep 2; doneecho "Daemon is ready"With Compose:
docker compose pulldocker compose up -dTo rollback, stop the container and start with the previous image tag. If the new version already ran a schema migration, restore the volume from backup to roll back.
Image details
Section titled “Image details”| Property | Value |
|---|---|
| Registry | ghcr.io/netclaw-dev/netclaw |
| Base | ubuntu:24.04 |
| Architectures | linux/amd64, linux/arm64 |
| Port | 5199 |
| Volume | /root/.netclaw |
| License | Apache-2.0 |
Built on Ubuntu 24.04 (not a minimal runtime), the image ships with git, jq, sqlite3, python3, curl, wget, gh, and more. Operators can apt-get install additional tools if the agent needs them.
Troubleshooting
Section titled “Troubleshooting”Container starts but CLI can’t connect
Section titled “Container starts but CLI can’t connect”Confirm the port mapping binds to 127.0.0.1 and nothing else is on port 5199:
ss -tlnp | grep 5199docker logs netclawContainer keeps restarting
Section titled “Container keeps restarting”The entrypoint restarts the daemon on every exit, and that’s by design. If it’s a crash loop, check docker logs netclaw for the cause. Common culprits: missing provider config, invalid API key, or a required field missing from netclaw.json.
Health check failing
Section titled “Health check failing”The 30-second start period gives the daemon time to initialize. If it’s still unhealthy after that, the daemon isn’t starting. Check logs and run netclaw doctor from the host, or docker exec netclaw netclaw doctor inside the container.
Related pages
Section titled “Related pages”- Models — model slot configuration
- Exposure Modes — remote access via Tailscale or Cloudflare Tunnel
- systemd Service — bare-metal Linux alternative
- OpenTelemetry — daemon metrics and log export
Resources
Section titled “Resources”- Docker Engine installation guide — platform-specific install instructions
- Docker Compose documentation — multi-container orchestration
- GitHub Container Registry (GHCR) — pulling and authenticating with ghcr.io
- .NET environment variable configuration — the double-underscore nesting convention
- Ollama model library — browse available models for local inference