diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..3f576c3 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,19 @@ +node_modules +npm-debug.log +.git +.gitignore +.dockerignore +.env +.env.local +.env.*.local +.next +out +build +dist +.DS_Store +*.md +.vscode +.idea +.eslintcache +.turbo +coverage diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..bcf5fcf --- /dev/null +++ b/Dockerfile @@ -0,0 +1,53 @@ +# Stage 1: Dependencies +FROM oven/bun:latest AS deps +WORKDIR /app + +# Copy package files +COPY package.json bun.lock* bun.lockb* package-lock.json* yarn.lock* ./ + +# Install dependencies using Bun +# Bun supports multiple lockfile formats and can work with npm/yarn/pnpm files +RUN bun install --frozen-lockfile || bun install + +# Stage 2: Builder +FROM deps AS builder +WORKDIR /app + +# Copy source code +COPY . . + +# Build the Next.js application +RUN bun run build + +# Stage 3: Production Runtime +FROM oven/bun:latest AS runner +WORKDIR /app + +# Set environment variables +ENV NODE_ENV=production +ENV HOST=0.0.0.0 +ENV PORT=3000 + +# Copy package.json +COPY --from=builder /app/package.json ./package.json + +# Copy node_modules from builder for faster layer +COPY --from=builder /app/node_modules ./node_modules + +# Copy built application from builder stage +COPY --from=builder /app/.next ./.next +COPY --from=builder /app/public ./public + +# Use existing 'bun' user already in the image for security +# The oven/bun image includes a non-root 'bun' user by default +USER bun + +# Expose port +EXPOSE 3000 + +# Health check +HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ + CMD bun -e "fetch('http://127.0.0.1:' + (process.env.PORT || 3000) + '/').then((res) => process.exit(res.ok ? 0 : 1)).catch(() => process.exit(1))" + +# Start the application +CMD ["bun", "run", "start"] diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4e63701 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,70 @@ +version: '3.9' + +services: + app: + # Delphitools Next.js Application - Powered by Bun + build: + context: . + dockerfile: Dockerfile + cache_from: + - type=registry,ref=delphitools:latest + + # Image identification + image: delphitools:latest + container_name: delphitools-app + + # Port mappings + ports: + - "3000:3000" + + # Environment variables + environment: + NODE_ENV: production + PORT: 3000 + HOST: 0.0.0.0 + + # Automatic restart on failure + restart: unless-stopped + + # Resource limits (optimized for Bun's efficiency) + deploy: + resources: + limits: + cpus: '1' + memory: 1G + reservations: + cpus: '0.5' + memory: 256M + + # Health check using Bun + healthcheck: + test: ["CMD", "bun", "-e", "fetch('http://127.0.0.1:3000/').then((res) => process.exit(res.ok ? 0 : 1)).catch(() => process.exit(1))"] + interval: 30s + timeout: 5s + retries: 3 + start_period: 10s + + # Logging configuration + logging: + driver: json-file + options: + max-size: "10m" + max-file: "3" + + # Security options + security_opt: + - no-new-privileges:true + + # Run as non-root user (bun user from oven/bun image) + user: "1000:1000" + +# Networks +networks: + default: + name: delphitools-network + driver: bridge + +# Named volumes +volumes: + node_modules: + driver: local