Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/theonetrade/backtest-kit-minio-s3-docker/llms.txt

Use this file to discover all available pages before exploring further.

The project ships three Docker Compose files: one for the MinIO object store, one for Redis, and one for the main backtest-kit container that bundles your compiled strategy with the backtest-kit runtime. MinIO and Redis can be started independently (or reused from an existing deployment) — the main container connects to them via environment variables rather than Docker-managed networking, using host.docker.internal to cross the container-to-host boundary.

MinIO (docker/minio/docker-compose.yaml)

MinIO acts as the S3-compatible source of truth for all 16 persist adapters. Every candle, signal, log entry, and strategy snapshot is stored as an object in the backtest-kit bucket, automatically created on first start.
docker/minio/docker-compose.yaml
services:
  minio:
    image: docker.io/tripolskypetr/minio:2022
    ports:
      - '9000:9000'
      - '9001:9001'
    volumes:
      - './minio_data:/data'
    environment:
      - MINIO_ROOT_USER=minioadmin
      - MINIO_ROOT_PASSWORD=minioadmin
      - MINIO_DEFAULT_BUCKETS=backtest-kit
    restart: always
volumes:
  minio_data:
Key details:
PropertyValueNotes
Imagetripolskypetr/minio:2022Pre-configured MinIO build with bucket auto-creation support
S3 API port9000Used by minio.Client in src/config/minio.ts
Console port9001Browser-based management UI
Volume./minio_data:/dataAll object data is written here; survives container restarts
MINIO_ROOT_USERminioadminMust match CC_MINIO_ACCESSKEY in .env
MINIO_ROOT_PASSWORDminioadminMust match CC_MINIO_SECRETKEY in .env
MINIO_DEFAULT_BUCKETSbacktest-kitBucket is created automatically on first start
Restart policyalwaysContainer restarts on crash or host reboot
Start MinIO:
docker-compose -f docker/minio/docker-compose.yaml up -d
Once running, open the MinIO console at http://localhost:9001 and log in with minioadmin / minioadmin (or whatever credentials you set in the compose file). You should see the backtest-kit bucket listed under Buckets.

Redis (docker/redis/docker-compose.yaml)

Redis serves as the time-ordered index for the three entity types that need newest-first listings (Log, Notification, Storage). It does not store object bodies — only lightweight per-minute sets of object names that allow listNewest to walk backwards through time in O(limit) without scanning the S3 bucket.
docker/redis/docker-compose.yaml
version: '3.8'

services:
  redis:
    image: redis:7.4.1
    container_name: redis
    ports:
      - "6379:6379"
    environment:
      - REDIS_PASSWORD=mysecurepassword
    command: ["redis-server", "--requirepass", "mysecurepassword"]
    volumes:
      - ./redis_data:/data
    restart: always

volumes:
  redis_data:
Key details:
PropertyValueNotes
Imageredis:7.4.1Official Redis image, pinned to a specific version
Port6379Standard Redis port; must match CC_REDIS_PORT in .env
PasswordmysecurepasswordSet via --requirepass; must match CC_REDIS_PASSWORD in .env
Volume./redis_data:/dataPersists Redis RDB / AOF snapshots across restarts
Restart policyalwaysContainer restarts on crash or host reboot
Redis is started with --requirepass mysecurepassword in the command array. The REDIS_PASSWORD environment variable shown in the compose file is informational only — the actual authentication is enforced by the --requirepass flag passed to redis-server.
Start Redis:
docker-compose -f docker/redis/docker-compose.yaml up -d

Main backtest-kit container (docker-compose.yaml)

The root docker-compose.yaml runs the backtest-kit runtime with your compiled strategy. It mounts the entire project directory as /workspace inside the container, so any ./build/index.cjs you produce on the host is immediately available to the entrypoint without a rebuild.
docker-compose.yaml
version: '3.8'

