# Taskboard Deployment Guide

This guide will help you deploy the Taskboard application using Docker and Portainer with nginx-proxy-manager.

## Prerequisites

- Docker installed
- Portainer running on your Ubuntu server
- nginx-proxy-manager set up and running
- Docker Hub account (for image hosting)
- Existing `.env` file with your configuration

## Key Features

✅ **Automatic Database Migrations**: Migrations run automatically on app startup  
✅ **Production-Ready**: Multi-stage build with security hardening  
✅ **Health Checks**: Built-in health monitoring  
✅ **Comprehensive Logging**: Structured logs with rotation  
✅ **nginx-proxy-manager Integration**: Seamless proxy setup  
✅ **Build Issues Fixed**: File API and bcryptjs compatibility resolved  
✅ **Peer Dependency Issues Fixed**: date-fns conflicts resolved with --legacy-peer-deps  

## Deployment Steps

### 1. Build Docker Image

Build your Docker image locally:

```bash
# Replace 'yourusername' with your Docker Hub username
docker build -t yourusername/taskboard:latest .
```

**What happens during build:**
- Installs all dependencies (including dev dependencies for build)
- **Fixed**: Uses `--legacy-peer-deps` to resolve date-fns version conflicts
- Generates Prisma client
- **Fixed**: File API compatibility during build process
- **Fixed**: bcryptjs Node.js API compatibility  
- Builds Next.js application with standalone output
- Creates production image with only necessary files
- Includes Prisma CLI for database migrations
- Sets up automatic migration on startup

**Build Environment Variables Set:**
- `NODE_ENV=production` - Production build mode
- `NEXT_TELEMETRY_DISABLED=1` - Disable telemetry during build
- `SKIP_ENV_VALIDATION=1` - Skip environment validation during build

**Dependency Resolution:**
- Uses `--legacy-peer-deps` to handle date-fns v4 with react-day-picker v8 compatibility
- Safe backward compatibility maintained for all date/calendar functionality

### 2. Push to Docker Hub

Login and push your image:

```bash
# Login to Docker Hub
docker login

# Push the image
docker push yourusername/taskboard:latest
```

### 3. Deploy with Portainer

#### Using Portainer UI:

1. **Login to Portainer**
2. **Navigate to Stacks**
3. **Click "Add Stack"**
4. **Enter Stack Name**: `taskboard`
5. **Copy the contents of `portainer-stack.yml`** into the web editor
6. **Set Environment Variables** (click "Environment variables" section):

   **Required Variables:**
   - `POSTGRES_PASSWORD` - Your database password (e.g., `mySecurePassword123`)
   - `NEXTAUTH_URL` - Your application URL (e.g., `https://taskboard.yourdomain.com`)
   - `AUTH_SECRET` - NextAuth secret key (32+ characters random string)
   - `DOCKER_IMAGE` - Your Docker image (e.g., `yourusername/taskboard:latest`)
   - `VIRTUAL_HOST` - Your domain name (e.g., `taskboard.yourdomain.com`)
   - `LETSENCRYPT_HOST` - Domain for SSL certificate (same as VIRTUAL_HOST)
   - `LETSENCRYPT_EMAIL` - Your email for Let's Encrypt (e.g., `admin@yourdomain.com`)

   **Optional Variables (if using Authentik):**
   - `AUTHENTIK_ID` - Your Authentik client ID
   - `AUTHENTIK_SECRET` - Your Authentik client secret

7. **Deploy the Stack**

### 4. Configure nginx-proxy-manager

