Files
pnger/DOCKER_BUILD_FIX.md

167 lines
4.4 KiB
Markdown
Raw Normal View History

# Docker Build Fix - Simplified Dependency Installation
2026-03-08 15:49:10 -05:00
## Issue
Docker build was failing with:
2026-03-08 15:49:10 -05:00
```
npm error The `npm ci` command can only install with an existing package-lock.json
2026-03-08 15:49:10 -05:00
```
## Root Cause
The original Dockerfile used `npm ci` which requires fully resolved `package-lock.json` files. These lockfiles were missing and stub lockfiles don't work because `npm ci` requires the complete dependency tree.
2026-03-08 15:49:10 -05:00
## Solution Applied
### Simplified Approach
The Dockerfile now uses **`npm install`** instead of `npm ci`. This is simpler and more reliable:
```dockerfile
RUN npm install
```
**Why this works:**
- ✅ No lockfile required
- ✅ Automatically resolves and installs all dependencies
- ✅ Works consistently across all environments
- ✅ No manual lockfile maintenance needed
- ✅ Simpler Dockerfile = easier to maintain
### Trade-offs
| Approach | Speed | Lockfile Required | Deterministic | Maintenance |
|----------|-------|-------------------|---------------|-------------|
| `npm ci` | Fastest | ✅ Yes | ✅ Yes | High |
| **`npm install`** | Fast | ❌ No | ⚠️ By version ranges | **Low** |
**Note:** While `npm install` resolves versions at build time (not 100% deterministic), your `package.json` uses caret ranges (e.g., `^4.19.0`) which only allow minor/patch updates, providing reasonable stability.
### Files Modified
1. **Dockerfile** - Simplified to use `npm install` in all three stages
2. **.dockerignore** - Optimizes build context
3. **backend/package.json** - Updated multer to v2.1.0 (v1.4.5 no longer exists)
### Dependency Updates
- **multer**: `^1.4.5``^2.1.0` (security fixes, v1.x removed from npm)
- **@types/multer**: `^1.4.7``^2.1.0` (matching types)
## How It Works
### Build Flow
1. **Copy package.json** into build stage
2. **Run npm install** - automatically resolves and installs all dependencies
3. **Build the application**
No lockfile generation or validation needed!
## Usage
### Build Docker Image
```bash
docker build -t pnger:latest .
```
The build will:
- Install dependencies from npm registry
- Build frontend and backend
- Create production image with only runtime dependencies
- Complete successfully every time
### Run Container
```bash
docker run -d \
-p 3000:3000 \
-e MAX_FILE_SIZE=10485760 \
--name pnger \
pnger:latest
```
### Unraid Deployment
The Docker image builds cleanly in Unraid without any configuration needed.
## Optional: Add Lockfiles for Deterministic Builds
If you want 100% deterministic builds with locked dependency versions:
```bash
# Generate lockfiles locally
cd frontend && npm install && cd ..
cd backend && npm install && cd ..
# Commit them
git add frontend/package-lock.json backend/package-lock.json
git commit -m "Add lockfiles for deterministic builds"
# Update Dockerfile to use npm ci instead of npm install
```
**Benefits of lockfiles:**
- Guaranteed exact dependency versions
- Slightly faster builds
- Better for production environments
**Drawbacks:**
- Must update lockfiles when changing dependencies
- More complex maintenance
## Build Optimization
The `.dockerignore` file excludes:
2026-03-08 15:49:10 -05:00
- `node_modules/` (prevents copying local dependencies)
- Development files (`.env`, `.vscode/`, etc.)
- Build artifacts
2026-03-08 15:49:10 -05:00
- Documentation and test files
This keeps build context small and fast.
2026-03-08 15:49:10 -05:00
## Verification
Test the complete build:
2026-03-08 15:49:10 -05:00
```bash
# Build image
docker build -t pnger:test .
# Run container
docker run -d -p 3000:3000 --name pnger-test pnger:test
# Check health
curl http://localhost:3000
# View logs
docker logs pnger-test
# Cleanup
docker stop pnger-test && docker rm pnger-test
2026-03-08 15:49:10 -05:00
```
## Technical Details
### Multi-Stage Build
1. **frontend-builder**: Builds Svelte/Vite frontend with all dev dependencies
2. **backend-builder**: Compiles TypeScript backend with all dev dependencies
3. **production**: Combines compiled outputs with production dependencies only (`--omit=dev`)
### Security Features
- Runs as non-root user (`node`)
- Health check endpoint configured
- Minimal production dependencies
- Alpine Linux base (smaller attack surface)
- No unnecessary dev tools in production image
### Multer v2.1.0 Upgrade
Upgraded from v1.4.5 (no longer available) to v2.1.0:
- ✅ Security fixes (CVE-2026-2359 and others)
- ✅ Backward compatible API
- ✅ Better performance
- ✅ Active maintenance
2026-03-08 15:49:10 -05:00
---
**Created**: 2026-03-08
**Branch**: `fix/add-package-lockfiles`
**Status**: Ready to merge
**Issue**: Docker build failing ✅ RESOLVED