services:
  backtest:
    image: tripolskypetr/backtest-kit
    platform: linux/amd64
    extra_hosts:
      - "host.docker.internal:host-gateway"
    container_name: backtest-kit-minio-s3-docker
    ports:
      - "60050:60050"
    restart: unless-stopped
    volumes:
      - ./:/workspace
    working_dir: /workspace
    environment:
      - MODE
      - STRATEGY_FILE
      - SYMBOL
      - STRATEGY
      - EXCHANGE
      - FRAME
      - UI
      - TELEGRAM
      - VERBOSE
      - NO_CACHE
      - NO_FLUSH
      - ENTRY
    env_file:
      - .env
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:60050/api/v1/health/health_check"]
      interval: 30s
      timeout: 10s
      retries: 3
Key details:
PropertyValueNotes
Imagetripolskypetr/backtest-kitOfficial backtest-kit container image
Platformlinux/amd64Explicit platform pin for Apple Silicon / ARM hosts
Web UI port60050Exposed when UI=1; open http://localhost:60050
Volume mount./:/workspaceFull project directory available inside the container
Working dir/workspaceAll relative paths (e.g. ./build/index.cjs) resolve here
env_file.envMinIO/Redis credentials loaded from .env at the project root
Health check/api/v1/health/health_checkPolled every 30s; container marked unhealthy after 3 failures
Restart policyunless-stoppedRestarts on crash but not when explicitly stopped with docker-compose down

Deploy commands

Pass MODE, ENTRY, and STRATEGY_FILE as environment variables on the command line. The UI=1 flag starts the web dashboard on port 60050.
MODE=backtest ENTRY=1 UI=1 STRATEGY_FILE=./build/index.cjs docker-compose up -d

npm scripts

The package.json includes convenience scripts that wrap the full deploy lifecycle:
# Build the strategy bundle, then start the container
npm run start:docker

# Stop and remove the container
npm run stop:docker

Health check

The container exposes a health endpoint that Docker polls automatically:
GET http://localhost:60050/api/v1/health/health_check
Check container status at any time with:
docker inspect --format='{{.State.Health.Status}}' backtest-kit-minio-s3-docker

Networking

The main backtest-kit container does not share a Docker network with the MinIO and Redis containers. Instead, it reaches them on the host machine via the host.docker.internal hostname:
extra_hosts:
  - "host.docker.internal:host-gateway"
This single line tells Docker to add an /etc/hosts entry inside the backtest-kit container that resolves host.docker.internal to the host’s gateway IP (the Docker bridge interface). The .env file then points the adapters at that address:
CC_MINIO_ENDPOINT=host.docker.internal
CC_REDIS_HOST=host.docker.internal
Platform behaviour summary:
Platformhost.docker.internal availability
Docker Desktop (macOS)Injected automatically — extra_hosts entry is redundant but harmless
Docker Desktop (Windows)Injected automatically — same as macOS
Docker Engine on LinuxRequires the extra_hosts: host-gateway entry; not injected by default
Remote infrastructure: If MinIO or Redis run on a different server (e.g. a dedicated storage host or a managed Redis service), override the endpoints in .env:
CC_MINIO_ENDPOINT=prod-minio.internal
CC_MINIO_PORT=9000
CC_MINIO_ACCESSKEY=<prod-access-key>
CC_MINIO_SECRETKEY=<prod-secret-key>

CC_REDIS_HOST=prod-redis.internal
CC_REDIS_PORT=6379
CC_REDIS_USER=default
CC_REDIS_PASSWORD=<prod-password>
The extra_hosts entry is still harmless in this case — the container simply won’t use host.docker.internal for infrastructure connections.
Volume persistenceBoth minio_data (in docker/minio/) and redis_data (in docker/redis/) are bind-mount volumes — data is written to the host filesystem under the respective docker/minio/minio_data and docker/redis/redis_data directories. This means all object data and Redis snapshots survive container restarts and upgrades. To wipe state and start fresh, stop the containers and delete the data directories manually before restarting.
Tailing logsAfter starting any of the three compose stacks, use docker-compose logs -f with the appropriate -f flag to follow container output in real time:
# Follow the main backtest-kit container
docker-compose logs -f

# Follow MinIO
docker-compose -f docker/minio/docker-compose.yaml logs -f

# Follow Redis
docker-compose -f docker/redis/docker-compose.yaml logs -f
The backtest-kit container emits structured log lines for every MinIO PUT/GET and Redis SADD operation when VERBOSE=1 is set, making it straightforward to trace adapter activity during a backtest run.

Build docs developers (and LLMs) love