| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- version: '3.8'
- services:
- # PostgreSQL Database Service (Production)
- db:
- image: postgres:15-alpine
- container_name: market-data-db-prod
- environment:
- POSTGRES_USER: ${DB_USER:-postgres}
- POSTGRES_PASSWORD: ${DB_PASSWORD}
- POSTGRES_DB: ${DB_NAME:-financial_data}
- PGDATA: /var/lib/postgresql/data/pgdata
- volumes:
- - market_data_db_data_prod:/var/lib/postgresql/data
- - ./docker/init-db.sh:/docker-entrypoint-initdb.d/init-db.sh
- # No exposed ports in production (internal only)
- healthcheck:
- test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-financial_data}"]
- interval: 10s
- timeout: 5s
- retries: 5
- networks:
- - market-data-network
- restart: unless-stopped
- # Production security: run as non-root
- user: "999:999"
- # Node.js API Service (Production)
- api:
- build:
- context: .
- dockerfile: Dockerfile
- target: production
- container_name: market-data-api-prod
- environment:
- - NODE_ENV=production
- - PORT=3000
- - DB_HOST=db
- - DB_PORT=5432
- - DB_NAME=${DB_NAME:-financial_data}
- - DB_USER=${DB_USER:-postgres}
- - DB_PASSWORD=${DB_PASSWORD}
- - CORS_ORIGIN=${CORS_ORIGIN:-*}
- - JWT_SECRET=${JWT_SECRET}
- - LOG_LEVEL=${LOG_LEVEL:-info}
- # No volume mounts in production (code is baked into image)
- # Optional: mount logs volume for persistence
- volumes:
- - market_data_logs_prod:/app/logs
- # No exposed ports (accessed only through nginx)
- depends_on:
- db:
- condition: service_healthy
- networks:
- - market-data-network
- restart: unless-stopped
- healthcheck:
- test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
- interval: 30s
- timeout: 10s
- start_period: 40s
- retries: 3
- # Nginx Reverse Proxy (Production)
- nginx:
- image: nginx:alpine
- container_name: market-data-nginx-prod
- ports:
- - "80:80"
- - "443:443"
- volumes:
- - ./nginx/nginx.prod.conf:/etc/nginx/nginx.conf:ro
- # SSL certificates (mount your certbot certificates here)
- - ${SSL_CERT_PATH:-./ssl/certs}:/etc/nginx/ssl/certs:ro
- - ${SSL_KEY_PATH:-./ssl/private}:/etc/nginx/ssl/private:ro
- depends_on:
- api:
- condition: service_healthy
- networks:
- - market-data-network
- restart: unless-stopped
- healthcheck:
- test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost/health"]
- interval: 30s
- timeout: 10s
- retries: 3
- volumes:
- market_data_db_data_prod:
- driver: local
- market_data_logs_prod:
- driver: local
- networks:
- market-data-network:
- driver: bridge
|