# syntax=docker/dockerfile:1 # ── Stage 1: deps ───────────────────────────────────────────────────────────── FROM oven/bun:1 AS deps WORKDIR /app COPY frontend/package.json frontend/bun.lock* ./ RUN bun install --frozen-lockfile # ── Stage 2: builder ────────────────────────────────────────────────────────── FROM oven/bun:1 AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY frontend/ . ENV NEXT_TELEMETRY_DISABLED=1 RUN bun run build # ── Stage 3: runner ─────────────────────────────────────────────────────────── FROM oven/bun:1-slim AS runner WORKDIR /app ENV NODE_ENV=production ENV NEXT_TELEMETRY_DISABLED=1 # Suppress debconf warnings in Docker ENV DEBIAN_FRONTEND=noninteractive # Dedicated non-root user RUN apt-get update && \ apt-get install -y --no-install-recommends adduser && \ rm -rf /var/lib/apt/lists/* && \ addgroup --system --gid 1001 nodejs && \ adduser --system --uid 1001 nextjs # Create writable data directory with proper permissions RUN mkdir -p /app/data/uploads && \ chown -R nextjs:nodejs /app/data && \ chmod 750 /app/data && \ chmod 700 /app/data/uploads # Copy only production artifacts from builder (no source code, no node_modules) COPY --from=builder /app/public ./public COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./ COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static # Secure filesystem permissions RUN chmod 755 /app && \ chmod 755 /app/.next && \ chmod 755 /app/public # Switch to non-root user USER nextjs # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ CMD bun --eval "import('http').then(h => h.request('http://localhost:3000/', res => process.exit(res.statusCode === 200 ? 0 : 1)).end())" || exit 1 EXPOSE 3000 ENV PORT=3000 ENV HOSTNAME=0.0.0.0 CMD ["bun", "server.js"]