# Docker Setup for APSKEL POS Backend

This document describes how to run the APSKEL POS Backend using Docker and Docker Compose.

## Prerequisites

- Docker (version 20.10 or later)
- Docker Compose (version 2.0 or later)
- Git (for cloning the repository)
- Go 1.21+ (for local development)

## Quick Start

### 1. Build and Run Production Environment

```bash
# Build and start all services
./docker-build.sh run

# Or manually:
docker-compose up -d
```

The application will be available at:
- **Backend API**: http://localhost:3300
- **Database**: localhost:5432
- **Redis**: localhost:6379

### 2. Development Environment

```bash
# Start development environment with live reload
./docker-build.sh dev

# Or manually:
docker-compose --profile dev up -d
```

Development environment provides:
- **Backend API (Dev)**: http://localhost:3001 (with live reload)
- **Backend API (Prod)**: http://localhost:3300
- Auto-restart on code changes using Air

### 3. Database Migrations

```bash
# Run database migrations
./docker-build.sh migrate

# Or manually:
docker-compose --profile migrate up migrate
```

## Build Script Usage

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

```bash
# Build Docker image
./docker-build.sh build

# Build and run production environment
./docker-build.sh run

# Start development environment
./docker-build.sh dev

# Run database migrations
./docker-build.sh migrate

# Stop all containers
./docker-build.sh stop

# Clean up containers and images
./docker-build.sh clean

# Show container logs
./docker-build.sh logs

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

## Services

### Backend API
- **Port**: 3300 (production), 3001 (development)
- **Health Check**: http://localhost:3300/health
- **Environment**: Configurable via `infra/` directory
- **User**: Runs as non-root user for security

### PostgreSQL Database
- **Port**: 5432
- **Database**: apskel_pos
- **Username**: apskel
- **Password**: See docker-compose.yaml
- **Volumes**: Persistent data storage

### Redis Cache
- **Port**: 6379
- **Usage**: Caching and session storage
- **Volumes**: Persistent data storage

## Environment Configuration

The application uses configuration files from the `infra/` directory:

- `infra/development.yaml` - Development configuration
- `infra/production.yaml` - Production configuration (create if needed)

### Configuration Structure

```yaml
server:
  port: 3300

postgresql:
  host: postgres  # Use service name in Docker
  port: 5432
  db: apskel_pos
  username: apskel
  password: 7a8UJbM2GgBWaseh0lnP3O5i1i5nINXk

jwt:
  token:
    secret: "your-jwt-secret"
    expires-ttl: 1440

s3:
  access_key_id: "your-s3-key"
  access_key_secret: "your-s3-secret"
  endpoint: "your-s3-endpoint"
  bucket_name: "your-bucket"

log:
  log_level: "info"
  log_format: "json"
```

## Docker Compose Profiles

### Default Profile (Production)
```bash
docker-compose up -d
```
Starts: postgres, redis, backend

### Development Profile
```bash
docker-compose --profile dev up -d
```
Starts: postgres, redis, backend, backend-dev

### Migration Profile
```bash
docker-compose --profile migrate up migrate
```
Runs: database migrations

## Health Checks

All services include health checks:

- **Backend**: HTTP GET /health
- **PostgreSQL**: pg_isready command
- **Redis**: Redis ping command

## Logging

View logs for specific services:

```bash
# All services
docker-compose logs -f

# Backend only
docker-compose logs -f backend

# Database only
docker-compose logs -f postgres

# Development backend
docker-compose logs -f backend-dev
```

## Volumes

### Persistent Volumes
- `postgres_data`: Database files
- `redis_data`: Redis persistence files
- `go_modules`: Go module cache (development)

### Bind Mounts
- `./infra:/infra:ro`: Configuration files (read-only)
- `./migrations:/app/migrations:ro`: Database migrations (read-only)
- `.:/app`: Source code (development only)

## Security

### Production Security Features
- Non-root user execution
- Read-only configuration mounts
- Minimal base image (Debian slim)
- Health checks for monitoring
- Resource limits (configurable)

### Network Security
- Internal Docker network isolation
- Only necessary ports exposed
- Service-to-service communication via Docker network

## Troubleshooting

### Common Issues

1. **Go Version Compatibility Error**
   ```bash
   # Error: package slices is not in GOROOT
   # Solution: Make sure Dockerfile uses Go 1.21+ 
   # Check go.mod file requires Go 1.21 or later
   ```

2. **Port Already in Use**
   ```bash
   # Check what's using the port
   lsof -i :3300
   
   # Change ports in docker-compose.yaml if needed
   ```

3. **Database Connection Failed**
   ```bash
   # Check if database is running
   docker-compose ps postgres
   
   # Check database logs
   docker-compose logs postgres
   ```

4. **Permission Denied**
   ```bash
   # Make sure script is executable
   chmod +x docker-build.sh
   ```

5. **Out of Disk Space**
   ```bash
   # Clean up unused Docker resources
   docker system prune -a
   
   # Remove old images
   docker image prune -a
   ```

### Debug Mode

Run containers in debug mode:

```bash
# Start with debug logs
ENV_MODE=development docker-compose up

# Enter running container
docker-compose exec backend sh

# Check application logs
docker-compose logs -f backend
```

### Performance Tuning

For production deployment:

1. **Resource Limits**: Add resource limits to docker-compose.yaml
2. **Environment**: Use production configuration
3. **Logging**: Adjust log levels
4. **Health Checks**: Tune intervals for your needs

```yaml
services:
  backend:
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M
```

## API Testing

Once the application is running, test the API:

```bash
# Health check
curl http://localhost:3300/health

# Analytics endpoint (requires authentication)
curl -H "Authorization: Bearer <token>" \
     -H "Organization-ID: <org-id>" \
     "http://localhost:3300/api/v1/analytics/profit-loss?date_from=01-12-2023&date_to=31-12-2023"
```

## Deployment

For production deployment:

1. Update configuration in `infra/production.yaml`
2. Set appropriate environment variables
3. Use production Docker Compose file
4. Configure reverse proxy (nginx, traefik)
5. Set up SSL certificates
6. Configure monitoring and logging

```bash
# Production deployment
ENV_MODE=production docker-compose -f docker-compose.prod.yaml up -d
``` 