# Cassandra — app + scheduler + MariaDB + daily backup sidecar. # .env is mounted read-only; never bake secrets into the image. services: db: image: mariadb:11 restart: unless-stopped environment: MARIADB_ROOT_PASSWORD: ${MARIADB_ROOT_PASSWORD:-changeme-root} MARIADB_DATABASE: ${MARIADB_DATABASE:-cassandra} MARIADB_USER: ${MARIADB_USER:-cassandra} MARIADB_PASSWORD: ${MARIADB_PASSWORD:-changeme} volumes: - db-data:/var/lib/mysql - ./backup:/backup healthcheck: test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] interval: 10s timeout: 5s retries: 10 redis: image: redis:7-alpine restart: unless-stopped # No volume mount: this is a cache / scratch store. Persistence would # undercut the "ephemeral pie" property — survival across restart is a # bug, not a feature. AOF/RDB disabled via --save "" --appendonly no. command: ["redis-server", "--save", "", "--appendonly", "no", "--maxmemory", "128mb", "--maxmemory-policy", "allkeys-lru"] healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 3s retries: 5 app: build: . restart: unless-stopped command: ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "1"] env_file: .env environment: DATABASE_URL: mysql+aiomysql://${MARIADB_USER:-cassandra}:${MARIADB_PASSWORD:-changeme}@db:3306/${MARIADB_DATABASE:-cassandra} REDIS_URL: redis://redis:6379/0 volumes: - ./config:/app/config:ro depends_on: db: condition: service_healthy redis: condition: service_healthy ports: - "${CASSANDRA_PORT:-8000}:8000" scheduler: build: . restart: unless-stopped command: ["python", "-m", "app.scheduler_main"] env_file: .env environment: DATABASE_URL: mysql+aiomysql://${MARIADB_USER:-cassandra}:${MARIADB_PASSWORD:-changeme}@db:3306/${MARIADB_DATABASE:-cassandra} REDIS_URL: redis://redis:6379/0 volumes: - ./config:/app/config:ro depends_on: db: condition: service_healthy redis: condition: service_healthy backup: image: mariadb:11 restart: unless-stopped environment: MARIADB_HOST: db MARIADB_USER: ${MARIADB_USER:-cassandra} MARIADB_PASSWORD: ${MARIADB_PASSWORD:-changeme} MARIADB_DATABASE: ${MARIADB_DATABASE:-cassandra} entrypoint: ["/bin/sh", "-c"] # Daily dump at 03:00 UTC; keeps last 14 days. command: | "while true; do sleep $$((86400 - $$(date +%s) % 86400 + 10800)); f=/backup/cassandra-$$(date -u +%Y-%m-%d).sql.gz; echo \"[backup] $$f\"; mariadb-dump -h $$MARIADB_HOST -u $$MARIADB_USER -p$$MARIADB_PASSWORD $$MARIADB_DATABASE | gzip > $$f || echo '[backup] FAILED'; find /backup -name 'cassandra-*.sql.gz' -mtime +14 -delete; done" volumes: - ./backup:/backup depends_on: db: condition: service_healthy volumes: db-data: