# Synor Testnet Docker Compose Configuration # Deploys 3 seed nodes for initial testnet bootstrap services: # ========================================================================== # Seed Node 1 (Primary Bootstrap) # ========================================================================== seed1: build: context: . dockerfile: Dockerfile container_name: synor-seed1 hostname: seed1 restart: unless-stopped command: - "run" - "--p2p-host=0.0.0.0" - "--p2p-port=17511" - "--rpc-host=0.0.0.0" - "--rpc-port=17110" - "--ws-port=17111" - "--mine" - "--coinbase=tsynor1qz232pysw8kezv2f4qxnhdufrlx5cmq78522mpuf8x5qlxu6j8sgcp05get" ports: - "17511:17511" # P2P - "17110:17110" # HTTP RPC - "17111:17111" # WebSocket RPC volumes: - seed1-data:/data/synor networks: synor-testnet: ipv4_address: 172.20.0.10 environment: - RUST_LOG=info - SYNOR_DATA_DIR=/data/synor - SYNOR_NETWORK=testnet healthcheck: test: ["CMD", "synord", "version"] interval: 30s timeout: 10s retries: 3 start_period: 60s # ========================================================================== # Seed Node 2 # ========================================================================== seed2: build: context: . dockerfile: Dockerfile container_name: synor-seed2 hostname: seed2 restart: unless-stopped command: - "run" - "--p2p-host=0.0.0.0" - "--p2p-port=17511" - "--rpc-host=0.0.0.0" - "--rpc-port=17110" - "--ws-port=17111" - "--seeds=172.20.0.10:17511" - "--mine" - "--coinbase=tsynor1qrjdvz69xxc3gyq24d0ejp73wxxxz0nqxjp2zklw3nx6zljunwe75zele44" ports: - "17521:17511" # P2P (offset port) - "17120:17110" # HTTP RPC - "17121:17111" # WebSocket RPC volumes: - seed2-data:/data/synor networks: synor-testnet: ipv4_address: 172.20.0.11 environment: - RUST_LOG=info - SYNOR_DATA_DIR=/data/synor - SYNOR_NETWORK=testnet depends_on: seed1: condition: service_healthy # ========================================================================== # Seed Node 3 # ========================================================================== seed3: build: context: . dockerfile: Dockerfile container_name: synor-seed3 hostname: seed3 restart: unless-stopped command: - "run" - "--p2p-host=0.0.0.0" - "--p2p-port=17511" - "--rpc-host=0.0.0.0" - "--rpc-port=17110" - "--ws-port=17111" - "--seeds=172.20.0.10:17511,172.20.0.11:17511" - "--mine" - "--coinbase=tsynor1qq0mt7lhwckdz3hg69dpcv3vxw8j56d7un7z8x93vrjmjqyel5u5yf77vt8" ports: - "17531:17511" # P2P (offset port) - "17130:17110" # HTTP RPC - "17131:17111" # WebSocket RPC volumes: - seed3-data:/data/synor networks: synor-testnet: ipv4_address: 172.20.0.12 environment: - RUST_LOG=info - SYNOR_DATA_DIR=/data/synor - SYNOR_NETWORK=testnet depends_on: seed1: condition: service_healthy # ========================================================================== # Web Wallet (React + Vite) # ========================================================================== web-wallet: build: context: ./apps/web dockerfile: Dockerfile container_name: synor-web-wallet hostname: web-wallet restart: unless-stopped ports: - "17300:80" networks: - synor-testnet depends_on: seed1: condition: service_healthy # ========================================================================== # Testnet Faucet Service # ========================================================================== faucet: build: context: . dockerfile: Dockerfile.faucet container_name: synor-faucet hostname: faucet restart: unless-stopped ports: - "8080:8080" environment: - SYNOR_RPC_URL=http://seed1:17110 - FAUCET_AMOUNT=1000000000 # 10 SYNOR in sompi - FAUCET_COOLDOWN=3600 # 1 hour between requests per address - RUST_LOG=info networks: - synor-testnet depends_on: seed1: condition: service_healthy # ========================================================================== # Block Explorer Backend (optional) # ========================================================================== explorer-api: build: context: . dockerfile: Dockerfile.explorer container_name: synor-explorer-api hostname: explorer-api restart: unless-stopped ports: - "17200:3000" environment: - SYNOR_RPC_URL=http://seed1:17110 - SYNOR_WS_URL=ws://seed1:17111 - DATABASE_URL=postgres://synor:synor@postgres:5432/explorer - EXPLORER_STATIC_DIR=/var/www/explorer - EXPLORER_CORS_ORIGINS=* - RUST_LOG=info networks: - synor-testnet depends_on: seed1: condition: service_healthy postgres: condition: service_healthy profiles: - explorer # ========================================================================== # PostgreSQL for Explorer # ========================================================================== postgres: image: postgres:16-alpine container_name: synor-postgres restart: unless-stopped environment: - POSTGRES_USER=synor - POSTGRES_PASSWORD=synor - POSTGRES_DB=explorer volumes: - postgres-data:/var/lib/postgresql/data networks: - synor-testnet healthcheck: test: ["CMD-SHELL", "pg_isready -U synor -d explorer"] interval: 10s timeout: 5s retries: 5 profiles: - explorer # ========================================================================== # Security Audit Service # ========================================================================== security-audit: build: context: . dockerfile: Dockerfile.security container_name: synor-security-audit volumes: - .:/app:ro profiles: - security # ========================================================================== # Prometheus - Metrics Collection # ========================================================================== prometheus: image: prom/prometheus:v2.48.0 container_name: synor-prometheus hostname: prometheus restart: unless-stopped command: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--storage.tsdb.retention.time=30d' - '--web.enable-lifecycle' ports: - "9090:9090" volumes: - ./monitoring/prometheus.yml:/etc/prometheus/prometheus.yml:ro - ./monitoring/alerts.yml:/etc/prometheus/alerts.yml:ro - prometheus-data:/prometheus networks: - synor-testnet profiles: - monitoring # ========================================================================== # Grafana - Visualization & Dashboards # ========================================================================== grafana: image: grafana/grafana:10.2.2 container_name: synor-grafana hostname: grafana restart: unless-stopped ports: - "3001:3000" # Using 3001 to avoid conflict with explorer-api environment: - GF_SECURITY_ADMIN_USER=admin - GF_SECURITY_ADMIN_PASSWORD=synor123 - GF_USERS_ALLOW_SIGN_UP=false - GF_SERVER_ROOT_URL=http://localhost:3000 volumes: - ./monitoring/grafana/provisioning:/etc/grafana/provisioning:ro - ./monitoring/grafana/dashboards:/var/lib/grafana/dashboards:ro - grafana-data:/var/lib/grafana networks: - synor-testnet depends_on: - prometheus profiles: - monitoring # ========================================================================== # Alertmanager - Alert Routing & Notifications # ========================================================================== alertmanager: image: prom/alertmanager:v0.26.0 container_name: synor-alertmanager hostname: alertmanager restart: unless-stopped command: - '--config.file=/etc/alertmanager/alertmanager.yml' - '--storage.path=/alertmanager' ports: - "9093:9093" volumes: - ./monitoring/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro - alertmanager-data:/alertmanager networks: - synor-testnet profiles: - monitoring # ========================================================================== # Node Exporter - System Metrics (optional but useful) # Note: Limited functionality on macOS Docker Desktop # ========================================================================== node-exporter: image: prom/node-exporter:v1.7.0 container_name: synor-node-exporter hostname: node-exporter restart: unless-stopped ports: - "9100:9100" # Note: Root filesystem mount doesn't work on macOS Docker Desktop # volumes: # - /:/host:ro,rslave # command: # - '--path.rootfs=/host' networks: - synor-testnet profiles: - monitoring # ============================================================================= # Networks # ============================================================================= networks: synor-testnet: driver: bridge ipam: driver: default config: - subnet: 172.20.0.0/16 # ============================================================================= # Volumes # ============================================================================= volumes: seed1-data: seed2-data: seed3-data: postgres-data: prometheus-data: grafana-data: alertmanager-data: