Skip to main content

Overview

The Exness Trading Platform uses Docker Compose to orchestrate 13 services across 4 categories: infrastructure, backend services, data processors, and frontend applications.

Service Architecture

Infrastructure Services

These foundational services provide data storage and caching:
services:
  postgres:
    image: postgres:16-alpine
    container_name: exness-postgres
    ports:
      - "5434:5432"
  
  timescaledb:
    image: timescale/timescaledb:latest-pg16
    container_name: exness-timescaledb
    ports:
      - "5433:5432"
  
  redis:
    image: redis:7-alpine
    container_name: exness-redis
    ports:
      - "6379:6379"
  
  mongodb:
    image: mongo:7.0
    container_name: exness-mongodb
    ports:
      - "27017:27017"

Complete Service Overview

1

Infrastructure Layer

postgres
PostgreSQL 16
Primary database for user accounts, orders, and transactional data.
  • Port: 5434 (mapped from 5432)
  • Database: exness
  • Credentials: postgresql/postgresql
timescaledb
TimescaleDB with PG16
Time-series database for historical market data and candles.
  • Port: 5433 (mapped from 5432)
  • Database: mydb
  • Credentials: myuser/mypassword
redis
Redis 7
In-memory cache for real-time data streams and pub/sub.
  • Port: 6379
  • Use Cases: Price streams, WebSocket pub/sub, queue management
mongodb
MongoDB 7.0
Document store for account snapshots and backups.
  • Port: 27017
  • Database: exness_snapshots
  • Credentials: admin/admin123
2

Database Migration

db-migrate
One-time Service
Runs Prisma migrations before application services start.Execution Flow:
  1. Waits for PostgreSQL to be healthy
  2. Tests database connectivity
  3. Runs bun run db:deploy from packages/db
  4. Exits successfully
  5. Triggers dependent services to start
Restart Policy: no (runs once per compose up)
3

Core Backend Services

backend
Express.js API
REST API server for trading operations.
  • Port: 8000
  • Dependencies: PostgreSQL, TimescaleDB, Redis, db-migrate
  • Features: Authentication, balance management, trade execution
engine
In-Memory Trading Engine
High-performance order processing engine.
  • Dependencies: PostgreSQL, TimescaleDB, Redis, db-migrate
  • Features: Sub-millisecond order execution, real-time balance updates
websocket-server
WebSocket Server
Real-time communication hub for live market data.
  • Port: 7070
  • Dependencies: Redis
  • Protocol: WebSocket with Redis Pub/Sub backend
dbstorage
Database Persistence
Handles data persistence and retrieval operations.
  • Dependencies: PostgreSQL, Redis, db-migrate
  • Features: Transaction logging, order history, user data
4

Data Processing Services

price-poller
Market Data Ingestion
Fetches real-time market data from Binance WebSocket API.
  • Dependencies: Redis
  • Features: Live price streaming, bid/ask calculation, spread management
batch-upload
Historical Data Processor
Processes and stores historical market data in TimescaleDB.
  • Dependencies: TimescaleDB, Redis
  • Features: Candle generation, data compression, retention policies
snap-shotting
Snapshot Service
Creates periodic snapshots of account states.
  • Dependencies: MongoDB, Engine
  • Features: Account backups, historical state tracking
5

Frontend Applications

web
Next.js Trading Platform
Main trading interface with real-time market data.
  • Port: 3001
  • Dependencies: Backend, db-migrate
  • Features: Trading dashboard, TradingView charts, order management
docs
Documentation Site
Platform documentation and API reference.
  • Port: 3000
  • Framework: Mintlify
prisma-studio
Database GUI
Visual database management interface.

Service Dependencies

The platform enforces strict service startup ordering:

Network Configuration

All services communicate over a dedicated bridge network:
networks:
  exness-network:
    driver: bridge
Services reference each other by container name (e.g., postgres, redis) within the network. External access uses mapped ports on localhost.

Volume Management

Persistent data is stored in named volumes:
volumes:
  postgres_data:      # User accounts and orders
  timescaledb_data:   # Historical market data
  redis_data:         # Cache and streams
  mongodb_data:       # Account snapshots

Environment Variable Injection

Services receive configuration through multiple methods:
services:
  backend:
    env_file:
      - .env
    environment:
      REDIS_URL: redis://redis:6379
      DATABASE_URL: postgresql://postgresql:postgresql@postgres:5432/exness
Container-specific environment variables override .env file values. Database connection strings use internal service names within the Docker network.

Health Check Configuration

All infrastructure services include health checks:
healthcheck:
  test: ["CMD-SHELL", "pg_isready -U postgresql -d exness"]
  interval: 10s
  timeout: 5s
  retries: 5

Common Operations

Starting the Platform

# Start all services
docker compose up -d

# View logs
docker compose logs -f

Stopping Services

# Stop all services
docker compose down

# Stop specific service
docker compose stop backend

Viewing Logs

# Follow all logs
docker compose logs -f

# Last 100 lines
docker compose logs --tail=100

Scaling Services

# Scale price poller to 3 instances
docker compose up -d --scale price-poller=3

# Scale websocket server
docker compose up -d --scale websocket-server=2
Only stateless services without port mappings can be scaled. Services like backend and web with fixed port mappings cannot be scaled without additional configuration.

Service Restart Policies

restart: unless-stopped  # Most services
restart: "no"           # db-migrate only
  • unless-stopped: Automatically restarts unless manually stopped
  • no: Runs once and exits (used for migrations)

Troubleshooting

Check service dependencies and health status:
docker compose ps
docker compose logs <service-name>
Common issues:
  • Dependent service not healthy
  • Port already in use
  • Missing environment variables
Verify database services are healthy:
docker compose ps postgres timescaledb
docker compose exec postgres pg_isready -U postgresql
Check connection strings in environment variables.
View migration logs:
docker compose logs db-migrate
Manually run migrations:
docker compose run --rm db-migrate
Increase Docker resource limits or add memory limits to services:
services:
  backend:
    deploy:
      resources:
        limits:
          memory: 2G

Production Considerations

The default docker-compose.yml is configured for development. Production deployments should:
  • Use strong, unique passwords
  • Enable TLS/SSL for all connections
  • Configure proper backup strategies
  • Set resource limits for all services
  • Use external secrets management
  • Enable production logging and monitoring

Production Checklist

Change all default passwords
Configure volume backups
Enable container resource limits
Set up external monitoring
Configure log aggregation
Enable HTTPS for frontend services
Set up automated health checks
Configure database backups

Next Steps

Environment Variables

Configure all environment variables for your deployment

Database Setup

Learn about database schema and migrations

Build docs developers (and LLMs) love