Compare commits
2 Commits
8c47aa3a11
...
aac81d6f29
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aac81d6f29 | ||
|
|
3c5e5d007a |
@@ -130,9 +130,7 @@ jobs:
|
||||
'set -euo pipefail
|
||||
cd /opt/libnovel
|
||||
doppler run -- docker compose pull backend runner ui caddy pocketbase
|
||||
# Restart only the services with new images, without waiting for dependencies
|
||||
doppler run -- docker compose up -d --no-deps backend runner ui caddy pocketbase
|
||||
doppler run -- docker compose up -d --remove-orphans'
|
||||
doppler run -- docker compose up -d --no-deps --remove-orphans backend runner ui caddy pocketbase'
|
||||
|
||||
# ── deploy homelab runner ─────────────────────────────────────────────────────
|
||||
# Syncs the homelab runner compose file and restarts the runner service.
|
||||
|
||||
225
DOCKERFILE_ANALYSIS.md
Normal file
225
DOCKERFILE_ANALYSIS.md
Normal file
@@ -0,0 +1,225 @@
|
||||
# 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)
|
||||
3975
ui/package-lock.json
generated
3975
ui/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -29,8 +29,6 @@
|
||||
"vite": "^7.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.1005.0",
|
||||
"@aws-sdk/s3-request-presigner": "^3.1005.0",
|
||||
"@grafana/faro-web-sdk": "^2.3.1",
|
||||
"@inlang/paraglide-js": "^2.15.1",
|
||||
"@opentelemetry/exporter-logs-otlp-http": "^0.214.0",
|
||||
|
||||
Reference in New Issue
Block a user