# Docker Compose Development Environment Setup

This guide explains how to set up and use the Docker Compose development environment for the CBT SaaS Platform.

## Prerequisites

- Docker Desktop or Docker Engine installed
- Docker Compose installed (usually included with Docker Desktop)
- At least 4GB of available RAM
- At least 10GB of available disk space

## Quick Start

1. **Start the environment:**
   ```bash
   ./docker-dev.sh start
   ```

2. **Access services:**
   - **Golang API**: http://localhost:8080
   - **Adminer (Database UI)**: http://localhost:8081
   - **PostgreSQL**: localhost:5432
   - **Redis**: localhost:6380

3. **Stop the environment:**
   ```bash
   ./docker-dev.sh stop
   ```

## Services

The Docker Compose setup includes the following services:

### PostgreSQL 16
- **Port**: 5432
- **Database**: `cbt`
- **Username**: `postgres`
- **Password**: `postgres`
- **Data persistence**: Yes (volume: `postgres_data`)

### Redis 7
- **Port**: 6380 (mapped from container port 6379)
- **Data persistence**: Yes (volume: `redis_data`)

### Golang API
- **Port**: 8080
- **Hot reload**: Yes (using Air)
- **Health checks**: Yes
- **Dependencies**: PostgreSQL, Redis

### Adminer
- **Port**: 8081
- **Purpose**: Database management UI
- **Default server**: `postgres`
- **Login**: Use PostgreSQL credentials above

## Configuration

### Environment Variables

Copy `.env.docker` to customize settings:

```bash
cp .env.docker .env.local
```

Key environment variables:

```env
# Database
DB_NAME=cbt
DB_USER=postgres
DB_PASSWORD=postgres
DB_PORT=5432

# Redis
REDIS_PORT=6380
REDIS_PASSWORD=

# API
API_PORT=8080

# Adminer
ADMINER_PORT=8081
```

### Port Conflicts

If you have existing services using these ports, modify the values in `.env.docker`:

```env
# Example: Use different ports
DB_PORT=5433
REDIS_PORT=6381
API_PORT=8082
ADMINER_PORT=8082
```

## Development Script

The `docker-dev.sh` script provides convenient commands:

```bash
# Start all services
./docker-dev.sh start

# Stop all services
./docker-dev.sh stop

# Restart all services
./docker-dev.sh restart

# Show service status
./docker-dev.sh status

# View logs (all services)
./docker-dev.sh logs

# View logs for specific service
./docker-dev.sh logs api
./docker-dev.sh logs postgres
./docker-dev.sh logs redis

# Rebuild containers
./docker-dev.sh rebuild

# Create database backup
./docker-dev.sh backup

# Restore database from backup
./docker-dev.sh restore backup_20260406_120000.sql

# Remove everything (including volumes)
./docker-dev.sh clean

# Show help
./docker-dev.sh help
```

## Hot Reload

The Golang API service includes hot reload functionality using Air. Changes to the code in `cbt-backend/` will automatically rebuild and restart the API service.

### Hot Reload Details:
- **Tool**: Air (live reload tool for Go)
- **Watch path**: `/app` (mounted from `./cbt-backend`)
- **Build output**: `./tmp/main`
- **Config**: `.air.toml`

## Health Checks

All services include health checks:

```bash
# Check API health
curl http://localhost:8080/api/v1/health

# Check database connectivity
curl http://localhost:8080/api/v1/health/db

# Check Redis connectivity
curl http://localhost:8080/api/v1/health/redis
```

Expected response:
```json
{
  "status": "ok",
  "time": "2026-04-06T12:00:00Z"
}
```

## Database Management

### Using Adminer

1. Open http://localhost:8081
2. Login with:
   - **System**: PostgreSQL
   - **Server**: `postgres`
   - **Username**: `postgres`
   - **Password**: `postgres`
   - **Database**: `cbt`

### Using psql (from host)

