# Cube Database - Docker & Podman Guide

## Overview

Run Cube database in containers using Docker or Podman with full cluster support.

## Quick Start

### Docker
```bash
# Build and start 3-node cluster
docker-compose up -d

# Check status
docker-compose ps

# View logs
docker-compose logs -f
```

### Podman
```bash
# Build and start 3-node cluster
podman-compose up -d

# Check status
podman-compose ps

# View logs
podman-compose logs -f
```

---

## Prerequisites

### Docker
```bash
# Install Docker
# Ubuntu/Debian:
sudo apt-get install docker.io docker-compose

# macOS:
brew install docker docker-compose

# Verify
docker --version
docker-compose --version
```

### Podman
```bash
# Install Podman
# Ubuntu/Debian:
sudo apt-get install podman podman-compose

# Fedora/RHEL:
sudo dnf install podman podman-compose

# macOS:
brew install podman podman-compose

# Verify
podman --version
podman-compose --version
```

---

## Building the Image

### Docker
```bash
# Build image
docker build -t cube-db:latest .

# Verify
docker images | grep cube-db
```

### Podman
```bash
# Build image
podman build -t cube-db:latest .

# Verify
podman images | grep cube-db
```

---

## Running Single Node

### Docker
```bash
# Run single node
docker run -d \
  --name cube-node-1 \
  -p 8080:8080 \
  -e CUBE_NODE_ID=node-1 \
  -e JAVA_OPTS="-Xmx1G" \
  -v cube-data:/var/lib/cube/data \
  cube-db:latest

# Check logs
docker logs -f cube-node-1

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

### Podman
```bash
# Run single node
podman run -d \
  --name cube-node-1 \
  -p 8080:8080 \
  -e CUBE_NODE_ID=node-1 \
  -e JAVA_OPTS="-Xmx1G" \
  -v cube-data:/var/lib/cube/data:Z \
  cube-db:latest

# Check logs
podman logs -f cube-node-1

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

---

## Running 3-Node Cluster

### Docker Compose

**docker-compose.yml** is already configured. Just run:

```bash
# Start cluster
docker-compose up -d

# View status
docker-compose ps

# Expected output:
#     Name              State    Ports
# --------------------------------------------
# cube-node-1    Up      0.0.0.0:8080->8080/tcp
# cube-node-2    Up      0.0.0.0:8081->8080/tcp
# cube-node-3    Up      0.0.0.0:8082->8080/tcp

# Check all are healthy
docker-compose ps | grep healthy

# View logs for all nodes
docker-compose logs -f

# View logs for specific node
docker-compose logs -f cube-node-1
```

### Podman Compose

**podman-compose.yml** is configured for Podman:

```bash
# Start cluster
podman-compose up -d

# View status
podman-compose ps

# Check health
for port in 8080 8081 8082; do
  echo "Node on port $port:"
  curl -s http://localhost:$port/api/v1/health
done

# View logs
podman-compose logs -f
```

---

## Connecting to the Cluster

### Using CubeShell

```bash
# From host machine
./run-shell.sh --host localhost --port 8080

# Connect to all nodes
cube> CONNECT localhost 8080
cube> CONNECT localhost 8081
cube> CONNECT localhost 8082
cube> NODES
```

### Using API

```bash
# Node 1
curl -X POST http://localhost:8080/api/v1/put \
  -H "Content-Type: application/json" \
  -d '{"key":"test","value":"hello"}'

# Node 2
curl http://localhost:8081/api/v1/get/test

# Node 3
curl http://localhost:8082/api/v1/get/test
```

### Exec into Container

**Docker:**
```bash
# Enter container
docker exec -it cube-node-1 /bin/bash

# Inside container
cd /opt/cube-db
curl localhost:8080/api/v1/health
```

**Podman:**
```bash
# Enter container
podman exec -it cube-node-1 /bin/bash

# Inside container
cd /opt/cube-db
curl localhost:8080/api/v1/health
```

---

## Environment Variables

