# Sendico Development Environment # Vault is ONLY used for application data (blockchain keys, external API keys) # NOT for infrastructure credentials (MongoDB, NATS use plain .env) x-common-env: &common-env env_file: - .env.dev networks: sendico-dev: name: sendico-dev driver: bridge volumes: dev-mongo1-data: dev-mongo2-data: dev-mongo3-data: dev-nats-data: dev-vault-data: dev-chain-gateway-vault-run: driver: local driver_opts: type: tmpfs device: tmpfs o: size=8m,uid=0,gid=0,mode=0700 dev-tron-gateway-vault-run: driver: local driver_opts: type: tmpfs device: tmpfs o: size=8m,uid=0,gid=0,mode=0700 # ============================================================================ # INFRASTRUCTURE SERVICES # ============================================================================ services: # -------------------------------------------------------------------------- # Vault (Single Node) - for application data ONLY # -------------------------------------------------------------------------- dev-vault: image: hashicorp/vault:latest container_name: dev-vault restart: unless-stopped cap_add: [IPC_LOCK] environment: VAULT_ADDR: http://0.0.0.0:8200 volumes: - dev-vault-data:/vault/file - ./ci/dev/vault/config.hcl:/vault/config/vault.hcl:ro command: vault server -config=/vault/config/vault.hcl ports: - "8200:8200" networks: - sendico-dev healthcheck: test: ["CMD-SHELL", "wget --spider --proxy off http://127.0.0.1:8200/v1/sys/health || [ $? -eq 1 ]"] interval: 30s timeout: 10s retries: 3 start_period: 10s # -------------------------------------------------------------------------- # MongoDB Replica Set (3 nodes) - plain credentials from .env # -------------------------------------------------------------------------- dev-mongo-1: <<: *common-env image: mongo:latest container_name: dev-mongo-1 restart: unless-stopped command: > mongod --replSet dev-rs --bind_ip_all --auth --keyFile /etc/mongo/mongo.key --port 27017 environment: MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER} MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD} volumes: - dev-mongo1-data:/data/db - ./ci/dev/mongo-key:/etc/mongo ports: - "27017:27017" networks: - sendico-dev healthcheck: test: ["CMD-SHELL", "mongosh --quiet --host localhost --port 27017 --eval 'db.runCommand({ ping: 1 }).ok' || exit 1"] interval: 10s timeout: 5s retries: 10 start_period: 30s dev-mongo-2: <<: *common-env image: mongo:latest container_name: dev-mongo-2 restart: unless-stopped command: > mongod --replSet dev-rs --bind_ip_all --auth --keyFile /etc/mongo/mongo.key --port 27017 environment: MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER} MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD} volumes: - dev-mongo2-data:/data/db - ./ci/dev/mongo-key:/etc/mongo networks: - sendico-dev healthcheck: test: ["CMD-SHELL", "mongosh --quiet --host localhost --port 27017 --eval 'db.runCommand({ ping: 1 }).ok' || exit 1"] interval: 10s timeout: 5s retries: 10 start_period: 30s dev-mongo-3: <<: *common-env image: mongo:latest container_name: dev-mongo-3 restart: unless-stopped command: > mongod --replSet dev-rs --bind_ip_all --auth --keyFile /etc/mongo/mongo.key --port 27017 environment: MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER} MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASSWORD} volumes: - dev-mongo3-data:/data/db - ./ci/dev/mongo-key:/etc/mongo networks: - sendico-dev healthcheck: test: ["CMD-SHELL", "mongosh --quiet --host localhost --port 27017 --eval 'db.runCommand({ ping: 1 }).ok' || exit 1"] interval: 10s timeout: 5s retries: 10 start_period: 30s # -------------------------------------------------------------------------- # MongoDB Replica Set Initialization # -------------------------------------------------------------------------- dev-mongo-init: <<: *common-env image: mongo:latest container_name: dev-mongo-init depends_on: dev-mongo-1: { condition: service_healthy } dev-mongo-2: { condition: service_healthy } dev-mongo-3: { condition: service_healthy } networks: - sendico-dev entrypoint: | bash -c ' set -euo pipefail echo "Waiting for MongoDB nodes..." until mongosh --quiet --host dev-mongo-1 --port 27017 --eval "db.adminCommand({ ping: 1 })"; do sleep 2 done echo "Initializing replica set..." mongosh --host dev-mongo-1 --port 27017 -u "${MONGO_USER}" -p "${MONGO_PASSWORD}" --authenticationDatabase admin < sh -c 'set -eu; umask 077; echo "$$CHAIN_GATEWAY_VAULT_ROLE_ID" > /run/vault/role_id; echo "$$CHAIN_GATEWAY_VAULT_SECRET_ID" > /run/vault/secret_id; unset CHAIN_GATEWAY_VAULT_ROLE_ID CHAIN_GATEWAY_VAULT_SECRET_ID; exec vault agent -config=/etc/vault/agent/chain-gateway.hcl' volumes: - ./ci/dev/vault-agent/chain-gateway.hcl:/etc/vault/agent/chain-gateway.hcl:ro - dev-chain-gateway-vault-run:/run/vault depends_on: dev-vault: { condition: service_healthy } healthcheck: test: ["CMD", "test", "-s", "/run/vault/token"] interval: 10s timeout: 5s retries: 6 networks: - sendico-dev # -------------------------------------------------------------------------- # Chain Gateway Service (blockchain - connects to Vault for keys) # -------------------------------------------------------------------------- dev-chain-gateway: <<: *common-env build: context: . dockerfile: ci/dev/chain-gateway.dockerfile image: sendico-dev/chain-gateway:latest container_name: dev-chain-gateway restart: unless-stopped depends_on: dev-mongo-init: { condition: service_completed_successfully } dev-nats: { condition: service_started } dev-discovery: { condition: service_started } dev-vault: { condition: service_healthy } dev-chain-gateway-vault-agent: { condition: service_healthy } volumes: - ./api/gateway/chain:/src/api/gateway/chain - ./api/gateway/chain/config.dev.yml:/app/config.yml:ro - dev-chain-gateway-vault-run:/run/vault:ro ports: - "50070:50070" - "9404:9404" networks: - sendico-dev environment: CHAIN_GATEWAY_MONGO_HOST: dev-mongo-1 CHAIN_GATEWAY_MONGO_PORT: 27017 CHAIN_GATEWAY_MONGO_DATABASE: chain_gateway CHAIN_GATEWAY_MONGO_USER: ${MONGO_USER} CHAIN_GATEWAY_MONGO_PASSWORD: ${MONGO_PASSWORD} CHAIN_GATEWAY_MONGO_AUTH_SOURCE: admin CHAIN_GATEWAY_MONGO_REPLICA_SET: dev-rs NATS_HOST: dev-nats NATS_PORT: 4222 NATS_USER: ${NATS_USER} NATS_PASSWORD: ${NATS_PASSWORD} NATS_URL: nats://${NATS_USER}:${NATS_PASSWORD}@dev-nats:4222 CHAIN_GATEWAY_GRPC_PORT: 50070 CHAIN_GATEWAY_METRICS_PORT: 9404 VAULT_ADDR: ${VAULT_ADDR} VAULT_TOKEN_FILE: /run/vault/token CHAIN_GATEWAY_RPC_URL: ${CHAIN_GATEWAY_RPC_URL} # -------------------------------------------------------------------------- # TRON Gateway Vault Agent (sidecar for AppRole authentication) # -------------------------------------------------------------------------- dev-tron-gateway-vault-agent: <<: *common-env image: hashicorp/vault:latest container_name: dev-tron-gateway-vault-agent restart: unless-stopped cap_add: ["IPC_LOCK"] environment: VAULT_ADDR: ${VAULT_ADDR} TRON_GATEWAY_VAULT_ROLE_ID: ${TRON_GATEWAY_VAULT_ROLE_ID} TRON_GATEWAY_VAULT_SECRET_ID: ${TRON_GATEWAY_VAULT_SECRET_ID} command: > sh -c 'set -eu; umask 077; echo "$$TRON_GATEWAY_VAULT_ROLE_ID" > /run/vault/role_id; echo "$$TRON_GATEWAY_VAULT_SECRET_ID" > /run/vault/secret_id; unset TRON_GATEWAY_VAULT_ROLE_ID TRON_GATEWAY_VAULT_SECRET_ID; exec vault agent -config=/etc/vault/agent/tron-gateway.hcl' volumes: - ./ci/dev/vault-agent/tron-gateway.hcl:/etc/vault/agent/tron-gateway.hcl:ro - dev-tron-gateway-vault-run:/run/vault depends_on: dev-vault: { condition: service_healthy } healthcheck: test: ["CMD", "test", "-s", "/run/vault/token"] interval: 10s timeout: 5s retries: 6 networks: - sendico-dev # -------------------------------------------------------------------------- # TRON Gateway Service (TRON blockchain - connects to Vault for keys) # -------------------------------------------------------------------------- dev-tron-gateway: <<: *common-env build: context: . dockerfile: ci/dev/tron-gateway.dockerfile image: sendico-dev/tron-gateway:latest container_name: dev-tron-gateway restart: unless-stopped depends_on: dev-mongo-init: { condition: service_completed_successfully } dev-nats: { condition: service_started } dev-discovery: { condition: service_started } dev-vault: { condition: service_healthy } dev-tron-gateway-vault-agent: { condition: service_healthy } volumes: - ./api/gateway/tron:/src/api/gateway/tron - ./api/gateway/tron/config.dev.yml:/app/config.yml:ro - dev-tron-gateway-vault-run:/run/vault:ro ports: - "50071:50071" - "9408:9408" networks: - sendico-dev environment: TRON_GATEWAY_MONGO_HOST: dev-mongo-1 TRON_GATEWAY_MONGO_PORT: 27017 TRON_GATEWAY_MONGO_DATABASE: tron_gateway TRON_GATEWAY_MONGO_USER: ${MONGO_USER} TRON_GATEWAY_MONGO_PASSWORD: ${MONGO_PASSWORD} TRON_GATEWAY_MONGO_AUTH_SOURCE: admin TRON_GATEWAY_MONGO_REPLICA_SET: dev-rs NATS_HOST: dev-nats NATS_PORT: 4222 NATS_USER: ${NATS_USER} NATS_PASSWORD: ${NATS_PASSWORD} NATS_URL: nats://${NATS_USER}:${NATS_PASSWORD}@dev-nats:4222 TRON_GATEWAY_GRPC_PORT: 50071 TRON_GATEWAY_METRICS_PORT: 9408 VAULT_ADDR: ${VAULT_ADDR} VAULT_TOKEN_FILE: /run/vault/token TRON_GATEWAY_RPC_URL: ${TRON_GATEWAY_RPC_URL:-} TRON_GATEWAY_GRPC_URL: ${TRON_GATEWAY_GRPC_URL:-} TRON_GATEWAY_GRPC_TOKEN: ${TRON_GATEWAY_GRPC_TOKEN:-} # -------------------------------------------------------------------------- # MNTX Gateway Service (card payouts) # -------------------------------------------------------------------------- dev-mntx-gateway: <<: *common-env build: context: . dockerfile: ci/dev/mntx-gateway.dockerfile image: sendico-dev/mntx-gateway:latest container_name: dev-mntx-gateway restart: unless-stopped depends_on: dev-nats: { condition: service_started } dev-discovery: { condition: service_started } dev-vault: { condition: service_healthy } volumes: - ./api/gateway/mntx:/src/api/gateway/mntx - ./api/gateway/mntx/config.dev.yml:/app/config.yml:ro ports: - "50075:50075" - "9405:9405" - "8084:8084" networks: - sendico-dev environment: MNTX_GATEWAY_MONGO_HOST: dev-mongo-1 MNTX_GATEWAY_MONGO_PORT: 27017 MNTX_GATEWAY_MONGO_DATABASE: mntx_gateway MNTX_GATEWAY_MONGO_USER: ${MONGO_USER} MNTX_GATEWAY_MONGO_PASSWORD: ${MONGO_PASSWORD} MNTX_GATEWAY_MONGO_AUTH_SOURCE: admin MNTX_GATEWAY_MONGO_REPLICA_SET: dev-rs NATS_HOST: dev-nats NATS_PORT: 4222 NATS_USER: ${NATS_USER} NATS_PASSWORD: ${NATS_PASSWORD} NATS_URL: nats://${NATS_USER}:${NATS_PASSWORD}@dev-nats:4222 MNTX_GATEWAY_GRPC_PORT: 50075 MNTX_GATEWAY_METRICS_PORT: 9405 MNTX_GATEWAY_HTTP_PORT: 8084 VAULT_ADDR: ${VAULT_ADDR} # -------------------------------------------------------------------------- # TGSettle Gateway Service (Telegram settlements) # -------------------------------------------------------------------------- dev-tgsettle-gateway: <<: *common-env build: context: . dockerfile: ci/dev/tgsettle-gateway.dockerfile image: sendico-dev/tgsettle-gateway:latest container_name: dev-tgsettle-gateway restart: unless-stopped depends_on: dev-mongo-init: { condition: service_completed_successfully } dev-nats: { condition: service_started } dev-discovery: { condition: service_started } dev-vault: { condition: service_healthy } volumes: - ./api/gateway/tgsettle:/src/api/gateway/tgsettle - ./api/gateway/tgsettle/config.dev.yml:/app/config.yml:ro ports: - "50080:50080" - "9406:9406" networks: - sendico-dev environment: TGSETTLE_GATEWAY_MONGO_HOST: dev-mongo-1 TGSETTLE_GATEWAY_MONGO_PORT: 27017 TGSETTLE_GATEWAY_MONGO_DATABASE: tgsettle_gateway TGSETTLE_GATEWAY_MONGO_USER: ${MONGO_USER} TGSETTLE_GATEWAY_MONGO_PASSWORD: ${MONGO_PASSWORD} TGSETTLE_GATEWAY_MONGO_AUTH_SOURCE: admin TGSETTLE_GATEWAY_MONGO_REPLICA_SET: dev-rs NATS_HOST: dev-nats NATS_PORT: 4222 NATS_USER: ${NATS_USER} NATS_PASSWORD: ${NATS_PASSWORD} NATS_URL: nats://${NATS_USER}:${NATS_PASSWORD}@dev-nats:4222 TGSETTLE_GATEWAY_GRPC_PORT: 50080 TGSETTLE_GATEWAY_METRICS_PORT: 9406 VAULT_ADDR: ${VAULT_ADDR} # -------------------------------------------------------------------------- # Notification Service # -------------------------------------------------------------------------- dev-notification: <<: *common-env build: context: . dockerfile: ci/dev/notification.dockerfile image: sendico-dev/notification:latest container_name: dev-notification restart: unless-stopped depends_on: dev-nats: { condition: service_started } volumes: - ./api/notification:/src/api/notification - ./api/notification/config.dev.yml:/app/config.yml:ro ports: - "8081:8081" networks: - sendico-dev environment: NATS_HOST: dev-nats NATS_PORT: 4222 NATS_USER: ${NATS_USER} NATS_PASSWORD: ${NATS_PASSWORD} NATS_URL: nats://${NATS_USER}:${NATS_PASSWORD}@dev-nats:4222 NOTIFICATION_HTTP_PORT: 8081 MONGO_HOST: dev-mongo-1 MONGO_PORT: 27017 MONGO_DATABASE: sendico MONGO_USER: ${MONGO_USER} MONGO_PASSWORD: ${MONGO_PASSWORD} MONGO_AUTH_SOURCE: admin MONGO_REPLICA_SET: dev-rs # -------------------------------------------------------------------------- # BFF (Backend for Frontend / Server) Service # -------------------------------------------------------------------------- dev-bff: <<: *common-env build: context: . dockerfile: ci/dev/bff.dockerfile image: sendico-dev/bff:latest container_name: dev-bff restart: unless-stopped depends_on: dev-mongo-init: { condition: service_completed_successfully } dev-nats: { condition: service_started } dev-ledger: { condition: service_started } dev-payments-orchestrator: { condition: service_started } dev-chain-gateway: { condition: service_started } volumes: - ./api/server:/src/api/server - ./api/server/config.dev.yml:/app/config.yml:ro ports: - "8080:8080" networks: - sendico-dev environment: MONGO_HOST: dev-mongo-1 MONGO_PORT: 27017 MONGO_DATABASE: sendico MONGO_USER: ${MONGO_USER} MONGO_PASSWORD: ${MONGO_PASSWORD} MONGO_AUTH_SOURCE: admin MONGO_REPLICA_SET: dev-rs MONGO_HOSTS_0: dev-mongo-1 MONGO_PORTS_0: 27017 MONGO_HOSTS_1: dev-mongo-2 MONGO_PORTS_1: 27017 MONGO_HOSTS_2: dev-mongo-3 MONGO_PORTS_2: 27017 NATS_HOST: dev-nats NATS_PORT: 4222 NATS_USER: ${NATS_USER} NATS_PASSWORD: ${NATS_PASSWORD} NATS_URL: nats://${NATS_USER}:${NATS_PASSWORD}@dev-nats:4222 LEDGER_ADDRESS: dev-ledger:50052 PAYMENTS_ADDRESS: dev-payments-orchestrator:50062 CHAIN_GATEWAY_ADDRESS: dev-chain-gateway:50070 BFF_HTTP_PORT: 8080 API_PROTOCOL: http SERVICE_HOST: localhost API_ENDPOINT: /api/v1 # -------------------------------------------------------------------------- # Frontend (Flutter Web) # -------------------------------------------------------------------------- dev-frontend: <<: *common-env build: context: . dockerfile: ci/dev/frontend.dockerfile image: sendico-dev/frontend:latest container_name: dev-frontend restart: unless-stopped depends_on: dev-bff: { condition: service_started } volumes: - ./ci/dev/Caddyfile.dev:/etc/caddy/Caddyfile:ro ports: - "3000:80" networks: - sendico-dev environment: BFF_URL: http://dev-bff:8080