diff --git a/.dockerignore b/.dockerignore index 3205ed6..d9695c7 100644 --- a/.dockerignore +++ b/.dockerignore @@ -10,7 +10,8 @@ LICENSE .vscode Makefile helm-charts -.env +.env*.local +.vercel .editorconfig .idea coverage* diff --git a/Dockerfile b/Dockerfile index 4079865..5a93b62 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,60 @@ # syntax=docker.io/docker/dockerfile:1 -FROM oven/bun:1.2.10 AS base +# Use multi-stage build for optimization +FROM oven/bun:1.2.10-alpine AS base +# Install dependencies only when needed +FROM base AS deps +WORKDIR /app + +# Copy package files COPY package.json bun.lock* ./ -RUN bun install --frozen-lockfile +# Install dependencies +RUN bun install --frozen-lockfile --production=false + +# Rebuild the source code only when needed +FROM base AS builder +WORKDIR /app + +# Copy dependencies from deps stage +COPY --from=deps /app/node_modules ./node_modules COPY . . +# Configure Next.js for standalone output +ENV NEXT_TELEMETRY_DISABLED=1 + +# Build the application RUN bun run build +# Production image, copy all the files and run next +FROM oven/bun:1.2.10-alpine AS runner +WORKDIR /app + +# Create non-root user for security +# RUN addgroup --system --gid 1001 nodejs +# RUN adduser --system --uid 1001 nextjs + +# Copy necessary files from builder stage +COPY --from=builder /app/public ./public +COPY --from=builder /app/.next/standalone ./ +COPY --from=builder /app/.next/static ./.next/static + +# Set environment variables +ENV NODE_ENV=production +ENV NEXT_TELEMETRY_DISABLED=1 +ENV PORT=3000 +ENV HOSTNAME="0.0.0.0" + +# Switch to non-root user +USER bun + +# Expose port EXPOSE 3000 -CMD ["bun", "start"] +# Health check +HEALTHCHECK --interval=30s --timeout=30s --start-period=5s --retries=3 \ + CMD bun --version || exit 1 + +# Start the application +CMD ["bun", "run", "server.js"] diff --git a/next.config.ts b/next.config.ts index 8e1047b..5f5ecc9 100644 --- a/next.config.ts +++ b/next.config.ts @@ -15,7 +15,10 @@ const withPWA = require("next-pwa")({ const nextConfig: NextConfig = withPWA({ /* config options here */ reactStrictMode: true, - // output: "standalone", + output: "standalone", + images: { + formats: ["image/webp", "image/avif"], + }, }); export default nextConfig;