```bash
# Connect to PostgreSQL
docker exec -it cbt-postgres psql -U postgres -d cbt

# Run SQL commands
SELECT version();
\dt  -- List tables
```

### Using redis-cli (from host)

```bash
# Connect to Redis
docker exec -it cbt-redis redis-cli

# Run Redis commands
PING
FLUSHDB  -- Clear all keys (use with caution)
```

## Data Persistence

Data is persisted in Docker volumes:

- `postgres_data`: PostgreSQL data directory
- `redis_data`: Redis data directory
- `go_modules`: Go module dependencies

### Backup and Restore

```bash
# Create backup
./docker-dev.sh backup

# Restore from backup
./docker-dev.sh restore backup_20260406_120000.sql
```

## Troubleshooting

### Services won't start

```bash
# Check logs
docker-compose logs

# Check specific service
docker-compose logs api

# Restart services
./docker-dev.sh restart
```

### Port conflicts

If you see "port is already allocated" errors:

1. Check what's using the port:
   ```bash
   lsof -i :8080  # Check API port
   lsof -i :5432  # Check PostgreSQL port
   lsof -i :6380  # Check Redis port
   ```

2. Update `.env.docker` with different ports

### Container keeps restarting

```bash
# Check container status
docker-compose ps

# View recent logs
docker-compose logs --tail=50 api

# Rebuild container
./docker-dev.sh rebuild
```

### Database connection issues

```bash
# Check PostgreSQL is healthy
docker-compose ps postgres

# Check PostgreSQL logs
docker-compose logs postgres

# Test connection from API container
docker-compose exec api ping postgres
```

### Clean restart

If you need to completely reset the environment:

```bash
# Stop and remove everything (including data)
./docker-dev.sh clean

# Start fresh
./docker-dev.sh start
```

## Development Workflow

1. **Start environment**: `./docker-dev.sh start`
2. **Make code changes**: Edit files in `cbt-backend/`
3. **View logs**: `./docker-dev.sh logs api`
4. **Test changes**: Access http://localhost:8080
5. **Stop when done**: `./docker-dev.sh stop`

## Architecture

```
┌─────────────────┐
│   Docker Host   │
│                 │
│ ┌─────────────┐ │
│ │   Adminer   │ │ ← Port 8081
│ └─────────────┘ │
│                 │
│ ┌─────────────┐ │
│ │  Go API     │ │ ← Port 8080
│ │  (hot reload)│ │
│ └─────────────┘ │
│        ↓        │
│ ┌─────────────┐ │
│ │ PostgreSQL  │ │ ← Port 5432
│ └─────────────┘ │
│        ↓        │
│ ┌─────────────┐ │
│ │   Redis     │ │ ← Port 6380
│ └─────────────┘ │
│                 │
│ ┌─────────────┐ │
│ │  Volumes    │ │
│ │  (data)     │ │
│ └─────────────┘ │
└─────────────────┘
```

## Production Considerations

This setup is for **development only**. For production:

1. Use separate containers for each service
2. Implement proper secrets management
3. Use TLS/SSL for all connections
4. Set resource limits on containers
5. Use external managed services (RDS, ElastiCache)
6. Implement proper monitoring and logging
7. Use multi-stage builds for smaller images
8. Scan images for vulnerabilities

## Additional Resources

- [Docker Compose Documentation](https://docs.docker.com/compose/)
- [PostgreSQL Docker Images](https://hub.docker.com/_/postgres)
- [Redis Docker Images](https://hub.docker.com/_/redis)
- [Air Hot Reload Tool](https://github.com/cosmtrek/air)
- [Adminer Documentation](https://www.adminer.org/)

## Support

For issues or questions:

1. Check the troubleshooting section above
2. Review service logs: `./docker-dev.sh logs`
3. Check Docker Desktop is running
4. Verify ports are not in use
5. Try clean restart: `./docker-dev.sh clean && ./docker-dev.sh start`
