Arkloop Developers

Deployment Guide

Arkloop orchestrates all services via compose.yaml, enabling a full deployment with a single command.

Service Overview

ServiceDescriptionDefault Port
postgresPostgreSQL 165432
pgbouncerOptional connection pool5433
redisCache/Queue6379
redis_gatewayOptional performance optimization: Gateway hot-path Redis cache
seaweedfsOptional S3-compatible object storage9000
migrateDatabase Migrations (One-time, exits after completion)
apiControl Plane API (Go)19001
gatewayReverse Proxy + Rate Limiting19000
workerJob Worker (Agent Execution Plane)
sandboxCode Sandbox (Firecracker / Docker)19002
openvikingVector Memory Service19010

The default startup order is kept by depends_on: postgres → migrate → api/worker, redis → api/gateway/worker. Optional profiles add pgbouncer, redis_gateway (optional performance optimization: Gateway hot-path cache), and seaweedfs only when you ask for them.

Quick Start

1. Prepare Environment Variables

cp .env.example .env

Edit .env and set at least the following required fields:

VariableDescription
ARKLOOP_POSTGRES_PASSWORDPostgreSQL Password
ARKLOOP_AUTH_JWT_SECRETJWT Signing Secret (at least 32 characters)
ARKLOOP_ENCRYPTION_KEYAES-256-GCM Key (32-byte hex)
ARKLOOP_STORAGE_BACKENDStorage backend, defaults to filesystem
ARKLOOP_STORAGE_ROOTLocal storage root directory

Generate secure keys:

# JWT Secret (at least 32 characters)
openssl rand -base64 48
 
# Encryption Key (32-byte hex)
openssl rand -hex 32

2. Start All Services

docker compose up -d

The default compose stack now connects directly to postgres and redis, and uses local filesystem storage, which fits single-node deployments. If you want the optional performance layer, set ARKLOOP_DOCKER_DATABASE_URL or ARKLOOP_DOCKER_GATEWAY_REDIS_URL in .env first, then run docker compose --profile performance up -d. If you switch to SeaweedFS or another S3-compatible backend, set ARKLOOP_STORAGE_BACKEND=s3 and run docker compose --profile s3 up -d seaweedfs.

The migrate service will automatically run migrations before api/worker starts and then exit. Check startup status:

docker compose ps

3. Access Services

EndpointDescription
http://localhost:19000Public entry point (with Gateway rate limiting/auth)

Internal services stay on the Docker network by default. If you need host-level debugging ports, start with the development override file:

docker compose -f compose.yaml -f compose.dev.yaml up -d

Platform Administrator Initialization

On initial deployment, you can bootstrap a platform_admin user via an environment variable (one-time).

Steps:

  1. Register / log in with an account
  2. Call GET /v1/auth/me to get the id
  3. Set in .env:
ARKLOOP_BOOTSTRAP_PLATFORM_ADMIN=<user_id>

Then restart the api service.

Tool Providers (Optional)

Tools like web_search and web_fetch require backend Provider and credential configuration.

Recommended approach (Universal for SaaS / Self-hosting):

  • Log into Console using the bootstrap platform_admin.
  • Configure Tool Providers with scope=platform as global defaults.
  • For individual tenant customization, override with scope=org.

Compatibility mode (Local quick start only):

  • Configure legacy web_search.* / web_fetch.* via environment variables (e.g., ARKLOOP_WEB_SEARCH_PROVIDER, ARKLOOP_WEB_SEARCH_TAVILY_API_KEY).

View Logs

# All services
docker compose logs -f
 
# Specific service
docker compose logs -f api
docker compose logs -f worker
docker compose logs -f gateway

Redeploy (After Code Update)

docker compose build api worker gateway
docker compose up -d

Migrations will automatically re-run before api starts. To force a manual migration run:

docker compose run --rm migrate up

Stop / Clean Up

# Stop, keep data
docker compose down
 
# Stop and remove volumes (reset database)
docker compose down -v

Sandbox rootfs Build

The Sandbox service uses Firecracker microVMs for user code execution, requiring a pre-built rootfs ext4 image.

Build rootfs

cd src/services/sandbox/rootfs
./build.sh

Build artifacts are output to src/services/sandbox/rootfs/output/python3.12.ext4.

Deploy to Target Machine

DEPLOY_HOST=user@host ./build.sh

Default deployment path is /opt/sandbox/rootfs/, override via DEPLOY_PATH.

Pre-installed Environment

CategoryContent
Python 3.12numpy, pandas, matplotlib, scipy, sympy, pillow, scikit-learn, requests, httpx, beautifulsoup4, lxml, openpyxl, pyyaml, rich
Node.js 20node, npm, npx
System Toolsbusybox, curl, git, jq, sqlite3

Modify pre-installed content: edit src/services/sandbox/rootfs/Dockerfile.python3.12 and rebuild.

