Corporate proxy (Zscaler) causes npm to fail inside Docker builds with 'Exit handler never called' error. This approach builds frontend on host where npm works, then copies pre-built dist/ into Docker image. New files: - Dockerfile.prebuilt: Single-stage build, copies frontend/dist - docker-compose.prebuilt.yml: Uses Dockerfile.prebuilt - .dockerignore.prebuilt: Allows frontend/dist to be included - start-docker-quick.sh: Quick restart without rebuild - DOCKER-PREBUILT-APPROACH.md: Documents workaround and comparison Benefits: - Builds in 2-3 minutes (not 15+) - Works behind corporate proxy - Simpler to debug - Faster iteration Trade-off: Requires npm on host, two-step build process For production: CI/CD builds frontend + image, pushes to registry
97 lines
2.6 KiB
Markdown
97 lines
2.6 KiB
Markdown
# Docker Pre-Built Frontend Approach
|
|
|
|
**Problem:** Zscaler corporate proxy causes npm to fail inside Docker builds with "Exit handler never called" error.
|
|
|
|
**Solution:** Build frontend on host (where npm works), copy pre-built dist/ into Docker image.
|
|
|
|
## Quick Start
|
|
|
|
```bash
|
|
# 1. Build frontend on host
|
|
cd frontend
|
|
npm ci
|
|
npm run build
|
|
|
|
# 2. Build Docker image (uses pre-built dist/)
|
|
cd ..
|
|
docker compose -f docker-compose.prebuilt.yml build
|
|
|
|
# 3. Start services
|
|
docker compose -f docker-compose.prebuilt.yml up -d
|
|
|
|
# 4. Initialize (first time only)
|
|
docker compose -f docker-compose.prebuilt.yml exec api flask db upgrade
|
|
docker compose -f docker-compose.prebuilt.yml exec api bash /app/scripts/bootstrap-plugins.sh
|
|
|
|
# 5. Access
|
|
https://localhost:5001
|
|
```
|
|
|
|
## Files
|
|
|
|
- `Dockerfile.prebuilt` - Simplified Dockerfile without npm build
|
|
- `docker-compose.prebuilt.yml` - Uses Dockerfile.prebuilt
|
|
- `.dockerignore.prebuilt` - Allows frontend/dist to be copied
|
|
|
|
## Why This Works
|
|
|
|
**Normal Dockerfile:**
|
|
- Multi-stage build
|
|
- Stage 1: Node 20 runs `npm ci` and `npm run build`
|
|
- Stage 2: Copies built frontend from stage 1
|
|
- **PROBLEM:** npm fails inside Docker with Zscaler proxy
|
|
|
|
**Pre-Built Approach:**
|
|
- Build frontend on Windows host (npm works here)
|
|
- Single-stage Dockerfile copies pre-built `frontend/dist/`
|
|
- Only installs Python dependencies
|
|
- **FASTER:** 2-3 minutes vs 15+ minutes
|
|
|
|
## Trade-offs
|
|
|
|
**Pros:**
|
|
- Avoids corporate proxy issues
|
|
- Much faster builds (no npm in container)
|
|
- Frontend build errors visible immediately
|
|
- Can iterate on frontend without rebuilding container
|
|
|
|
**Cons:**
|
|
- Requires npm on host machine
|
|
- Two-step build process
|
|
- frontend/dist must be in version control OR built before deployment
|
|
|
|
## For Production (CI/CD)
|
|
|
|
```yaml
|
|
# GitHub Actions / Jenkins example
|
|
- name: Build frontend
|
|
run: |
|
|
cd frontend
|
|
npm ci
|
|
npm run build
|
|
|
|
- name: Build Docker image
|
|
run: |
|
|
docker build -f Dockerfile.prebuilt -t shopdb:${{ github.sha }} .
|
|
|
|
- name: Push to registry
|
|
run: |
|
|
docker push shopdb:${{ github.sha }}
|
|
```
|
|
|
|
## Comparison
|
|
|
|
| Approach | Build Time | Corporate Proxy | Complexity | Production Ready |
|
|
|----------|-----------|----------------|------------|------------------|
|
|
| Multi-stage Dockerfile | 15+ min | ❌ Fails | High | ❌ No |
|
|
| Pre-built frontend | 2-3 min | ✅ Works | Medium | ⚠️ Yes (with CI/CD) |
|
|
| Pre-built images from registry | 30 sec | ✅ Works | Low | ✅ Yes |
|
|
|
|
## Next Steps
|
|
|
|
For true production deployment:
|
|
1. Set up CI/CD to build frontend + Docker image
|
|
2. Push to container registry
|
|
3. Sites pull pre-built images
|
|
4. No build step at deployment site
|