HERO IMAGE: - Generated 3 concepts with gemini-3-pro-image-preview, picked #1 - Phone showing 'Payment Received' notification at a charity gala dinner - Warm tungsten bokeh chandeliers against dark bg-gray-950 - Directly visualizes the headline: 'money in the bank' - Candid documentary angle, not looking at camera, brand compliant IMAGE OPTIMIZATION (85% total reduction): - All 21 images resized: landscape max 1200px, portrait max 1000px - Compressed JPEG quality 80, progressive encoding, EXIF stripped - Total: 13.6MB -> 2.1MB (saved 11.5MB) - Individual savings: 81-90% per image NEXT.JS IMAGE PIPELINE: - Added sharp (10x faster than squoosh for image processing) - next.config.mjs: WebP format, proper device/image sizes, 1yr cache TTL - Dockerfile: libc6-compat + NEXT_SHARP_PATH for Alpine sharp support - First request: ~3s (processing), cached: <1s WebP served sizes: hero 52KB, cards 32-40KB (vs original 500-800KB JPEGs)
32 lines
861 B
Docker
32 lines
861 B
Docker
FROM node:20-alpine AS base
|
|
|
|
FROM base AS deps
|
|
WORKDIR /app
|
|
COPY package.json package-lock.json ./
|
|
RUN npm ci
|
|
|
|
FROM base AS builder
|
|
WORKDIR /app
|
|
COPY --from=deps /app/node_modules ./node_modules
|
|
COPY . .
|
|
RUN npx prisma generate
|
|
RUN npm run build
|
|
|
|
FROM base AS runner
|
|
WORKDIR /app
|
|
ENV NODE_ENV=production
|
|
# sharp needs these native libs for image optimization
|
|
RUN apk add --no-cache libc6-compat
|
|
RUN addgroup --system --gid 1001 nodejs
|
|
RUN adduser --system --uid 1001 nextjs
|
|
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
|
|
COPY --from=builder /app/prisma ./prisma
|
|
# sharp is bundled in standalone output when installed
|
|
ENV NEXT_SHARP_PATH=/app/node_modules/sharp
|
|
USER nextjs
|
|
EXPOSE 3000
|
|
ENV PORT=3000
|
|
CMD ["node", "server.js"]
|