# syntax=docker/dockerfile:1 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ı ── FROM base AS deps 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 ./ # 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 # 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 # 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 WORKDIR /app ENV NODE_ENV=production ENV NEXT_TELEMETRY_DISABLED=1 RUN addgroup --system --gid 1001 nodejs && \ adduser --system --uid 1001 nextjs # 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/ # Migration'lar: entrypoint açılışta db-goc.mjs ile volume'deki app.db'ye uygular COPY drizzle ./drizzle COPY scripts/db-goc.mjs ./scripts/db-goc.mjs COPY scripts/docker-entrypoint.sh ./docker-entrypoint.sh # SQLite veri dizini RUN chmod +x /app/docker-entrypoint.sh && \ mkdir -p /app/data && \ chown -R nextjs:nodejs /app/data /app/seed USER nextjs EXPOSE 3000 ENV PORT=3000 ENV HOSTNAME="0.0.0.0" CMD ["/app/docker-entrypoint.sh"]