task-board/DEPLOYMENT_FIXES.md
2025-06-26 19:51:52 +04:00

7.4 KiB

Deployment Fixes Documentation

Overview

This document outlines the critical changes made to resolve deployment issues when containerizing the Next.js taskboard application with Docker and Portainer.

Major Issues Fixed

1. File API Reference Error

Problem: ReferenceError: File is not defined during build process Root Cause: Using z.instanceof(File) in Zod schemas - File API not available in server-side rendering context Solution:

  • Replaced z.instanceof(File) with runtime type guards in schema validation
  • Updated file validation to use object shape validation instead of instanceof checks
  • Modified affected schemas in src/features/workspaces/schemas.ts and src/features/projects/schemas.ts
// Before (caused error)
image: z.instanceof(File).optional()

// After (working solution)
image: z.any().optional() // with runtime validation in components

2. bcryptjs Edge Runtime Compatibility

Problem: TypeError: process.on is not a function and bcryptjs conflicts in Edge Runtime Root Cause: NextAuth and bcryptjs trying to use Node.js APIs in Edge Runtime environment Solution:

  • Added webpack externals configuration in next.config.mjs
  • Configured serverComponentsExternalPackages to handle bcryptjs properly
  • Replaced NextAuth middleware with simple pass-through middleware
// next.config.mjs additions
webpack: (config) => {
  config.externals = [...(config.externals || []), 'bcryptjs'];
  return config;
},
serverComponentsExternalPackages: ['bcryptjs']

3. Peer Dependency Conflicts

Problem: date-fns version conflicts between dependencies Root Cause: react-day-picker@8.10.1 requires date-fns@^2.28.0 || ^3.0.0 but project uses date-fns@^4.1.0 Solution:

  • Added --legacy-peer-deps flag to npm install in Dockerfile
  • This allows npm to use older dependency resolution algorithm that's more permissive
# Updated npm install commands
RUN npm ci --only=production --legacy-peer-deps

4. Middleware Edge Runtime Issues

Problem: NextAuth middleware causing Edge Runtime errors in Docker environment Root Cause: NextAuth middleware trying to access Node.js APIs not available in Edge Runtime Solution:

  • Removed complex NextAuth middleware (src/middleware.ts deleted)
  • Implemented simple pass-through middleware
  • Moved authentication checks to page/component level where they run in Node.js runtime
// Simple middleware approach (in components)
export { default } from "next-auth/middleware"
export const config = { matcher: [] } // Empty matcher = no middleware interference

5. Docker Build Optimization

Problem: Large Docker images and slow builds Solution:

  • Added output: 'standalone' to Next.js config for optimized Docker builds
  • Multi-stage Docker build to reduce final image size
  • Automatic database migrations on container startup
// next.config.mjs
const nextConfig = {
  output: 'standalone', // Critical for Docker optimization
  // ... other config
}

6. Error Handling and Debugging

Added: Comprehensive error handling and logging

  • Client-side error boundary (src/components/client-error-handler.tsx)
  • Enhanced error reporting in layout components
  • Debug logging throughout the application for troubleshooting

7. RPC Configuration Updates

Problem: File handling in RPC calls Solution: Updated src/lib/rpc.ts to properly handle file uploads and form data in containerized environment

Configuration Changes Made

next.config.mjs

const nextConfig = {
  output: 'standalone', // Essential for Docker
  webpack: (config) => {
    config.externals = [...(config.externals || []), 'bcryptjs'];
    return config;
  },
  serverComponentsExternalPackages: ['bcryptjs'],
  experimental: {
    serverActions: {
      bodySizeLimit: '10mb'
    }
  }
}

Dockerfile

# Key additions for fixing build issues
RUN npm ci --only=production --legacy-peer-deps
RUN npx prisma generate
RUN npm run build

Schema Updates

  • Replaced z.instanceof(File) with runtime validation
  • Updated form handling to work with containerized environment
  • Fixed file upload validation logic

Impact of Changes

Before Fixes

  • Build failures due to File API errors
  • Runtime errors from bcryptjs in Edge Runtime
  • Peer dependency conflicts preventing installation
  • 500 internal server errors from middleware issues

After Fixes

  • Clean Docker builds without errors
  • Stable runtime performance
  • Proper authentication flow
  • Working file uploads and form submissions
  • Successful deployment to Portainer

Key Takeaways

  1. Edge Runtime Limitations: Be careful with dependencies that require Node.js APIs when using Edge Runtime
  2. File API Availability: File constructor not available in all Next.js contexts - use runtime validation instead
  3. Dependency Management: --legacy-peer-deps can resolve complex dependency conflicts
  4. Docker Optimization: output: 'standalone' is crucial for efficient Next.js Docker deployments
  5. Middleware Simplicity: Sometimes simpler middleware approaches work better in containerized environments

Files Modified

  • next.config.mjs - Build configuration and externals
  • src/app/layout.tsx - Error handling and logging
  • src/lib/rpc.ts - File handling improvements
  • src/features/workspaces/schemas.ts - Schema validation fixes
  • src/features/projects/schemas.ts - Schema validation fixes
  • src/components/client-error-handler.tsx - Error boundary (new)
  • Dockerfile - Build process improvements
  • Various form components - File handling updates

The combination of these changes resolved all deployment issues and enabled successful containerized deployment with Portainer and nginx-proxy-manager integration.

CI/CD Guide: Free Setup with Database Persistence

Overview

This guide explains how to set up a completely free CI/CD pipeline using open-source tools and addresses database persistence concerns when deploying containerized applications.

Free CI/CD Solutions (No Portainer Webhooks Needed)

Since you already have Gitea and a runner container:

How it works:

  1. Gitea Actions (built into Gitea) works like GitHub Actions
  2. Your runner container executes workflows defined in .gitea/workflows/*.yml
  3. On push to main branch → workflow triggers → builds Docker image → deploys directly to your server

Deployment Methods:

  • SSH Deployment: Workflow SSHs into your server and runs docker-compose up -d
  • Docker API: Direct API calls to Docker daemon on your server
  • Docker Swarm: Use docker service update for rolling updates
  • Simple Container Restart: Pull new image and restart containers

Option 2: Other Free Alternatives

  • Drone CI: Lightweight, Docker-native CI/CD
  • Jenkins: Classic option, can run in Docker
  • GitLab CE: Self-hosted with built-in CI/CD
  • Woodpecker CI: Fork of Drone, simpler setup

Option 3: Simple Script-Based Approach

  • Git Hooks: Post-receive hook on your Git server
  • Cron + Git Pull: Simple script that checks for updates
  • Webhook Alternatives: Use free services like webhook.site or build simple webhook receiver

Database Persistence (Your Data is Safe! 🎉)

Short Answer: You will NOT lose database data when rebuilding your app image.

Here's why:

Container vs Data Separation