name: ${DZENTRA_COMPOSE_PROJECT_NAME:?DZENTRA_COMPOSE_PROJECT_NAME must be set} services: postgres: build: context: ../.. dockerfile: infra/docker/postgres/Dockerfile image: ${DZENTRA_POSTGRES_IMAGE:-dzentra-postgres:16.14-hardened} pull_policy: build restart: "no" environment: POSTGRES_DB: ${DB_NAME:-dzentra_bot} POSTGRES_USER: ${POSTGRES_ADMIN_USER:-dzentra_admin} POSTGRES_PASSWORD_FILE: /run/secrets/postgres_admin_password APP_DB_USER: ${DB_USER:-dzentra_bot} secrets: - postgres_admin_password - db_password volumes: - dzentra_postgres_data:/var/lib/postgresql/data healthcheck: test: - CMD - /usr/local/bin/dzentra-postgres-healthcheck interval: 5s timeout: 3s retries: 3 start_period: 10s networks: - database security_opt: - no-new-privileges:true cap_drop: - ALL cap_add: - CHOWN - DAC_OVERRIDE - FOWNER - SETGID - SETUID read_only: true tmpfs: - /tmp:rw,noexec,nosuid,nodev,size=64m - /var/run/postgresql:rw,nosuid,nodev,size=16m stop_grace_period: ${POSTGRES_STOP_GRACE_PERIOD:?POSTGRES_STOP_GRACE_PERIOD must be set} bot: build: context: ../.. dockerfile: infra/docker/Dockerfile image: ${DZENTRA_BOT_IMAGE:-dzentra-bot:local} pull_policy: build restart: "no" init: true user: "10001:10001" environment: BOT_TOKEN_FILE: /run/secrets/bot_token BOT_PARSE_MODE: ${BOT_PARSE_MODE:-HTML} APP_ENV: ${APP_ENV:-prod} LOG_LEVEL: ${LOG_LEVEL:-INFO} TZ: ${TZ:-Europe/Minsk} DEBUG_ENABLED: ${DEBUG_ENABLED:-false} DZENTRA_RUNTIME_ENV_FILE: /var/lib/dzentra/runtime.env DB_HOST: postgres DB_PORT: "5432" DB_NAME: ${DB_NAME:-dzentra_bot} DB_USER: ${DB_USER:-dzentra_bot} DB_PASSWORD_FILE: /run/secrets/db_password MARKET_DATA_STORAGE_ENABLED: ${MARKET_DATA_STORAGE_ENABLED:-false} MARKET_DATA_STORAGE_POOL_MIN_SIZE: ${MARKET_DATA_STORAGE_POOL_MIN_SIZE:-1} MARKET_DATA_STORAGE_POOL_MAX_SIZE: ${MARKET_DATA_STORAGE_POOL_MAX_SIZE:-4} MARKET_DATA_STORAGE_POOL_TIMEOUT_SECONDS: ${MARKET_DATA_STORAGE_POOL_TIMEOUT_SECONDS:-10} EXCHANGE_ENABLED: ${EXCHANGE_ENABLED:-false} EXCHANGE_NAME: ${EXCHANGE_NAME:-dzengi} EXCHANGE_BASE_URL: ${EXCHANGE_BASE_URL:-} EXCHANGE_WS_URL: ${EXCHANGE_WS_URL:-} EXCHANGE_TIMEOUT_SEC: ${EXCHANGE_TIMEOUT_SEC:-10} EXCHANGE_TESTNET: ${EXCHANGE_TESTNET:-false} DEFAULT_SYMBOL: ${DEFAULT_SYMBOL:-ETH/USD_LEVERAGE} TRADE_STREAM_ENABLED: ${TRADE_STREAM_ENABLED:-false} TRADE_STREAM_WS_URL: ${TRADE_STREAM_WS_URL:-} TRADE_STREAM_SYMBOLS: ${TRADE_STREAM_SYMBOLS:-} TRADE_STREAM_OPEN_TIMEOUT_SECONDS: ${TRADE_STREAM_OPEN_TIMEOUT_SECONDS:-10} TRADE_STREAM_PROBE_TIMEOUT_SECONDS: ${TRADE_STREAM_PROBE_TIMEOUT_SECONDS:-20} TRADE_STREAM_CLOSE_TIMEOUT_SECONDS: ${TRADE_STREAM_CLOSE_TIMEOUT_SECONDS:-10} TRADE_STREAM_HEARTBEAT_TIMEOUT_SECONDS: ${TRADE_STREAM_HEARTBEAT_TIMEOUT_SECONDS:-30} TRADE_STREAM_SCHEDULER_INTERVAL_SECONDS: ${TRADE_STREAM_SCHEDULER_INTERVAL_SECONDS:-5} TRADE_STREAM_RECOVERY_WINDOW_MS: ${TRADE_STREAM_RECOVERY_WINDOW_MS:-3599999} TRADE_STREAM_SUBSCRIPTION_ACK_TIMEOUT_SECONDS: ${TRADE_STREAM_SUBSCRIPTION_ACK_TIMEOUT_SECONDS:-10} TRADE_STREAM_STARTUP_MARKET_BUFFER_CAPACITY: ${TRADE_STREAM_STARTUP_MARKET_BUFFER_CAPACITY:-10000} secrets: - bot_token - db_password volumes: - dzentra_runtime_config:/var/lib/dzentra depends_on: postgres: condition: service_healthy networks: - database - egress security_opt: - no-new-privileges:true cap_drop: - ALL read_only: true tmpfs: - /tmp:rw,noexec,nosuid,nodev,size=64m stop_grace_period: ${BOT_STOP_GRACE_PERIOD:?BOT_STOP_GRACE_PERIOD must be set} volumes: dzentra_postgres_data: dzentra_runtime_config: networks: database: internal: true egress: secrets: postgres_admin_password: file: ${POSTGRES_ADMIN_PASSWORD_SECRET_FILE:?POSTGRES_ADMIN_PASSWORD_SECRET_FILE must be set} bot_token: file: ${BOT_TOKEN_SECRET_FILE:?BOT_TOKEN_SECRET_FILE must be set} db_password: file: ${DB_PASSWORD_SECRET_FILE:?DB_PASSWORD_SECRET_FILE must be set}