622 lines
14 KiB
Markdown
622 lines
14 KiB
Markdown
# 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)
|