Every Clawker project has a .clawker.yaml file in the project root. Create one with:
How Configuration Works
Clawker uses a layered configuration system that discovers, loads, and merges YAML files from multiple locations. Understanding this system is key to using Clawker effectively — especially in monorepos, shared environments, or when you want per-directory overrides.
Discovery and Merge
When you run any Clawker command, the configuration engine:
- Walk-up discovery — Starting from your current working directory, walks up the directory tree to the registered project root, probing for config files at each level.
- Explicit paths — Checks the user config directory (
~/.config/clawker/) for additional config files.
- Defaults — Applies built-in defaults as the lowest-priority base layer.
Files found closer to CWD have higher priority than files found further up the tree. This means a .clawker.yaml in a subdirectory overrides values from the one at the project root.
Merge rules:
- Scalars (strings, numbers, booleans): closest-to-CWD wins.
- Maps (objects): recursively merged — keys from higher-priority files override, but unmentioned keys from lower-priority files are preserved.
- Slices (arrays): replaced entirely by higher-priority files, unless the field is tagged for union merge (e.g., firewall
add_domains).
File Placement
At each directory level during walk-up, the engine checks two placement styles:
| Style | Path | When |
|---|
| Directory form | .clawker/clawker.yaml | When a .clawker/ directory exists |
| Flat dotfile form | .clawker.yaml | When no .clawker/ directory exists |
The directory form takes precedence. Both .yaml and .yml extensions are accepted.
Walk-up discovery is bounded — it never walks past the registered project root and never reaches ~/.config/clawker/. Home-level configs are loaded separately via the explicit path mechanism.
Local Overrides
Clawker also discovers clawker.local.yaml (or .clawker.local.yaml / .clawker/clawker.local.yaml) files alongside the main config. These are intended for machine-specific or developer-specific settings that shouldn’t be committed to version control.
At each directory level, both clawker.yaml and clawker.local.yaml are discovered. The local file merges at the same priority level but is loaded after the main file, so its values win.
.clawker.yaml # Committed to git
.clawker.local.yaml # In .gitignore -- personal overrides
Precedence (Highest to Lowest)
1. .clawker.yaml in CWD (or .clawker/clawker.yaml)
2. .clawker.local.yaml in CWD
3. .clawker.yaml in parent directory
4. .clawker.local.yaml in parent directory
5. ... (continues up to project root)
6. .clawker.yaml at project root
7. .clawker.local.yaml at project root
8. ~/.config/clawker/clawker.yaml (user-level overrides)
9. Built-in defaults
Project Registration
Walk-up discovery requires your project to be registered in the project registry. This is how Clawker knows where to stop walking up:
# Register during project init
clawker project init
# Or register an existing project
clawker project register
If CWD is not within a registered project, walk-up is skipped entirely and only the user config directory and defaults are used.
The registry lives at ~/.local/share/clawker/registry.yaml and maps project names to filesystem paths (managed via clawker project commands):
projects:
- name: "my-app"
root: "/Users/dev/my-app"
worktrees:
feature-auth:
path: "/Users/dev/.local/share/clawker/worktrees/my-app-auth-a1b2c3d4e5f6"
branch: "feature/auth"
Monorepo Support
The layered merge system enables monorepo workflows. Place a shared .clawker.yaml at the repo root with common settings, then add per-service overrides in subdirectories:
monorepo/
├── .clawker.yaml # Shared: base image, firewall rules, common packages
├── services/
│ ├── api/
│ │ └── .clawker.yaml # Override: add Python packages, different image
│ └── web/
│ └── .clawker.yaml # Override: add Node packages, different env vars
To create a subdir config, run clawker init from inside the subdirectory. It detects that you’re inside an existing project and skips project registration — going straight to preset selection and config file creation. The resulting file layers on top of the root config.
cd services/api
clawker init # Interactive: pick a preset, customize
clawker init --yes # Non-interactive: Bare preset defaults
When you run clawker run from services/api/, the engine merges:
services/api/.clawker.yaml (highest priority)
.clawker.yaml at repo root
~/.config/clawker/clawker.yaml (if exists)
- Built-in defaults
Only the fields you specify in the subdirectory config are overridden. Everything else inherits from the parent.
Writes
When Clawker writes configuration changes (e.g., via clawker project init), each field is routed back to the file it originally came from (provenance tracking). New fields that didn’t come from any file are written to the highest-priority discovered file. All writes are atomic (temp file + fsync + rename) with advisory file locking for cross-process safety.
Project Configuration Schema
The complete .clawker.yaml schema with all fields and nested object structures. Descriptions are shown as comments.
build:
# Starting Docker image (e.g. node:20-slim, python:3.12); clawker layers tools on top
image: <string> # default: n/a | required: false
# Use your own Dockerfile instead of clawker's generated one; ignores image, packages, and instructions
dockerfile: <string> # default: n/a | required: false
# System packages (apt/apk) needed by your project that aren't in the base image
packages: # default: ripgrep | required: false
- <string>
# Directory to use as Docker build context when using a custom Dockerfile (relative to project root)
context: <string> # default: n/a | required: false
instructions:
# Bake config files or credentials into the image (e.g. .npmrc, SSH config)
copy:
# File or directory to copy from your project
- src: <string> # default: n/a | required: false
# Where to place it inside the container
dest: <string> # default: n/a | required: false
# Set file ownership (e.g. claude:claude)
chown: <string> # default: n/a | required: false
# Set file permissions (e.g. 0644)
chmod: <string> # default: n/a | required: false
# Environment variables baked into the image; use agent.env for runtime-only vars
env: # default: n/a | required: false
<key>: <value>
# Custom Docker labels for image metadata or tooling integration
labels: # default: n/a | required: false
<key>: <value>
# Build-time variables resolved during docker build (ARG); not available at runtime
args:
# Build argument name (referenced as $NAME in Dockerfile instructions)
- name: <string> # default: n/a | required: false
# Value used when not overridden by --build-arg at build time
default: <string> # default: n/a | required: false
# Setup commands that run as the container user (e.g. npm install -g, pip install)
user_run: # default: n/a | required: false
- <string>
# Setup commands that need root privileges (e.g. system config, additional repos)
root_run: # default: n/a | required: false
- <string>
inject:
# Add Dockerfile instructions while root with only the base image — e.g. apt sources, proxy config, or CA certs that package installation depends on
after_from: # default: n/a | required: false
- <string>
# Add Dockerfile instructions while root with system packages available — e.g. compile native libraries or install tools that need those packages
after_packages: # default: n/a | required: false
- <string>
# Add Dockerfile instructions while root with the claude user created — e.g. set up directories, fix permissions, or configure services
after_user_setup: # default: n/a | required: false
- <string>
# Add Dockerfile instructions as the claude user — e.g. install dotfiles, configure your shell, or set up user-level tools
after_user_switch: # default: n/a | required: false
- <string>
# Add Dockerfile instructions as the claude user with Claude Code available — e.g. add MCP servers, install plugins, or extensions
after_claude_install: # default: n/a | required: false
- <string>
# Add Dockerfile instructions at the very end — e.g. final environment tweaks or cleanup that must happen after everything else
before_entrypoint: # default: n/a | required: false
- <string>
agent:
# Load environment variables from .env-style files (e.g. .env.local)
env_file: # default: n/a | required: false
- <string>
# Pass specific host env vars into the container (e.g. AWS_PROFILE, GITHUB_TOKEN)
from_env: # default: n/a | required: false
- <string>
# Set container env vars directly; use from_env to forward host values instead
env: # default: n/a | required: false
<key>: <value>
# Editor for git commits and interactive editing inside the container
editor: <string> # default: n/a | required: false
# Visual editor ($VISUAL) for the container
visual: <string> # default: n/a | required: false
claude_code:
config:
# How to initialize Claude Code config: copy syncs host settings/plugins, fresh starts clean
strategy: <string> # default: copy | required: false
# Let the container use your host API keys so you don't have to re-authenticate
use_host_auth: <boolean> # default: true | required: false
# Share files between host and container via ~/.clawker-share (read-only in container)
enable_shared_dir: <boolean> # default: false | required: false
# Shell commands run after container starts but before Claude Code launches (e.g. install MCP servers)
post_init: <string> # default: n/a | required: false
workspace:
# bind mounts your project live (edits sync); snapshot copies it (isolated, disposable)
default_mode: <string> # default: bind | required: true
security:
firewall:
# Shorthand: domains the container can reach over HTTPS (converted to TLS rules)
add_domains: # default: n/a | required: false
- <string>
# Full egress rules with protocol, port, and path control
rules:
# Domain or IP the container needs to reach (e.g. api.github.com, registry.npmjs.org)
- dst: <string> # default: n/a | required: false
# Connection protocol: tls (HTTPS, default), tcp (plain), or http (MITM-inspected)
proto: <string> # default: n/a | required: false
# Override the default port (443 for TLS, 80 for HTTP)
port: <integer> # default: n/a | required: false
# Allow or deny traffic to this destination (default: allow)
action: <string> # default: n/a | required: false
# Fine-grained HTTP path filtering when proto is http (requires MITM inspection)
path_rules: # default: n/a | required: false
# URL path prefix to match (e.g. /v1/api, /repos/myorg)
- path: <string> # default: n/a | required: false
# Whether to allow or deny requests matching this path
action: <string> # default: n/a | required: false
# What to do with HTTP paths that don't match any path rule (allow or deny)
path_default: <string> # default: n/a | required: false
# Mount the host Docker socket (DooD, not DinD) — lets the container manage sibling containers but is a security risk
docker_socket: <boolean> # default: false | required: true
# Linux capabilities granted to the container; NET_ADMIN and NET_RAW are required — removing them will break the firewall
cap_add: # default: NET_ADMIN,NET_RAW | required: false
- <string>
# Run a proxy for browser-based auth flows and credential forwarding from the host
enable_host_proxy: <boolean> # default: true | required: false
git_credentials:
# Let git clone/push use your host HTTPS credentials (via host proxy)
forward_https: <boolean> # default: true | required: false
# Let git use your host SSH keys for cloning and pushing
forward_ssh: <boolean> # default: true | required: false
# Let git sign commits using your host GPG keys
forward_gpg: <boolean> # default: true | required: false
# Sync your host .gitconfig (aliases, user.name, user.email) into the container
copy_git_config: <boolean> # default: true | required: false
loop:
# Hard cap on iterations to prevent runaway loops
max_loops: <integer> # default: n/a | required: false
# Stop early if this many consecutive loops make no progress
stagnation_threshold: <integer> # default: n/a | required: false
# Kill the loop after this long regardless of progress
timeout_minutes: <integer> # default: n/a | required: false
# Throttle API calls to control cost
calls_per_hour: <integer> # default: n/a | required: false
# Quality score at which the task is considered done
completion_threshold: <integer> # default: n/a | required: false
# Discard loop state after this many hours of inactivity
session_expiration_hours: <integer> # default: n/a | required: false
# Stop if the same error repeats this many times (stuck in a loop)
same_error_threshold: <integer> # default: n/a | required: false
# Stop if output quality drops by this amount between iterations
output_decline_threshold: <integer> # default: n/a | required: false
# Stop if the agent only runs tests for this many loops without code changes
max_consecutive_test_loops: <integer> # default: n/a | required: false
# Pause between iterations (e.g. to avoid rate limits)
loop_delay_seconds: <integer> # default: n/a | required: false
# Minimum safety score required before marking a task complete
safety_completion_threshold: <integer> # default: n/a | required: false
# Run Claude Code with --dangerously-skip-permissions for fully autonomous loops
skip_permissions: <boolean> # default: n/a | required: false
# Script called on loop events (start, complete, error) for custom integrations
hooks_file: <string> # default: n/a | required: false
# Extra instructions appended to Claude's system prompt in each loop iteration
append_system_prompt: <string> # default: n/a | required: false
Project Configuration Reference
The following tables are auto-generated from the schema struct tags in internal/config/schema.go. Each section corresponds to a top-level key in .clawker.yaml.
build
| Field | Type | Default | Description |
|---|
image | string | — | Starting Docker image (e.g. node:20-slim, python:3.12); clawker layers tools on top |
dockerfile | string | — | Use your own Dockerfile instead of clawker’s generated one; ignores image, packages, and instructions |
packages | string list | ripgrep | System packages (apt/apk) needed by your project that aren’t in the base image |
context | string | — | Directory to use as Docker build context when using a custom Dockerfile (relative to project root) |
instructions
| Field | Type | Default | Description |
|---|
copy | object list | — | Bake config files or credentials into the image (e.g. .npmrc, SSH config) |
env | key-value map | — | Environment variables baked into the image; use agent.env for runtime-only vars |
labels | key-value map | — | Custom Docker labels for image metadata or tooling integration |
args | object list | — | Build-time variables resolved during docker build (ARG); not available at runtime |
user_run | string list | — | Setup commands that run as the container user (e.g. npm install -g, pip install) |
root_run | string list | — | Setup commands that need root privileges (e.g. system config, additional repos) |
inject
| Field | Type | Default | Description |
|---|
after_from | string list | — | Add Dockerfile instructions while root with only the base image — e.g. apt sources, proxy config, or CA certs that package installation depends on |
after_packages | string list | — | Add Dockerfile instructions while root with system packages available — e.g. compile native libraries or install tools that need those packages |
after_user_setup | string list | — | Add Dockerfile instructions while root with the claude user created — e.g. set up directories, fix permissions, or configure services |
after_user_switch | string list | — | Add Dockerfile instructions as the claude user — e.g. install dotfiles, configure your shell, or set up user-level tools |
after_claude_install | string list | — | Add Dockerfile instructions as the claude user with Claude Code available — e.g. add MCP servers, install plugins, or extensions |
before_entrypoint | string list | — | Add Dockerfile instructions at the very end — e.g. final environment tweaks or cleanup that must happen after everything else |
agent
| Field | Type | Default | Description |
|---|
env_file | string list | — | Load environment variables from .env-style files (e.g. .env.local) |
from_env | string list | — | Pass specific host env vars into the container (e.g. AWS_PROFILE, GITHUB_TOKEN) |
env | key-value map | — | Set container env vars directly; use from_env to forward host values instead |
editor | string | — | Editor for git commits and interactive editing inside the container |
visual | string | — | Visual editor ($VISUAL) for the container |
enable_shared_dir | boolean | false | Share files between host and container via ~/.clawker-share (read-only in container) |
post_init | string | — | Shell commands run after container starts but before Claude Code launches (e.g. install MCP servers) |
claude_code
| Field | Type | Default | Description |
|---|
strategy | string | copy | How to initialize Claude Code config: copy syncs host settings/plugins, fresh starts clean |
use_host_auth | boolean | true | Let the container use your host API keys so you don’t have to re-authenticate |
workspace
| Field | Type | Default | Description |
|---|
default_mode | string | bind | bind mounts your project live (edits sync); snapshot copies it (isolated, disposable) (required) |
security
| Field | Type | Default | Description |
|---|
docker_socket | boolean | false | Mount the host Docker socket (DooD, not DinD) — lets the container manage sibling containers but is a security risk (required) |
cap_add | string list | NET_ADMIN,NET_RAW | Linux capabilities granted to the container; NET_ADMIN and NET_RAW are required — removing them will break the firewall |
enable_host_proxy | boolean | true | Run a proxy for browser-based auth flows and credential forwarding from the host |
firewall
| Field | Type | Default | Description |
|---|
add_domains | string list | — | Shorthand: domains the container can reach over HTTPS (converted to TLS rules) |
rules | object list | — | Full egress rules with protocol, port, and path control |
git_credentials
| Field | Type | Default | Description |
|---|
forward_https | boolean | true | Let git clone/push use your host HTTPS credentials (via host proxy) |
forward_ssh | boolean | true | Let git use your host SSH keys for cloning and pushing |
forward_gpg | boolean | true | Let git sign commits using your host GPG keys |
copy_git_config | boolean | true | Sync your host .gitconfig (aliases, user.name, user.email) into the container |
loop
| Field | Type | Default | Description |
|---|
max_loops | integer | — | Hard cap on iterations to prevent runaway loops |
stagnation_threshold | integer | — | Stop early if this many consecutive loops make no progress |
timeout_minutes | integer | — | Kill the loop after this long regardless of progress |
calls_per_hour | integer | — | Throttle API calls to control cost |
completion_threshold | integer | — | Quality score at which the task is considered done |
session_expiration_hours | integer | — | Discard loop state after this many hours of inactivity |
same_error_threshold | integer | — | Stop if the same error repeats this many times (stuck in a loop) |
output_decline_threshold | integer | — | Stop if output quality drops by this amount between iterations |
max_consecutive_test_loops | integer | — | Stop if the agent only runs tests for this many loops without code changes |
loop_delay_seconds | integer | — | Pause between iterations (e.g. to avoid rate limits) |
safety_completion_threshold | integer | — | Minimum safety score required before marking a task complete |
skip_permissions | boolean | — | Run Claude Code with —dangerously-skip-permissions for fully autonomous loops |
hooks_file | string | — | Script called on loop events (start, complete, error) for custom integrations |
append_system_prompt | string | — | Extra instructions appended to Claude’s system prompt in each loop iteration |
Interactive Editing
Instead of editing YAML by hand, you can use Clawker’s built-in interactive editor:
# Edit project configuration (.clawker.yaml)
clawker project edit
# Edit user settings (settings.yaml)
clawker settings edit
The editor opens a TUI with your configuration fields grouped into tabs. You can browse fields, see their current values and defaults, edit them inline, and save. When you save a field, you choose which config layer to write it to — for example, saving to a local override file instead of the committed project config. The editor also shows which file each value comes from, so you can see exactly how the layered merge is working.
User Settings Schema
The complete settings.yaml schema.
logging:
# Write structured logs to disk for debugging and diagnostics
file_enabled: <boolean> # default: true | required: false
# Rotate the log file when it exceeds this size
max_size_mb: <integer> # default: 50 | required: false
# Delete rotated logs older than this
max_age_days: <integer> # default: 7 | required: false
# Number of rotated log files to keep
max_backups: <integer> # default: 3 | required: false
# Gzip rotated logs to save disk space
compress: <boolean> # default: true | required: false
otel:
# Send logs to the OTEL collector for Grafana/Loki visibility
enabled: <boolean> # default: true | required: false
# Give up on an export batch after this long
timeout_seconds: <integer> # default: 5 | required: false
# Buffer this many log records before dropping (increase if you see gaps)
max_queue_size: <integer> # default: 2048 | required: false
# How often to flush buffered logs to the collector
export_interval_seconds: <integer> # default: 5 | required: false
monitoring:
# Override the auto-detected OTEL collector URL (e.g. for a remote collector)
otel_collector_endpoint: <string> # default: n/a | required: false
# Host port for the OTEL HTTP receiver
otel_collector_port: <integer> # default: 4318 | required: false
# Hostname for reaching the collector from the host
otel_collector_host: <string> # default: localhost | required: false
# Docker network hostname containers use to reach the collector
otel_collector_internal: <string> # default: otel-collector | required: false
# Host port for the OTEL gRPC receiver
otel_grpc_port: <integer> # default: 4317 | required: false
# Host port for Loki log ingestion
loki_port: <integer> # default: 3100 | required: false
# Host port for Prometheus metrics UI
prometheus_port: <integer> # default: 9090 | required: false
# Host port for Jaeger tracing UI
jaeger_port: <integer> # default: 16686 | required: false
# Host port for Grafana dashboards
grafana_port: <integer> # default: 3000 | required: false
# Host port for Prometheus internal metrics
prometheus_metrics_port: <integer> # default: 8889 | required: false
telemetry:
# OTEL collector HTTP path for metrics
metrics_path: <string> # default: /v1/metrics | required: false
# OTEL collector HTTP path for logs
logs_path: <string> # default: /v1/logs | required: false
# How often Claude exports metrics (lower = more granular, higher = less overhead)
metric_export_interval_ms: <integer> # default: 10000 | required: false
# How often Claude exports logs (lower = more real-time, higher = less overhead)
logs_export_interval_ms: <integer> # default: 5000 | required: false
# Capture full tool call inputs/outputs in telemetry (verbose but useful for debugging)
log_tool_details: <boolean> # default: true | required: false
# Capture user prompts in telemetry (disable for privacy)
log_user_prompts: <boolean> # default: true | required: false
# Tag telemetry with your Anthropic account ID (useful for multi-user setups)
include_account_uuid: <boolean> # default: true | required: false
# Tag telemetry with session ID to correlate events across a single run
include_session_id: <boolean> # default: true | required: false
host_proxy:
manager:
# Local port the host proxy listens on (change if 18374 conflicts)
port: <integer> # default: 18374 | required: false
daemon:
# Local port the proxy daemon binds to
port: <integer> # default: 18374 | required: false
# How often to check if containers still need the proxy
poll_interval: <duration> # default: 30s | required: false
# How long to keep the proxy alive after the last container stops
grace_period: <duration> # default: 60s | required: false
# Restart the proxy daemon after this many consecutive failures
max_consecutive_errs: <integer> # default: 10 | required: false
firewall:
# Master switch for the Envoy firewall; when off, containers have unrestricted network access
enable: <boolean> # default: true | required: true
User Settings Reference
Global settings live at ~/.config/clawker/settings.yaml. The following tables are auto-generated from the schema struct tags.
logging
| Field | Type | Default | Description |
|---|
file_enabled | boolean | true | Write structured logs to disk for debugging and diagnostics |
max_size_mb | integer | 50 | Rotate the log file when it exceeds this size |
max_age_days | integer | 7 | Delete rotated logs older than this |
max_backups | integer | 3 | Number of rotated log files to keep |
compress | boolean | true | Gzip rotated logs to save disk space |
otel
| Field | Type | Default | Description |
|---|
enabled | boolean | true | Send logs to the OTEL collector for Grafana/Loki visibility |
timeout_seconds | integer | 5 | Give up on an export batch after this long |
max_queue_size | integer | 2048 | Buffer this many log records before dropping (increase if you see gaps) |
export_interval_seconds | integer | 5 | How often to flush buffered logs to the collector |
monitoring
| Field | Type | Default | Description |
|---|
otel_collector_endpoint | string | — | Override the auto-detected OTEL collector URL (e.g. for a remote collector) |
otel_collector_port | integer | 4318 | Host port for the OTEL HTTP receiver |
otel_collector_host | string | localhost | Hostname for reaching the collector from the host |
otel_collector_internal | string | otel-collector | Docker network hostname containers use to reach the collector |
otel_grpc_port | integer | 4317 | Host port for the OTEL gRPC receiver |
loki_port | integer | 3100 | Host port for Loki log ingestion |
prometheus_port | integer | 9090 | Host port for Prometheus metrics UI |
jaeger_port | integer | 16686 | Host port for Jaeger tracing UI |
grafana_port | integer | 3000 | Host port for Grafana dashboards |
prometheus_metrics_port | integer | 8889 | Host port for Prometheus internal metrics |
telemetry
| Field | Type | Default | Description |
|---|
metrics_path | string | /v1/metrics | OTEL collector HTTP path for metrics |
logs_path | string | /v1/logs | OTEL collector HTTP path for logs |
metric_export_interval_ms | integer | 10000 | How often Claude exports metrics (lower = more granular, higher = less overhead) |
logs_export_interval_ms | integer | 5000 | How often Claude exports logs (lower = more real-time, higher = less overhead) |
log_tool_details | boolean | true | Capture full tool call inputs/outputs in telemetry (verbose but useful for debugging) |
log_user_prompts | boolean | true | Capture user prompts in telemetry (disable for privacy) |
include_account_uuid | boolean | true | Tag telemetry with your Anthropic account ID (useful for multi-user setups) |
include_session_id | boolean | true | Tag telemetry with session ID to correlate events across a single run |
host_proxy
manager
| Field | Type | Default | Description |
|---|
port | integer | 18374 | Local port the host proxy listens on (change if 18374 conflicts) |
daemon
| Field | Type | Default | Description |
|---|
port | integer | 18374 | Local port the proxy daemon binds to |
poll_interval | duration | 30s | How often to check if containers still need the proxy |
grace_period | duration | 60s | How long to keep the proxy alive after the last container stops |
max_consecutive_errs | integer | 10 | Restart the proxy daemon after this many consecutive failures |
firewall
| Field | Type | Default | Description |
|---|
enable | boolean | true | Master switch for the Envoy firewall; when off, containers have unrestricted network access (required) |
You can also place a clawker.yaml in ~/.config/clawker/ to set user-level project config defaults. This file is merged as the lowest-priority project config layer (just above built-in defaults), so any project-level .clawker.yaml overrides it.
Directory Structure
Clawker follows the XDG Base Directory Specification. Files are organized across three directories:
| Directory | Default Path | Contents |
|---|
| Config | ~/.config/clawker/ | settings.yaml, clawker.yaml (user-level project overrides) |
| Data | ~/.local/share/clawker/ | registry.yaml, worktree directories, .clawker-share |
| State | ~/.local/state/clawker/ | Log files, PID files, loop sessions, update cache |
Override with environment variables: CLAWKER_CONFIG_DIR, CLAWKER_DATA_DIR, CLAWKER_STATE_DIR.