# Docker Setup for GridPilot

This document describes the Docker setup for local development and production deployment of GridPilot.

## Quick Start

### Development

Start all services with hot-reloading:
```bash
npm run docker:dev:build
```

This will:
- Start PostgreSQL database on port 5432
- Start API on port 3000 (with debugger on 9229)
- Start Website on port 3001
- Enable hot-reloading for both apps

Access:
- Website: http://localhost:3001
- API: http://localhost:3000
- Database: localhost:5432

### Production

Start all services in production mode:
```bash
npm run docker:prod:build
```

This will:
- Build optimized Docker images
- Start PostgreSQL, Redis, API, Website, and Nginx
- Enable health checks, auto-restart, and resource limits
- Configure caching and performance optimizations

Access:
- Nginx (Website + API): http://localhost:80

## Available Commands

### Development
- `npm run docker:dev` - Start dev environment
- `npm run docker:dev:build` - Rebuild and start
- `npm run docker:dev:down` - Stop services
- `npm run docker:dev:logs` - View logs
- `npm run docker:dev:clean` - Stop and remove volumes

### Production
- `npm run docker:prod` - Start prod environment
- `npm run docker:prod:build` - Rebuild and start
- `npm run docker:prod:down` - Stop services
- `npm run docker:prod:logs` - View logs
- `npm run docker:prod:clean` - Stop and remove volumes

## Environment Variables

### Development (.env.development)
Copy and customize as needed. Default values work out of the box.

### Production (.env.production)
**IMPORTANT**: Update these before deploying:
- Database credentials (POSTGRES_PASSWORD, DATABASE_URL)
- API URLs (NEXT_PUBLIC_API_URL, NEXT_PUBLIC_SITE_URL)
- Vercel KV credentials (required for production)

## Architecture

### Development Setup
- Hot-reloading enabled via volume mounts
- Source code changes reflect immediately
- Database persisted in named volume
- Debug port exposed for API (9229)

### Production Setup
- Multi-stage builds for optimized images
- Only production dependencies included
- Nginx reverse proxy for both services
- Health checks for all services
- Auto-restart on failure

## Docker Services

### API (NestJS)
- Dev: `apps/api/Dockerfile.dev`
- Prod: `apps/api/Dockerfile.prod`
- Port: 3000
- Debug: 9229 (dev only)

### Website (Next.js)
- Dev: `apps/website/Dockerfile.dev`
- Prod: `apps/website/Dockerfile.prod`
- Port: 3001 (dev), 3000 (prod)

### Database (PostgreSQL)
- Image: postgres:15-alpine
- Port: 5432 (internal)
- Data: Persisted in Docker volume
- Optimized with performance tuning parameters

### Redis (Production only)
- Image: redis:7-alpine
- Port: 6379 (internal)
- Configured with:
  - LRU eviction policy
  - 512MB max memory
  - AOF persistence
  - Password protection

### Nginx (Production only)
- Reverse proxy for website + API
- Features:
  - Rate limiting (API: 10r/s, General: 30r/s)
  - Security headers (XSS, CSP, Frame-Options)
  - Gzip compression
  - Static asset caching
  - Connection pooling
  - Request buffering
- Port: 80, 443

## Troubleshooting

### Services won't start
```bash
# Clean everything and rebuild
npm run docker:dev:clean
npm run docker:dev:build
```

### Hot-reloading not working
Check that volume mounts are correct in docker-compose.dev.yml

### Database connection issues
Ensure DATABASE_URL in .env matches the database service configuration

### Check logs
```bash
# All services
npm run docker:dev:logs

# Specific service
docker-compose -f docker-compose.dev.yml logs -f api
docker-compose -f docker-compose.dev.yml logs -f website
docker-compose -f docker-compose.dev.yml logs -f db
```

## Tips

1. **First time setup**: Use `docker:dev:build` to ensure images are built
2. **Clean slate**: Use `docker:dev:clean` to remove all data and start fresh
3. **Production testing**: Test prod setup locally before deploying
4. **Database access**: Use any PostgreSQL client with credentials from .env file
5. **Debugging**: Attach debugger to port 9229 for API debugging

## Production Deployment

Before deploying to production:

1. Update `.env.production` with real credentials
2. Configure SSL certificates in `nginx/ssl/`
3. Update Nginx configuration for HTTPS
4. Set proper domain names in environment variables
5. Consider using Docker secrets for sensitive data

## File Structure

```
.
├── docker-compose.dev.yml       # Development orchestration
├── docker-compose.prod.yml      # Production orchestration
├── .env.development             # Dev environment variables
├── .env.production              # Prod environment variables
├── apps/
│   ├── api/
│   │   ├── Dockerfile.dev       # API dev image
│   │   ├── Dockerfile.prod      # API prod image
│   │   └── .dockerignore
│   └── website/
│       ├── Dockerfile.dev       # Website dev image
│       ├── Dockerfile.prod      # Website prod image
│       └── .dockerignore
└── nginx/
    └── nginx.conf               # Nginx configuration