services: # PostgreSQL Database postgres: image: postgres:16-alpine container_name: trading_bot_db restart: unless-stopped environment: POSTGRES_USER: ${DB_USER:-trading_bot} POSTGRES_PASSWORD: ${DB_PASSWORD:-trading_bot_2026} POSTGRES_DB: ${DB_NAME:-trading_db} TZ: Asia/Jakarta ports: - "${DB_PORT:-5432}:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./docker/init-db:/docker-entrypoint-initdb.d:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-trading_bot} -d ${DB_NAME:-trading_db}"] interval: 10s timeout: 5s retries: 5 networks: - trading_bot_network # Trading Bot API (reads bot_status.json from shared volume) trading-api: build: context: . dockerfile: Dockerfile container_name: trading_bot_api restart: unless-stopped environment: TZ: Asia/Jakarta DB_HOST: postgres DB_PORT: 5432 DB_NAME: ${DB_NAME:-trading_db} DB_USER: ${DB_USER:-trading_bot} DB_PASSWORD: ${DB_PASSWORD:-trading_bot_2026} ports: - "${API_PORT:-8000}:8000" volumes: # Mount data/ so API can read bot_status.json written by the bot on host - ./data:/app/data:ro depends_on: postgres: condition: service_healthy networks: - trading_bot_network healthcheck: test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/health')"] interval: 30s timeout: 10s retries: 3 start_period: 10s # Web Dashboard (Next.js Frontend) dashboard: build: context: ./web-dashboard dockerfile: Dockerfile container_name: trading_bot_dashboard restart: unless-stopped ports: - "${DASHBOARD_PORT:-3000}:3000" depends_on: trading-api: condition: service_healthy networks: - trading_bot_network healthcheck: test: ["CMD", "wget", "--spider", "-q", "http://localhost:3000"] interval: 30s timeout: 10s retries: 3 start_period: 30s # pgAdmin (OPTIONAL - for database management) pgadmin: image: dpage/pgadmin4:latest container_name: trading_bot_pgadmin restart: unless-stopped environment: PGADMIN_DEFAULT_EMAIL: ${PGADMIN_EMAIL:-admin@trading.local} PGADMIN_DEFAULT_PASSWORD: ${PGADMIN_PASSWORD:-admin123} PGADMIN_CONFIG_SERVER_MODE: 'False' ports: - "${PGADMIN_PORT:-5050}:80" volumes: - pgadmin_data:/var/lib/pgadmin depends_on: postgres: condition: service_healthy networks: - trading_bot_network profiles: - admin # Only start with: docker-compose --profile admin up volumes: postgres_data: name: trading_bot_postgres_data pgadmin_data: name: trading_bot_pgadmin_data networks: trading_bot_network: name: trading_bot_network driver: bridge