Sandbox Deployment

Sandbox supports two backend Providers, switched via sandbox.provider configuration (or ARKLOOP_SANDBOX_PROVIDER environment variable).

Firecracker Mode (Default)

Linux + KVM environment, using microVM isolation:

docker compose --profile firecracker up -d sandbox

Requires /dev/kvm device and Firecracker binary.

Run it with least privilege; privileged is no longer required.

Docker Mode

macOS / Windows (WSL2) / No KVM environment, using Docker container isolation:

# Point to a user-scoped Docker socket
export ARKLOOP_SANDBOX_DOCKER_SOCKET_PATH=/run/user/1000/docker.sock
 
# Start
docker compose --profile docker-sandbox up -d sandbox-docker

Compose will build the local sandbox-agent image from src/services/sandbox/Dockerfile.agent and tag it as arkloop/sandbox-agent:dev by default.

On Linux, prefer the rootless Docker user socket. On macOS / Windows Docker Desktop, use the socket under the user's home directory instead of the system-level /var/run/docker.sock.

sandbox-docker itself stays on the Compose networks, while spawned sandbox-agent containers join the internal arkloop_sandbox_agent network. Host networking is not used.

Local Development (Direct Run)

cd src/services/sandbox
go build -o sandbox-bin ./cmd/sandbox
 
# Docker Mode
ARKLOOP_SANDBOX_PROVIDER=docker \
DOCKER_HOST=unix:///run/user/1000/docker.sock \
ARKLOOP_SANDBOX_SOCKET_DIR=/tmp/sandbox \
ARKLOOP_SANDBOX_TEMPLATES_PATH="" \
./sandbox-bin

Sandbox Configuration

Runtime parameters are configured via Console > Configuration > Sandbox page (written to platform_settings table), or can be overridden with environment variables:

Config KeyEnv VarDefaultDescription
sandbox.providerARKLOOP_SANDBOX_PROVIDERfirecrackerBackend type
sandbox.allow_egressARKLOOP_SANDBOX_ALLOW_EGRESStrueWhether Sandbox backends may access the public network
sandbox.docker_imageARKLOOP_SANDBOX_DOCKER_IMAGEarkloop/sandbox-agent:devDocker agent image used for local Docker backend runs
sandbox.max_sessionsARKLOOP_SANDBOX_MAX_SESSIONS50Max concurrent sessions
sandbox.boot_timeout_sARKLOOP_SANDBOX_BOOT_TIMEOUT_S30Boot timeout (seconds)
sandbox.warm_liteARKLOOP_SANDBOX_WARM_LITE3Pre-warmed lite instances
sandbox.warm_proARKLOOP_SANDBOX_WARM_PRO2Pre-warmed pro instances
sandbox.warm_ultraARKLOOP_SANDBOX_WARM_ULTRA1Pre-warmed ultra instances
sandbox.idle_timeout_lite_sARKLOOP_SANDBOX_IDLE_TIMEOUT_LITE_S180Lite idle timeout (seconds)
sandbox.idle_timeout_pro_sARKLOOP_SANDBOX_IDLE_TIMEOUT_PRO_S300Pro idle timeout (seconds)
sandbox.idle_timeout_ultra_sARKLOOP_SANDBOX_IDLE_TIMEOUT_ULTRA_S600Ultra idle timeout (seconds)
sandbox.max_lifetime_sARKLOOP_SANDBOX_MAX_LIFETIME_S1800Max lifetime (seconds)

Deployment-level parameters (ENV only, not in Console):

VariableDefaultDescription
ARKLOOP_SANDBOX_ADDR0.0.0.0:19002Service listener address
ARKLOOP_FIRECRACKER_BIN/usr/bin/firecrackerFirecracker binary path
ARKLOOP_SANDBOX_KERNEL_IMAGE/opt/sandbox/vmlinuxKernel image path
ARKLOOP_SANDBOX_ROOTFS/opt/sandbox/rootfs.ext4rootfs path
ARKLOOP_SANDBOX_SOCKET_DIR/run/sandboxTemp file directory
ARKLOOP_SANDBOX_TEMPLATES_PATH/opt/sandbox/templates.jsonTemplate file path
ARKLOOP_SANDBOX_EGRESS_INTERFACEeth0Firecracker NAT uplink interface
ARKLOOP_SANDBOX_FIRECRACKER_TAP_PREFIXarktapFirecracker TAP name prefix
ARKLOOP_SANDBOX_FIRECRACKER_TAP_CIDR172.29.0.0/16Firecracker TAP address pool
ARKLOOP_SANDBOX_FIRECRACKER_DNS1.1.1.1,8.8.8.8Firecracker guest DNS servers
ARKLOOP_SANDBOX_DOCKER_SOCKET_PATH-Required for the docker-sandbox profile; path to the host user-scoped Docker socket

Local Development Mode