| Variable | Default | Description |
|----------|---------|-------------|
| `CUBE_NODE_ID` | node-1 | Unique node identifier |
| `CUBE_HOST` | 0.0.0.0 | Listen address |
| `CUBE_PORT` | 8080 | API port |
| `CUBE_DATA_DIR` | /var/lib/cube/data | Data directory |
| `CUBE_HINTS_DIR` | /var/lib/cube/hints | Hints directory |
| `JAVA_OPTS` | -Xmx1G -Xms512M | JVM options |

### Custom Configuration

```bash
docker run -d \
  --name cube-custom \
  -p 9090:9090 \
  -e CUBE_NODE_ID=custom-node \
  -e CUBE_PORT=9090 \
  -e JAVA_OPTS="-Xmx2G -Xms1G" \
  cube-db:latest
```

---

## Volume Management

### Docker

```bash
# List volumes
docker volume ls | grep cube

# Inspect volume
docker volume inspect cube-node-1-data

# Backup volume
docker run --rm \
  -v cube-node-1-data:/data \
  -v $(pwd):/backup \
  ubuntu tar czf /backup/cube-node-1-backup.tar.gz /data

# Restore volume
docker run --rm \
  -v cube-node-1-data:/data \
  -v $(pwd):/backup \
  ubuntu tar xzf /backup/cube-node-1-backup.tar.gz -C /

# Remove volume (WARNING: deletes data)
docker volume rm cube-node-1-data
```

### Podman

```bash
# List volumes
podman volume ls | grep cube

# Inspect volume
podman volume inspect cube-node-1-data

# Backup volume
podman run --rm \
  -v cube-node-1-data:/data:Z \
  -v $(pwd):/backup:Z \
  ubuntu tar czf /backup/cube-node-1-backup.tar.gz /data

# Restore volume
podman run --rm \
  -v cube-node-1-data:/data:Z \
  -v $(pwd):/backup:Z \
  ubuntu tar xzf /backup/cube-node-1-backup.tar.gz -C /

# Remove volume
podman volume rm cube-node-1-data
```

---

## Cluster Operations

### Stop Cluster

**Docker:**
```bash
docker-compose stop
```

**Podman:**
```bash
podman-compose stop
```

### Restart Cluster

**Docker:**
```bash
docker-compose restart
```

**Podman:**
```bash
podman-compose restart
```

### Remove Cluster (keeps volumes)

**Docker:**
```bash
docker-compose down
```

**Podman:**
```bash
podman-compose down
```

### Remove Everything (including volumes)

**Docker:**
```bash
docker-compose down -v
```

**Podman:**
```bash
podman-compose down -v
```

---

## Scaling the Cluster

### Add Node 4

Edit `docker-compose.yml` or `podman-compose.yml`:

```yaml
  cube-node-4:
    build: .
    container_name: cube-node-4
    hostname: cube-node-4
    environment:
      - CUBE_NODE_ID=node-4
      - CUBE_HOST=cube-node-4
      - CUBE_PORT=8080
    ports:
      - "8083:8080"
    volumes:
      - cube-node-4-data:/var/lib/cube/data:Z
      - cube-node-4-hints:/var/lib/cube/hints:Z
    networks:
      - cube-cluster
```

Then:
```bash
docker-compose up -d
# or
podman-compose up -d
```

---

## Monitoring

### Health Checks

```bash
# Check all nodes
for port in 8080 8081 8082; do
  echo "Node $port:"
  curl -s http://localhost:$port/api/v1/health | jq
done

# Output:
# {
#   "status": "UP",
#   "database": "Cube DB",
#   "version": "1.0.0"
# }
```

### Statistics

```bash
# Get stats from each node
for port in 8080 8081 8082; do
  echo "Node $port stats:"
  curl -s http://localhost:$port/api/v1/stats | jq
done
```

### Container Stats

**Docker:**
```bash
docker stats cube-node-1 cube-node-2 cube-node-3
```

**Podman:**
```bash
podman stats cube-node-1 cube-node-2 cube-node-3
```

### Logs

**Docker:**
```bash
# All nodes
docker-compose logs -f

# Specific node
docker logs -f cube-node-1

# Last 100 lines
docker logs --tail 100 cube-node-1

# Since timestamp
docker logs --since 2024-01-01T00:00:00 cube-node-1
```

