Docker - Containerization Platform
Overview
Docker is our primary containerization platform, enabling consistent deployment across development, staging, and production environments. We use Docker to package applications with their dependencies, ensuring reliability and portability.
Why Docker?
- ๐ฆ Consistency: Same environment across all stages
- ๐ Portability: Run anywhere Docker is supported
- ๐ง Isolation: Applications run in isolated containers
- ๐ Scalability: Easy horizontal scaling
- ๐ Version Control: Image versioning and rollbacks
Docker at Tresor
Use Cases
- Application deployment
- Microservices architecture
- Development environments
- CI/CD pipelines
- Database containers for development
Container Registry
- AWS ECR for production images
- Docker Hub for public images
- GitLab Registry for internal images
Getting Started
Installation
# Ubuntu/Debian
curl -fsSL https://get.docker.com -o get-docker.sh
sh get-docker.sh
# Add user to docker group
sudo usermod -aG docker $USER
Basic Commands
# Build image
docker build -t myapp:latest .
# Run container
docker run -d -p 3000:3000 --name myapp myapp:latest
# View logs
docker logs -f myapp
# Execute command in container
docker exec -it myapp bash
Best Practices
Dockerfile Optimization
Multi-stage Builds
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Production stage
FROM node:18-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
RUN npm ci --only=production
EXPOSE 3000
CMD ["node", "dist/index.js"]
Layer Caching
# Good: Dependencies cached separately
COPY package*.json ./
RUN npm ci
COPY . .
# Bad: Any code change invalidates npm install
COPY . .
RUN npm ci
Security Best Practices
# Use specific versions
FROM node:18.17.1-alpine
# Run as non-root user
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
USER nodejs
# Copy with correct permissions
COPY --chown=nodejs:nodejs . .
Docker Compose
Development Environment
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=development
- DATABASE_URL=postgresql://user:pass@db:5432/myapp
volumes:
- .:/app
- /app/node_modules
depends_on:
- db
- redis
db:
image: postgres:15-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
postgres_data:
Production Considerations
version: '3.8'
services:
app:
image: myapp:${VERSION:-latest}
deploy:
replicas: 3
resources:
limits:
cpus: '0.5'
memory: 512M
reservations:
cpus: '0.25'
memory: 256M
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
Common Patterns
Node.js Application
FROM node:18-alpine
# Install dumb-init for proper signal handling
RUN apk add --no-cache dumb-init
WORKDIR /app
# Copy and install dependencies
COPY package*.json ./
RUN npm ci --only=production
# Copy application
COPY . .
# Create non-root user
USER node
EXPOSE 3000
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "server.js"]
Python Application
FROM python:3.11-slim
WORKDIR /app
# Install dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Copy application
COPY . .
# Run as non-root
RUN useradd -m -u 1001 python
USER python
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
Static Website
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Serve stage
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Docker in CI/CD
GitHub Actions
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
push: true
tags: |
user/app:latest
user/app:${{ github.sha }}
cache-from: type=registry,ref=user/app:buildcache
cache-to: type=registry,ref=user/app:buildcache,mode=max
Image Scanning
# Scan for vulnerabilities
docker scan myapp:latest
# Using Trivy
trivy image myapp:latest
Debugging
Common Issues
- Container exits immediately
- Permission errors
- Network connectivity
- Volume mount issues
Debugging Commands
# View container logs
docker logs --tail 50 -f container_name
# Inspect container
docker inspect container_name
# View running processes
docker top container_name
# Check resource usage
docker stats
# Debug networking
docker network inspect bridge
Debug Container
# Add debugging tools to production image
FROM myapp:latest
RUN apk add --no-cache curl wget vim bash
CMD ["/bin/bash"]
Performance Optimization
Image Size Reduction
- Use Alpine Linux base images
- Multi-stage builds
- Remove unnecessary files
- Combine RUN commands
- Use .dockerignore
Build Performance
- Leverage build cache
- Use BuildKit
- Parallel builds
- Cache mount for package managers
Security
Image Scanning
# Scan with Docker Scout
docker scout cves myapp:latest
# Generate SBOM
docker sbom myapp:latest
Runtime Security
- Read-only root filesystem
- Drop unnecessary capabilities
- Use security profiles (AppArmor/SELinux)
- Limit resources
Monitoring
Container Metrics
- CPU usage
- Memory consumption
- Network I/O
- Disk usage
Logging
- Centralized logging with Fluentd
- Log rotation
- Structured logging
Resources
Team Support
For Docker-related questions:
- DevOps Team
- Platform Engineering Team
- Security Team (for image scanning)