During development, you typically run the API on the host machine (for debugging/hot-reloading) while infrastructure runs in Docker:

# Start the minimal infrastructure only
docker compose -f compose.yaml -f compose.dev.yaml up -d postgres redis
 
# Optional performance layer
docker compose -f compose.yaml -f compose.dev.yaml --profile performance up -d pgbouncer redis_gateway
 
# Optional object storage
docker compose -f compose.yaml -f compose.dev.yaml --profile s3 up -d seaweedfs
 
# Run migrations
cd src/services/api
ARKLOOP_LOAD_DOTENV=1 ARKLOOP_DOTENV_FILE=../../.env go run ./cmd/migrate up
 
# Run API on host
ARKLOOP_LOAD_DOTENV=1 ARKLOOP_DOTENV_FILE=../../.env go run ./cmd/api

If you need to use the Gateway, point upstream to the host:

ARKLOOP_GATEWAY_UPSTREAM=http://host.docker.internal:19001 docker compose -f compose.yaml -f compose.dev.yaml up -d gateway

Full Environment Variable Reference

Database

VariableDefaultDescription
ARKLOOP_DATABASE_URLMain connection string (points to PgBouncer in production)
ARKLOOP_DATABASE_DIRECT_URLDirect DSN (reserved for SSE LISTEN/NOTIFY)
ARKLOOP_POSTGRES_USERarkloop
ARKLOOP_POSTGRES_PASSWORDRequired
ARKLOOP_POSTGRES_DBarkloop
ARKLOOP_PGBOUNCER_POOL_SIZE200PgBouncer pool size
ARKLOOP_PGBOUNCER_MAX_CLIENT_CONN1000PgBouncer max client connections

Redis

VariableDefaultDescription
ARKLOOP_REDIS_URLRedis connection string
ARKLOOP_REDIS_PASSWORDarkloop_redis

Storage

VariableDefaultDescription
ARKLOOP_STORAGE_BACKENDfilesystemDefault for local deploys; use s3 for multi-node setups
ARKLOOP_STORAGE_ROOT/var/lib/arkloop/storageRoot directory for the filesystem backend

Object Storage (Optional SeaweedFS / S3-Compatible)

VariableDefaultDescription
ARKLOOP_S3_ENDPOINTEndpoint URL for the s3 backend
ARKLOOP_S3_ACCESS_KEYarkloop
ARKLOOP_S3_SECRET_KEYRequired for the s3 backend
ARKLOOP_S3_BUCKETarkloop
ARKLOOP_S3_REGIONus-east-1

Authentication & Encryption

VariableDefaultDescription
ARKLOOP_AUTH_JWT_SECRETRequired
ARKLOOP_AUTH_ACCESS_TOKEN_TTL_SECONDS900Access Token TTL
ARKLOOP_AUTH_REFRESH_TOKEN_TTL_SECONDS2592000Refresh Token TTL
ARKLOOP_ENCRYPTION_KEYAES-256-GCM key (Required)

API

VariableDefaultDescription
ARKLOOP_API_GO_ADDR0.0.0.0:19001Listener address (inside container)
ARKLOOP_API_PORT19001Host port mapping used by compose.dev.yaml
ARKLOOP_BOOTSTRAP_PLATFORM_ADMINPlatform admin user_id (UUID) for initial deployment

Gateway

VariableDefaultDescription
ARKLOOP_GATEWAY_UPSTREAMhttp://api:19001Upstream API address
ARKLOOP_GATEWAY_PORT19000Default public entry point
ARKLOOP_GATEWAY_TRUST_INCOMING_TRACE_ID0Whether to trust upstream X-Trace-Id
ARKLOOP_RATELIMIT_CAPACITY600Rate limit bucket capacity
ARKLOOP_RATELIMIT_RATE_PER_MINUTE300Replenishment rate per minute

Worker

VariableDefaultDescription
ARKLOOP_WORKER_CONCURRENCY4Worker concurrency level
ARKLOOP_WORKER_QUEUE_JOB_TYPESrun.executeJob types handled
ARKLOOP_TELEGRAM_BOT_API_BASE_URLhttps://api.telegram.orgTelegram Bot API base URL (Worker / Desktop: send, typing, reactions)
ARKLOOP_CHANNEL_MESSAGE_SEGMENT_DELAY_MS50Delay between long-message segments (ms)

Telegram channel

Inbound: API webhook; without a public URL, Desktop uses getUpdates polling and the same run / mw_channel_delivery path. In channels.config_json: telegram_typing_indicator (default true), telegram_reaction_emoji (empty disables; if set, reaction is applied to the inbound user message after successful delivery).

Debugging

VariableDefaultDescription
ARKLOOP_LLM_DEBUG_EVENTS0Write raw LLM chunks to run_events
ARKLOOP_TOOL_ALLOWLISTEmptyDeprecated compatibility flag; logged but does not gate runtime tools