mirror of
https://github.com/wshobson/agents.git
synced 2026-03-18 09:37:15 +00:00
Major quality improvements across all tools and workflows: - Expanded from 1,952 to 23,686 lines (12.1x growth) - Added 89 complete code examples with production-ready implementations - Integrated modern 2024/2025 technologies and best practices - Established consistent structure across all files - Added 64 reference workflows with real-world scenarios Phase 1 - Critical Workflows (4 files): - git-workflow: 9→118 lines - Complete git workflow orchestration - legacy-modernize: 10→110 lines - Strangler fig pattern implementation - multi-platform: 10→181 lines - API-first cross-platform development - improve-agent: 13→292 lines - Systematic agent optimization Phase 2 - Unstructured Tools (8 files): - issue: 33→636 lines - GitHub issue resolution expert - prompt-optimize: 49→1,207 lines - Advanced prompt engineering - data-pipeline: 56→2,312 lines - Production-ready pipeline architecture - data-validation: 56→1,674 lines - Comprehensive validation framework - error-analysis: 56→1,154 lines - Modern observability and debugging - langchain-agent: 56→2,735 lines - LangChain 0.1+ with LangGraph - ai-review: 63→1,597 lines - AI-powered code review system - deploy-checklist: 71→1,631 lines - GitOps and progressive delivery Phase 3 - Mid-Length Tools (4 files): - tdd-red: 111→1,763 lines - Property-based testing and decision frameworks - tdd-green: 130→842 lines - Implementation patterns and type-driven development - tdd-refactor: 174→1,860 lines - SOLID examples and architecture refactoring - refactor-clean: 267→886 lines - AI code review and static analysis integration Phase 4 - Short Workflows (7 files): - ml-pipeline: 43→292 lines - MLOps with experiment tracking - smart-fix: 44→834 lines - Intelligent debugging with AI assistance - full-stack-feature: 58→113 lines - API-first full-stack development - security-hardening: 63→118 lines - DevSecOps with zero-trust - data-driven-feature: 70→160 lines - A/B testing and analytics - performance-optimization: 70→111 lines - APM and Core Web Vitals - full-review: 76→124 lines - Multi-phase comprehensive review Phase 5 - Small Files (9 files): - onboard: 24→394 lines - Remote-first onboarding specialist - multi-agent-review: 63→194 lines - Multi-agent orchestration - context-save: 65→155 lines - Context management with vector DBs - context-restore: 65→157 lines - Context restoration and RAG - smart-debug: 65→1,727 lines - AI-assisted debugging with observability - standup-notes: 68→765 lines - Async-first with Git integration - multi-agent-optimize: 85→189 lines - Performance optimization framework - incident-response: 80→146 lines - SRE practices and incident command - feature-development: 84→144 lines - End-to-end feature workflow Technologies integrated: - AI/ML: GitHub Copilot, Claude Code, LangChain 0.1+, Voyage AI embeddings - Observability: OpenTelemetry, DataDog, Sentry, Honeycomb, Prometheus - DevSecOps: Snyk, Trivy, Semgrep, CodeQL, OWASP Top 10 - Cloud: Kubernetes, GitOps (ArgoCD/Flux), AWS/Azure/GCP - Frameworks: React 19, Next.js 15, FastAPI, Django 5, Pydantic v2 - Data: Apache Spark, Airflow, Delta Lake, Great Expectations All files now include: - Clear role statements and expertise definitions - Structured Context/Requirements sections - 6-8 major instruction sections (tools) or 3-4 phases (workflows) - Multiple complete code examples in various languages - Modern framework integrations - Real-world reference implementations
2334 lines
72 KiB
Markdown
2334 lines
72 KiB
Markdown
# Docker Optimization
|
|
|
|
You are a Docker optimization expert specializing in creating efficient, secure, and minimal container images. Optimize Dockerfiles for size, build speed, security, and runtime performance while following container best practices.
|
|
|
|
## Context
|
|
The user needs to optimize Docker images and containers for production use. Focus on reducing image size, improving build times, implementing security best practices, and ensuring efficient runtime performance.
|
|
|
|
## Requirements
|
|
$ARGUMENTS
|
|
|
|
## Instructions
|
|
|
|
### 1. Container Optimization Strategy Selection
|
|
|
|
Choose the right optimization approach based on your application type and requirements:
|
|
|
|
**Optimization Strategy Matrix**
|
|
```python
|
|
from typing import Dict, List, Any, Optional
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
import docker
|
|
import json
|
|
import subprocess
|
|
import tempfile
|
|
|
|
@dataclass
|
|
class OptimizationRecommendation:
|
|
category: str
|
|
priority: str
|
|
impact: str
|
|
effort: str
|
|
description: str
|
|
implementation: str
|
|
validation: str
|
|
|
|
class SmartDockerOptimizer:
|
|
def __init__(self):
|
|
self.client = docker.from_env()
|
|
self.optimization_strategies = {
|
|
'web_application': {
|
|
'priorities': ['security', 'size', 'startup_time', 'build_speed'],
|
|
'recommended_base': 'alpine or distroless',
|
|
'patterns': ['multi_stage', 'layer_caching', 'dependency_optimization']
|
|
},
|
|
'microservice': {
|
|
'priorities': ['size', 'startup_time', 'security', 'resource_usage'],
|
|
'recommended_base': 'scratch or distroless',
|
|
'patterns': ['minimal_dependencies', 'static_compilation', 'health_checks']
|
|
},
|
|
'data_processing': {
|
|
'priorities': ['performance', 'resource_usage', 'build_speed', 'size'],
|
|
'recommended_base': 'slim or specific runtime',
|
|
'patterns': ['parallel_processing', 'volume_optimization', 'memory_tuning']
|
|
},
|
|
'machine_learning': {
|
|
'priorities': ['gpu_support', 'model_size', 'inference_speed', 'dependency_mgmt'],
|
|
'recommended_base': 'nvidia/cuda or tensorflow/tensorflow',
|
|
'patterns': ['model_optimization', 'cuda_optimization', 'multi_stage_ml']
|
|
}
|
|
}
|
|
|
|
def detect_application_type(self, project_path: str) -> str:
|
|
"""Automatically detect application type from project structure"""
|
|
path = Path(project_path)
|
|
|
|
# Check for ML indicators
|
|
ml_indicators = ['requirements.txt', 'environment.yml', 'model.pkl', 'model.h5']
|
|
ml_keywords = ['tensorflow', 'pytorch', 'scikit-learn', 'keras', 'numpy', 'pandas']
|
|
|
|
if any((path / f).exists() for f in ml_indicators):
|
|
if (path / 'requirements.txt').exists():
|
|
with open(path / 'requirements.txt') as f:
|
|
content = f.read().lower()
|
|
if any(keyword in content for keyword in ml_keywords):
|
|
return 'machine_learning'
|
|
|
|
# Check for microservice indicators
|
|
if any(f.name in ['go.mod', 'main.go', 'cmd'] for f in path.iterdir()):
|
|
return 'microservice'
|
|
|
|
# Check for data processing
|
|
data_indicators = ['airflow', 'kafka', 'spark', 'hadoop']
|
|
if any((path / f).exists() for f in ['docker-compose.yml', 'k8s']):
|
|
return 'data_processing'
|
|
|
|
# Default to web application
|
|
return 'web_application'
|
|
|
|
def analyze_dockerfile_comprehensively(self, dockerfile_path: str, project_path: str) -> Dict[str, Any]:
|
|
"""
|
|
Comprehensive Dockerfile analysis with modern optimization recommendations
|
|
"""
|
|
app_type = self.detect_application_type(project_path)
|
|
|
|
with open(dockerfile_path, 'r') as f:
|
|
content = f.read()
|
|
|
|
analysis = {
|
|
'application_type': app_type,
|
|
'current_issues': [],
|
|
'optimization_opportunities': [],
|
|
'security_risks': [],
|
|
'performance_improvements': [],
|
|
'size_optimizations': [],
|
|
'build_optimizations': [],
|
|
'recommendations': []
|
|
}
|
|
|
|
# Comprehensive analysis
|
|
self._analyze_base_image_strategy(content, analysis)
|
|
self._analyze_layer_efficiency(content, analysis)
|
|
self._analyze_security_posture(content, analysis)
|
|
self._analyze_build_performance(content, analysis)
|
|
self._analyze_runtime_optimization(content, analysis)
|
|
self._generate_strategic_recommendations(analysis, app_type)
|
|
|
|
return analysis
|
|
|
|
def _analyze_base_image_strategy(self, content: str, analysis: Dict):
|
|
"""Analyze base image selection and optimization opportunities"""
|
|
base_image_patterns = {
|
|
'outdated_versions': {
|
|
'pattern': r'FROM\s+([^:]+):(?!latest)([0-9]+\.[0-9]+)(?:\s|$)',
|
|
'severity': 'medium',
|
|
'recommendation': 'Consider updating to latest stable version'
|
|
},
|
|
'latest_tag': {
|
|
'pattern': r'FROM\s+([^:]+):latest',
|
|
'severity': 'high',
|
|
'recommendation': 'Pin to specific version for reproducible builds'
|
|
},
|
|
'large_base_images': {
|
|
'patterns': [
|
|
r'FROM\s+ubuntu(?!.*slim)',
|
|
r'FROM\s+centos',
|
|
r'FROM\s+debian(?!.*slim)',
|
|
r'FROM\s+node(?!.*alpine)'
|
|
],
|
|
'severity': 'medium',
|
|
'recommendation': 'Consider using smaller alternatives (alpine, slim, distroless)'
|
|
},
|
|
'missing_multi_stage': {
|
|
'pattern': r'FROM\s+(?!.*AS\s+)',
|
|
'count_threshold': 1,
|
|
'severity': 'low',
|
|
'recommendation': 'Consider multi-stage builds for smaller final images'
|
|
}
|
|
}
|
|
|
|
# Check for base image optimization opportunities
|
|
for issue_type, config in base_image_patterns.items():
|
|
if 'patterns' in config:
|
|
for pattern in config['patterns']:
|
|
if re.search(pattern, content, re.IGNORECASE):
|
|
analysis['size_optimizations'].append({
|
|
'type': issue_type,
|
|
'severity': config['severity'],
|
|
'description': config['recommendation'],
|
|
'potential_savings': self._estimate_size_savings(issue_type)
|
|
})
|
|
elif 'pattern' in config:
|
|
matches = re.findall(config['pattern'], content, re.IGNORECASE)
|
|
if matches:
|
|
analysis['current_issues'].append({
|
|
'type': issue_type,
|
|
'severity': config['severity'],
|
|
'instances': len(matches),
|
|
'description': config['recommendation']
|
|
})
|
|
|
|
def _analyze_layer_efficiency(self, content: str, analysis: Dict):
|
|
"""Analyze Docker layer efficiency and caching opportunities"""
|
|
lines = content.split('\n')
|
|
run_commands = [line for line in lines if line.strip().startswith('RUN')]
|
|
|
|
# Multiple RUN commands analysis
|
|
if len(run_commands) > 3:
|
|
analysis['build_optimizations'].append({
|
|
'type': 'excessive_layers',
|
|
'severity': 'medium',
|
|
'current_count': len(run_commands),
|
|
'recommended_count': '1-3',
|
|
'description': f'Found {len(run_commands)} RUN commands. Consider combining related operations.',
|
|
'implementation': 'Combine RUN commands with && to reduce layers'
|
|
})
|
|
|
|
# Package manager cleanup analysis
|
|
package_managers = {
|
|
'apt': {'install': r'apt-get\s+install', 'cleanup': r'rm\s+-rf\s+/var/lib/apt/lists'},
|
|
'yum': {'install': r'yum\s+install', 'cleanup': r'yum\s+clean\s+all'},
|
|
'apk': {'install': r'apk\s+add', 'cleanup': r'rm\s+-rf\s+/var/cache/apk'}
|
|
}
|
|
|
|
for pm_name, patterns in package_managers.items():
|
|
if re.search(patterns['install'], content) and not re.search(patterns['cleanup'], content):
|
|
analysis['size_optimizations'].append({
|
|
'type': f'{pm_name}_cleanup_missing',
|
|
'severity': 'medium',
|
|
'description': f'Missing {pm_name} cache cleanup',
|
|
'potential_savings': '50-200MB',
|
|
'implementation': f'Add cleanup command in same RUN layer'
|
|
})
|
|
|
|
# Copy optimization analysis
|
|
copy_commands = [line for line in lines if line.strip().startswith(('COPY', 'ADD'))]
|
|
if any('.' in cmd for cmd in copy_commands):
|
|
analysis['build_optimizations'].append({
|
|
'type': 'inefficient_copy',
|
|
'severity': 'low',
|
|
'description': 'Consider using .dockerignore and specific COPY commands',
|
|
'implementation': 'Copy only necessary files to improve build cache efficiency'
|
|
})
|
|
|
|
def _generate_strategic_recommendations(self, analysis: Dict, app_type: str):
|
|
"""Generate strategic optimization recommendations based on application type"""
|
|
strategy = self.optimization_strategies[app_type]
|
|
|
|
# Priority-based recommendations
|
|
for priority in strategy['priorities']:
|
|
if priority == 'security':
|
|
analysis['recommendations'].append(OptimizationRecommendation(
|
|
category='Security',
|
|
priority='High',
|
|
impact='Critical',
|
|
effort='Medium',
|
|
description='Implement security scanning and hardening',
|
|
implementation=self._get_security_implementation(app_type),
|
|
validation='Run Trivy and Hadolint scans'
|
|
))
|
|
elif priority == 'size':
|
|
analysis['recommendations'].append(OptimizationRecommendation(
|
|
category='Size Optimization',
|
|
priority='High',
|
|
impact='High',
|
|
effort='Low',
|
|
description=f'Use {strategy["recommended_base"]} base image',
|
|
implementation=self._get_size_implementation(app_type),
|
|
validation='Compare image sizes before/after'
|
|
))
|
|
elif priority == 'startup_time':
|
|
analysis['recommendations'].append(OptimizationRecommendation(
|
|
category='Startup Performance',
|
|
priority='Medium',
|
|
impact='High',
|
|
effort='Medium',
|
|
description='Optimize application startup time',
|
|
implementation=self._get_startup_implementation(app_type),
|
|
validation='Measure container startup time'
|
|
))
|
|
|
|
def _estimate_size_savings(self, optimization_type: str) -> str:
|
|
"""Estimate potential size savings for optimization"""
|
|
savings_map = {
|
|
'large_base_images': '200-800MB',
|
|
'apt_cleanup_missing': '50-200MB',
|
|
'yum_cleanup_missing': '100-300MB',
|
|
'apk_cleanup_missing': '20-100MB',
|
|
'excessive_layers': '10-50MB',
|
|
'multi_stage_optimization': '100-500MB'
|
|
}
|
|
return savings_map.get(optimization_type, '10-50MB')
|
|
|
|
def _get_security_implementation(self, app_type: str) -> str:
|
|
"""Get security implementation based on app type"""
|
|
implementations = {
|
|
'web_application': 'Non-root user, security scanning, minimal packages',
|
|
'microservice': 'Distroless base, static compilation, capability dropping',
|
|
'data_processing': 'Secure data handling, encrypted volumes, network policies',
|
|
'machine_learning': 'Model encryption, secure model serving, GPU security'
|
|
}
|
|
return implementations.get(app_type, 'Standard security hardening')
|
|
```
|
|
|
|
**Advanced Multi-Framework Dockerfile Generator**
|
|
```python
|
|
class FrameworkOptimizedDockerfileGenerator:
|
|
def __init__(self):
|
|
self.templates = {
|
|
'node_express': self._generate_node_express_optimized,
|
|
'python_fastapi': self._generate_python_fastapi_optimized,
|
|
'python_django': self._generate_python_django_optimized,
|
|
'golang_gin': self._generate_golang_optimized,
|
|
'java_spring': self._generate_java_spring_optimized,
|
|
'rust_actix': self._generate_rust_optimized,
|
|
'dotnet_core': self._generate_dotnet_optimized
|
|
}
|
|
|
|
def generate_optimized_dockerfile(self, framework: str, config: Dict[str, Any]) -> str:
|
|
"""Generate highly optimized Dockerfile for specific framework"""
|
|
if framework not in self.templates:
|
|
raise ValueError(f"Unsupported framework: {framework}")
|
|
|
|
return self.templates[framework](config)
|
|
|
|
def _generate_node_express_optimized(self, config: Dict) -> str:
|
|
"""Generate optimized Node.js Express Dockerfile"""
|
|
node_version = config.get('node_version', '20')
|
|
use_bun = config.get('use_bun', False)
|
|
|
|
if use_bun:
|
|
return f"""
|
|
# Optimized Node.js with Bun - Ultra-fast builds and runtime
|
|
FROM oven/bun:{config.get('bun_version', 'latest')} AS base
|
|
|
|
# Install dependencies (bun is much faster than npm)
|
|
WORKDIR /app
|
|
COPY package.json bun.lockb* ./
|
|
RUN bun install --frozen-lockfile --production
|
|
|
|
# Build stage
|
|
FROM base AS build
|
|
COPY . .
|
|
RUN bun run build
|
|
|
|
# Production stage
|
|
FROM gcr.io/distroless/nodejs{node_version}-debian11
|
|
WORKDIR /app
|
|
|
|
# Copy built application
|
|
COPY --from=build --chown=nonroot:nonroot /app/dist ./dist
|
|
COPY --from=build --chown=nonroot:nonroot /app/node_modules ./node_modules
|
|
COPY --from=build --chown=nonroot:nonroot /app/package.json ./
|
|
|
|
# Security: Run as non-root
|
|
USER nonroot
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
|
|
CMD ["node", "-e", "require('http').get('http://localhost:3000/health', (res) => process.exit(res.statusCode === 200 ? 0 : 1)).on('error', () => process.exit(1))"]
|
|
|
|
EXPOSE 3000
|
|
CMD ["node", "dist/index.js"]
|
|
"""
|
|
|
|
return f"""
|
|
# Optimized Node.js Express - Production-ready multi-stage build
|
|
FROM node:{node_version}-alpine AS deps
|
|
|
|
# Install dumb-init for proper signal handling
|
|
RUN apk add --no-cache dumb-init
|
|
|
|
# Create app directory with proper permissions
|
|
RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001
|
|
WORKDIR /app
|
|
USER nodejs
|
|
|
|
# Copy package files and install dependencies
|
|
COPY --chown=nodejs:nodejs package*.json ./
|
|
RUN npm ci --only=production --no-audit --no-fund && npm cache clean --force
|
|
|
|
# Build stage
|
|
FROM node:{node_version}-alpine AS build
|
|
WORKDIR /app
|
|
COPY package*.json ./
|
|
RUN npm ci --no-audit --no-fund
|
|
COPY . .
|
|
RUN npm run build && npm run test
|
|
|
|
# Production stage
|
|
FROM node:{node_version}-alpine AS production
|
|
|
|
# Install dumb-init
|
|
RUN apk add --no-cache dumb-init
|
|
|
|
# Create user and app directory
|
|
RUN addgroup -g 1001 -S nodejs && adduser -S nodejs -u 1001
|
|
WORKDIR /app
|
|
USER nodejs
|
|
|
|
# Copy built application
|
|
COPY --from=build --chown=nodejs:nodejs /app/dist ./dist
|
|
COPY --from=deps --chown=nodejs:nodejs /app/node_modules ./node_modules
|
|
COPY --from=build --chown=nodejs:nodejs /app/package.json ./
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
|
|
CMD node healthcheck.js || exit 1
|
|
|
|
# Expose port
|
|
EXPOSE 3000
|
|
|
|
# Use dumb-init for proper signal handling
|
|
ENTRYPOINT ["dumb-init", "--"]
|
|
CMD ["node", "dist/index.js"]
|
|
"""
|
|
|
|
def _generate_python_fastapi_optimized(self, config: Dict) -> str:
|
|
"""Generate optimized Python FastAPI Dockerfile"""
|
|
python_version = config.get('python_version', '3.11')
|
|
use_uv = config.get('use_uv', True)
|
|
|
|
if use_uv:
|
|
return f"""
|
|
# Ultra-fast Python with uv package manager
|
|
FROM python:{python_version}-slim AS base
|
|
|
|
# Install uv - the fastest Python package manager
|
|
RUN pip install uv
|
|
|
|
# Build dependencies
|
|
FROM base AS build
|
|
WORKDIR /app
|
|
|
|
# Copy requirements and install dependencies with uv
|
|
COPY requirements.txt ./
|
|
RUN uv venv /opt/venv && \\
|
|
. /opt/venv/bin/activate && \\
|
|
uv pip install --no-cache-dir -r requirements.txt
|
|
|
|
# Production stage
|
|
FROM python:{python_version}-slim AS production
|
|
|
|
# Install security updates
|
|
RUN apt-get update && apt-get upgrade -y && \\
|
|
apt-get install -y --no-install-recommends dumb-init && \\
|
|
rm -rf /var/lib/apt/lists/*
|
|
|
|
# Create non-root user
|
|
RUN useradd -m -u 1001 appuser
|
|
WORKDIR /app
|
|
|
|
# Copy virtual environment
|
|
COPY --from=build /opt/venv /opt/venv
|
|
ENV PATH="/opt/venv/bin:$PATH"
|
|
|
|
# Copy application
|
|
COPY --chown=appuser:appuser . .
|
|
|
|
# Security: Run as non-root
|
|
USER appuser
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \\
|
|
CMD python -c "import requests; requests.get('http://localhost:8000/health', timeout=5)"
|
|
|
|
EXPOSE 8000
|
|
|
|
# Use dumb-init and Gunicorn for production
|
|
ENTRYPOINT ["dumb-init", "--"]
|
|
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "--worker-class", "uvicorn.workers.UvicornWorker", "app.main:app"]
|
|
"""
|
|
|
|
# Standard optimized Python Dockerfile
|
|
return f"""
|
|
# Optimized Python FastAPI - Production-ready
|
|
FROM python:{python_version}-slim AS build
|
|
|
|
# Install build dependencies
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \\
|
|
build-essential \\
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Create virtual environment
|
|
RUN python -m venv /opt/venv
|
|
ENV PATH="/opt/venv/bin:$PATH"
|
|
|
|
# Install Python dependencies
|
|
COPY requirements.txt .
|
|
RUN pip install --no-cache-dir --upgrade pip && \\
|
|
pip install --no-cache-dir -r requirements.txt
|
|
|
|
# Production stage
|
|
FROM python:{python_version}-slim AS production
|
|
|
|
# Install runtime dependencies and security updates
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \\
|
|
dumb-init \\
|
|
&& apt-get upgrade -y \\
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Create non-root user
|
|
RUN useradd -m -u 1001 appuser
|
|
WORKDIR /app
|
|
|
|
# Copy virtual environment
|
|
COPY --from=build /opt/venv /opt/venv
|
|
ENV PATH="/opt/venv/bin:$PATH" \\
|
|
PYTHONUNBUFFERED=1 \\
|
|
PYTHONDONTWRITEBYTECODE=1 \\
|
|
PYTHONOPTIMIZE=2
|
|
|
|
# Copy application
|
|
COPY --chown=appuser:appuser . .
|
|
|
|
# Security: Run as non-root
|
|
USER appuser
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \\
|
|
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health', timeout=5)"
|
|
|
|
EXPOSE 8000
|
|
|
|
# Production server with proper signal handling
|
|
ENTRYPOINT ["dumb-init", "--"]
|
|
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "--worker-class", "uvicorn.workers.UvicornWorker", "app.main:app"]
|
|
"""
|
|
|
|
def _generate_golang_optimized(self, config: Dict) -> str:
|
|
"""Generate optimized Go Dockerfile with minimal final image"""
|
|
go_version = config.get('go_version', '1.21')
|
|
|
|
return f"""
|
|
# Optimized Go build - Ultra-minimal final image
|
|
FROM golang:{go_version}-alpine AS build
|
|
|
|
# Install git for go modules
|
|
RUN apk add --no-cache git ca-certificates tzdata
|
|
|
|
# Create build directory
|
|
WORKDIR /build
|
|
|
|
# Copy go mod files and download dependencies
|
|
COPY go.mod go.sum ./
|
|
RUN go mod download && go mod verify
|
|
|
|
# Copy source code
|
|
COPY . .
|
|
|
|
# Build static binary with optimizations
|
|
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \\
|
|
-ldflags='-w -s -extldflags "-static"' \\
|
|
-a -installsuffix cgo \\
|
|
-o app .
|
|
|
|
# Final stage - minimal scratch image
|
|
FROM scratch
|
|
|
|
# Copy necessary files from build stage
|
|
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
|
COPY --from=build /usr/share/zoneinfo /usr/share/zoneinfo
|
|
COPY --from=build /build/app /app
|
|
|
|
# Health check (using the app itself)
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \\
|
|
CMD ["/app", "--health-check"]
|
|
|
|
EXPOSE 8080
|
|
|
|
# Run the binary
|
|
ENTRYPOINT ["/app"]
|
|
"""
|
|
|
|
def _check_base_image(self, content, analysis):
|
|
"""Enhanced base image optimization analysis"""
|
|
from_match = re.search(r'^FROM\s+(.+?)(?:\s+AS\s+\w+)?$', content, re.MULTILINE)
|
|
if from_match:
|
|
base_image = from_match.group(1)
|
|
|
|
# Check for latest tag
|
|
if ':latest' in base_image or not ':' in base_image:
|
|
analysis['security_risks'].append({
|
|
'issue': 'Using latest or no tag',
|
|
'severity': 'HIGH',
|
|
'fix': 'Pin to specific version',
|
|
'example': f'FROM {base_image.split(":")[0]}:1.2.3',
|
|
'impact': 'Unpredictable builds, security vulnerabilities'
|
|
})
|
|
|
|
# Enhanced base image recommendations
|
|
optimization_recommendations = {
|
|
'ubuntu': {
|
|
'alternatives': ['ubuntu:22.04-slim', 'debian:bullseye-slim', 'alpine:3.18'],
|
|
'savings': '400-600MB',
|
|
'notes': 'Consider distroless for production'
|
|
},
|
|
'debian': {
|
|
'alternatives': ['debian:bullseye-slim', 'alpine:3.18', 'gcr.io/distroless/base'],
|
|
'savings': '300-500MB',
|
|
'notes': 'Distroless provides better security'
|
|
},
|
|
'centos': {
|
|
'alternatives': ['alpine:3.18', 'gcr.io/distroless/base', 'ubuntu:22.04-slim'],
|
|
'savings': '200-400MB',
|
|
'notes': 'CentOS is deprecated, migrate to alternatives'
|
|
},
|
|
'node': {
|
|
'alternatives': ['node:20-alpine', 'node:20-slim', 'gcr.io/distroless/nodejs20'],
|
|
'savings': '300-700MB',
|
|
'notes': 'Alpine is smallest, distroless is most secure'
|
|
},
|
|
'python': {
|
|
'alternatives': ['python:3.11-slim', 'python:3.11-alpine', 'gcr.io/distroless/python3'],
|
|
'savings': '400-800MB',
|
|
'notes': 'Slim balances size and compatibility'
|
|
}
|
|
}
|
|
|
|
for base_name, config in optimization_recommendations.items():
|
|
if base_name in base_image and 'slim' not in base_image and 'alpine' not in base_image:
|
|
analysis['size_impact'].append({
|
|
'issue': f'Large base image: {base_image}',
|
|
'impact': config['savings'],
|
|
'alternatives': config['alternatives'],
|
|
'recommendation': f"Switch to {config['alternatives'][0]} for optimal size/compatibility balance",
|
|
'notes': config['notes']
|
|
})
|
|
|
|
# Check for deprecated or insecure base images
|
|
deprecated_images = {
|
|
'centos:7': 'EOL reached, migrate to Rocky Linux or Alpine',
|
|
'ubuntu:18.04': 'LTS ended, upgrade to ubuntu:22.04',
|
|
'node:14': 'Node 14 is EOL, upgrade to node:18 or node:20',
|
|
'python:3.8': 'Python 3.8 will reach EOL soon, upgrade to 3.11+'
|
|
}
|
|
|
|
for deprecated, message in deprecated_images.items():
|
|
if deprecated in base_image:
|
|
analysis['security_risks'].append({
|
|
'issue': f'Deprecated base image: {deprecated}',
|
|
'severity': 'MEDIUM',
|
|
'fix': message,
|
|
'impact': 'Security vulnerabilities, no security updates'
|
|
})
|
|
|
|
def _check_layer_optimization(self, content, analysis):
|
|
"""Enhanced layer optimization analysis with modern best practices"""
|
|
lines = content.split('\n')
|
|
|
|
# Check for multiple RUN commands
|
|
run_commands = [line for line in lines if line.strip().startswith('RUN')]
|
|
if len(run_commands) > 5:
|
|
analysis['build_performance'].append({
|
|
'issue': f'Excessive RUN commands ({len(run_commands)})',
|
|
'impact': f'Creates {len(run_commands)} unnecessary layers',
|
|
'fix': 'Combine related RUN commands with && \\',
|
|
'optimization': f'Could reduce to 2-3 layers, saving ~{len(run_commands) * 10}MB'
|
|
})
|
|
|
|
# Enhanced package manager cleanup checks
|
|
package_managers = {
|
|
'apt': {
|
|
'install_pattern': r'RUN.*apt-get.*install',
|
|
'cleanup_pattern': r'rm\s+-rf\s+/var/lib/apt/lists',
|
|
'update_pattern': r'apt-get\s+update',
|
|
'combined_check': r'RUN.*apt-get\s+update.*&&.*apt-get\s+install.*&&.*rm\s+-rf\s+/var/lib/apt/lists',
|
|
'recommended_pattern': 'RUN apt-get update && apt-get install -y --no-install-recommends <packages> && rm -rf /var/lib/apt/lists/*'
|
|
},
|
|
'yum': {
|
|
'install_pattern': r'RUN.*yum.*install',
|
|
'cleanup_pattern': r'yum\s+clean\s+all',
|
|
'recommended_pattern': 'RUN yum install -y <packages> && yum clean all'
|
|
},
|
|
'apk': {
|
|
'install_pattern': r'RUN.*apk.*add',
|
|
'cleanup_pattern': r'--no-cache|rm\s+-rf\s+/var/cache/apk',
|
|
'recommended_pattern': 'RUN apk add --no-cache <packages>'
|
|
},
|
|
'pip': {
|
|
'install_pattern': r'RUN.*pip.*install',
|
|
'cleanup_pattern': r'--no-cache-dir|pip\s+cache\s+purge',
|
|
'recommended_pattern': 'RUN pip install --no-cache-dir <packages>'
|
|
}
|
|
}
|
|
|
|
for pm_name, patterns in package_managers.items():
|
|
has_install = re.search(patterns['install_pattern'], content)
|
|
has_cleanup = re.search(patterns['cleanup_pattern'], content)
|
|
|
|
if has_install and not has_cleanup:
|
|
potential_savings = {
|
|
'apt': '50-200MB',
|
|
'yum': '100-300MB',
|
|
'apk': '5-50MB',
|
|
'pip': '20-100MB'
|
|
}.get(pm_name, '10-50MB')
|
|
|
|
analysis['size_impact'].append({
|
|
'issue': f'{pm_name} package manager without cleanup',
|
|
'impact': potential_savings,
|
|
'fix': f'Add cleanup in same RUN command',
|
|
'example': patterns['recommended_pattern'],
|
|
'severity': 'MEDIUM'
|
|
})
|
|
|
|
# Check for inefficient COPY operations
|
|
copy_commands = [line for line in lines if line.strip().startswith(('COPY', 'ADD'))]
|
|
for cmd in copy_commands:
|
|
if 'COPY . .' in cmd or 'COPY ./ ./' in cmd:
|
|
analysis['build_performance'].append({
|
|
'issue': 'Inefficient COPY command copying entire context',
|
|
'impact': 'Poor build cache efficiency, slower builds',
|
|
'fix': 'Use specific COPY commands and .dockerignore',
|
|
'example': 'COPY package*.json ./ && COPY src/ ./src/',
|
|
'note': 'Copy dependency files first for better caching'
|
|
})
|
|
|
|
# Check for BuildKit optimizations
|
|
if '--mount=type=cache' not in content:
|
|
analysis['build_performance'].append({
|
|
'issue': 'Missing BuildKit cache mounts',
|
|
'impact': 'Slower builds, no dependency caching',
|
|
'fix': 'Use BuildKit cache mounts for package managers',
|
|
'example': 'RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txt',
|
|
'note': 'Requires DOCKER_BUILDKIT=1'
|
|
})
|
|
|
|
# Check for multi-stage build opportunities
|
|
from_statements = re.findall(r'FROM\s+([^\s]+)', content)
|
|
if len(from_statements) == 1 and any(keyword in content.lower() for keyword in ['build', 'compile', 'npm install', 'pip install']):
|
|
analysis['size_impact'].append({
|
|
'issue': 'Single-stage build with development dependencies',
|
|
'impact': '100-500MB from build tools and dev dependencies',
|
|
'fix': 'Implement multi-stage build',
|
|
'example': 'Separate build and runtime stages',
|
|
'potential_savings': '200-800MB'
|
|
})
|
|
```
|
|
|
|
### 2. Advanced Multi-Stage Build Strategies
|
|
|
|
Implement sophisticated multi-stage builds with modern optimization techniques:
|
|
|
|
**Ultra-Optimized Multi-Stage Patterns**
|
|
```dockerfile
|
|
# Pattern 1: Node.js with Bun - Next-generation JavaScript runtime
|
|
# 5x faster installs, 4x faster runtime, 90% smaller images
|
|
FROM oven/bun:1.0-alpine AS base
|
|
|
|
# Stage 1: Dependency Resolution with Bun
|
|
FROM base AS deps
|
|
WORKDIR /app
|
|
|
|
# Bun lockfile for deterministic builds
|
|
COPY package.json bun.lockb* ./
|
|
|
|
# Ultra-fast dependency installation
|
|
RUN bun install --frozen-lockfile --production
|
|
|
|
# Stage 2: Build with development dependencies
|
|
FROM base AS build
|
|
WORKDIR /app
|
|
|
|
# Copy package files
|
|
COPY package.json bun.lockb* ./
|
|
|
|
# Install all dependencies (including dev)
|
|
RUN bun install --frozen-lockfile
|
|
|
|
# Copy source and build
|
|
COPY . .
|
|
RUN bun run build && bun test
|
|
|
|
# Stage 3: Security scanning (optional but recommended)
|
|
FROM build AS security-scan
|
|
RUN apk add --no-cache curl
|
|
# Download and run Trivy for vulnerability scanning
|
|
RUN curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin && \
|
|
trivy fs --exit-code 1 --no-progress --severity HIGH,CRITICAL /app
|
|
|
|
# Stage 4: Ultra-minimal production with distroless
|
|
FROM gcr.io/distroless/nodejs20-debian11 AS production
|
|
|
|
# Copy only what's needed for production
|
|
COPY --from=deps --chown=nonroot:nonroot /app/node_modules ./node_modules
|
|
COPY --from=build --chown=nonroot:nonroot /app/dist ./dist
|
|
COPY --from=build --chown=nonroot:nonroot /app/package.json ./
|
|
|
|
# Distroless already runs as non-root
|
|
USER nonroot
|
|
|
|
# Health check using Node.js built-in capabilities
|
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
|
|
CMD ["node", "-e", "require('http').get('http://localhost:3000/health',(r)=>process.exit(r.statusCode===200?0:1)).on('error',()=>process.exit(1))"]
|
|
|
|
EXPOSE 3000
|
|
CMD ["node", "dist/index.js"]
|
|
```
|
|
|
|
**Advanced Python Multi-Stage with UV Package Manager**
|
|
```dockerfile
|
|
# Pattern 2: Python with UV - 10-100x faster than pip
|
|
FROM python:3.11-slim AS base
|
|
|
|
# Install UV - next generation Python package manager
|
|
RUN pip install uv
|
|
|
|
# Stage 1: Dependency resolution with UV
|
|
FROM base AS deps
|
|
WORKDIR /app
|
|
|
|
# Copy requirements
|
|
COPY requirements.txt requirements-dev.txt ./
|
|
|
|
# Create virtual environment and install production dependencies with UV
|
|
RUN uv venv /opt/venv
|
|
ENV PATH="/opt/venv/bin:$PATH"
|
|
RUN uv pip install --no-cache -r requirements.txt
|
|
|
|
# Stage 2: Build and test
|
|
FROM base AS build
|
|
WORKDIR /app
|
|
|
|
# Install all dependencies including dev
|
|
RUN uv venv /opt/venv
|
|
ENV PATH="/opt/venv/bin:$PATH"
|
|
COPY requirements*.txt ./
|
|
RUN uv pip install --no-cache -r requirements.txt -r requirements-dev.txt
|
|
|
|
# Copy source and run tests
|
|
COPY . .
|
|
RUN python -m pytest tests/ --cov=src --cov-report=term-missing
|
|
RUN python -m black --check src/
|
|
RUN python -m isort --check-only src/
|
|
RUN python -m mypy src/
|
|
|
|
# Stage 3: Security and compliance scanning
|
|
FROM build AS security
|
|
RUN uv pip install safety bandit
|
|
RUN safety check
|
|
RUN bandit -r src/ -f json -o bandit-report.json
|
|
|
|
# Stage 4: Optimized production with distroless
|
|
FROM gcr.io/distroless/python3-debian11 AS production
|
|
|
|
# Copy virtual environment and application
|
|
COPY --from=deps /opt/venv /opt/venv
|
|
COPY --from=build /app/src ./src
|
|
COPY --from=build /app/requirements.txt ./
|
|
|
|
# Set environment for production
|
|
ENV PATH="/opt/venv/bin:$PATH" \
|
|
PYTHONUNBUFFERED=1 \
|
|
PYTHONDONTWRITEBYTECODE=1 \
|
|
PYTHONOPTIMIZE=2
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
|
|
CMD ["python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health', timeout=5)"]
|
|
|
|
EXPOSE 8000
|
|
CMD ["python", "-m", "gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "--worker-class", "uvicorn.workers.UvicornWorker", "src.main:app"]
|
|
```
|
|
|
|
**Go Static Binary with Scratch Base**
|
|
```dockerfile
|
|
# Pattern 3: Go with ultra-minimal scratch base
|
|
FROM golang:1.21-alpine AS base
|
|
|
|
# Install build dependencies
|
|
RUN apk add --no-cache git ca-certificates tzdata upx
|
|
|
|
# Stage 1: Dependency download
|
|
FROM base AS deps
|
|
WORKDIR /src
|
|
|
|
# Copy go mod files
|
|
COPY go.mod go.sum ./
|
|
|
|
# Download dependencies with module cache
|
|
RUN --mount=type=cache,target=/go/pkg/mod \
|
|
go mod download
|
|
|
|
# Stage 2: Build with optimizations
|
|
FROM base AS build
|
|
WORKDIR /src
|
|
|
|
# Copy dependencies from cache
|
|
COPY --from=deps /go/pkg /go/pkg
|
|
COPY . .
|
|
|
|
# Build static binary with extreme optimizations
|
|
RUN --mount=type=cache,target=/go/pkg/mod \
|
|
--mount=type=cache,target=/root/.cache/go-build \
|
|
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build \
|
|
-ldflags='-w -s -extldflags "-static"' \
|
|
-a -installsuffix cgo \
|
|
-trimpath \
|
|
-o app ./cmd/server
|
|
|
|
# Compress binary with UPX (optional, 50-70% size reduction)
|
|
RUN upx --best --lzma app
|
|
|
|
# Stage 3: Testing
|
|
FROM build AS test
|
|
RUN go test -v ./...
|
|
RUN go vet ./...
|
|
RUN golangci-lint run
|
|
|
|
# Stage 4: Minimal scratch image (2-5MB final image)
|
|
FROM scratch AS production
|
|
|
|
# Copy essential files
|
|
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
|
COPY --from=build /usr/share/zoneinfo /usr/share/zoneinfo
|
|
COPY --from=build /src/app /app
|
|
|
|
# Health check using app's built-in health endpoint
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
CMD ["/app", "-health-check"]
|
|
|
|
EXPOSE 8080
|
|
ENTRYPOINT ["/app"]
|
|
```
|
|
|
|
**Rust with Cross-Compilation and Security**
|
|
```dockerfile
|
|
# Pattern 4: Rust with musl for static linking
|
|
FROM rust:1.70-alpine AS base
|
|
|
|
# Install musl development tools
|
|
RUN apk add --no-cache musl-dev openssl-dev
|
|
|
|
# Stage 1: Dependency caching
|
|
FROM base AS deps
|
|
WORKDIR /app
|
|
|
|
# Copy Cargo files
|
|
COPY Cargo.toml Cargo.lock ./
|
|
|
|
# Create dummy main and build dependencies
|
|
RUN mkdir src && echo 'fn main() {}' > src/main.rs
|
|
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
|
--mount=type=cache,target=/app/target \
|
|
cargo build --release --target x86_64-unknown-linux-musl
|
|
|
|
# Stage 2: Build application
|
|
FROM base AS build
|
|
WORKDIR /app
|
|
|
|
# Copy dependencies from cache
|
|
COPY --from=deps /usr/local/cargo /usr/local/cargo
|
|
COPY . .
|
|
|
|
# Build optimized static binary
|
|
RUN --mount=type=cache,target=/usr/local/cargo/registry \
|
|
--mount=type=cache,target=/app/target \
|
|
cargo build --release --target x86_64-unknown-linux-musl && \
|
|
cp target/x86_64-unknown-linux-musl/release/app /app/app
|
|
|
|
# Strip binary for smaller size
|
|
RUN strip /app/app
|
|
|
|
# Stage 3: Security scanning
|
|
FROM build AS security
|
|
RUN cargo audit
|
|
RUN cargo clippy -- -D warnings
|
|
|
|
# Stage 4: Minimal scratch image
|
|
FROM scratch AS production
|
|
|
|
# Copy static binary
|
|
COPY --from=build /app/app /app
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
CMD ["/app", "--health"]
|
|
|
|
EXPOSE 8000
|
|
ENTRYPOINT ["/app"]
|
|
```
|
|
|
|
**Java Spring Boot with GraalVM Native Image**
|
|
```dockerfile
|
|
# Pattern 5: Java with GraalVM Native Image (sub-second startup)
|
|
FROM ghcr.io/graalvm/graalvm-ce:java17 AS base
|
|
|
|
# Install native-image component
|
|
RUN gu install native-image
|
|
|
|
# Stage 1: Dependencies
|
|
FROM base AS deps
|
|
WORKDIR /app
|
|
|
|
# Copy Maven/Gradle files
|
|
COPY pom.xml ./
|
|
COPY .mvn .mvn
|
|
COPY mvnw ./
|
|
|
|
# Download dependencies
|
|
RUN ./mvnw dependency:go-offline
|
|
|
|
# Stage 2: Build application
|
|
FROM base AS build
|
|
WORKDIR /app
|
|
|
|
# Copy dependencies and source
|
|
COPY --from=deps /root/.m2 /root/.m2
|
|
COPY . .
|
|
|
|
# Build JAR
|
|
RUN ./mvnw clean package -DskipTests
|
|
|
|
# Build native image
|
|
RUN native-image \
|
|
-jar target/*.jar \
|
|
--no-fallback \
|
|
--static \
|
|
--libc=musl \
|
|
-H:+ReportExceptionStackTraces \
|
|
-H:+AddAllCharsets \
|
|
-H:IncludeResourceBundles=sun.util.resources.TimeZoneNames \
|
|
app
|
|
|
|
# Stage 3: Testing
|
|
FROM build AS test
|
|
RUN ./mvnw test
|
|
|
|
# Stage 4: Ultra-minimal final image (20-50MB vs 200-300MB)
|
|
FROM scratch AS production
|
|
|
|
# Copy native binary
|
|
COPY --from=build /app/app /app
|
|
|
|
# Health check
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=2s --retries=3 \
|
|
CMD ["/app", "--health"]
|
|
|
|
EXPOSE 8080
|
|
ENTRYPOINT ["/app"]
|
|
```
|
|
|
|
**Python Multi-Stage Example**
|
|
```dockerfile
|
|
# Stage 1: Build dependencies
|
|
FROM python:3.11-slim AS builder
|
|
|
|
# Install build dependencies
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
gcc \
|
|
libc6-dev \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Create virtual environment
|
|
RUN python -m venv /opt/venv
|
|
ENV PATH="/opt/venv/bin:$PATH"
|
|
|
|
# Install Python dependencies
|
|
COPY requirements.txt .
|
|
RUN pip install --no-cache-dir -r requirements.txt
|
|
|
|
# Stage 2: Runtime
|
|
FROM python:3.11-slim AS runtime
|
|
|
|
# Copy virtual environment from builder
|
|
COPY --from=builder /opt/venv /opt/venv
|
|
ENV PATH="/opt/venv/bin:$PATH"
|
|
|
|
# Create non-root user
|
|
RUN useradd -m -u 1001 appuser
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy application
|
|
COPY --chown=appuser:appuser . .
|
|
|
|
USER appuser
|
|
|
|
# Gunicorn for production
|
|
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "app:application"]
|
|
```
|
|
|
|
### 3. Image Size Optimization
|
|
|
|
Minimize Docker image size:
|
|
|
|
**Size Reduction Techniques**
|
|
```dockerfile
|
|
# Alpine-based optimization
|
|
FROM alpine:3.18
|
|
|
|
# Install only necessary packages
|
|
RUN apk add --no-cache \
|
|
python3 \
|
|
py3-pip \
|
|
&& pip3 install --no-cache-dir --upgrade pip
|
|
|
|
# Use --no-cache-dir for pip
|
|
COPY requirements.txt .
|
|
RUN pip3 install --no-cache-dir -r requirements.txt
|
|
|
|
# Remove unnecessary files
|
|
RUN find /usr/local -type d -name __pycache__ -exec rm -rf {} + \
|
|
&& find /usr/local -type f -name '*.pyc' -delete
|
|
|
|
# Golang example with scratch image
|
|
FROM golang:1.21-alpine AS builder
|
|
WORKDIR /build
|
|
COPY . .
|
|
# Build static binary
|
|
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-s -w' -o app .
|
|
|
|
# Final stage: scratch
|
|
FROM scratch
|
|
# Copy only the binary
|
|
COPY --from=builder /build/app /app
|
|
# Copy SSL certificates for HTTPS
|
|
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
|
|
ENTRYPOINT ["/app"]
|
|
```
|
|
|
|
**Layer Optimization Script**
|
|
```python
|
|
def optimize_dockerfile_layers(dockerfile_content):
|
|
"""
|
|
Optimize Dockerfile layers
|
|
"""
|
|
optimizations = []
|
|
|
|
# Combine RUN commands
|
|
run_commands = re.findall(r'^RUN\s+(.+?)(?=^(?:RUN|FROM|COPY|ADD|ENV|EXPOSE|CMD|ENTRYPOINT|WORKDIR)|\Z)',
|
|
dockerfile_content, re.MULTILINE | re.DOTALL)
|
|
|
|
if len(run_commands) > 1:
|
|
combined = ' && \\\n '.join(cmd.strip() for cmd in run_commands)
|
|
optimizations.append({
|
|
'original': '\n'.join(f'RUN {cmd}' for cmd in run_commands),
|
|
'optimized': f'RUN {combined}',
|
|
'benefit': f'Reduces {len(run_commands)} layers to 1'
|
|
})
|
|
|
|
# Optimize package installation
|
|
apt_install = re.search(r'RUN\s+apt-get\s+update.*?apt-get\s+install\s+(.+?)(?=^(?:RUN|FROM)|\Z)',
|
|
dockerfile_content, re.MULTILINE | re.DOTALL)
|
|
|
|
if apt_install:
|
|
packages = apt_install.group(1)
|
|
optimized = f"""RUN apt-get update && apt-get install -y --no-install-recommends \\
|
|
{packages.strip()} \\
|
|
&& rm -rf /var/lib/apt/lists/*"""
|
|
|
|
optimizations.append({
|
|
'original': apt_install.group(0),
|
|
'optimized': optimized,
|
|
'benefit': 'Reduces image size by cleaning apt cache'
|
|
})
|
|
|
|
return optimizations
|
|
```
|
|
|
|
### 4. Build Performance Optimization
|
|
|
|
Speed up Docker builds:
|
|
|
|
**.dockerignore Optimization**
|
|
```
|
|
# .dockerignore
|
|
# Version control
|
|
.git
|
|
.gitignore
|
|
|
|
# Development
|
|
.vscode
|
|
.idea
|
|
*.swp
|
|
*.swo
|
|
|
|
# Dependencies
|
|
node_modules
|
|
vendor
|
|
venv
|
|
__pycache__
|
|
|
|
# Build artifacts
|
|
dist
|
|
build
|
|
*.egg-info
|
|
target
|
|
|
|
# Tests
|
|
test
|
|
tests
|
|
*.test.js
|
|
*.spec.js
|
|
coverage
|
|
.pytest_cache
|
|
|
|
# Documentation
|
|
docs
|
|
*.md
|
|
LICENSE
|
|
|
|
# Environment
|
|
.env
|
|
.env.*
|
|
|
|
# Logs
|
|
*.log
|
|
logs
|
|
|
|
# OS files
|
|
.DS_Store
|
|
Thumbs.db
|
|
|
|
# CI/CD
|
|
.github
|
|
.gitlab
|
|
.circleci
|
|
Jenkinsfile
|
|
|
|
# Docker
|
|
Dockerfile*
|
|
docker-compose*
|
|
.dockerignore
|
|
```
|
|
|
|
**Build Cache Optimization**
|
|
```dockerfile
|
|
# Optimize build cache
|
|
FROM node:18-alpine
|
|
|
|
WORKDIR /app
|
|
|
|
# Copy package files first (changes less frequently)
|
|
COPY package*.json ./
|
|
|
|
# Install dependencies (cached if package files haven't changed)
|
|
RUN npm ci --only=production
|
|
|
|
# Copy source code (changes frequently)
|
|
COPY . .
|
|
|
|
# Build application
|
|
RUN npm run build
|
|
|
|
# Use BuildKit cache mounts
|
|
FROM node:18-alpine AS builder
|
|
WORKDIR /app
|
|
|
|
# Mount cache for package manager
|
|
RUN --mount=type=cache,target=/root/.npm \
|
|
npm ci --only=production
|
|
|
|
# Mount cache for build artifacts
|
|
RUN --mount=type=cache,target=/app/.cache \
|
|
npm run build
|
|
```
|
|
|
|
### 5. Security Hardening
|
|
|
|
Implement security best practices:
|
|
|
|
**Security-Hardened Dockerfile**
|
|
```dockerfile
|
|
# Use specific version and minimal base image
|
|
FROM alpine:3.18.4
|
|
|
|
# Install security updates
|
|
RUN apk update && apk upgrade && apk add --no-cache \
|
|
ca-certificates \
|
|
&& rm -rf /var/cache/apk/*
|
|
|
|
# Create non-root user
|
|
RUN addgroup -g 1001 -S appgroup && \
|
|
adduser -S appuser -u 1001 -G appgroup
|
|
|
|
# Set secure permissions
|
|
RUN mkdir /app && chown -R appuser:appgroup /app
|
|
WORKDIR /app
|
|
|
|
# Copy with correct ownership
|
|
COPY --chown=appuser:appgroup . .
|
|
|
|
# Drop all capabilities
|
|
USER appuser
|
|
|
|
# Read-only root filesystem
|
|
# Add volumes for writable directories
|
|
VOLUME ["/tmp", "/app/logs"]
|
|
|
|
# Security labels
|
|
LABEL security.scan="trivy" \
|
|
security.updates="auto"
|
|
|
|
# Health check with timeout
|
|
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
|
|
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
|
|
|
|
# Run as PID 1 to handle signals properly
|
|
ENTRYPOINT ["dumb-init", "--"]
|
|
CMD ["./app"]
|
|
```
|
|
|
|
**Security Scanning Integration**
|
|
```yaml
|
|
# .github/workflows/docker-security.yml
|
|
name: Docker Security Scan
|
|
|
|
on:
|
|
push:
|
|
paths:
|
|
- 'Dockerfile*'
|
|
- '.dockerignore'
|
|
|
|
jobs:
|
|
scan:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v3
|
|
|
|
- name: Run Trivy vulnerability scanner
|
|
uses: aquasecurity/trivy-action@master
|
|
with:
|
|
image-ref: '${{ github.repository }}:${{ github.sha }}'
|
|
format: 'sarif'
|
|
output: 'trivy-results.sarif'
|
|
severity: 'CRITICAL,HIGH'
|
|
|
|
- name: Upload Trivy scan results
|
|
uses: github/codeql-action/upload-sarif@v2
|
|
with:
|
|
sarif_file: 'trivy-results.sarif'
|
|
|
|
- name: Run Hadolint
|
|
uses: hadolint/hadolint-action@v3.1.0
|
|
with:
|
|
dockerfile: Dockerfile
|
|
format: sarif
|
|
output-file: hadolint-results.sarif
|
|
|
|
- name: Upload Hadolint scan results
|
|
uses: github/codeql-action/upload-sarif@v2
|
|
with:
|
|
sarif_file: hadolint-results.sarif
|
|
```
|
|
|
|
### 6. Runtime Optimization
|
|
|
|
Optimize container runtime performance:
|
|
|
|
**Runtime Configuration**
|
|
```dockerfile
|
|
# JVM optimization example
|
|
FROM eclipse-temurin:17-jre-alpine
|
|
|
|
# JVM memory settings based on container limits
|
|
ENV JAVA_OPTS="-XX:MaxRAMPercentage=75.0 \
|
|
-XX:InitialRAMPercentage=50.0 \
|
|
-XX:+UseContainerSupport \
|
|
-XX:+OptimizeStringConcat \
|
|
-XX:+UseStringDeduplication \
|
|
-Djava.security.egd=file:/dev/./urandom"
|
|
|
|
# Node.js optimization
|
|
FROM node:18-alpine
|
|
ENV NODE_ENV=production \
|
|
NODE_OPTIONS="--max-old-space-size=1024 --optimize-for-size"
|
|
|
|
# Python optimization
|
|
FROM python:3.11-slim
|
|
ENV PYTHONUNBUFFERED=1 \
|
|
PYTHONDONTWRITEBYTECODE=1 \
|
|
PYTHONOPTIMIZE=2
|
|
|
|
# Nginx optimization
|
|
FROM nginx:alpine
|
|
COPY nginx-optimized.conf /etc/nginx/nginx.conf
|
|
# Enable gzip, caching, and connection pooling
|
|
```
|
|
|
|
### 7. Docker Compose Optimization
|
|
|
|
Optimize multi-container applications:
|
|
|
|
```yaml
|
|
# docker-compose.yml
|
|
version: '3.9'
|
|
|
|
services:
|
|
app:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
cache_from:
|
|
- ${REGISTRY}/app:latest
|
|
- ${REGISTRY}/app:builder
|
|
args:
|
|
BUILDKIT_INLINE_CACHE: 1
|
|
image: ${REGISTRY}/app:${VERSION:-latest}
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
cpus: '1'
|
|
memory: 512M
|
|
reservations:
|
|
cpus: '0.5'
|
|
memory: 256M
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
|
interval: 30s
|
|
timeout: 10s
|
|
retries: 3
|
|
start_period: 40s
|
|
restart: unless-stopped
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
command: redis-server --maxmemory 256mb --maxmemory-policy allkeys-lru
|
|
deploy:
|
|
resources:
|
|
limits:
|
|
memory: 256M
|
|
volumes:
|
|
- type: tmpfs
|
|
target: /data
|
|
tmpfs:
|
|
size: 268435456 # 256MB
|
|
|
|
nginx:
|
|
image: nginx:alpine
|
|
volumes:
|
|
- type: bind
|
|
source: ./nginx.conf
|
|
target: /etc/nginx/nginx.conf
|
|
read_only: true
|
|
depends_on:
|
|
app:
|
|
condition: service_healthy
|
|
```
|
|
|
|
### 8. Build Automation
|
|
|
|
Automate optimized builds:
|
|
|
|
```bash
|
|
#!/bin/bash
|
|
# build-optimize.sh
|
|
|
|
set -euo pipefail
|
|
|
|
# Variables
|
|
IMAGE_NAME="${1:-myapp}"
|
|
VERSION="${2:-latest}"
|
|
PLATFORMS="${3:-linux/amd64,linux/arm64}"
|
|
|
|
echo "🏗️ Building optimized Docker image..."
|
|
|
|
# Enable BuildKit
|
|
export DOCKER_BUILDKIT=1
|
|
|
|
# Build with cache
|
|
docker buildx build \
|
|
--platform "${PLATFORMS}" \
|
|
--cache-from "type=registry,ref=${IMAGE_NAME}:buildcache" \
|
|
--cache-to "type=registry,ref=${IMAGE_NAME}:buildcache,mode=max" \
|
|
--tag "${IMAGE_NAME}:${VERSION}" \
|
|
--build-arg BUILDKIT_INLINE_CACHE=1 \
|
|
--progress=plain \
|
|
--push \
|
|
.
|
|
|
|
# Analyze image size
|
|
echo "📊 Image analysis:"
|
|
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
|
|
wagoodman/dive:latest "${IMAGE_NAME}:${VERSION}"
|
|
|
|
# Security scan
|
|
echo "🔒 Security scan:"
|
|
trivy image "${IMAGE_NAME}:${VERSION}"
|
|
|
|
# Size report
|
|
echo "📏 Size comparison:"
|
|
docker images "${IMAGE_NAME}" --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
|
|
```
|
|
|
|
### 9. Monitoring and Metrics
|
|
|
|
Track container performance:
|
|
|
|
```python
|
|
# container-metrics.py
|
|
import docker
|
|
import json
|
|
from datetime import datetime
|
|
|
|
class ContainerMonitor:
|
|
def __init__(self):
|
|
self.client = docker.from_env()
|
|
|
|
def collect_metrics(self, container_name):
|
|
"""Collect container performance metrics"""
|
|
container = self.client.containers.get(container_name)
|
|
stats = container.stats(stream=False)
|
|
|
|
metrics = {
|
|
'timestamp': datetime.now().isoformat(),
|
|
'container': container_name,
|
|
'cpu': self._calculate_cpu_percent(stats),
|
|
'memory': self._calculate_memory_usage(stats),
|
|
'network': self._calculate_network_io(stats),
|
|
'disk': self._calculate_disk_io(stats)
|
|
}
|
|
|
|
return metrics
|
|
|
|
def _calculate_cpu_percent(self, stats):
|
|
"""Calculate CPU usage percentage"""
|
|
cpu_delta = stats['cpu_stats']['cpu_usage']['total_usage'] - \
|
|
stats['precpu_stats']['cpu_usage']['total_usage']
|
|
system_delta = stats['cpu_stats']['system_cpu_usage'] - \
|
|
stats['precpu_stats']['system_cpu_usage']
|
|
|
|
if system_delta > 0 and cpu_delta > 0:
|
|
cpu_percent = (cpu_delta / system_delta) * \
|
|
len(stats['cpu_stats']['cpu_usage']['percpu_usage']) * 100.0
|
|
return round(cpu_percent, 2)
|
|
return 0.0
|
|
|
|
def _calculate_memory_usage(self, stats):
|
|
"""Calculate memory usage"""
|
|
usage = stats['memory_stats']['usage']
|
|
limit = stats['memory_stats']['limit']
|
|
|
|
return {
|
|
'usage_bytes': usage,
|
|
'limit_bytes': limit,
|
|
'percent': round((usage / limit) * 100, 2)
|
|
}
|
|
```
|
|
|
|
### 10. Best Practices Checklist
|
|
|
|
```python
|
|
def generate_dockerfile_checklist():
|
|
"""Generate Dockerfile best practices checklist"""
|
|
checklist = """
|
|
## Dockerfile Best Practices Checklist
|
|
|
|
### Base Image
|
|
- [ ] Use specific version tags (not :latest)
|
|
- [ ] Use minimal base images (alpine, slim, distroless)
|
|
- [ ] Keep base images updated
|
|
- [ ] Use official images when possible
|
|
|
|
### Layers & Caching
|
|
- [ ] Order commands from least to most frequently changing
|
|
- [ ] Combine RUN commands where appropriate
|
|
- [ ] Clean up in the same layer (apt cache, pip cache)
|
|
- [ ] Use .dockerignore to exclude unnecessary files
|
|
|
|
### Security
|
|
- [ ] Run as non-root user
|
|
- [ ] Don't store secrets in images
|
|
- [ ] Scan images for vulnerabilities
|
|
- [ ] Use COPY instead of ADD
|
|
- [ ] Set read-only root filesystem where possible
|
|
|
|
### Size Optimization
|
|
- [ ] Use multi-stage builds
|
|
- [ ] Remove unnecessary dependencies
|
|
- [ ] Clear package manager caches
|
|
- [ ] Remove temporary files and build artifacts
|
|
- [ ] Use --no-install-recommends for apt
|
|
|
|
### Performance
|
|
- [ ] Set appropriate resource limits
|
|
- [ ] Use health checks
|
|
- [ ] Optimize for startup time
|
|
- [ ] Configure logging appropriately
|
|
- [ ] Use BuildKit for faster builds
|
|
|
|
### Maintainability
|
|
- [ ] Include LABEL metadata
|
|
- [ ] Document exposed ports with EXPOSE
|
|
- [ ] Use ARG for build-time variables
|
|
- [ ] Include meaningful comments
|
|
- [ ] Version your Dockerfiles
|
|
"""
|
|
return checklist
|
|
```
|
|
|
|
## Output Format
|
|
|
|
1. **Analysis Report**: Current Dockerfile issues and optimization opportunities
|
|
2. **Optimized Dockerfile**: Rewritten Dockerfile with all optimizations
|
|
3. **Size Comparison**: Before/after image size analysis
|
|
4. **Build Performance**: Build time improvements and caching strategy
|
|
5. **Security Report**: Security scan results and hardening recommendations
|
|
6. **Runtime Config**: Optimized runtime settings for the application
|
|
7. **Monitoring Setup**: Container metrics and performance tracking
|
|
8. **Migration Guide**: Step-by-step guide to implement optimizations
|
|
|
|
## Cross-Command Integration
|
|
|
|
### Complete Container-First Development Workflow
|
|
|
|
**Containerized Development Pipeline**
|
|
```bash
|
|
# 1. Generate containerized API scaffolding
|
|
/api-scaffold
|
|
framework: "fastapi"
|
|
deployment_target: "kubernetes"
|
|
containerization: true
|
|
monitoring: true
|
|
|
|
# 2. Optimize containers for production
|
|
/docker-optimize
|
|
optimization_level: "production"
|
|
security_hardening: true
|
|
multi_stage_build: true
|
|
|
|
# 3. Security scan container images
|
|
/security-scan
|
|
scan_types: ["container", "dockerfile", "runtime"]
|
|
image_name: "app:optimized"
|
|
generate_sbom: true
|
|
|
|
# 4. Generate K8s manifests for optimized containers
|
|
/k8s-manifest
|
|
container_security: "strict"
|
|
resource_optimization: true
|
|
horizontal_scaling: true
|
|
```
|
|
|
|
**Integrated Container Configuration**
|
|
```python
|
|
# container-config.py - Shared across all commands
|
|
class IntegratedContainerConfig:
|
|
def __init__(self):
|
|
self.api_config = self.load_api_config() # From /api-scaffold
|
|
self.security_config = self.load_security_config() # From /security-scan
|
|
self.k8s_config = self.load_k8s_config() # From /k8s-manifest
|
|
self.test_config = self.load_test_config() # From /test-harness
|
|
|
|
def generate_optimized_dockerfile(self):
|
|
"""Generate Dockerfile optimized for the specific application"""
|
|
framework = self.api_config.get('framework', 'python')
|
|
security_level = self.security_config.get('level', 'standard')
|
|
deployment_target = self.k8s_config.get('platform', 'kubernetes')
|
|
|
|
if framework == 'fastapi':
|
|
return self.generate_fastapi_dockerfile(security_level, deployment_target)
|
|
elif framework == 'express':
|
|
return self.generate_express_dockerfile(security_level, deployment_target)
|
|
elif framework == 'django':
|
|
return self.generate_django_dockerfile(security_level, deployment_target)
|
|
|
|
def generate_fastapi_dockerfile(self, security_level, deployment_target):
|
|
"""Generate optimized FastAPI Dockerfile"""
|
|
dockerfile_content = {
|
|
'base_image': self.select_base_image('python', security_level),
|
|
'build_stages': self.configure_build_stages(),
|
|
'security_configs': self.apply_security_configurations(security_level),
|
|
'runtime_optimizations': self.configure_runtime_optimizations(),
|
|
'monitoring_setup': self.configure_monitoring_setup(),
|
|
'health_checks': self.configure_health_checks()
|
|
}
|
|
return dockerfile_content
|
|
|
|
def select_base_image(self, language, security_level):
|
|
"""Select optimal base image based on security and size requirements"""
|
|
base_images = {
|
|
'python': {
|
|
'minimal': 'python:3.11-alpine',
|
|
'standard': 'python:3.11-slim-bookworm',
|
|
'secure': 'chainguard/python:latest-dev',
|
|
'distroless': 'gcr.io/distroless/python3-debian12'
|
|
}
|
|
}
|
|
|
|
if security_level == 'strict':
|
|
return base_images[language]['distroless']
|
|
elif security_level == 'enhanced':
|
|
return base_images[language]['secure']
|
|
else:
|
|
return base_images[language]['standard']
|
|
|
|
def configure_build_stages(self):
|
|
"""Configure multi-stage build optimization"""
|
|
return {
|
|
'dependencies_stage': {
|
|
'name': 'dependencies',
|
|
'base': 'python:3.11-slim-bookworm',
|
|
'actions': [
|
|
'COPY requirements.txt .',
|
|
'RUN pip install --no-cache-dir --user -r requirements.txt'
|
|
]
|
|
},
|
|
'security_stage': {
|
|
'name': 'security-scan',
|
|
'base': 'dependencies',
|
|
'actions': [
|
|
'RUN pip-audit --format=json --output=/tmp/security-report.json',
|
|
'RUN safety check --json --output=/tmp/safety-report.json'
|
|
]
|
|
},
|
|
'runtime_stage': {
|
|
'name': 'runtime',
|
|
'base': 'python:3.11-slim-bookworm',
|
|
'actions': [
|
|
'COPY --from=dependencies /root/.local /root/.local',
|
|
'COPY --from=security-scan /tmp/*-report.json /security-reports/'
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
**API Container Integration**
|
|
```dockerfile
|
|
# Dockerfile.api - Generated from /api-scaffold + /docker-optimize
|
|
# Multi-stage build optimized for FastAPI applications
|
|
FROM python:3.11-slim-bookworm AS base
|
|
|
|
# Set environment variables for optimization
|
|
ENV PYTHONUNBUFFERED=1 \
|
|
PYTHONDONTWRITEBYTECODE=1 \
|
|
PIP_NO_CACHE_DIR=1 \
|
|
PIP_DISABLE_PIP_VERSION_CHECK=1
|
|
|
|
# Stage 1: Dependencies
|
|
FROM base AS dependencies
|
|
WORKDIR /app
|
|
|
|
# Install system dependencies for building Python packages
|
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
build-essential \
|
|
&& rm -rf /var/lib/apt/lists/*
|
|
|
|
# Copy and install Python dependencies
|
|
COPY requirements.txt .
|
|
RUN pip install --user --no-warn-script-location -r requirements.txt
|
|
|
|
# Stage 2: Security scanning
|
|
FROM dependencies AS security-scan
|
|
RUN pip install --user pip-audit safety bandit
|
|
|
|
# Copy source code for security scanning
|
|
COPY . .
|
|
|
|
# Run security scans during build
|
|
RUN python -m bandit -r . -f json -o /tmp/bandit-report.json || true
|
|
RUN python -m safety check --json --output /tmp/safety-report.json || true
|
|
RUN python -m pip_audit --format=json --output=/tmp/pip-audit-report.json || true
|
|
|
|
# Stage 3: Testing (optional, can be skipped in production builds)
|
|
FROM security-scan AS testing
|
|
RUN pip install --user pytest pytest-cov
|
|
|
|
# Run tests during build (from /test-harness integration)
|
|
RUN python -m pytest tests/ --cov=src --cov-report=json --cov-report=term
|
|
|
|
# Stage 4: Production runtime
|
|
FROM base AS runtime
|
|
|
|
# Create non-root user for security
|
|
RUN groupadd -r appuser && useradd -r -g appuser appuser
|
|
|
|
# Set up application directory
|
|
WORKDIR /app
|
|
RUN chown appuser:appuser /app
|
|
|
|
# Copy Python packages from dependencies stage
|
|
COPY --from=dependencies --chown=appuser:appuser /root/.local /home/appuser/.local
|
|
|
|
# Copy security reports from security stage
|
|
COPY --from=security-scan /tmp/*-report.json /app/security-reports/
|
|
|
|
# Copy application code
|
|
COPY --chown=appuser:appuser . .
|
|
|
|
# Update PATH to include user packages
|
|
ENV PATH=/home/appuser/.local/bin:$PATH
|
|
|
|
# Switch to non-root user
|
|
USER appuser
|
|
|
|
# Configure health check (integrates with K8s health checks)
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
|
|
CMD python -c "import requests; requests.get('http://localhost:8000/health', timeout=5)"
|
|
|
|
# Expose port (configured from API scaffold)
|
|
EXPOSE 8000
|
|
|
|
# Set optimal startup command
|
|
CMD ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
|
|
```
|
|
|
|
**Database Container Integration**
|
|
```dockerfile
|
|
# Dockerfile.db - Generated for database migrations from /db-migrate
|
|
FROM postgres:15-alpine AS base
|
|
|
|
# Install migration tools
|
|
RUN apk add --no-cache python3 py3-pip
|
|
RUN pip3 install alembic psycopg2-binary
|
|
|
|
# Create migration user
|
|
RUN addgroup -g 1001 migration && adduser -D -u 1001 -G migration migration
|
|
|
|
# Stage 1: Migration preparation
|
|
FROM base AS migration-prep
|
|
WORKDIR /migrations
|
|
|
|
# Copy migration scripts from /db-migrate output
|
|
COPY --chown=migration:migration migrations/ ./
|
|
COPY --chown=migration:migration alembic.ini ./
|
|
|
|
# Validate migration scripts
|
|
USER migration
|
|
RUN alembic check || echo "Migration validation completed"
|
|
|
|
# Stage 2: Production database
|
|
FROM postgres:15-alpine AS production
|
|
|
|
# Copy validated migrations
|
|
COPY --from=migration-prep --chown=postgres:postgres /migrations /docker-entrypoint-initdb.d/
|
|
|
|
# Configure PostgreSQL for production
|
|
RUN echo "shared_preload_libraries = 'pg_stat_statements'" >> /usr/local/share/postgresql/postgresql.conf.sample
|
|
RUN echo "track_activity_query_size = 2048" >> /usr/local/share/postgresql/postgresql.conf.sample
|
|
RUN echo "log_min_duration_statement = 1000" >> /usr/local/share/postgresql/postgresql.conf.sample
|
|
|
|
# Security configurations from /security-scan
|
|
RUN echo "ssl = on" >> /usr/local/share/postgresql/postgresql.conf.sample
|
|
RUN echo "log_connections = on" >> /usr/local/share/postgresql/postgresql.conf.sample
|
|
RUN echo "log_disconnections = on" >> /usr/local/share/postgresql/postgresql.conf.sample
|
|
|
|
EXPOSE 5432
|
|
```
|
|
|
|
**Frontend Container Integration**
|
|
```dockerfile
|
|
# Dockerfile.frontend - Generated from /frontend-optimize + /docker-optimize
|
|
# Multi-stage build for React/Vue applications
|
|
FROM node:18-alpine AS base
|
|
|
|
# Set environment variables
|
|
ENV NODE_ENV=production \
|
|
NPM_CONFIG_CACHE=/tmp/.npm
|
|
|
|
# Stage 1: Dependencies
|
|
FROM base AS dependencies
|
|
WORKDIR /app
|
|
|
|
# Copy package files
|
|
COPY package*.json ./
|
|
|
|
# Install dependencies with optimization
|
|
RUN npm ci --only=production --silent
|
|
|
|
# Stage 2: Build application
|
|
FROM base AS build
|
|
WORKDIR /app
|
|
|
|
# Copy dependencies
|
|
COPY --from=dependencies /app/node_modules ./node_modules
|
|
|
|
# Copy source code
|
|
COPY . .
|
|
|
|
# Build application with optimizations from /frontend-optimize
|
|
RUN npm run build
|
|
|
|
# Run security audit
|
|
RUN npm audit --audit-level high --production
|
|
|
|
# Stage 3: Security scanning
|
|
FROM build AS security-scan
|
|
|
|
# Install security scanning tools
|
|
RUN npm install -g retire snyk
|
|
|
|
# Run security scans
|
|
RUN retire --outputformat json --outputpath /tmp/retire-report.json || true
|
|
RUN snyk test --json > /tmp/snyk-report.json || true
|
|
|
|
# Stage 4: Production server
|
|
FROM nginx:alpine AS production
|
|
|
|
# Install security updates
|
|
RUN apk update && apk upgrade && apk add --no-cache dumb-init
|
|
|
|
# Create non-root user
|
|
RUN addgroup -g 1001 www && adduser -D -u 1001 -G www www
|
|
|
|
# Copy built application
|
|
COPY --from=build --chown=www:www /app/dist /usr/share/nginx/html
|
|
|
|
# Copy security reports
|
|
COPY --from=security-scan /tmp/*-report.json /var/log/security/
|
|
|
|
# Copy optimized nginx configuration
|
|
COPY nginx.conf /etc/nginx/nginx.conf
|
|
|
|
# Configure proper file permissions
|
|
RUN chown -R www:www /usr/share/nginx/html
|
|
RUN chmod -R 755 /usr/share/nginx/html
|
|
|
|
# Use non-root user
|
|
USER www
|
|
|
|
# Health check for frontend
|
|
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
|
|
CMD wget --no-verbose --tries=1 --spider http://localhost:80/ || exit 1
|
|
|
|
EXPOSE 80
|
|
|
|
# Use dumb-init for proper signal handling
|
|
ENTRYPOINT ["dumb-init", "--"]
|
|
CMD ["nginx", "-g", "daemon off;"]
|
|
```
|
|
|
|
**Kubernetes Container Integration**
|
|
```yaml
|
|
# k8s-optimized-deployment.yaml - From /k8s-manifest + /docker-optimize
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: container-config
|
|
namespace: production
|
|
data:
|
|
optimization-level: "production"
|
|
security-level: "strict"
|
|
monitoring-enabled: "true"
|
|
|
|
---
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: optimized-api
|
|
namespace: production
|
|
labels:
|
|
app: api
|
|
optimization: enabled
|
|
spec:
|
|
replicas: 3
|
|
strategy:
|
|
type: RollingUpdate
|
|
rollingUpdate:
|
|
maxUnavailable: 1
|
|
maxSurge: 1
|
|
selector:
|
|
matchLabels:
|
|
app: api
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: api
|
|
annotations:
|
|
# Container optimization annotations
|
|
container.seccomp.security.alpha.kubernetes.io/defaultProfileName: runtime/default
|
|
container.apparmor.security.beta.kubernetes.io/api: runtime/default
|
|
spec:
|
|
# Optimized pod configuration
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 1001
|
|
runAsGroup: 1001
|
|
fsGroup: 1001
|
|
seccompProfile:
|
|
type: RuntimeDefault
|
|
|
|
# Resource optimization from container analysis
|
|
containers:
|
|
- name: api
|
|
image: registry.company.com/api:optimized-latest
|
|
imagePullPolicy: Always
|
|
|
|
# Optimized resource allocation
|
|
resources:
|
|
requests:
|
|
memory: "128Mi" # Optimized based on actual usage
|
|
cpu: "100m" # Optimized based on load testing
|
|
ephemeral-storage: "1Gi"
|
|
limits:
|
|
memory: "512Mi" # Prevents OOM, allows burst
|
|
cpu: "500m" # Allows processing spikes
|
|
ephemeral-storage: "2Gi"
|
|
|
|
# Container security optimization
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
readOnlyRootFilesystem: true
|
|
runAsNonRoot: true
|
|
runAsUser: 1001
|
|
capabilities:
|
|
drop:
|
|
- ALL
|
|
add:
|
|
- NET_BIND_SERVICE
|
|
|
|
# Optimized startup and health checks
|
|
ports:
|
|
- containerPort: 8000
|
|
protocol: TCP
|
|
|
|
# Fast startup probe
|
|
startupProbe:
|
|
httpGet:
|
|
path: /startup
|
|
port: 8000
|
|
failureThreshold: 30
|
|
periodSeconds: 1
|
|
|
|
# Optimized health checks
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /health
|
|
port: 8000
|
|
initialDelaySeconds: 5
|
|
periodSeconds: 10
|
|
timeoutSeconds: 5
|
|
failureThreshold: 3
|
|
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /ready
|
|
port: 8000
|
|
initialDelaySeconds: 2
|
|
periodSeconds: 5
|
|
timeoutSeconds: 3
|
|
|
|
# Environment variables from container optimization
|
|
env:
|
|
- name: OPTIMIZATION_LEVEL
|
|
valueFrom:
|
|
configMapKeyRef:
|
|
name: container-config
|
|
key: optimization-level
|
|
- name: PYTHONUNBUFFERED
|
|
value: "1"
|
|
- name: WORKERS
|
|
value: "4"
|
|
|
|
# Optimized volume mounts
|
|
volumeMounts:
|
|
- name: tmp-volume
|
|
mountPath: /tmp
|
|
- name: cache-volume
|
|
mountPath: /app/cache
|
|
- name: security-reports
|
|
mountPath: /app/security-reports
|
|
readOnly: true
|
|
|
|
# Optimized volumes
|
|
volumes:
|
|
- name: tmp-volume
|
|
emptyDir:
|
|
sizeLimit: 100Mi
|
|
- name: cache-volume
|
|
emptyDir:
|
|
sizeLimit: 500Mi
|
|
- name: security-reports
|
|
configMap:
|
|
name: security-reports
|
|
|
|
---
|
|
# Horizontal Pod Autoscaler with container metrics
|
|
apiVersion: autoscaling/v2
|
|
kind: HorizontalPodAutoscaler
|
|
metadata:
|
|
name: api-hpa
|
|
namespace: production
|
|
spec:
|
|
scaleTargetRef:
|
|
apiVersion: apps/v1
|
|
kind: Deployment
|
|
name: optimized-api
|
|
minReplicas: 2
|
|
maxReplicas: 10
|
|
metrics:
|
|
- type: Resource
|
|
resource:
|
|
name: cpu
|
|
target:
|
|
type: Utilization
|
|
averageUtilization: 70
|
|
- type: Resource
|
|
resource:
|
|
name: memory
|
|
target:
|
|
type: Utilization
|
|
averageUtilization: 80
|
|
behavior:
|
|
scaleDown:
|
|
stabilizationWindowSeconds: 300
|
|
policies:
|
|
- type: Percent
|
|
value: 50
|
|
periodSeconds: 60
|
|
scaleUp:
|
|
stabilizationWindowSeconds: 60
|
|
policies:
|
|
- type: Percent
|
|
value: 100
|
|
periodSeconds: 15
|
|
|
|
---
|
|
# Pod Disruption Budget for rolling updates
|
|
apiVersion: policy/v1
|
|
kind: PodDisruptionBudget
|
|
metadata:
|
|
name: api-pdb
|
|
namespace: production
|
|
spec:
|
|
minAvailable: 1
|
|
selector:
|
|
matchLabels:
|
|
app: api
|
|
```
|
|
|
|
**CI/CD Container Integration**
|
|
```yaml
|
|
# .github/workflows/container-pipeline.yml
|
|
name: Optimized Container Pipeline
|
|
|
|
on:
|
|
push:
|
|
branches: [main, develop]
|
|
pull_request:
|
|
branches: [main]
|
|
|
|
env:
|
|
REGISTRY: ghcr.io
|
|
IMAGE_NAME: ${{ github.repository }}
|
|
|
|
jobs:
|
|
build-and-optimize:
|
|
runs-on: ubuntu-latest
|
|
permissions:
|
|
contents: read
|
|
packages: write
|
|
security-events: write
|
|
|
|
strategy:
|
|
matrix:
|
|
service: [api, frontend, database]
|
|
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
# 1. Build multi-stage container
|
|
- name: Set up Docker Buildx
|
|
uses: docker/setup-buildx-action@v3
|
|
with:
|
|
driver-opts: network=host
|
|
|
|
- name: Log in to Container Registry
|
|
uses: docker/login-action@v3
|
|
with:
|
|
registry: ${{ env.REGISTRY }}
|
|
username: ${{ github.actor }}
|
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
|
|
# 2. Build optimized images
|
|
- name: Build and push container images
|
|
uses: docker/build-push-action@v5
|
|
with:
|
|
context: .
|
|
file: Dockerfile.${{ matrix.service }}
|
|
push: true
|
|
tags: |
|
|
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.service }}:${{ github.sha }}
|
|
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.service }}:latest
|
|
cache-from: type=gha
|
|
cache-to: type=gha,mode=max
|
|
platforms: linux/amd64,linux/arm64
|
|
|
|
# 3. Container security scanning
|
|
- name: Run Trivy vulnerability scanner
|
|
uses: aquasecurity/trivy-action@master
|
|
with:
|
|
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.service }}:${{ github.sha }}
|
|
format: 'sarif'
|
|
output: 'trivy-results-${{ matrix.service }}.sarif'
|
|
|
|
# 4. Container optimization analysis
|
|
- name: Analyze container optimization
|
|
run: |
|
|
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" | \
|
|
grep ${{ matrix.service }} > container-analysis-${{ matrix.service }}.txt
|
|
|
|
# Compare with baseline
|
|
if [ -f baseline-sizes.txt ]; then
|
|
echo "Size comparison for ${{ matrix.service }}:" >> size-comparison.txt
|
|
echo "Previous: $(grep ${{ matrix.service }} baseline-sizes.txt || echo 'N/A')" >> size-comparison.txt
|
|
echo "Current: $(grep ${{ matrix.service }} container-analysis-${{ matrix.service }}.txt)" >> size-comparison.txt
|
|
fi
|
|
|
|
# 5. Performance testing
|
|
- name: Container performance testing
|
|
run: |
|
|
# Start container for performance testing
|
|
docker run -d --name test-${{ matrix.service }} \
|
|
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.service }}:${{ github.sha }}
|
|
|
|
# Wait for startup
|
|
sleep 30
|
|
|
|
# Run basic performance tests
|
|
if [ "${{ matrix.service }}" = "api" ]; then
|
|
docker exec test-${{ matrix.service }} \
|
|
python -c "import requests; print(requests.get('http://localhost:8000/health').status_code)"
|
|
fi
|
|
|
|
# Cleanup
|
|
docker stop test-${{ matrix.service }}
|
|
docker rm test-${{ matrix.service }}
|
|
|
|
# 6. Upload security results
|
|
- name: Upload Trivy scan results to GitHub Security tab
|
|
uses: github/codeql-action/upload-sarif@v2
|
|
with:
|
|
sarif_file: 'trivy-results-${{ matrix.service }}.sarif'
|
|
|
|
# 7. Generate optimization report
|
|
- name: Generate optimization report
|
|
run: |
|
|
cat > optimization-report-${{ matrix.service }}.md << EOF
|
|
# Container Optimization Report - ${{ matrix.service }}
|
|
|
|
## Build Information
|
|
- **Image**: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/${{ matrix.service }}:${{ github.sha }}
|
|
- **Build Date**: $(date)
|
|
- **Platforms**: linux/amd64, linux/arm64
|
|
|
|
## Size Analysis
|
|
$(cat container-analysis-${{ matrix.service }}.txt)
|
|
|
|
## Security Scan
|
|
- **Scanner**: Trivy
|
|
- **Results**: See Security tab for detailed findings
|
|
|
|
## Optimizations Applied
|
|
- Multi-stage build for minimal image size
|
|
- Security hardening with non-root user
|
|
- Layer caching for faster builds
|
|
- Health checks for reliability
|
|
EOF
|
|
|
|
- name: Upload optimization report
|
|
uses: actions/upload-artifact@v3
|
|
with:
|
|
name: optimization-report-${{ matrix.service }}
|
|
path: optimization-report-${{ matrix.service }}.md
|
|
|
|
deploy-to-staging:
|
|
needs: build-and-optimize
|
|
runs-on: ubuntu-latest
|
|
if: github.ref == 'refs/heads/develop'
|
|
|
|
steps:
|
|
- name: Deploy to staging
|
|
run: |
|
|
# Update K8s manifests with new image tags
|
|
# Apply optimized K8s configurations
|
|
kubectl set image deployment/optimized-api \
|
|
api=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}/api:${{ github.sha }} \
|
|
--namespace=staging
|
|
```
|
|
|
|
**Monitoring Integration**
|
|
```python
|
|
# container_monitoring.py - Integrated container monitoring
|
|
import docker
|
|
import psutil
|
|
from prometheus_client import CollectorRegistry, Gauge, Counter, Histogram
|
|
from typing import Dict, Any
|
|
|
|
class ContainerOptimizationMonitor:
|
|
"""Monitor container performance and optimization metrics"""
|
|
|
|
def __init__(self):
|
|
self.docker_client = docker.from_env()
|
|
self.registry = CollectorRegistry()
|
|
|
|
# Metrics from container optimization
|
|
self.container_size_gauge = Gauge(
|
|
'container_image_size_bytes',
|
|
'Container image size in bytes',
|
|
['service', 'optimization_level'],
|
|
registry=self.registry
|
|
)
|
|
|
|
self.container_startup_time = Histogram(
|
|
'container_startup_seconds',
|
|
'Container startup time in seconds',
|
|
['service'],
|
|
registry=self.registry
|
|
)
|
|
|
|
self.resource_usage_gauge = Gauge(
|
|
'container_resource_usage_ratio',
|
|
'Container resource usage ratio (used/limit)',
|
|
['service', 'resource_type'],
|
|
registry=self.registry
|
|
)
|
|
|
|
def monitor_optimization_metrics(self):
|
|
"""Monitor container optimization effectiveness"""
|
|
containers = self.docker_client.containers.list()
|
|
|
|
optimization_metrics = {}
|
|
|
|
for container in containers:
|
|
service_name = container.labels.get('app', 'unknown')
|
|
|
|
# Monitor image size efficiency
|
|
image = container.image
|
|
size_mb = self.get_image_size(image.id) / (1024 * 1024)
|
|
|
|
# Monitor resource efficiency
|
|
stats = container.stats(stream=False)
|
|
memory_usage = self.calculate_memory_efficiency(stats)
|
|
cpu_usage = self.calculate_cpu_efficiency(stats)
|
|
|
|
# Monitor startup performance
|
|
startup_time = self.get_container_startup_time(container)
|
|
|
|
optimization_metrics[service_name] = {
|
|
'image_size_mb': size_mb,
|
|
'memory_efficiency': memory_usage,
|
|
'cpu_efficiency': cpu_usage,
|
|
'startup_time_seconds': startup_time,
|
|
'optimization_score': self.calculate_optimization_score(
|
|
size_mb, memory_usage, cpu_usage, startup_time
|
|
)
|
|
}
|
|
|
|
# Update Prometheus metrics
|
|
self.container_size_gauge.labels(
|
|
service=service_name,
|
|
optimization_level='production'
|
|
).set(size_mb)
|
|
|
|
self.container_startup_time.labels(
|
|
service=service_name
|
|
).observe(startup_time)
|
|
|
|
return optimization_metrics
|
|
|
|
def calculate_optimization_score(self, size_mb, memory_eff, cpu_eff, startup_time):
|
|
"""Calculate overall optimization score (0-100)"""
|
|
size_score = max(0, 100 - (size_mb / 10)) # Penalty for large images
|
|
memory_score = (1 - memory_eff) * 100 # Reward for efficient memory use
|
|
cpu_score = (1 - cpu_eff) * 100 # Reward for efficient CPU use
|
|
startup_score = max(0, 100 - startup_time * 10) # Penalty for slow startup
|
|
|
|
return (size_score + memory_score + cpu_score + startup_score) / 4
|
|
```
|
|
|
|
This comprehensive integration ensures containers are optimized across the entire development lifecycle, from build-time optimization through runtime monitoring and Kubernetes deployment. |