Skip to main content
The Indicator Service ships with a Docker Compose configuration that brings up the full stack: the API service, MongoDB, and Redis. A companion docker-compose.override.yml adds RabbitMQ and a development data producer.
The default RabbitMQ credentials (guest/guest) must be changed before deploying to any environment accessible over a network. Set RABBITMQ_DEFAULT_USER, RABBITMQ_DEFAULT_PASS, and update RABBITMQ_URL accordingly.

Services

The docker-compose.yml defines three services:
docker-compose.yml
services:
  indicator-service:
    build: .
    container_name: indicator-service
    environment:
      - ORIGINS=${ORIGINS:-localhost}
      - REDIS_HOST=indicators-redis
      - REDIS_PORT=6379
      - MONGO_URI=mongodb://indicators-mongo/indicators
    restart: on-failure
    depends_on:
      indicators-mongo:
        condition: service_healthy
      indicators-redis:
        condition: service_started
    networks:
      - indicator-network
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health/"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 10s
    develop:
      watch:
        - action: sync
          path: ./app
          target: /app
          ignore:
            - __pycache__/
        - action: rebuild
          path: requirements.txt

  indicators-redis:
    image: "redis:alpine"
    container_name: indicators-redis
    networks:
      - indicator-network
    restart: on-failure

  indicators-mongo:
    image: "mongo:latest"
    container_name: indicators-mongo
    environment:
      MONGO_INITDB_DATABASE: indicators
    volumes:
      - indicators_db:/data/db
    networks:
      - indicator-network
    healthcheck:
      test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
      interval: 6s
      timeout: 5s
      retries: 5
      start_period: 6s
    restart: on-failure

networks:
  indicator-network:
    name: indicator-network

volumes:
  indicators_db:
ServiceImageRole
indicator-serviceBuilt from DockerfileFastAPI application
indicators-mongomongo:latestPrimary data store
indicators-redisredis:alpineCache layer

Health checks

The indicator-service polls http://localhost:8080/health/ every 10 seconds with a 5-second timeout and allows up to 3 retries before marking the container unhealthy. It also waits 10 seconds after startup before running the first check (start_period: 10s), giving uvicorn time to bind. MongoDB is checked with mongosh --eval "db.adminCommand('ping')"every 6 seconds (5-second timeout, up to 5 retries). The indicator-service will not start until MongoDB passes this check.

Volumes and networking

  • indicators_db — a named Docker volume that persists MongoDB data across container restarts and recreations. Removing this volume will permanently delete stored indicator data.
  • indicator-network — a bridge network shared by all services. Containers communicate using their service names as hostnames (e.g., indicators-mongo, indicators-redis).

Development override

docker-compose.override.yml is automatically merged when you run docker compose commands. It adds RabbitMQ and exposes the service port locally:
docker-compose.override.yml
services:
  indicator-service:
    environment:
      - RABBITMQ_URL=amqp://guest:guest@indicators-rabbitmq/
    depends_on:
      rabbitmq:
        condition: service_healthy
    ports:
      - "8080:8080"

  rabbitmq:
    image: "rabbitmq:3-management"
    container_name: indicator-rabbitmq
    ports:
      - "5672:5672"
      - "15674:15672"
    environment:
      - RABBITMQ_DEFAULT_USER=guest
      - RABBITMQ_DEFAULT_PASS=guest
    networks:
      - indicator-network
    healthcheck:
      test: ["CMD", "rabbitmq-diagnostics", "check_port_connectivity"]
      interval: 6s
      timeout: 5s
      retries: 5
      start_period: 6s
    restart: on-failure

  data-producer:
    build:
      context: .
      dockerfile: data-producer-example/data_producer/Dockerfile
    container_name: indicator-data-producer
    profiles: ["development"]
    environment:
      - RABBITMQ_URL=amqp://guest:guest@rabbitmq/
      - API_URL=http://indicator-service:8080
    depends_on:
      rabbitmq:
        condition: service_healthy
      indicator-service:
        condition: service_started
    networks:
      - indicator-network
    restart: on-failure
The data-producer service uses the development profile and is not started by default. Activate it with --profile development. The RabbitMQ management UI is available at http://localhost:15674 when using the override file.

Deployment

1

Create a .env file

Copy .env.example and fill in your values:
cp .env.example .env
At minimum, set ORIGINS to your frontend’s origin and update the RabbitMQ credentials.
2

Build the service image

docker compose build
3

Start the stack

docker compose up -d
Docker Compose waits for MongoDB to pass its health check before starting indicator-service.
4

Verify the service is healthy

docker compose ps
The indicator-service container should show healthy once the /health/ check passes. You can also query the endpoint directly:
curl http://localhost:8080/health/
5

View logs

docker compose logs -f indicator-service

Hot reload development

Use docker compose watch to sync local code changes into the running container without a full rebuild:
docker compose watch
The watch configuration in docker-compose.yml does the following:
TriggerAction
Any file change under ./app/Synced directly into /app inside the container. uvicorn’s --reload flag picks up the change immediately. __pycache__/ is excluded.
requirements.txt changesTriggers a full image rebuild and container restart.

Individual commands

# Stop and remove containers (data volume is preserved)
docker compose down

# Stop and remove containers AND the MongoDB data volume
docker compose down -v

# Rebuild only the service image
docker compose build indicator-service

# Restart only the service
docker compose restart indicator-service

# Run with the development data producer
docker compose --profile development up -d

Build docs developers (and LLMs) love