docker-templateslisted
Install: claude install-skill komluk/scaffolding
## Multi-stage Build Pattern
```dockerfile
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production=false
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine AS production
WORKDIR /app
# Security: Non-root user
RUN addgroup -g 1001 -S nodejs && \
adduser -S nextjs -u 1001
# Copy only production artifacts
COPY --from=builder --chown=nextjs:nodejs /app/dist ./dist
COPY --from=builder --chown=nextjs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nextjs:nodejs /app/package.json ./
USER nextjs
EXPOSE 3000
# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
CMD ["node", "dist/server.js"]
```
## Docker Security Best Practices
| Practice | Implementation |
|----------|----------------|
| Non-root user | `USER nodejs` after setup |
| Minimal base image | Use `-alpine` variants |
| No secrets in image | Use runtime env vars |
| Pin versions | `FROM node:20.10.0-alpine` |
| .dockerignore | Exclude node_modules, .git, .env |
| Read-only filesystem | `--read-only` flag when possible |
| Resource limits | Set memory/CPU limits |
## Docker Compose Patterns
```yaml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
target: production
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=${D