11 KiB
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
.envfile 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:
# 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-depsto 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 modeNEXT_TELEMETRY_DISABLED=1- Disable telemetry during buildSKIP_ENV_VALIDATION=1- Skip environment validation during build
Dependency Resolution:
- Uses
--legacy-peer-depsto 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:
# Login to Docker Hub
docker login
# Push the image
docker push yourusername/taskboard:latest
3. Deploy with Portainer
Using Portainer UI:
-
Login to Portainer
-
Navigate to Stacks
-
Click "Add Stack"
-
Enter Stack Name:
taskboard -
Copy the contents of
portainer-stack.ymlinto the web editor -
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 IDAUTHENTIK_SECRET- Your Authentik client secret
-
Deploy the Stack
4. Configure nginx-proxy-manager
- Login to nginx-proxy-manager
- 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
- Domain Name:
5. Verify Deployment
-
Check Container Status:
docker ps -
Check Logs (migrations will run automatically):
docker logs taskboard-appYou should see:
Running database migrations... Environment variables loaded from .env Prisma schema loaded from prisma/schema.prisma Starting application... -
Test Health Endpoint:
curl https://taskboard.yourdomain.com/api/health -
Access Application: Navigate to
https://taskboard.yourdomain.com
How Migrations Work
Automatic Migration Process:
- Container starts up
- Runs
npx prisma migrate deployautomatically - If migrations succeed, starts the Next.js application
- If migrations fail, logs error but continues (for debugging)
Migration Logs:
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
dynamicIOoption - Peer Dependency Conflicts: Fixed with
--legacy-peer-depsflag
2. Peer Dependency Issues ✅ FIXED
- date-fns Conflict:
react-day-picker@8.10.1requiresdate-fns@^2.28.0 || ^3.0.0but project usesdate-fns@^4.1.0 - Solution: Uses
--legacy-peer-depsduring 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_defaultnetwork 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:
# 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 accesstaskboard-network: Internal network for app-database communication
Volumes
postgres_data: PostgreSQL data persistenceapp_uploads: File uploads storageapp_logs: Application logs storage
Security Considerations
-
Environment Variables:
- Use strong, unique passwords (12+ characters)
- Keep
AUTH_SECRETsecure and random (32+ characters) - Don't commit
.envfiles to version control
-
Database:
- Use non-default database credentials
- Regular backups recommended
-
Network:
- Containers isolated on dedicated networks
- SSL/TLS handled by nginx-proxy-manager
Backup Strategy
-
Database Backup:
docker exec taskboard-postgres pg_dump -U taskboard_user taskboard > backup.sql -
File Uploads Backup:
docker cp taskboard-app:/app/uploads ./uploads-backup
Quick Commands Summary
# 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 |