Docker build'ini optimize et: OOM kökü çözümü + bellek sınırlı builder
All checks were successful
Deploy / deploy (push) Successful in 7m33s

Prod VPS'te next build sırasında makineyi kilitleyen OOM'un çözümü:

- serverExternalPackages'a @google/genai, @anthropic-ai/sdk, resend eklendi;
  Turbopack artık genai'nin protobufjs/google-auth-library/ws zincirini
  derlemiyor (c2aba25 sonrası OOM'un tetiği buydu).
- Docker build'inde (BUILD_KAYNAK_KISITLI=1) bellek kısıtları: Turbopack 1.5G
  hedefi, statik üretim tek worker × 4 sayfa, prerender source map kapalı.
- Dockerfile: runner'a tam node_modules kopyası kaldırıldı (imaj ~1.9G→966M),
  pnpm store + .next/cache BuildKit cache mount'ları, açık COPY listesi,
  V8 heap sınırı.
- scripts/standalone-linkleri-onar.sh: Turbopack ESM external'ların kök
  node_modules symlink'ini nft trace'ine yazmıyor; eksik linkler build sonrası
  tamamlanmazsa runtime MODULE_NOT_FOUND ile düşer.
- ci.yaml: build bellek sınırlı buildx docker-container builder'da (2200m,
  max-parallelism 1; BuildKit --memory bayrağını yok sayıyor), deploy
  up -d --no-build ile ayrıldı, temizlik if: always() ile her koşuda.
- compose: app'e mem_limit 1g + oom_score_adj -600.
- Kullanılmayan simple-icons ve @react-pdf/renderer kaldırıldı; npm artığı
  package-lock.json silindi.

Doğrulama: imaj 2 CPU/2GiB VM'de sıfırdan build edildi, konteynerde ana
sayfa/universite 200 ve üç ESM external import OK.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-08-06 17:20:17 +03:00
parent e62c6f07df
commit 4c618781f6
9 changed files with 172 additions and 12912 deletions

View File

@@ -1,6 +1,8 @@
FROM node:20-alpine AS base
# syntax=docker/dockerfile:1
# pnpm kurulumu
FROM node:20-alpine AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable && corepack prepare pnpm@10.8.1 --activate
# ── Bağımlılık katmanı ──
@@ -9,17 +11,36 @@ WORKDIR /app
# better-sqlite3 Alpine'de kaynaktan derleniyor (musl için prebuilt yok)
RUN apk add --no-cache python3 make g++
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
# pnpm store cache mount'ta yaşar: lockfile değişse bile inen paketler yeniden inmez
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
pnpm install --frozen-lockfile
# ── Derleme katmanı ──
FROM base AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
# Build girdileri açık listelenir: docs/, scripts/, CI dosyası değişiklikleri
# bu katmanı invalide edemez. next build'in okuduğu her şey burada:
# content/ (rehber.ts), data/ (db.ts prerender), public/ (opengraph-image).
COPY package.json next.config.ts tsconfig.json postcss.config.mjs ./
COPY scripts/standalone-linkleri-onar.sh ./scripts/
COPY public ./public
COPY data ./data
COPY content ./content
COPY src ./src
ENV NEXT_TELEMETRY_DISABLED=1
# data/ .dockerignore'da; libsql build sırasında file:./data/app.db açabilsin diye boş dizin gerekli
RUN mkdir -p data && pnpm build
# V8 heap sınırı ana süreç + statik üretim worker'larına miras kalır.
# Turbopack'ın Rust tarafı bu sınırın dışında; onun hedefi next.config.ts'te
# turbopackMemoryLimit ile verilir (BUILD_KAYNAK_KISITLI bloğu).
ENV NODE_OPTIONS="--max-old-space-size=1536"
ENV BUILD_KAYNAK_KISITLI=1
RUN --mount=type=cache,id=next-cache,target=/app/.next/cache \
pnpm build
# Turbopack, ESM external'ların (@google/genai vb.) kök node_modules symlink'ini
# nft trace'ine yazmıyor; eksik linkler tamamlanmazsa runtime MODULE_NOT_FOUND
# ile düşer. Ayrıntı script'in başındaki açıklamada.
RUN sh scripts/standalone-linkleri-onar.sh .next/standalone
# ── Çalıştırma katmanı ──
FROM node:20-alpine AS runner
@@ -31,12 +52,16 @@ ENV NEXT_TELEMETRY_DISABLED=1
RUN addgroup --system --gid 1001 nodejs && \
adduser --system --uid 1001 nextjs
# Bağımlılıklar
COPY --from=deps /app/node_modules ./node_modules
# standalone çıktı, file-tracing ile seçilmiş kendi minimal node_modules'unu
# içerir (serverExternalPackages dahil) — tam node_modules kopyalanmaz.
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
# Trace, data/yokatlas.db'yi de standalone'a koyuyor; runtime'da /app/data
# volume'ü bunu gölgelediği için imajdan atılır (~22M).
RUN rm -rf /app/data
# Seed veritabanları: entrypoint açılışta bunları /app/data volume'üne kopyalar
COPY data/ ./seed/
COPY scripts/docker-entrypoint.sh ./docker-entrypoint.sh