**Podman:**
```bash
# All nodes
podman-compose logs -f

# Specific node
podman logs -f cube-node-1

# Last 100 lines
podman logs --tail 100 cube-node-1
```

---

## Testing Node Recovery

### Simulate Node Failure

**Docker:**
```bash
# Stop node 3
docker stop cube-node-3

# Write data while node 3 is down
curl -X POST http://localhost:8080/api/v1/put \
  -H "Content-Type: application/json" \
  -d '{"key":"test:recovery","value":"data during outage"}'

# Restart node 3
docker start cube-node-3

# Wait 10 seconds for hint replay
sleep 10

# Verify data on node 3
curl http://localhost:8082/api/v1/get/test:recovery
```

**Podman:**
```bash
# Stop node 3
podman stop cube-node-3

# Write data
curl -X POST http://localhost:8080/api/v1/put \
  -H "Content-Type: application/json" \
  -d '{"key":"test:recovery","value":"data during outage"}'

# Restart node 3
podman start cube-node-3

# Wait for hint replay
sleep 10

# Verify
curl http://localhost:8082/api/v1/get/test:recovery
```

---

## Production Deployment

### Resource Limits

Add to `docker-compose.yml`:

```yaml
services:
  cube-node-1:
    # ... existing config ...
    deploy:
      resources:
        limits:
          cpus: '2'
          memory: 2G
        reservations:
          cpus: '1'
          memory: 1G
```

### Logging

Configure JSON logging:

```yaml
services:
  cube-node-1:
    # ... existing config ...
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
```

### Networking

Use host networking for better performance:

```bash
docker run -d \
  --name cube-node-1 \
  --network host \
  -e CUBE_PORT=8080 \
  cube-db:latest
```

---

## Troubleshooting

### Container won't start

```bash
# Check logs
docker logs cube-node-1

# Common issues:
# - Port already in use
# - Volume permission issues
# - Out of memory
```

### Can't connect between nodes

```bash
# Check network
docker network inspect cube_cube-cluster

# Ensure all containers are on same network
docker network connect cube_cube-cluster cube-node-1
```

### Volume permission issues (Podman)

```bash
# Add :Z flag to volumes for SELinux
-v cube-data:/var/lib/cube/data:Z
```

### Out of memory

```bash
# Increase heap size
-e JAVA_OPTS="-Xmx2G -Xms1G"
```

---

## Podman-Specific Features

### Rootless Containers

```bash
# Run without root
podman run -d \
  --name cube-node-1 \
  -p 8080:8080 \
  cube-db:latest

# Check user
podman exec cube-node-1 whoami
# Output: cubedb (non-root)
```

### Pods

Create a pod for all nodes:

```bash
# Create pod
podman pod create --name cube-cluster -p 8080-8082:8080

# Run nodes in pod
podman run -d --pod cube-cluster \
  --name cube-node-1 \
  -e CUBE_NODE_ID=node-1 \
  cube-db:latest

# List pods
podman pod ps
```

### SystemD Integration

```bash
# Generate systemd unit
podman generate systemd --new --name cube-node-1 \
  > ~/.config/systemd/user/cube-node-1.service

# Enable and start
systemctl --user enable cube-node-1
systemctl --user start cube-node-1
```

---

## Summary

| Feature | Docker | Podman |
|---------|--------|--------|
| Multi-node cluster | ✓ | ✓ |
| Volume persistence | ✓ | ✓ |
| Health checks | ✓ | ✓ |
| Rootless | ✗ | ✓ |
| SystemD integration | ✗ | ✓ |
| Pods | ✗ | ✓ |

Both work great! Choose based on your preference:
- **Docker**: Industry standard, great tooling
- **Podman**: Rootless, daemonless, pod support

---

## Quick Reference

```bash
# Build
docker build -t cube-db .

# Run single node
docker run -d -p 8080:8080 cube-db

# Run cluster
docker-compose up -d

# Check status
docker-compose ps

# View logs
docker logs -f cube-node-1

# Stop cluster
docker-compose down

# Clean up
docker-compose down -v
```

**Your Cube database is now containerized!** 🐳