1. **Login to nginx-proxy-manager**
2. **Add Proxy Host**:
   - **Domain Name**: `taskboard.yourdomain.com`
   - **Scheme**: `http`
   - **Forward Hostname/IP**: `taskboard-app` (container name)
   - **Forward Port**: `3000`
   - **Enable SSL**: Yes (Let's Encrypt)
   - **Email**: Your email for Let's Encrypt

### 5. Verify Deployment

1. **Check Container Status**:
   ```bash
   docker ps
   ```

2. **Check Logs** (migrations will run automatically):
   ```bash
   docker logs taskboard-app
   ```
   You should see:
   ```
   Running database migrations...
   Environment variables loaded from .env
   Prisma schema loaded from prisma/schema.prisma
   Starting application...
   ```

3. **Test Health Endpoint**:
   ```bash
   curl https://taskboard.yourdomain.com/api/health
   ```

4. **Access Application**:
   Navigate to `https://taskboard.yourdomain.com`

## How Migrations Work

**Automatic Migration Process:**
1. Container starts up
2. Runs `npx prisma migrate deploy` automatically
3. If migrations succeed, starts the Next.js application
4. If migrations fail, logs error but continues (for debugging)

**Migration Logs:**
```bash
docker logs taskboard-app
```

## Environment Variables Required

Make sure your `.env` file contains these variables (or set them in Portainer):

| Variable | Description | Example | Required |
|----------|-------------|---------|----------|
| `POSTGRES_PASSWORD` | Database password | `secure_password_123` | ✅ |
| `NEXTAUTH_URL` | Application URL | `https://taskboard.yourdomain.com` | ✅ |
| `AUTH_SECRET` | NextAuth secret | `32+ character random string` | ✅ |
| `DOCKER_IMAGE` | Docker image name | `yourusername/taskboard:latest` | ✅ |
| `VIRTUAL_HOST` | Domain for proxy | `taskboard.yourdomain.com` | ✅ |
| `LETSENCRYPT_HOST` | SSL certificate domain | `taskboard.yourdomain.com` | ✅ |
| `LETSENCRYPT_EMAIL` | Email for SSL cert | `admin@yourdomain.com` | ✅ |
| `AUTHENTIK_ID` | Authentik client ID | `your_client_id` | ❌ |
| `AUTHENTIK_SECRET` | Authentik client secret | `your_client_secret` | ❌ |

## Troubleshooting

### Common Issues

#### 1. Build Failures ✅ **FIXED**
- **File API Issues**: Fixed by adding runtime checks for File API availability
- **bcryptjs Issues**: Fixed with webpack externals and serverComponentsExternalPackages
- **Next.js Config Issues**: Removed invalid `dynamicIO` option
- **Peer Dependency Conflicts**: Fixed with `--legacy-peer-deps` flag

#### 2. Peer Dependency Issues ✅ **FIXED**
- **date-fns Conflict**: `react-day-picker@8.10.1` requires `date-fns@^2.28.0 || ^3.0.0` but project uses `date-fns@^4.1.0`
- **Solution**: Uses `--legacy-peer-deps` during install - safe backward compatibility
- **Calendar Functionality**: Works perfectly with date-fns v4 due to backward compatibility

#### 3. Database Connection Issues
- **Check if PostgreSQL container is running**: `docker ps`
- **Verify database credentials** in environment variables
- **Check network connectivity**: Both containers should be on `taskboard-network`

#### 4. Migration Issues
- **Check migration logs**: `docker logs taskboard-app`
- **Look for migration output**: Shows during container startup
- **Manual migration**: If needed, run `docker exec taskboard-app npx prisma migrate deploy`

#### 5. NextAuth Issues
- **Verify `AUTH_SECRET`**: Must be 32+ characters and secure
- **Check `NEXTAUTH_URL`**: Must match your domain exactly (including https://)
- **Authentik configuration**: Ensure Authentik settings are correct (if using)

#### 6. nginx-proxy-manager Issues
- **Verify network**: Check if `nginx-proxy-manager_default` network exists
- **Container connectivity**: Ensure containers can communicate
- **Domain matching**: VIRTUAL_HOST must match your domain exactly

#### 7. File Upload Issues ✅ **FIXED**
- **File API compatibility**: Fixed with conditional File type checking
- **Server-side file handling**: Properly handles File objects in API routes
- **Build-time errors**: Resolved with runtime type guards

### Log Analysis

**Container Logs:**
```bash
# App logs (includes migration output)
docker logs -f taskboard-app

# Database logs
docker logs -f taskboard-postgres
```

**What to look for in logs:**
- Migration success/failure messages
- Database connection status
- Application startup messages
- Health check results
- **No more File API errors during build**
- **No more peer dependency conflicts**

### Health Checks

**Application Health Check:**
- **Endpoint**: `https://yourdomain.com/api/health`
- **Returns**: Status, timestamp, uptime
- **Frequency**: Every 30 seconds

**Database Health Check:**
- **Method**: PostgreSQL ping
- **Frequency**: Every 30 seconds

## Architecture

```
Internet
    ↓
nginx-proxy-manager (SSL termination, domain routing)
    ↓
taskboard-app (Next.js application on port 3000)
    ↓ (on startup)
Database Migrations
    ↓
taskboard-postgres (PostgreSQL database on port 5432)
```

## Networks
- `nginx-proxy-manager_default`: External network for proxy access
- `taskboard-network`: Internal network for app-database communication

## Volumes
- `postgres_data`: PostgreSQL data persistence
- `app_uploads`: File uploads storage
- `app_logs`: Application logs storage

## Security Considerations

1. **Environment Variables**:
   - Use strong, unique passwords (12+ characters)
   - Keep `AUTH_SECRET` secure and random (32+ characters)
   - Don't commit `.env` files to version control

2. **Database**:
   - Use non-default database credentials
   - Regular backups recommended

3. **Network**:
   - Containers isolated on dedicated networks
   - SSL/TLS handled by nginx-proxy-manager

## Backup Strategy

1. **Database Backup**:
   ```bash
   docker exec taskboard-postgres pg_dump -U taskboard_user taskboard > backup.sql
   ```

2. **File Uploads Backup**:
   ```bash
   docker cp taskboard-app:/app/uploads ./uploads-backup
   ```

## Quick Commands Summary

```bash
# Build image
docker build -t yourusername/taskboard:latest .

# Push to Docker Hub  
docker login
docker push yourusername/taskboard:latest

# Check running containers
docker ps

# View logs (includes migration output)
docker logs taskboard-app

# Health check
curl https://yourdomain.com/api/health

# Manual migration (if needed)
docker exec taskboard-app npx prisma migrate deploy
```

## What's Fixed ✅

✅ **Build Issues**: Proper dependency installation for Next.js build  
✅ **Migration Issues**: Automatic migrations on startup  
✅ **Health Check Issues**: Curl properly installed  
✅ **Prisma Issues**: CLI available for migrations  
✅ **Production Optimization**: Multi-stage build with security hardening  
✅ **File API Issues**: Runtime type guards for File objects  
✅ **bcryptjs Issues**: Webpack externals and server components config  
✅ **Next.js Config Issues**: Removed invalid experimental options  
✅ **Peer Dependency Issues**: date-fns v4 compatibility with --legacy-peer-deps  
✅ **Calendar Functionality**: Works perfectly with date-fns v4 due to backward compatibility  

## Build Error Solutions

| Error | Solution |
|-------|----------|
| `File is not defined` | ✅ Fixed with runtime File API checks |
| `bcryptjs Node.js API` warnings | ✅ Fixed with webpack externals |
| `Invalid dynamicIO option` | ✅ Removed from next.config.mjs |
| `Cannot find module 'zod'` | ✅ Proper dependency installation |
| `ERESOLVE date-fns conflict` | ✅ Using `--legacy-peer-deps` flag |
| `react-day-picker peer deps` | ✅ Safe backward compatibility maintained |
| Build failing on dependencies | ✅ Using npm install with legacy-peer-deps |