Docker Deployment
July 12, 2026 · View on GitHub
Deploy InnoClaw with Docker in under 2 minutes.
Prerequisites
- Docker Engine 24+ and Docker Compose v2
- At least one AI API key (OpenAI, Anthropic, etc.)
Quick Start
git clone https://github.com/SpectrAI-Initiative/InnoClaw.git
cd InnoClaw
cp .env.production.example .env.production.local
# Edit .env.production.local — set at least one API key
docker compose up -d
Open http://localhost:3000.
Configuration
Environment Variables
Edit .env.production.local before starting. Key variables:
| Variable | Required | Description |
|---|---|---|
WORKSPACE_ROOTS | Yes | Comma-separated paths inside the container (e.g., /research) |
OPENAI_API_KEY | At least one AI key | OpenAI API key |
ANTHROPIC_API_KEY | Anthropic API key | |
DATABASE_URL | No | SQLite path (default: ./data/innoclaw.db) |
AUTH_MODE | No | Set to disabled only for trusted deployments that should bypass registration/login |
AUTH_SINGLE_ADMIN | No | Set to true to enforce one bootstrapped administrator and ordinary-user registration |
AUTH_COOKIE_SECURE | No | Defaults to true in production; use false only for a temporary plain-HTTP rollout |
AUTH_SECRET | Production | Long random value used to sign session cookies |
LLM_PROVIDER | No | Default provider (openai, anthropic, etc.) |
OPENAI_REASONING_EFFORT | No | OpenAI reasoning effort; ultra is normalized to xhigh |
See .env.production.example for the full list.
To run without application-level registration or login, set AUTH_MODE=disabled in .env.production.local before starting the container. Anyone who can reach the service gets admin-level access, so use it only behind trusted network access or another access-control layer.
Bootstrap a Single Administrator
For a public multi-user deployment, configure at least:
AUTH_MODE=local
AUTH_SINGLE_ADMIN=true
AUTH_COOKIE_SECURE=true
AUTH_SECRET=replace-with-a-long-random-secret
WORKSPACE_ROOTS=/research
Start the container so migrations complete, then create the sole administrator with a password supplied only through standard input:
umask 077
openssl rand -base64 32 > /tmp/innoclaw-admin-password
docker compose exec -T innoclaw node /app/admin-cli/scripts/bootstrap-admin.js \
--email admin@example.com --name Administrator \
< /tmp/innoclaw-admin-password
Store the generated password in your password manager and securely remove the temporary file after delivery. Re-running the same command is idempotent and does not rotate an existing administrator password. Bootstrap must finish before public registration becomes available. Registered users are always ordinary users and cannot promote themselves or another account.
For a temporary plain-HTTP rollout, set AUTH_COOKIE_SECURE=false so browsers
can send the session cookie. This does not encrypt credentials or traffic.
Move to HTTPS and restore AUTH_COOKIE_SECURE=true as soon as possible.
OpenAI-Compatible Reasoning
OPENAI_REASONING_EFFORT accepts none, minimal, low, medium, high,
and xhigh. The operator-friendly value ultra is normalized to xhigh
before OpenAI language-model calls. Omit the variable to retain the provider
default. The setting does not affect embeddings or non-OpenAI providers; verify
that a custom OpenAI-compatible endpoint supports the normalized value.
Volumes
| Container Path | Purpose | Compose Default |
|---|---|---|
/app/data | SQLite database, HF datasets, embeddings | Named volume innoclaw-data |
/research | Your workspace files | HOST_WORKSPACE_PATH env var or ./workspace |
In single-administrator mode, an ordinary user's effective root is provisioned
lazily at /research/users/<immutable-user-id> with private permissions. Users
can create and operate only their own workspaces. The administrator can view and
manage workspace records across the full /research operator root.
To expose multiple workspace directories, add more volume mounts in docker-compose.yml and update WORKSPACE_ROOTS accordingly:
volumes:
- innoclaw-data:/app/data
- /home/user/papers:/papers
- /home/user/code:/code
WORKSPACE_ROOTS=/papers,/code
Port
Default: 3000. Change in docker-compose.yml:
ports:
- "8080:3000"
Reverse Proxy
InnoClaw works behind any reverse proxy. Examples:
Nginx
limit_req_zone $binary_remote_addr zone=innoclaw_login:10m rate=10r/m;
limit_req_zone $binary_remote_addr zone=innoclaw_register:10m rate=1r/m;
server {
listen 443 ssl;
server_name innoclaw.example.com;
ssl_certificate /etc/ssl/certs/innoclaw.pem;
ssl_certificate_key /etc/ssl/private/innoclaw.key;
location = /api/auth/login {
limit_req zone=innoclaw_login burst=10 nodelay;
limit_req_status 429;
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location = /api/auth/register {
limit_req zone=innoclaw_register burst=2 nodelay;
limit_req_status 429;
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Caddy
innoclaw.example.com {
reverse_proxy localhost:3000
}
Caddy handles TLS automatically.
Persistent Data & Backups
All persistent state lives in the innoclaw-data volume:
innoclaw.db— SQLite database (notebooks, chat history, settings)hf-datasets/— cached HuggingFace datasets
Back up the database while the service is running:
docker compose exec -T innoclaw node -e \
'const Database=require("better-sqlite3");const db=new Database("/app/data/innoclaw.db");db.backup("/app/data/innoclaw.db.backup").then(()=>db.close())'
docker cp "$(docker compose ps -q innoclaw):/app/data/innoclaw.db.backup" ./backup.db
The online backup API includes committed WAL state. Also back up the root-readable environment file and reverse-proxy configuration, and retain the previous image until login, workspace isolation, and model inference smoke tests pass.
Upgrading
git pull
docker compose build
docker compose up -d
Database migrations run automatically on container startup — no manual steps needed. The canonical workspace-path preflight runs before the unique path index. If two legacy rows resolve to the same filesystem path, startup stops and reports the colliding workspace IDs instead of deleting or reassigning data.
Build from Scratch
docker build -t innoclaw .
docker run -d \
--name innoclaw \
-p 3000:3000 \
--env-file .env.production.local \
-v innoclaw-data:/app/data \
-v /path/to/your/research:/research \
innoclaw
Troubleshooting
| Issue | Fix |
|---|---|
/app/data is not writable | Ensure the Docker volume is mounted and the container user has write access |
workspace root missing | Mount your host directory in docker-compose.yml and match WORKSPACE_ROOTS |
no AI API key detected | Edit .env.production.local and set at least one valid API key |
drizzle-kit migrate failed | Usually harmless on first run; check that /app/data is writable |
| Container exits immediately | Run docker compose logs innoclaw to see the startup error |