This guide walks you through standing up the complete PostgreSQL + Redis + Pgpool-II stack and executing a strategy in backtest mode. By the end you will have a running Pgpool-II cluster (1 primary + 2 streaming replicas), a Redis instance, and a compiled strategy bundle running against real historical candle data — all wired to the 16 persist adapters without changing a single line of strategy code.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/backtest-kit/backtest-kit-redis-postgres-pgpool-docker/llms.txt
Use this file to discover all available pages before exploring further.
Prerequisites
Before starting, make sure the following are available on your machine:- Node.js 18+ — required to build and run the strategy bundle locally.
- Docker and Docker Compose — used to run PostgreSQL, Pgpool-II, and Redis.
Option A: Local Run (Host Node, Dockerized Infrastructure)
Run Node.js directly on your host while PostgreSQL, Pgpool-II, and Redis run in Docker. This is the fastest way to iterate on strategy code — rebuild and restart Node without touching the containers.Start the Pgpool-II cluster
This single command boots a full cluster: one primary PostgreSQL node and two streaming replicas, all fronted by Pgpool-II on port
5432.First boot takes approximately 60–90 seconds while the replica containers clone the primary’s data directory via
pg_basebackup. Wait for both replica containers to report healthy before proceeding.Start Redis
:6379 with password mysecurepassword. The O(1) ID cache layers on top of PostgreSQL automatically once the app connects.Configure environment variables
Copy the example environment file and review the connection strings:The defaults in
.env.example point to the Dockerized infrastructure using host.docker.internal:host.docker.internal resolves to the host machine from inside Docker containers. If your infrastructure runs on a remote host, replace these values with the appropriate hostnames or IP addresses.Build and run a backtest
npm run start compiles the TypeScript strategy bundle with Rollup before launching the @backtest-kit/cli runner.--entry flag activates the strategy entry point, --backtest selects backtest mode, and --ui enables the web dashboard.Option B: Full Docker Deploy
Bundle the strategy, runner, and@backtest-kit/cli into a single Docker Compose stack. Useful for CI, staging, or any environment where Node.js is not installed on the host.
Build the strategy bundle
The main
docker-compose.yaml mounts the project as /workspace inside the container, so the compiled bundle must exist before the container starts.Start everything with Docker Compose
Pass the mode and entry flags as environment variables:The
MODE variable accepts backtest, live, or paper. ENTRY=1 corresponds to the --entry CLI flag. UI=1 enables the web dashboard on :60050.Switching Modes
The same compiled bundle supports all three backtest-kit execution modes. Pass the appropriate flag to select the mode at runtime.What Happens on First Boot
When the app connects to a fresh PostgreSQL instance, TypeORM’ssynchronize: true setting inspects the registered entity schemas and issues the necessary CREATE TABLE and CREATE UNIQUE INDEX statements automatically.
No manual migration step is required. All 16 tables and their compound unique indexes are created on first connect. Re-running against an existing database is safe — TypeORM only applies the diff.
(symbol, strategyName, exchangeName) on signal-items) is also the conflict target for every atomic upsert, so the schema and the write logic stay in sync by construction.
Next Steps
Docker Layout
Understand the three Compose files (
pgpool, postgres, redis) and the main app Compose file, including how host.docker.internal bridges containers to host infrastructure.Environment Variables
Full reference for every environment variable consumed by the runner container and the CLI —
MODE, STRATEGY_FILE, ENTRY, UI, TELEGRAM, and the CC_* connection strings.Persistence Overview
Deep-dive into the 16 adapt adapter architecture: how the
BaseCRUD and BaseMap base classes work, the read path (Redis hit → Postgres PK lookup → cache backfill), and soft-delete tombstone semantics.Atomicity
Detailed explanation of the
INSERT … ON CONFLICT … DO UPDATE … RETURNING * pattern, why a follow-up SELECT is never issued, and how this satisfies backtest-kit’s write-durability contract across a real replica cluster.