# TaskFlow - Docker Deployment Guide

This guide explains how to deploy TaskFlow using Docker with a separate PostgreSQL database.

## Prerequisites

- Docker Engine 20.10 or later
- Docker Compose 2.0 or later
- At least 2GB of available RAM
- 10GB of available disk space

## Quick Start

### 1. Environment Configuration

Create a `.env` file in the root directory:

```bash
cp .env.example .env
```

Edit the `.env` file with your configuration:

```env
# Application Configuration
NODE_ENV=production
PORT=5000

# Database Configuration
POSTGRES_USER=taskflow
POSTGRES_PASSWORD=your_secure_password_here
POSTGRES_DB=taskflow
POSTGRES_PORT=5432

# Database URL (update with your credentials)
DATABASE_URL=postgresql://taskflow:your_secure_password_here@postgres:5432/taskflow

# Application Port (external mapping)
APP_PORT=5000
```

**Important:** Change the `POSTGRES_PASSWORD` to a secure password!

### 2. Start the Application

```bash
# Build and start all services
docker-compose up -d

# View logs
docker-compose logs -f

# Check service status
docker-compose ps
```

The application will be available at `http://localhost:5000`

### 3. Stop the Application

```bash
# Stop services
docker-compose down

# Stop and remove volumes (WARNING: This will delete all data!)
docker-compose down -v
```

## Production Deployment

### Using Docker Stack (Swarm Mode)

1. **Initialize Docker Swarm** (if not already done):

```bash
docker swarm init
```

2. **Create a production `.env` file**:

```bash
# Set secure credentials
export POSTGRES_PASSWORD="your_very_secure_password"
export POSTGRES_USER="taskflow"
export POSTGRES_DB="taskflow"
```

3. **Deploy the stack**:

```bash
docker stack deploy -c docker-compose.yml taskflow
```

4. **Check stack status**:

```bash
docker stack services taskflow
docker stack ps taskflow
```

5. **View logs**:

```bash
docker service logs taskflow_app
docker service logs taskflow_postgres
```

6. **Remove the stack**:

```bash
docker stack rm taskflow
```

### Using External PostgreSQL Database

If you want to use an external PostgreSQL instance instead of the containerized one:

1. **Update `.env` file**:

```env
DATABASE_URL=postgresql://username:password@your-db-host:5432/your-db-name
```

2. **Modify `docker-compose.yml`** to remove the postgres service:

```yaml
version: '3.8'

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
      target: production
    container_name: taskflow-app
    restart: unless-stopped
    environment:
      NODE_ENV: production
      DATABASE_URL: ${DATABASE_URL}
      PORT: 5000
    ports:
      - "${APP_PORT:-5000}:5000"
```

3. **Start only the app service**:

```bash
docker-compose up app -d
```

## Database Management

### Backup Database

```bash
# Create backup
docker exec taskflow-db pg_dump -U taskflow taskflow > backup_$(date +%Y%m%d_%H%M%S).sql

# Or using docker-compose
docker-compose exec postgres pg_dump -U taskflow taskflow > backup.sql
```

### Restore Database

```bash
# Restore from backup
docker exec -i taskflow-db psql -U taskflow taskflow < backup.sql

# Or using docker-compose
docker-compose exec -T postgres psql -U taskflow taskflow < backup.sql
```

### Access Database

```bash
# Connect to PostgreSQL shell
docker exec -it taskflow-db psql -U taskflow -d taskflow

# Or using docker-compose
docker-compose exec postgres psql -U taskflow -d taskflow
```

### Run Migrations

The application automatically runs database migrations on startup. To manually trigger migrations:

```bash
# Inside the container
docker exec taskflow-app npm run db:push

# Or rebuild and restart
docker-compose up --build -d
```

## Monitoring and Maintenance

### Health Checks

Both services have health checks configured:

- **App**: `http://localhost:5000/api/health`
- **Database**: Automatic PostgreSQL health check

Check health status:

```bash
docker-compose ps
```

### View Logs

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

# Specific service
docker-compose logs -f app
docker-compose logs -f postgres

# Last 100 lines
docker-compose logs --tail=100 app
```

### Update Application

```bash
# Pull latest changes
git pull

# Rebuild and restart
docker-compose up --build -d

# Remove old images
docker image prune -f
```

## Troubleshooting

### Application won't start

1. Check logs: `docker-compose logs app`
2. Verify DATABASE_URL is correct
3. Ensure PostgreSQL is healthy: `docker-compose ps`

### Database connection errors

1. Verify PostgreSQL is running: `docker-compose ps postgres`
2. Check connection string in `.env`
3. Ensure network connectivity: `docker network inspect taskflow_taskflow-network`

### Port already in use

Change the `APP_PORT` in `.env` file:

```env
APP_PORT=8080
```

Then restart: `docker-compose up -d`

### Out of disk space

```bash
# Remove unused images
docker image prune -a

# Remove unused volumes
docker volume prune

# Remove unused networks
docker network prune
```

## Security Best Practices

1. **Change default passwords** in `.env` file
2. **Use environment variables** for sensitive data
3. **Enable SSL/TLS** for production databases
4. **Restrict network access** using firewall rules
5. **Regular backups** of database
6. **Keep Docker images updated** regularly
7. **Use secrets management** for production (Docker Secrets, Vault, etc.)

## Performance Tuning

### PostgreSQL

Edit `docker-compose.yml` to add PostgreSQL configuration:

```yaml
postgres:
  command: postgres -c max_connections=200 -c shared_buffers=256MB
```

### Application

Scale the application service:

```bash
docker-compose up -d --scale app=3
```

## Support

For issues and questions:
- Check logs first: `docker-compose logs`
- Review this guide
- Check Docker and PostgreSQL documentation
