version: '3.8' services: # PostgreSQL Database postgres: image: postgres:15-alpine container_name: uploader-bot-postgres restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB:-my_uploader_db} POSTGRES_USER: ${POSTGRES_USER:-my_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-secure_password} POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C" volumes: - postgres_data:/var/lib/postgresql/data - ./scripts/init-db.sql:/docker-entrypoint-initdb.d/01-init.sql:ro ports: - "5432:5432" networks: - uploader_network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-my_user} -d ${POSTGRES_DB:-my_uploader_db}"] interval: 10s timeout: 5s retries: 5 start_period: 30s # Redis Cache redis: image: redis:7-alpine container_name: uploader-bot-redis restart: unless-stopped command: > redis-server --appendonly yes --maxmemory 512mb --maxmemory-policy allkeys-lru --save 900 1 --save 300 10 --save 60 10000 volumes: - redis_data:/data ports: - "6379:6379" networks: - uploader_network healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 3s retries: 5 start_period: 10s # Main Application (MY Uploader Bot) app: build: context: .. dockerfile: deployment/Dockerfile.simple container_name: uploader-bot-app command: python start_my_network.py restart: unless-stopped depends_on: postgres: condition: service_healthy redis: condition: service_healthy environment: # Database DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-my_user}:${POSTGRES_PASSWORD:-secure_password}@postgres:5432/${POSTGRES_DB:-my_uploader_db} POSTGRES_HOST: postgres POSTGRES_PORT: 5432 POSTGRES_DB: ${POSTGRES_DB:-my_uploader_db} POSTGRES_USER: ${POSTGRES_USER:-my_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-secure_password} # Redis REDIS_URL: redis://redis:6379/0 REDIS_HOST: redis REDIS_PORT: 6379 # Application NODE_ENV: ${NODE_ENV:-production} DEBUG: ${DEBUG:-false} LOG_LEVEL: ${LOG_LEVEL:-INFO} # MY Network MY_NETWORK_NODE_ID: ${MY_NETWORK_NODE_ID} MY_NETWORK_PORT: ${MY_NETWORK_PORT:-15100} MY_NETWORK_HOST: ${MY_NETWORK_HOST:-0.0.0.0} MY_NETWORK_DOMAIN: ${MY_NETWORK_DOMAIN} MY_NETWORK_SSL_ENABLED: ${MY_NETWORK_SSL_ENABLED:-true} # API Settings API_HOST: ${API_HOST:-0.0.0.0} API_PORT: ${API_PORT:-15100} API_WORKERS: ${API_WORKERS:-4} MAX_UPLOAD_SIZE: ${MAX_UPLOAD_SIZE:-100MB} # Security SECRET_KEY: ${SECRET_KEY} JWT_SECRET: ${JWT_SECRET} ENCRYPTION_KEY: ${ENCRYPTION_KEY} # Converter (on-demand) CONVERTER_DOCKER_IMAGE: ${CONVERTER_DOCKER_IMAGE:-my-converter:latest} CONVERTER_SHARED_PATH: ${CONVERTER_SHARED_PATH:-/shared/converter} CONVERTER_MAX_PARALLEL: ${CONVERTER_MAX_PARALLEL:-3} CONVERTER_TIMEOUT: ${CONVERTER_TIMEOUT:-300} ports: - "15100:15100" volumes: - app_data:/app/data - app_logs:/app/logs - /var/run/docker.sock:/var/run/docker.sock # For on-demand converter containers - converter_shared:/shared/converter networks: - uploader_network healthcheck: test: ["CMD", "python", "-c", "import requests; requests.get('http://localhost:15100/health')"] interval: 30s timeout: 10s retries: 3 start_period: 60s # Indexer Service indexer: build: context: .. dockerfile: deployment/Dockerfile container_name: uploader-bot-indexer restart: unless-stopped command: python -m app indexer depends_on: postgres: condition: service_healthy redis: condition: service_healthy environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-my_user}:${POSTGRES_PASSWORD:-secure_password}@postgres:5432/${POSTGRES_DB:-my_uploader_db} REDIS_URL: redis://redis:6379/0 LOG_LEVEL: ${LOG_LEVEL:-INFO} SERVICE_NAME: indexer volumes: - app_logs:/app/logs - app_data:/app/data networks: - uploader_network # TON Daemon Service ton_daemon: build: context: .. dockerfile: deployment/Dockerfile container_name: uploader-bot-ton-daemon command: python -m app ton_daemon restart: unless-stopped depends_on: postgres: condition: service_healthy redis: condition: service_healthy environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-my_user}:${POSTGRES_PASSWORD:-secure_password}@postgres:5432/${POSTGRES_DB:-my_uploader_db} REDIS_URL: redis://redis:6379/0 LOG_LEVEL: ${LOG_LEVEL:-INFO} SERVICE_NAME: ton_daemon volumes: - app_logs:/app/logs - app_data:/app/data networks: - uploader_network # License Index Service license_index: build: context: .. dockerfile: deployment/Dockerfile container_name: uploader-bot-license-index command: python -m app license_index restart: unless-stopped depends_on: postgres: condition: service_healthy redis: condition: service_healthy environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-my_user}:${POSTGRES_PASSWORD:-secure_password}@postgres:5432/${POSTGRES_DB:-my_uploader_db} REDIS_URL: redis://redis:6379/0 LOG_LEVEL: ${LOG_LEVEL:-INFO} SERVICE_NAME: license_index volumes: - app_logs:/app/logs - app_data:/app/data networks: - uploader_network # Convert Process Service convert_process: build: context: .. dockerfile: deployment/Dockerfile container_name: uploader-bot-convert-process command: python -m app convert_process restart: unless-stopped depends_on: postgres: condition: service_healthy redis: condition: service_healthy environment: DATABASE_URL: postgresql+asyncpg://${POSTGRES_USER:-my_user}:${POSTGRES_PASSWORD:-secure_password}@postgres:5432/${POSTGRES_DB:-my_uploader_db} REDIS_URL: redis://redis:6379/0 LOG_LEVEL: ${LOG_LEVEL:-INFO} SERVICE_NAME: convert_process volumes: - app_logs:/app/logs - app_data:/app/data - /var/run/docker.sock:/var/run/docker.sock - converter_shared:/shared/converter networks: - uploader_network # Converter Build (for creating converter image) converter-build: build: context: ./modules/converter-module dockerfile: Dockerfile image: my-converter:latest container_name: uploader-bot-converter-build profiles: ["build-only"] # Only runs during build volumes: - converter_shared:/shared/converter networks: - uploader_network volumes: postgres_data: driver: local redis_data: driver: local app_data: driver: local app_logs: driver: local converter_shared: driver: local networks: uploader_network: driver: bridge ipam: config: - subnet: 172.20.0.0/16