Skip to main content
The Exchange platform is fully containerized, allowing you to run all services using Docker Compose. This guide covers both infrastructure-only and full containerized deployments.

Architecture overview

The platform consists of the following containerized services:
  • Router - REST API server (port 8080)
  • Engine - Order matching engine (port 8081)
  • WebSocket Stream - Real-time market data (port 4000)
  • Database Processor - Database operations (port 8083)
  • PostgreSQL - Persistent storage (port 5432)
  • Redis - Pub/sub and caching (port 6379)

Docker Compose files

The project includes two Docker Compose configurations:

docker-compose.yml

Runs infrastructure services (PostgreSQL and Redis):
docker/docker-compose.yml
version: "3"

services:
  db:
    container_name: exchange-postgres
    image: postgres
    command: -c 'max_connections=800'
    shm_size: 1gb
    restart: always
    ports:
      - "5000:5432"
    volumes:
      - ./postgres-data:/var/lib/postgresql/data

  redis:
    container_name: exchange-redis
    image: redis:6.2-alpine
    command: redis-server --save 20 1 --loglevel warning
    restart: always
    ports:
      - "6380:6379"
    volumes:
      - ./redis-data:/var/lib/redis/data

docker-compose-core.yml

Runs all application services (Router, Engine, WebSocket Stream, DB Processor):
docker/docker-compose-core.yml
version: "3"

services:
  router:
    container_name: exchange-router
    build:
      context: ..
      dockerfile: docker/Dockerfile.router
    restart: always
    ports:
      - "7000:8080"

  engine:
    container_name: exchange-engine
    build:
      context: ..
      dockerfile: docker/Dockerfile.engine
    restart: always
    ports:
      - "7001:8081"

  ws-stream:
    container_name: exchange-ws-stream
    build:
      context: ..
      dockerfile: docker/Dockerfile.ws-stream
    restart: always
    ports:
      - "7002:4000"

  db-processor:
    container_name: exchange-db-processor
    build:
      context: ..
      dockerfile: docker/Dockerfile.db-processor
    restart: always
    ports:
      - "7003:8083"

Quick start

1

Configure environment

Copy the example environment file for Docker:
cd docker
cp .env.example .env
The default configuration works for containerized deployment:
POSTGRES_HOST=exchange-postgres
POSTGRES_DB=exchange-db
POSTGRES_USER=root
POSTGRES_PASSWORD=root
POSTGRES_PORT=5432

SERVER_ADDR=0.0.0.0:8080
WS_STREAM_URL=0.0.0.0:4000

REDIS_URL=redis://exchange-redis:6379

PG__USER=root
PG__PASSWORD=root
PG__HOST=exchange-postgres
PG__PORT=5432
PG__DBNAME=exchange-db
PG__POOL_MAX_SIZE=16

DATABASE_URL=postgres://root:root@exchange-postgres:5432/exchange-db
2

Start infrastructure services

Start PostgreSQL and Redis:
docker compose -f docker-compose.yml up -d
Verify services are running:
docker ps
3

Build and start application services

Build and start all application services:
docker compose -f docker-compose-core.yml up
Or run in detached mode:
docker compose -f docker-compose-core.yml up -d

Using the convenience script

The project includes a helper script to manage both compose files:
docker/docker.sh
#!/bin/bash
docker compose -f docker-compose-core.yml down
docker compose -f docker-compose.yml down

docker compose -f docker-compose.yml up -d
docker compose -f docker-compose-core.yml up
Run it with:
cd docker
chmod +x docker.sh
./docker.sh

Port mappings

Infrastructure services

ContainerInternal PortExternal Port
exchange-postgres54325000
exchange-redis63796380

Application services

ContainerInternal PortExternal Port
exchange-router80807000
exchange-engine80817001
exchange-ws-stream40007002
exchange-db-processor80837003
Application services use external ports in the 7000 range to avoid conflicts with local development.

Dockerfiles

All services use multi-stage builds for optimized image sizes:

Build stage pattern

FROM rust:1.87-slim AS builder

WORKDIR /app
COPY . .

# Set SQLX to offline mode
ENV SQLX_OFFLINE=true

# Build the binary
RUN cargo build --release --bin <service-name>

Runtime stage pattern

FROM debian:bookworm-slim

WORKDIR /app

# Install runtime dependencies
RUN apt-get update && \
    apt-get install -y --no-install-recommends ca-certificates && \
    rm -rf /var/lib/apt/lists/*

# Copy the binary from builder
COPY --from=builder /app/target/release/<service-name> /app/<service-name>

# Set environment variables
ENV RUST_LOG=info

EXPOSE <port>

CMD ["/app/<service-name>"]

Resource limits

All services are configured with memory limits:
deploy:
  resources:
    limits:
      memory: 5G
Adjust memory limits based on your available system resources and expected load.

Volumes and data persistence

PostgreSQL data

Data is persisted in:
docker/postgres-data/

Redis data

Data is persisted in:
docker/redis-data/
These directories are created automatically and should be added to .gitignore.

Networking

Services communicate over a Docker bridge network named exchange:
networks:
  gateway:
    name: exchange
    external: false  # for infrastructure
    external: true   # for application services

Managing services

View logs

docker compose -f docker-compose-core.yml logs -f

Restart services

# Restart all services
docker compose -f docker-compose-core.yml restart

# Restart specific service
docker restart exchange-router

Stop services

# Stop application services
docker compose -f docker-compose-core.yml down

# Stop infrastructure
docker compose -f docker-compose.yml down

# Stop and remove volumes
docker compose -f docker-compose.yml down -v

Rebuild services

# Rebuild without cache
docker compose -f docker-compose-core.yml build --no-cache

# Rebuild and restart
docker compose -f docker-compose-core.yml up --build

Health checks

Check if services are healthy:
# Check all containers
docker ps

# Check specific service health
docker inspect exchange-router | grep Status

# Test PostgreSQL
docker exec -it exchange-postgres psql -U root -d exchange-db -c "SELECT 1;"

# Test Redis
docker exec -it exchange-redis redis-cli ping

Troubleshooting

Build failures

If Docker builds fail:
# Clean Docker build cache
docker builder prune -a

# Remove all containers and rebuild
docker compose -f docker-compose-core.yml down
docker compose -f docker-compose-core.yml build --no-cache

Network issues

If services can’t communicate:
# Recreate network
docker network rm exchange
docker compose -f docker-compose.yml up -d

# Inspect network
docker network inspect exchange

Container crashes

Check container logs for errors:
docker logs exchange-router
Verify environment variables:
docker exec -it exchange-router env

Next steps

Build docs developers (and LLMs) love