task-board/DEPLOYMENT.md
2025-06-24 14:26:42 +04:00

325 lines
11 KiB
Markdown

# 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 |