# Dockerfile Templates Reference Comprehensive Dockerfile templates for Eureka platform deployments. Use these templates based on framework detection. ## Eureka Platform Environment **See also:** `eureka-infrastructure.md` for full infrastructure details. ### Runtime Environment Variables (Injected by Eureka) ```bash # Database DATABASE_URL # MinIO MINIO_ENDPOINT MINIO_PORT MINIO_ROOT_USER MINIO_ROOT_PASSWORD MINIO_BUCKET_NAME MINIO_USE_SSL MINIO_PUBLIC_URL ``` **IMPORTANT:** These are runtime variables. Do NOT hardcode in Dockerfile. ## Framework Detection Logic ```javascript function detectFramework(packageJson, files) { const deps = { ...packageJson?.dependencies, ...packageJson?.devDependencies }; // Check for ORMs first (affects base image choice) const hasPrisma = !!deps['prisma'] || !!deps['@prisma/client']; const hasDrizzle = !!deps['drizzle-orm']; // Frontend/Full-stack if (deps['next']) return hasPrisma ? 'nextjs-prisma' : 'nextjs'; if (deps['nuxt']) return 'nuxt'; if (deps['@remix-run/node']) return 'remix'; if (deps['@sveltejs/kit']) return 'sveltekit'; if (deps['vite'] && deps['react']) return 'react-vite'; if (deps['react-scripts']) return 'react-cra'; if (deps['vite'] && deps['vue']) return 'vue-vite'; if (deps['@angular/core']) return 'angular'; // Backend Node.js if (deps['@nestjs/core']) return hasPrisma ? 'nestjs-prisma' : 'nestjs'; if (deps['fastify']) return hasPrisma ? 'fastify-prisma' : 'fastify'; if (deps['express']) return hasPrisma ? 'express-prisma' : 'express'; if (deps['hono']) return 'hono'; // Python if (files['requirements.txt']) { const reqs = files['requirements.txt']; if (reqs.includes('fastapi')) return 'fastapi'; if (reqs.includes('flask')) return 'flask'; if (reqs.includes('django')) return 'django'; } // Go if (files['go.mod']) return 'go'; // Rust if (files['Cargo.toml']) return 'rust'; return 'unknown'; } ``` ## Key Considerations by Framework | Framework | Base Image | Special Requirements | Port | |---------------|------------------------|---------------------------------------|------| | + Prisma | node:20-alpine3.18 | openssl1.1-compat, dummy DATABASE_URL | - | | Next.js | node:20-alpine | output: 'standalone' in config | 3000 | | Nuxt 3 | node:20-alpine | - | 3000 | | SvelteKit | node:20-alpine | - | 3000 | | Remix | node:20-alpine | - | 3000 | | React/Vue SPA | nginx:alpine | nginx.conf for SPA routing | 80 | | Angular | nginx:alpine | nginx.conf for SPA routing | 80 | | Express | node:20-alpine | - | 3000 | | Fastify | node:20-alpine | - | 3000 | | NestJS | node:20-alpine | - | 3000 | | Hono | node:20-alpine | - | 3000 | | FastAPI | python:3.12-slim | uvicorn | 8000 | | Flask | python:3.12-slim | gunicorn | 5000 | | Django | python:3.12-slim | gunicorn, collectstatic | 8000 | | Go | golang:alpine → alpine | CGO_ENABLED=0 for static binary | 8080 | | Rust | rust:alpine → alpine | musl-dev for static linking | 8080 | --- ## Frontend Frameworks ### React (Vite) ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci COPY . . RUN npm run build FROM nginx:alpine AS runner COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] ``` **Required nginx.conf for SPA:** ```nginx server { listen 80; location / { root /usr/share/nginx/html; index index.html; try_files $uri $uri/ /index.html; } } ``` ### React (Create React App) ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci COPY . . RUN npm run build FROM nginx:alpine AS runner COPY --from=builder /app/build /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] ``` ### Vue.js (Vite) ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci COPY . . RUN npm run build FROM nginx:alpine AS runner COPY --from=builder /app/dist /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] ``` ### Angular ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci COPY . . RUN npm run build --prod FROM nginx:alpine AS runner COPY --from=builder /app/dist/*/browser /usr/share/nginx/html COPY nginx.conf /etc/nginx/conf.d/default.conf EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] ``` ### Svelte/SvelteKit ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY --from=builder /app/build ./build COPY --from=builder /app/package.json ./ RUN npm ci --omit=dev EXPOSE 3000 CMD ["node", "build"] ``` --- ## Full-Stack Frameworks ### Next.js (App Router) - Basic ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci COPY . . ENV NEXT_TELEMETRY_DISABLED=1 RUN npm run build FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs COPY --from=builder /app/public ./public COPY --from=builder /app/.next/standalone ./ COPY --from=builder /app/.next/static ./.next/static USER nextjs EXPOSE 3000 ENV PORT=3000 HOSTNAME="0.0.0.0" CMD ["node", "server.js"] ``` **Required next.config.js:** ```javascript module.exports = { output: 'standalone' } ``` ### Next.js + Prisma ```dockerfile FROM node:20-alpine3.18 AS base FROM base AS deps RUN apk add --no-cache libc6-compat openssl1.1-compat WORKDIR /app COPY package.json package-lock.json* ./ COPY prisma ./prisma/ RUN npm ci ENV DATABASE_URL="file:./placeholder.db" RUN npx prisma generate FROM base AS builder RUN apk add --no-cache openssl1.1-compat WORKDIR /app COPY --from=deps /app/node_modules ./node_modules COPY . . ENV DATABASE_URL="file:./placeholder.db" RUN npx prisma generate ENV NEXT_TELEMETRY_DISABLED=1 RUN npm run build FROM base AS runner RUN apk add --no-cache openssl1.1-compat WORKDIR /app ENV NODE_ENV=production RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs COPY --from=builder /app/public ./public COPY --from=builder /app/.next/standalone ./ COPY --from=builder /app/.next/static ./.next/static COPY --from=builder /app/prisma ./prisma COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma COPY --from=builder /app/node_modules/@prisma ./node_modules/@prisma USER nextjs EXPOSE 3000 ENV PORT=3000 HOSTNAME="0.0.0.0" CMD ["node", "server.js"] ``` ### Nuxt.js 3 ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY --from=builder /app/.output ./ EXPOSE 3000 CMD ["node", ".output/server/index.mjs"] ``` ### Remix ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY --from=builder /app/node_modules ./node_modules COPY --from=builder /app/build ./build COPY --from=builder /app/public ./public COPY --from=builder /app/package.json ./ EXPOSE 3000 CMD ["npm", "start"] ``` --- ## Backend Frameworks ### Express.js / Node.js ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci COPY . . RUN npm run build 2>/dev/null || true FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY package.json package-lock.json* ./ RUN npm ci --omit=dev COPY --from=builder /app/dist ./dist 2>/dev/null || true COPY --from=builder /app/src ./src 2>/dev/null || true COPY --from=builder /app/*.js ./ 2>/dev/null || true EXPOSE 3000 CMD ["node", "dist/index.js"] ``` ### Express + Prisma ```dockerfile FROM node:20-alpine3.18 AS builder RUN apk add --no-cache openssl1.1-compat WORKDIR /app COPY package.json package-lock.json* ./ COPY prisma ./prisma/ RUN npm ci ENV DATABASE_URL="file:./placeholder.db" RUN npx prisma generate COPY . . RUN npm run build 2>/dev/null || true FROM node:20-alpine3.18 AS runner RUN apk add --no-cache openssl1.1-compat WORKDIR /app ENV NODE_ENV=production COPY package.json package-lock.json* ./ RUN npm ci --omit=dev COPY --from=builder /app/dist ./dist COPY --from=builder /app/prisma ./prisma COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma COPY --from=builder /app/node_modules/@prisma ./node_modules/@prisma EXPOSE 3000 CMD ["node", "dist/index.js"] ``` ### Fastify ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY package.json package-lock.json* ./ RUN npm ci --omit=dev COPY --from=builder /app/dist ./dist EXPOSE 3000 CMD ["node", "dist/index.js"] ``` ### NestJS ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY package.json package-lock.json* ./ RUN npm ci --omit=dev COPY --from=builder /app/dist ./dist EXPOSE 3000 CMD ["node", "dist/main.js"] ``` ### NestJS + Prisma ```dockerfile FROM node:20-alpine3.18 AS builder RUN apk add --no-cache openssl1.1-compat WORKDIR /app COPY package.json package-lock.json* ./ COPY prisma ./prisma/ RUN npm ci ENV DATABASE_URL="file:./placeholder.db" RUN npx prisma generate COPY . . RUN npm run build FROM node:20-alpine3.18 AS runner RUN apk add --no-cache openssl1.1-compat WORKDIR /app ENV NODE_ENV=production COPY package.json package-lock.json* ./ RUN npm ci --omit=dev COPY --from=builder /app/dist ./dist COPY --from=builder /app/prisma ./prisma COPY --from=builder /app/node_modules/.prisma ./node_modules/.prisma COPY --from=builder /app/node_modules/@prisma ./node_modules/@prisma EXPOSE 3000 CMD ["node", "dist/main.js"] ``` ### Hono ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json* ./ RUN npm ci COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY package.json package-lock.json* ./ RUN npm ci --omit=dev COPY --from=builder /app/dist ./dist EXPOSE 3000 CMD ["node", "dist/index.js"] ``` --- ## Python Frameworks ### FastAPI ```dockerfile FROM python:3.12-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt FROM python:3.12-slim AS runner WORKDIR /app COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages COPY . . EXPOSE 8000 CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] ``` ### Flask ```dockerfile FROM python:3.12-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt FROM python:3.12-slim AS runner WORKDIR /app COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages COPY . . EXPOSE 5000 CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"] ``` ### Django ```dockerfile FROM python:3.12-slim AS builder WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt FROM python:3.12-slim AS runner WORKDIR /app COPY --from=builder /usr/local/lib/python3.12/site-packages /usr/local/lib/python3.12/site-packages COPY . . RUN python manage.py collectstatic --noinput EXPOSE 8000 CMD ["gunicorn", "--bind", "0.0.0.0:8000", "project.wsgi:application"] ``` --- ## Other Languages ### Go (Gin/Echo/Fiber) ```dockerfile FROM golang:1.22-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -o main . FROM alpine:latest AS runner RUN apk --no-cache add ca-certificates WORKDIR /app COPY --from=builder /app/main . EXPOSE 8080 CMD ["./main"] ``` ### Rust (Actix/Axum) ```dockerfile FROM rust:1.75-alpine AS builder RUN apk add --no-cache musl-dev WORKDIR /app COPY Cargo.toml Cargo.lock ./ COPY src ./src RUN cargo build --release FROM alpine:latest AS runner RUN apk --no-cache add ca-certificates WORKDIR /app COPY --from=builder /app/target/release/app . EXPOSE 8080 CMD ["./app"] ``` --- ## Supporting Files ### nginx.conf (for SPAs) ```nginx server { listen 80; server_name _; root /usr/share/nginx/html; index index.html; # Gzip compression gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml; # SPA routing - all routes to index.html location / { try_files $uri $uri/ /index.html; } # Cache static assets location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2)$ { expires 1y; add_header Cache-Control "public, immutable"; } # Security headers add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; } ``` ### .dockerignore (recommended) ``` node_modules .git .gitignore *.md .env* .next dist build coverage .nyc_output *.log .DS_Store Thumbs.db ``` --- ## Eureka Deployment Checklist Before generating Dockerfile: 1. **Detect framework** from package.json/requirements.txt/go.mod/Cargo.toml 2. **Check for ORMs** (Prisma, Drizzle) → use alpine3.18 + openssl1.1-compat 3. **Validate config**: - Next.js: `output: 'standalone'` in next.config.js - SPAs: nginx.conf exists or needs generation 4. **Set build-time env vars** (DATABASE_URL for Prisma) 5. **Expose correct port** based on framework defaults 6. **Generate .dockerignore** if missing ## Usage by Agents When creating a Dockerfile: 1. Read package.json to detect framework 2. Check for prisma directory or @prisma/client dependency 3. Select appropriate template from this reference 4. Validate framework-specific requirements 5. Generate Dockerfile and supporting files (nginx.conf, .dockerignore)