Files
task-manager/DOCKER-FIX.md
T
paul-nothaft e0512aa412
continuous-integration/drone/push Build is passing
Fix Vite module not found error in production Docker deployments
Update Dockerfile to compile server files separately without bundling, preventing Vite dependency issues in production. Includes troubleshooting documentation for the Vite module error.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: ceced2fc-aa46-458d-ba87-ddd4b7bb1518
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/659922a9-0087-461c-90dd-6d9a58b81d4d/ceced2fc-aa46-458d-ba87-ddd4b7bb1518/SBF5OKZ
2025-10-23 15:00:04 +00:00

142 lines
4.3 KiB
Markdown

# Docker Deployment Fix - Vite Module Error
## Problem
When deploying the TaskFlow application using a Docker image built by Drone CI, the container failed to start with the following error:
```
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'vite' imported from /app/dist/index.js
```
## Root Cause
The issue occurred because:
1. **Build Process**: The original build script used esbuild with the `--bundle` flag, which bundled all imports (including dynamic imports) into a single `dist/index.js` file
2. **Production Dependencies**: The Dockerfile only installed production dependencies (excluding dev dependencies like `vite`)
3. **Import Resolution**: Even though the code conditionally imported vite only in development, the bundled JavaScript still contained references to the vite module
4. **Runtime Failure**: At runtime in production, Node.js tried to resolve the vite module which wasn't available in node_modules
## Solution Implemented
### Changed Build Strategy
Instead of bundling all server code into a single file, we now compile each server file separately without bundling:
**Before (bundled):**
```bash
esbuild server/index.ts --platform=node --packages=external --bundle --format=esm --outdir=dist
```
**After (separate compilation):**
```bash
esbuild server/index.ts server/routes.ts server/storage.ts server/db.ts server/static.ts --platform=node --packages=external --format=esm --outdir=dist
```
### Updated Dockerfile
The Dockerfile now explicitly compiles each server module separately:
```dockerfile
# Build server files separately (without bundling)
RUN npx esbuild server/index.ts server/routes.ts server/storage.ts server/db.ts server/static.ts --platform=node --packages=external --format=esm --outdir=dist
```
### Created Production-Only Module
Created `server/static.ts` containing only production dependencies:
- `log()` function for logging
- `serveStatic()` function for serving built frontend assets
- **No vite imports**
### Conditional Module Loading
Updated `server/index.ts` to dynamically load the appropriate module:
```typescript
if (app.get("env") === "development") {
const viteModule = await import("./vite"); // Loads vite in dev
// ...
} else {
const staticModule = await import("./static"); // Loads production module
// ...
}
```
## How It Works Now
### Development Mode
1. NODE_ENV is set to "development"
2. Server imports `./vite` module (includes vite dependency)
3. Vite dev server starts with HMR
### Production Mode (Docker)
1. NODE_ENV is set to "production"
2. Server imports `./static` module (no vite dependency)
3. Serves pre-built static files from `dist/public`
4. vite is never loaded or required
## Files Modified
-`server/static.ts` - New production-only module
-`server/index.ts` - Conditional module loading
-`Dockerfile` - Separate server file compilation
## Testing
### Local Development
```bash
npm run dev
# Should work as before with Vite HMR
```
### Docker Build & Run
```bash
# Build image (or let Drone CI do it)
docker build -t taskflow:latest .
# Run with docker-compose
docker-compose up -d
# Check logs
docker-compose logs -f app
# Should see:
# serving on port 5000
# Database schema is up to date
# ✓ Database initialized successfully
```
## Benefits
1.**Smaller Production Image** - Only production dependencies included
2.**Faster Startup** - No vite module loading in production
3.**Cleaner Separation** - Development and production code paths are separate
4.**Easier Debugging** - Separate compiled files instead of one bundled file
5.**No Runtime Errors** - Production never tries to load vite
## Drone CI Integration
Your `.drone.yml` file doesn't need any changes. The Docker build process now correctly handles the server compilation.
When Drone builds your image, it will:
1. Install all dependencies (dev + prod) in build stage
2. Build frontend with Vite
3. Compile server files separately
4. Copy only production dependencies to final image
5. Copy compiled server files (without vite references)
## Deployment
After Drone builds and pushes your image, deploy it with:
```bash
# Pull latest image
docker pull registry.local.nothaft.cloud/taskflow:latest
# Start with docker-compose
docker-compose up -d
```
The application will now start successfully without the vite module error! 🚀