# Dockerfile Dependency Analysis ## Current Image Sizes | Image | Size | Status | |-------|------|--------| | backend | 179MB | ✅ Good | | runner | 178MB | ✅ Good | | pocketbase | 37MB | ✅ Excellent | | caddy | 114MB | ✅ Good | | ui | **413MB** | ⚠️ **LARGE** | --- ## UI Dependencies Analysis (413MB image) ### Production Dependencies (package.json) | Package | Used? | Size Impact | Notes | |---------|-------|-------------|-------| | `@aws-sdk/client-s3` | ❌ **UNUSED** | ~100MB | **REMOVE** - Not imported anywhere | | `@aws-sdk/s3-request-presigner` | ❌ **UNUSED** | ~50MB | **REMOVE** - Not imported anywhere | | `@grafana/faro-web-sdk` | ✅ Used | ~2MB | Keep - RUM tracking | | `@inlang/paraglide-js` | ✅ Used | ~1MB | Keep - i18n | | `@opentelemetry/*` (5 packages) | ✅ Used | ~15MB | Keep - Server-side tracing | | `@sentry/sveltekit` | ✅ Used | ~10MB | Keep - Error tracking | | `cropperjs` | ✅ Used | ~500KB | Keep - Avatar cropping | | `ioredis` | ✅ Used | ~5MB | Keep - Redis client (server-side) | | `marked` | ✅ Used | ~500KB | Keep - Markdown parsing | | `pocketbase` | ✅ Used | ~200KB | Keep - PocketBase client | | **EXTRANEOUS** | | | | | `@playwright/test` | ❌ **EXTRANEOUS** | ~50MB | **REMOVE** - Should be devDependency | | `playwright-core` | ❌ **EXTRANEOUS** | ~50MB | **REMOVE** - Should be devDependency | | `playwright` | ❌ **EXTRANEOUS** | ~50MB | **REMOVE** - Should be devDependency | **Total waste: ~300MB (AWS SDK + Playwright)** ### Why AWS SDK is in dependencies? Checking git history... it was likely added for direct S3 uploads but never actually used. The backend handles all S3 operations. --- ## Backend Dependencies Analysis (179MB image) ### Docker Image Breakdown ```dockerfile FROM alpine:3.21 # ~7MB base RUN apk add ffmpeg # ~40MB (needed for audio transcoding) RUN apk add ca-certificates # ~200KB (needed for HTTPS) COPY /out/backend # ~130MB (Go binary + stdlib) ``` **All dependencies justified:** - ✅ `ffmpeg` - Required for pocket-tts WAV→MP3 transcoding - ✅ `ca-certificates` - Required for HTTPS connections to external services - ✅ Go binary includes all dependencies (static linking) ### Go Module Analysis ```bash go list -m all | wc -l # 169 modules ``` Go binaries are statically linked, so unused imports don't increase image size. The build process with `-ldflags="-s -w"` strips symbols and debug info. **Optimization already applied:** ✅ - CGO_ENABLED=0 (static linking, no libc dependency) - -ldflags="-s -w" (strip symbols, ~20% size reduction) - BuildKit cache mounts (faster rebuilds) --- ## Caddy Dependencies Analysis (114MB image) ```dockerfile FROM caddy:2-alpine # ~50MB base COPY /usr/bin/caddy # ~60MB (with 3 plugins) COPY errors/ # ~4MB (error page assets) ``` **Plugins in use:** - ✅ `caddy-ratelimit` - Used for API rate limiting - ✅ `caddy-crowdsec-bouncer` - Used for CrowdSec integration - ✅ `caddy-l4` - Used for TCP/UDP proxying (Redis TLS proxy) **All plugins justified** - actively used in production Caddyfile. --- ## Recommendations ### 1. Remove AWS SDK from UI (PRIORITY: HIGH) **Impact:** ~150MB reduction (413MB → 263MB, 36% smaller) ```bash cd ui npm uninstall @aws-sdk/client-s3 @aws-sdk/s3-request-presigner ``` **Risk:** None - confirmed unused via grep ### 2. Remove Playwright from production (PRIORITY: HIGH) **Impact:** ~150MB reduction (263MB → 113MB, 57% smaller) **Issue:** Playwright packages are marked as "extraneous" - they're installed but not in package.json. This happens when: - Someone ran `npm install playwright` without `--save-dev` - package-lock.json got corrupted **Fix:** ```bash cd ui rm -rf node_modules package-lock.json npm install ``` This will regenerate package-lock.json without the extraneous packages. ### 3. Consider distroless for backend/runner (OPTIONAL) **Impact:** ~10-15MB reduction per image **Current:** Alpine + ffmpeg (required) **Alternative:** Use distroless + statically compiled ffmpeg **Tradeoff:** - Pros: Smaller attack surface, smaller image - Cons: Harder to debug, need to bundle ffmpeg binary - Verdict: **NOT WORTH IT** - ffmpeg from apk is well-maintained ### 4. Use .dockerignore (ALREADY GOOD ✅) Both UI and backend have proper .dockerignore files: - ✅ node_modules excluded (ui) - ✅ build artifacts excluded - ✅ .git excluded --- ## Expected Results After Cleanup | Image | Before | After | Savings | |-------|--------|-------|---------| | backend | 179MB | 179MB | 0MB (already optimal) | | runner | 178MB | 178MB | 0MB (already optimal) | | pocketbase | 37MB | 37MB | 0MB (already optimal) | | caddy | 114MB | 114MB | 0MB (already optimal) | | ui | **413MB** | **~110MB** | **~300MB (73% smaller)** | **Total deployment size reduction:** ~300MB **Deployment time improvement:** ~20-30s faster (less to pull from Docker Hub) --- ## Action Plan ```bash # 1. Clean up UI dependencies cd ui npm uninstall @aws-sdk/client-s3 @aws-sdk/s3-request-presigner rm -rf node_modules package-lock.json npm install # 2. Verify no imports remain grep -r "@aws-sdk" src/ # Should return nothing grep -r "playwright" src/ # Should return nothing # 3. Test build locally npm run build # 4. Commit changes git add package.json package-lock.json git commit -m "chore: remove unused AWS SDK and Playwright dependencies from UI - Remove @aws-sdk/client-s3 and @aws-sdk/s3-request-presigner (~150MB) - Remove extraneous Playwright packages (~150MB) - UI image size: 413MB → ~110MB (73% smaller) All S3 operations are handled by the backend, not the UI." # 5. Tag and deploy git tag v4.3.7 -m "chore: remove unused dependencies, reduce UI image by 73%" git push origin --tags ``` --- ## Backend/Runner Go Dependencies (For Reference) The Go images are already well-optimized. Here are the main dependencies: **Backend (179MB):** - PocketBase SDK - MinIO SDK (S3) - Meilisearch SDK - Redis SDK (ioredis equivalent) - HTTP router (chi) - OpenTelemetry SDK **Runner (178MB):** - Same as backend - + Chromedp (headless Chrome for scraping) - + Audio processing libs All are actively used - no dead code found. --- ## Conclusion **Current state:** - Backend, runner, pocketbase, caddy: ✅ Already well-optimized - UI: ⚠️ Carrying 300MB of unused dependencies **Impact of cleanup:** - 73% smaller UI image - Faster deployments - Lower bandwidth costs - Cleaner dependency tree **Effort:** ~5 minutes (remove 2 packages + regenerate lockfile) **Risk:** Very low (confirmed unused via code search)