version: '3.8' services: # ================================================================ # MariaDB Database Service # ================================================================ mariadb: image: mariadb:latest container_name: evoting_db restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-rootpass123} MYSQL_DATABASE: ${DB_NAME:-evoting_db} MYSQL_USER: ${DB_USER:-evoting_user} MYSQL_PASSWORD: ${DB_PASSWORD:-evoting_pass123} MYSQL_INITDB_SKIP_TZINFO: 1 ports: - "${DB_PORT:-3306}:3306" volumes: - evoting_data:/var/lib/mysql - ./docker/init.sql:/docker-entrypoint-initdb.d/01-init.sql - ./docker/populate_past_elections.sql:/docker-entrypoint-initdb.d/02-populate.sql - ./docker/create_active_election.sql:/docker-entrypoint-initdb.d/03-active.sql networks: - evoting_network healthcheck: test: ["CMD", "mariadb-admin", "ping", "-h", "localhost", "--silent"] timeout: 20s retries: 10 start_period: 40s logging: driver: "json-file" options: max-size: "10m" max-file: "3" # ================================================================ # Bootnode Service (Peer Discovery for PoA Validators) # ================================================================ bootnode: build: context: . dockerfile: docker/Dockerfile.bootnode container_name: evoting_bootnode restart: unless-stopped ports: - "8546:8546" networks: - evoting_network environment: BOOTNODE_PORT: 8546 PYTHONUNBUFFERED: 1 healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8546/health"] interval: 30s timeout: 10s retries: 3 start_period: 10s logging: driver: "json-file" options: max-size: "10m" max-file: "3" # ================================================================ # Backend FastAPI Service # ================================================================ backend: build: context: . dockerfile: docker/Dockerfile.backend container_name: evoting_backend restart: unless-stopped environment: DB_HOST: mariadb DB_PORT: 3306 DB_NAME: ${DB_NAME:-evoting_db} DB_USER: ${DB_USER:-evoting_user} DB_PASSWORD: ${DB_PASSWORD:-evoting_pass123} SECRET_KEY: ${SECRET_KEY:-your-secret-key-change-in-production} DEBUG: ${DEBUG:-false} PYTHONUNBUFFERED: 1 ports: - "${BACKEND_PORT:-8000}:8000" depends_on: mariadb: condition: service_healthy volumes: - ./backend:/app/backend - backend_cache:/app/.cache networks: - evoting_network command: uvicorn backend.main:app --host 0.0.0.0 --port 8000 --reload healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8000/health"] interval: 30s timeout: 10s retries: 3 start_period: 40s logging: driver: "json-file" options: max-size: "10m" max-file: "3" # ================================================================ # PoA Validator 1 Service # Proof-of-Authority blockchain consensus node # ================================================================ validator-1: build: context: . dockerfile: docker/Dockerfile.validator container_name: evoting_validator_1 restart: unless-stopped environment: NODE_ID: validator-1 PRIVATE_KEY: ${VALIDATOR_1_PRIVATE_KEY:-0x1234567890abcdef} BOOTNODE_URL: http://bootnode:8546 RPC_PORT: 8001 P2P_PORT: 30303 PYTHONUNBUFFERED: 1 ports: - "8001:8001" - "30303:30303" depends_on: - bootnode networks: - evoting_network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8001/health"] interval: 30s timeout: 10s retries: 3 start_period: 20s logging: driver: "json-file" options: max-size: "10m" max-file: "3" # ================================================================ # PoA Validator 2 Service # Proof-of-Authority blockchain consensus node # ================================================================ validator-2: build: context: . dockerfile: docker/Dockerfile.validator container_name: evoting_validator_2 restart: unless-stopped environment: NODE_ID: validator-2 PRIVATE_KEY: ${VALIDATOR_2_PRIVATE_KEY:-0xfedcba9876543210} BOOTNODE_URL: http://bootnode:8546 RPC_PORT: 8002 P2P_PORT: 30304 PYTHONUNBUFFERED: 1 ports: - "8002:8002" - "30304:30304" depends_on: - bootnode networks: - evoting_network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8002/health"] interval: 30s timeout: 10s retries: 3 start_period: 20s logging: driver: "json-file" options: max-size: "10m" max-file: "3" # ================================================================ # PoA Validator 3 Service # Proof-of-Authority blockchain consensus node # ================================================================ validator-3: build: context: . dockerfile: docker/Dockerfile.validator container_name: evoting_validator_3 restart: unless-stopped environment: NODE_ID: validator-3 PRIVATE_KEY: ${VALIDATOR_3_PRIVATE_KEY:-0xabcdefabcdefabcd} BOOTNODE_URL: http://bootnode:8546 RPC_PORT: 8003 P2P_PORT: 30305 PYTHONUNBUFFERED: 1 ports: - "8003:8003" - "30305:30305" depends_on: - bootnode networks: - evoting_network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8003/health"] interval: 30s timeout: 10s retries: 3 start_period: 20s logging: driver: "json-file" options: max-size: "10m" max-file: "3" # ================================================================ # Frontend Next.js Service # ================================================================ frontend: build: context: . dockerfile: docker/Dockerfile.frontend args: NEXT_PUBLIC_API_URL: http://localhost:${BACKEND_PORT:-8000} container_name: evoting_frontend restart: unless-stopped ports: - "${FRONTEND_PORT:-3000}:3000" depends_on: - backend - validator-1 - validator-2 - validator-3 environment: NEXT_PUBLIC_API_URL: http://localhost:${BACKEND_PORT:-8000} NODE_ENV: production networks: - evoting_network healthcheck: test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/"] interval: 30s timeout: 10s retries: 3 start_period: 40s logging: driver: "json-file" options: max-size: "10m" max-file: "3" # ================================================================ # Optional: Adminer (Database Management UI) # Access at http://localhost:8081 # ================================================================ adminer: image: adminer:latest container_name: evoting_adminer restart: unless-stopped ports: - "8081:8080" depends_on: - mariadb networks: - evoting_network environment: ADMINER_DEFAULT_SERVER: mariadb logging: driver: "json-file" options: max-size: "10m" max-file: "3" volumes: evoting_data: driver: local backend_cache: driver: local networks: evoting_network: driver: bridge ipam: config: - subnet: 172.25.0.0/16