# 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=1024"
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
# V8, cgroup bellek sınırını GÖRMEZ: heap üst sınırını konteynerin değil host'un
# RAM'ine göre seçer (host 4 GB ise ~2 GB). docker-compose'daki mem_limit=1g ile
# birleşince sonuç, V8 daha GC yapmadan kernel'ın konteyneri OOM ile öldürmesi
# olur; o anda açık olan istek ters vekilde 502 "Bad Gateway" olarak düşer
# (22 Eyl 2026: liste üretiminin hemen ardından alınan 502 raporu). Sınır elle
# verilir: mem_limit'in ~%75'i; kalanı native taraf (better-sqlite3, mmap'lı
# SQLite sayfaları, Node'un kendi RSS'i) için ayrılır. mem_limit değişirse bu
# sayı da değişmeli.
ENV NODE_OPTIONS="--max-old-space-size=768"

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 + Next'in runtime'da yazdığı image/fetch cache dizini
# (.next'in geri kalanı root'ta kalır; salt-okunur olması sorun değil)
RUN chmod +x /app/docker-entrypoint.sh && \
    mkdir -p /app/data /app/.next/cache && \
    chown -R nextjs:nodejs /app/data /app/seed /app/.next/cache

USER nextjs

EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

# Konteyner gerçekten istek karşılıyor mu (alpine'de curl yok, Node 20'nin
# global fetch'i kullanılır). Uç bilerek en ucuz olanı: app/api/saglik DB'ye,
# oturuma, AI'ya dokunmaz. Süreç OOM ile ölüp yeniden açılırken `docker ps`
# durumu "unhealthy" gösterir — 502'lerin kaynağı tahmine kalmaz.
HEALTHCHECK --interval=30s --timeout=5s --start-period=45s --retries=3 \
  CMD node -e "fetch('http://127.0.0.1:3000/api/saglik').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"

CMD ["/app/docker-entrypoint.sh"]
