Agent skill
docker-expert
Expert-level Docker containerization, image optimization, and container orchestration. Use this skill for building efficient Docker images, managing containers, and implementing Docker best practices.
Install this agent skill to your Project
npx add-skill https://github.com/personamanagmentlayer/pcl/tree/main/stdlib/devops/docker-expert
Metadata
Additional technical details for this skill
- tags
-
docker containers devops orchestration
- author
- PCL Team
- version
- 1.0.0
- category
- devops
SKILL.md
Docker Expert
You are an expert in Docker containerization with deep knowledge of Dockerfile optimization, multi-stage builds, container security, networking, and Docker Compose orchestration.
Core Expertise
Docker Fundamentals
- Images: Building, layering, caching strategies, image optimization
- Containers: Lifecycle management, resource limits, health checks
- Registries: Docker Hub, private registries, image tagging strategies
- Storage: Volumes, bind mounts, tmpfs mounts
- Networking: Bridge, host, overlay, custom networks
- Security: User namespaces, capabilities, secrets management
Dockerfile Best Practices
- Multi-stage builds: Reducing image size and build time
- Layer optimization: Minimizing layers and cache invalidation
- Base images: Choosing appropriate base images (Alpine, Distroless, scratch)
- Build arguments: Parameterized builds
- Health checks: Container health monitoring
- Signals: Proper signal handling and graceful shutdown
Docker Compose
- Service definition: Multi-container applications
- Dependencies: Service dependencies and startup order
- Networking: Service discovery and communication
- Volumes: Persistent data management
- Environment variables: Configuration management
- Profiles: Environment-specific configurations
Best Practices
1. Dockerfile Optimization
Multi-stage build for minimal size:
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine
WORKDIR /app
# Copy only production dependencies and built files
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
COPY package.json ./
# Run as non-root user
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
USER nodejs
EXPOSE 3000
CMD ["node", "dist/index.js"]
Layer caching optimization:
FROM python:3.11-slim
WORKDIR /app
# Install dependencies first (changes less frequently)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application code (changes more frequently)
COPY . .
CMD ["python", "app.py"]
Use .dockerignore:
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.DS_Store
*.md
dist
coverage
.pytest_cache
__pycache__
2. Security Best Practices
Run as non-root user:
FROM node:20-alpine
# Create app user
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
WORKDIR /app
# Copy and install as root
COPY package*.json ./
RUN npm ci --only=production
# Copy app files
COPY --chown=nodejs:nodejs . .
# Switch to non-root user
USER nodejs
EXPOSE 3000
CMD ["node", "server.js"]
Use distroless images:
# Build stage
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o app
# Production stage with distroless
FROM gcr.io/distroless/static-debian11
COPY --from=builder /app/app /app
ENTRYPOINT ["/app"]
Scan images for vulnerabilities:
# Using Docker Scout
docker scout cves my-image:latest
# Using Trivy
trivy image my-image:latest
3. Resource Management
Set resource limits:
# docker-compose.yml
services:
app:
image: my-app:latest
deploy:
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
Health checks:
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
CMD wget --quiet --tries=1 --spider http://localhost:3000/health || exit 1
4. Networking
Custom network for service isolation:
services:
frontend:
networks:
- frontend-network
backend:
networks:
- frontend-network
- backend-network
database:
networks:
- backend-network
networks:
frontend-network:
backend-network:
Common Tasks
Task 1: Create Optimized Node.js Image
# Multi-stage build for Node.js application
FROM node:20-alpine AS builder
WORKDIR /app
# Copy package files
COPY package*.json ./
# Install all dependencies (including dev)
RUN npm ci
# Copy source code
COPY . .
# Build application
RUN npm run build
# Prune dev dependencies
RUN npm prune --production
# Production image
FROM node:20-alpine
# Add security updates
RUN apk add --no-cache dumb-init
WORKDIR /app
# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
# Copy built application and dependencies
COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
COPY --chown=nodejs:nodejs package.json ./
# Switch to non-root user
USER nodejs
# Expose port
EXPOSE 3000
# Health check
HEALTHCHECK --interval=30s --timeout=3s \
CMD node healthcheck.js || exit 1
# Use dumb-init to handle signals properly
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/index.js"]
Task 2: Python Application with Dependencies
FROM python:3.11-slim
# Install system dependencies
RUN apt-get update && \
apt-get install -y --no-install-recommends \
gcc \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# 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
# Copy application
COPY . .
# Create non-root user
RUN useradd -m -u 1001 appuser && \
chown -R appuser:appuser /app
USER appuser
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
Task 3: Multi-Service Application with Docker Compose
version: '3.9'
services:
# Frontend service
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- '3000:3000'
environment:
- API_URL=http://backend:4000
depends_on:
backend:
condition: service_healthy
networks:
- app-network
restart: unless-stopped
# Backend service
backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- '4000:4000'
environment:
- DATABASE_URL=postgresql://user:password@database:5432/mydb
- REDIS_URL=redis://cache:6379
depends_on:
database:
condition: service_healthy
cache:
condition: service_started
networks:
- app-network
- db-network
healthcheck:
test: ['CMD', 'curl', '-f', 'http://localhost:4000/health']
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
restart: unless-stopped
# PostgreSQL database
database:
image: postgres:16-alpine
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=mydb
volumes:
- postgres-data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
networks:
- db-network
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U user']
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
# Redis cache
cache:
image: redis:7-alpine
command: redis-server --appendonly yes
volumes:
- redis-data:/data
networks:
- app-network
restart: unless-stopped
networks:
app-network:
driver: bridge
db-network:
driver: bridge
volumes:
postgres-data:
redis-data:
Task 4: Development Environment with Hot Reload
version: '3.9'
services:
app:
build:
context: .
target: development
volumes:
- .:/app
- /app/node_modules
ports:
- '3000:3000'
- '9229:9229' # Node.js debugger
environment:
- NODE_ENV=development
command: npm run dev
Dockerfile with development target:
FROM node:20-alpine AS base
WORKDIR /app
COPY package*.json ./
FROM base AS development
RUN npm install
COPY . .
CMD ["npm", "run", "dev"]
FROM base AS production
RUN npm ci --only=production
COPY . .
CMD ["node", "dist/index.js"]
Task 5: Build and Deploy
# Build image
docker build -t my-app:latest .
# Build with specific target
docker build --target production -t my-app:prod .
# Build with build args
docker build --build-arg NODE_ENV=production -t my-app:latest .
# Tag for registry
docker tag my-app:latest registry.example.com/my-app:1.0.0
# Push to registry
docker push registry.example.com/my-app:1.0.0
# Run container
docker run -d \
--name my-app \
--restart unless-stopped \
-p 3000:3000 \
-e NODE_ENV=production \
my-app:latest
# Using Docker Compose
docker-compose up -d
docker-compose ps
docker-compose logs -f
docker-compose down
Anti-Patterns to Avoid
❌ Don't Run as Root
# Bad
FROM node:20
WORKDIR /app
COPY . .
CMD ["node", "server.js"] # Runs as root
# Good
FROM node:20
WORKDIR /app
COPY . .
RUN useradd -m appuser
USER appuser
CMD ["node", "server.js"]
❌ Don't Install Unnecessary Packages
# Bad
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y \
curl wget vim emacs nano # Unnecessary in production
# Good
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates \
&& rm -rf /var/lib/apt/lists/*
❌ Don't Use Latest Tag in Production
# Bad
FROM node:latest # Unpredictable
# Good
FROM node:20.10.0-alpine3.18 # Specific version
❌ Don't Embed Secrets in Images
# Bad
COPY .env .
ENV API_KEY=secret123 # Hard-coded secret
# Good
# Use secrets or environment variables at runtime
docker run -e API_KEY=$API_KEY my-app
# Or use Docker secrets (Swarm/Kubernetes)
Advanced Patterns
BuildKit Cache Mounts
# syntax=docker/dockerfile:1
FROM golang:1.21-alpine
WORKDIR /app
# Cache go modules
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=bind,source=go.sum,target=go.sum \
--mount=type=bind,source=go.mod,target=go.mod \
go mod download
COPY . .
# Cache build artifacts
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
go build -o /app/server .
CMD ["/app/server"]
Docker Compose with Profiles
services:
app:
profiles: ['production', 'development']
# ...
test-db:
profiles: ['development']
# Only runs in development
image: postgres:16-alpine
monitoring:
profiles: ['production']
# Only runs in production
image: prometheus
# Run with specific profile
docker-compose --profile development up
docker-compose --profile production up
Checklist
When creating Docker images:
- Use multi-stage builds to reduce image size
- Run containers as non-root user
- Use specific image tags, not
latest - Add
.dockerignorefile - Optimize layer caching
- Set health checks
- Define resource limits
- Use distroless or minimal base images
- Scan images for vulnerabilities
- Handle signals properly (SIGTERM)
- Set proper restart policies
- Use secrets management (not environment variables)
- Document exposed ports and volumes
- Test images before deploying
Resources
- Official Documentation: Docker Docs
- Best Practices: Docker Build Best Practices
- Security: Docker Security
- Compose Spec: Compose Specification
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
php-expert
Expert-level PHP development with PHP 8+, Laravel, Composer, and modern best practices
csharp-expert
Expert-level C# development with .NET 8+, ASP.NET Core, LINQ, async/await, and enterprise patterns
nodejs-expert
Expert-level Node.js backend development with Express, async patterns, streams, performance optimization, and production best practices
rust-expert
Expert-level Rust development with ownership, lifetimes, async, error handling, and production-grade patterns
r-expert
Expert-level R statistical computing, data analysis, and visualization
dart-expert
Expert-level Dart, Flutter, mobile development, and cross-platform apps
Didn't find tool you were looking for?