version: '3.8' services: # PostgreSQL Database postgres: image: postgres:15-alpine container_name: skrzynka-postgres restart: unless-stopped environment: POSTGRES_DB: skrzynka_impostora POSTGRES_USER: skrzynka_user POSTGRES_PASSWORD: skrzynka_password PGDATA: /var/lib/postgresql/data/pgdata volumes: - postgres_data:/var/lib/postgresql/data - ./database/init:/docker-entrypoint-initdb.d ports: - "5432:5432" networks: - skrzynka-network healthcheck: test: ["CMD-SHELL", "pg_isready -U skrzynka_user -d skrzynka_impostora"] interval: 10s timeout: 5s retries: 5 # Redis for caching (optional) redis: image: redis:7-alpine container_name: skrzynka-redis restart: unless-stopped ports: - "6379:6379" volumes: - redis_data:/data networks: - skrzynka-network healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 10s timeout: 5s retries: 5 # Discord Bot Application bot: build: context: . dockerfile: Dockerfile container_name: skrzynka-bot restart: unless-stopped environment: # Database DATABASE_URL: postgresql://skrzynka_user:skrzynka_password@postgres:5432/skrzynka_impostora DB_HOST: postgres DB_PORT: 5432 DB_NAME: skrzynka_impostora DB_USER: skrzynka_user DB_PASSWORD: skrzynka_password # Discord Bot (należy ustawić w .env lub przez docker secrets) DISCORD_TOKEN: ${DISCORD_TOKEN} DISCORD_CLIENT_ID: ${DISCORD_CLIENT_ID} DISCORD_CLIENT_SECRET: ${DISCORD_CLIENT_SECRET} # Web Panel JWT_SECRET: ${JWT_SECRET:-super_secret_jwt_key_change_in_production} SESSION_SECRET: ${SESSION_SECRET:-super_secret_session_key_change_in_production} WEB_PORT: 3001 API_PORT: 3000 # OAuth2 OAUTH2_REDIRECT_URI: ${OAUTH2_REDIRECT_URI:-http://localhost:3001/auth/discord/callback} # Environment NODE_ENV: ${NODE_ENV:-production} LOG_LEVEL: ${LOG_LEVEL:-info} # Redis (optional) REDIS_URL: redis://redis:6379 ports: - "3000:3000" - "3001:3001" depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - skrzynka-network volumes: - ./logs:/app/logs healthcheck: test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000/api/health', (res) => { process.exit(res.statusCode === 200 ? 0 : 1) })"] interval: 30s timeout: 10s retries: 3 start_period: 40s # Nginx Reverse Proxy (production) nginx: image: nginx:alpine container_name: skrzynka-nginx restart: unless-stopped ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/conf.d:/etc/nginx/conf.d:ro - ./ssl:/etc/nginx/ssl:ro - nginx_logs:/var/log/nginx depends_on: - bot networks: - skrzynka-network profiles: - production # Volumes volumes: postgres_data: driver: local redis_data: driver: local nginx_logs: driver: local # Networks networks: skrzynka-network: driver: bridge