Skip to main content

Overview

NanoARB provides Docker configurations for both development and production deployments. The multi-stage Dockerfile is optimized for minimal latency and small image size, critical for high-frequency trading applications.

Container Architecture

The deployment uses a multi-stage build process:

Stage 1: Build Environment

Builds the Rust application with all necessary dependencies:
FROM rust:1.84-bookworm AS builder
Key optimizations:
  • Dependency caching: Copies Cargo.toml files first to cache dependency builds
  • Release build: Compiles with --release flag for maximum performance
  • Binary stripping: Removes debug symbols to reduce image size

Stage 2: Runtime Environment

Creates a minimal runtime container:
FROM debian:bookworm-slim AS runtime
Security features:
  • Runs as non-root user (nanoarb)
  • Only includes runtime dependencies (ca-certificates, libssl3)
  • Health check endpoint configured

Docker Compose Configurations

Full Stack Deployment

The docker-compose.yml file deploys the complete stack including monitoring:
services:
  nanoarb:      # Trading engine
  prometheus:   # Metrics collection
  grafana:      # Visualization dashboards
Key configuration details:
services:
  nanoarb:
    build:
      context: ..
      dockerfile: docker/Dockerfile
    container_name: nanoarb-engine
    restart: unless-stopped
    ports:
      - "9090:9090"  # Metrics endpoint
    volumes:
      - ./config.toml:/app/config.toml:ro
      - nanoarb-data:/app/data
      - nanoarb-logs:/app/logs
      - ../models:/app/models:ro
    environment:
      - RUST_LOG=info
      - RUST_BACKTRACE=1
    deploy:
      resources:
        limits:
          cpus: '4'
          memory: 4G
        reservations:
          cpus: '2'
          memory: 2G
Resource limits:
  • CPU: 2-4 cores reserved for consistent performance
  • Memory: 2-4GB allocated for order book and strategy state

Monitoring-Only Stack

For local development, use docker-compose-monitoring.yml to run only Prometheus and Grafana while running the trading engine natively:
docker compose -f docker/docker-compose-monitoring.yml up -d
This configuration:
  • Runs Prometheus on port 9091
  • Runs Grafana on port 3000
  • Scrapes metrics from host machine via host.docker.internal:9090

Setup Commands

Building the Image

# Build from source root
docker build -f docker/Dockerfile -t nanoarb:latest .
Build takes approximately 5-10 minutes on first run due to Rust dependency compilation. Subsequent builds leverage Docker layer caching.

Starting the Stack

cd docker
docker compose up -d
Starts all services in detached mode.

Viewing Logs

# View engine logs
docker compose logs -f nanoarb

# View all logs
docker compose logs -f

Checking Status

# Check container health
docker compose ps

# Check metrics endpoint
curl http://localhost:9090/metrics

# Check health endpoint
curl http://localhost:9090/health

Teardown Commands

Stop Services

# Stop all containers
docker compose down

# Stop and remove volumes (caution: deletes data)
docker compose down -v

Clean Up

# Remove dangling images
docker image prune

# Full cleanup (removes all unused containers, networks, images)
docker system prune -a

Volume Management

The deployment creates persistent volumes:
VolumePurposeLocation
nanoarb-dataMarket data and state/app/data
nanoarb-logsApplication logs/app/logs
prometheus-dataMetrics time-series/prometheus
grafana-dataDashboard configs/var/lib/grafana

Backup Volumes

# Backup data volume
docker run --rm -v nanoarb-data:/data -v $(pwd):/backup \
  alpine tar czf /backup/nanoarb-data.tar.gz -C /data .

Restore Volumes

# Restore data volume
docker run --rm -v nanoarb-data:/data -v $(pwd):/backup \
  alpine tar xzf /backup/nanoarb-data.tar.gz -C /data

Configuration

The default configuration is mounted from docker/config.toml:
name = "nanoarb"
log_level = "info"
metrics_port = 9090
data_dir = "/app/data"

[trading]
live_enabled = false
symbols = ["ESH24"]
initial_capital = 1000000.0
max_position = 50
max_order_size = 10
Configuration override:
# Use custom config
docker compose run -v ./my-config.toml:/app/config.toml nanoarb

Environment Variables

The container accepts these environment variables:
VariableDefaultDescription
RUST_LOGinfoLog level (debug, info, warn, error)
RUST_BACKTRACE1Enable stack traces on errors
PORT9090Metrics server port
NANOARB_CONFIG/app/config.tomlConfiguration file path

Networking

All services communicate via the nanoarb-network bridge network:
  • nanoarb: Exposes port 9090 for metrics
  • prometheus: Exposes port 9091 (mapped from 9090)
  • grafana: Exposes port 3000 for dashboards
Prometheus scrapes the trading engine at nanoarb:9090 when using the full stack, or host.docker.internal:9090 in monitoring-only mode.

Health Checks

The trading engine includes a health check that runs every 30 seconds:
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
    CMD curl -f http://localhost:${PORT:-9090}/health || exit 1
View health status:
docker inspect --format='{{.State.Health.Status}}' nanoarb-engine

Troubleshooting

Container Won’t Start

# Check logs
docker compose logs nanoarb

# Check container status
docker compose ps

# Inspect container
docker inspect nanoarb-engine

Port Conflicts

If ports are already in use, modify the port mappings in docker-compose.yml:
ports:
  - "9091:9090"  # Change host port to 9091

Memory Issues

Adjust memory limits if the container is killed:
deploy:
  resources:
    limits:
      memory: 8G  # Increase limit

Next Steps