Skip to content
IRC-Coding IRC-Coding
Docker Container Images Dockerfile Docker Compose Kubernetes DevOps Containerization

Docker Containers: Images, Dockerfile & Compose

Master Docker containerization with images, Dockerfile, Docker Compose, and Kubernetes. Practical examples included.

S

schutzgeist

1 min read

Docker Container: Fundamentals, Images, Dockerfile & Docker Compose

Docker revolutionized software development through containerization. It enables consistent environments from development to production and solves the “works on my machine” problem.

Docker Fundamentals

What is Containerization?

Containerization is an operating system-level virtualization technology that runs applications with all their dependencies in isolated environments.

Docker vs Virtual Machines

# Virtual Machine (VM)
# - Complete operating system
# - Hypervisor required
# - High resource consumption
# - Slow startup

# Docker Container
# - Shared operating system kernel
# - No hypervisor required
# - Low resource consumption
# - Fast startup

Docker Architecture

# Docker Components
# 1. Docker Daemon (dockerd)
#    - Manages containers, images, networks, volumes
#    - Runs in the background
#    - API endpoint for clients

# 2. Docker Client (docker)
#    - Command-line interface
#    - Communicates with Docker Daemon
#    - User interaction

# 3. Docker Registry
#    - Storage for images (Docker Hub)
#    - Public and private registries

# 4. Docker Objects
#    - Images: Templates for containers
#    - Containers: Running instances
#    - Networks: Container communication
#    - Volumes: Data storage

Docker Installation and Setup

Installation

# Ubuntu/Debian
sudo apt update
sudo apt install docker.io
sudo systemctl start docker
sudo systemctl enable docker

# CentOS/RHEL
sudo yum install docker
sudo systemctl start docker
sudo systemctl enable docker

# Docker Desktop (Windows/Mac)
# Download from https://www.docker.com/products/docker-desktop

# Add user to docker group
sudo usermod -aG docker $USER
newgrp docker

# Verify installation
docker --version
docker info

Basic Commands

# Docker version and system information
docker version
docker info
docker system df

# Manage images
docker images
docker pull ubuntu:latest
docker search nginx
docker rmi nginx:latest

# Manage containers
docker ps                    # Running containers
docker ps -a               # All containers
docker run nginx           # Start container
docker stop container_id   # Stop container
docker rm container_id     # Remove container

# Logs and inspection
docker logs container_id
docker inspect container_id
docker exec -it container_id bash

Docker Images

What are Docker Images?

Docker images are read-only templates used to create containers. They consist of multiple layers.

Image Structure

# Docker image layer structure
# 1. Base Layer (e.g. Ubuntu)
# 2. Dependencies Layer (e.g. Python)
# 3. Application Layer (e.g. Web app)
# 4. Configuration Layer (e.g. environment variables)

# Display layers
docker history nginx:latest

# Image information
docker inspect nginx:latest

Dockerfile

A Dockerfile is a text file with instructions for creating a Docker image.

# Dockerfile example for Node.js application

# Base image
FROM node:16-alpine

# Metadata
LABEL maintainer="max@example.com"
LABEL version="1.0"
LABEL description="Node.js web application"

# Working directory
WORKDIR /app

# Environment variables
ENV NODE_ENV=production
ENV PORT=3000

# Copy files
COPY package*.json ./
RUN npm install --production

# Copy application code
COPY . .

# Create user (security best practice)
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
USER nodejs

# Expose port
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# Start command
CMD ["node", "server.js"]

Dockerfile Best Practices

# Best practices for Dockerfile

# 1. Minimalist base image
FROM alpine:latest

# 2. Use specific tags (not latest)
FROM node:16.14.2-alpine

# 3. Use .dockerignore
# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
README.md
.env

# 4. Optimize layer caching
COPY package*.json ./
RUN npm install
COPY . .

# 5. Multi-stage builds
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM node:16-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]

# 6. Security best practices
USER nonrootuser
RUN rm -rf /var/cache/apk/*

Create and manage images

# Build image
docker build -t myapp:1.0 .
docker build -t myapp:latest -f Dockerfile.prod .

# Image with build arguments
docker build --build-arg NODE_ENV=production -t myapp:prod .

# Multi-platform build
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:multi .

# Tag images
docker tag myapp:1.0 myregistry/myapp:1.0
docker tag myapp:latest myregistry/myapp:latest

# Push images
docker login myregistry.com
docker push myregistry/myapp:1.0
docker push myregistry/myapp:latest

# Clean up images
docker image prune -f
docker image prune -a -f

Docker Containers

Container Lifecycle

# Create and start container
docker run --name mywebserver -d -p 8080:80 nginx

# Container with volumes
docker run --name mydb -v /data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=password mysql:8.0

# Container with network
docker network create mynetwork
docker run --name myapp --network mynetwork -d myapp:latest

# Manage containers
docker start mywebserver
docker stop mywebserver
docker restart mywebserver
docker pause mywebserver
docker unpause mywebserver

# Inspect containers
docker logs mywebserver
docker logs -f mywebserver  # Follow logs
docker stats mywebserver    # Resource usage
docker exec -it mywebserver bash

Container Configuration

# Resource limits
docker run --memory="512m" --cpus="1.0" myapp:latest

# Environment variables
docker run -e NODE_ENV=production -e PORT=3000 myapp:latest

# Volumes
docker run -v /host/path:/container/path myapp:latest
docker run -v myvolume:/container/path myapp:latest

# Ports
docker run -p 8080:80 -p 8443:443 myapp:latest

# Networks
docker run --network bridge myapp:latest
docker run --network host myapp:latest
docker run --network none myapp:latest

# Restart policies
docker run --restart=always myapp:latest
docker run --restart=on-failure:5 myapp:latest
docker run --restart=unless-stopped myapp:latest

Docker Volumes

# Volume types
# 1. Bind mounts: Host file system
docker run -v /host/data:/container/data myapp:latest

# 2. Named volumes: Docker-managed
docker volume create mydata
docker run -v mydata:/container/data myapp:latest

# 3. Anonymous volumes: Automatically created
docker run -v /container/data myapp:latest

# Volume management
docker volume ls
docker volume inspect mydata
docker volume rm mydata
docker volume prune

# Backup and restore
docker run --rm -v mydata:/data -v $(pwd):/backup alpine tar czf /backup/mydata-backup.tar.gz /data
docker run --rm -v mydata:/data -v $(pwd):/backup alpine tar xzf /backup/mydata-backup.tar.gz -C /

Docker Networks

Network Types

# Bridge Network (Standard)
docker network create mybridge
docker run --network mybridge myapp:latest

# Host Network
docker run --network host myapp:latest

# None Network
docker run --network none myapp:latest

# Overlay Network (Multi-Host)
docker network create --driver overlay myoverlay

Network Configuration

# Create network
docker network create --driver bridge --subnet 192.168.1.0/24 mynetwork

# Container with network
docker run --network mynetwork --ip 192.168.1.10 myapp:latest

# Network connections
docker network connect mynetwork mycontainer
docker network disconnect mynetwork mycontainer

# Network inspection
docker network inspect mynetwork
docker network ls
docker network prune

Docker Compose

Docker Compose Basics

Docker Compose enables the definition and management of multi-container applications.

# docker-compose.yml
version: '3.8'

services:
  # Web Service
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://user:password@db:5432/myapp
    depends_on:
      - db
      - redis
    volumes:
      - ./logs:/app/logs
    restart: unless-stopped
    networks:
      - app-network

  # Database Service
  db:
    image: postgres:13
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    restart: unless-stopped
    networks:
      - app-network

  # Redis Cache
  redis:
    image: redis:6-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    restart: unless-stopped
    networks:
      - app-network

  # Nginx Reverse Proxy
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - web
    restart: unless-stopped
    networks:
      - app-network

# Volumes
volumes:
  postgres_data:
  redis_data:

# Networks
networks:
  app-network:
    driver: bridge

Docker Compose Commands

# Start services
docker-compose up
docker-compose up -d  # Detached mode
docker-compose up --build  # With rebuild

# Stop services
docker-compose down
docker-compose down -v  # With volumes

# View logs
docker-compose logs
docker-compose logs -f web
docker-compose logs --tail=100 web

# Manage services
docker-compose ps
docker-compose restart web
docker-compose stop web
docker-compose start web

# Scaling
docker-compose up -d --scale web=3

# Build images
docker-compose build
docker-compose build --no-cache
docker-compose build web

# Environment variables
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up

Environment-Specific Configuration

# docker-compose.override.yml (Development)
version: '3.8'

services:
  web:
    environment:
      - NODE_ENV=development
    volumes:
      - .:/app
      - /app/node_modules
    command: npm run dev

  db:
    ports:
      - "5432:5432"

# docker-compose.prod.yml (Production)
version: '3.8'

services:
  web:
    environment:
      - NODE_ENV=production
    deploy:
      replicas: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 512M

  nginx:
    ports:
      - "80:80"
      - "443:443"

Docker Security

Security Best Practices

# 1. Minimal base image
FROM alpine:latest

# 2. Non-root user
RUN addgroup -g 1001 -S appgroup && \
    adduser -S appuser -u 1001 -G appgroup
USER appuser

# 3. Use secrets (not in image)
# docker run --secret=mysecret myapp:latest

# 4. READONLY filesystem
docker run --read-only --tmpfs /tmp myapp:latest

# 5. Resource limits
docker run --memory=512m --cpus=1.0 myapp:latest

Docker Security Scanning

# Scan image with Trivy
trivy image myapp:latest

# Docker Scout (official tool)
docker scout cves myapp:latest

# Security check in Dockerfile
hadolint Dockerfile

Docker Monitoring and Logging

Logging Strategies

# docker-compose.yml with logging configuration
version: '3.8'

services:
  web:
    image: myapp:latest
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    labels:
      - "logging=promtail"

  # ELK Stack for logging
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.14.0
    environment:
      - discovery.type=single-node
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data

  logstash:
    image: docker.elastic.co/logstash/logstash:7.14.0
    volumes:
      - ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf

  kibana:
    image: docker.elastic.co/kibana/kibana:7.14.0
    ports:
      - "5601:5601"
    depends_on:
      - elasticsearch

Monitoring with Prometheus

# docker-compose.monitoring.yml
version: '3.8'

services:
  prometheus:
    image: prom/prometheus:latest
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus

  grafana:
    image: grafana/grafana:latest
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana
      - ./grafana/dashboards:/etc/grafana/provisioning/dashboards

  node-exporter:
    image: prom/node-exporter:latest
    ports:
      - "9100:9100"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro

volumes:
  prometheus_data:
  grafana_data:

Docker and Kubernetes

Kubernetes Basics

# kubernetes/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myregistry/myapp:1.0
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5

Docker to Kubernetes Migration

# Kompose for conversion
kompose convert -f docker-compose.yml

# Apply Kubernetes manifest
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml

# Manage deployment
kubectl get deployments
kubectl get pods
kubectl logs -f deployment/myapp-deployment
kubectl scale deployment myapp-deployment --replicas=5

Docker Best Practices

Performance Optimization

# Multi-stage build for smaller images
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY . .
RUN npm run build

FROM node:16-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]

Production Deployment

# docker-compose.prod.yml
version: '3.8'

services:
  web:
    image: myregistry/myapp:${VERSION}
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 10s
        failure_action: rollback
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

Troubleshooting

Common Issues

# 1. Container won't start
docker logs container_id
docker inspect container_id

# 2. Out of disk space
docker system df
docker system prune -a -f
docker volume prune -f

# 3. Network issues
docker network inspect network_name
docker exec -it container_id ping other_container

# 4. Permission issues
sudo chown -R $USER:$USER /var/run/docker.sock

# 5. Image pull issues
docker system prune -f
docker pull --no-cache image_name

Debugging Techniques

# Inspect container
docker exec -it container_id /bin/sh
docker exec -it container_id /bin/bash

# Copy files
docker cp container_id:/path/file.txt .
docker cp file.txt container_id:/path/

# Analyze image layers
docker history image_name
dive image_name

# Performance analysis
docker stats
docker top container_id

Exam-Relevant Concepts

Important Docker Commands

CommandDescriptionUsage
docker buildCreate imageFrom Dockerfile
docker runStart containerRun application
docker-compose upStart multi-containerDevelopment environment
docker pushUpload imageRegistry upload
docker pullDownload imageRegistry download

Typical Exam Tasks

  1. Create Dockerfiles for various applications
  2. Configure Docker Compose for multi-container apps
  3. Implement security best practices
  4. Optimize Docker images for production
  5. Migrate applications to Kubernetes

Summary

Docker is fundamental to modern software development:

  • Containerization: Consistent environments everywhere
  • Images: Reusable templates for applications
  • Dockerfile: Automated build processes
  • Docker Compose: Define multi-container applications
  • Kubernetes: Orchestration for large deployments

Good Docker management requires understanding of container concepts, security practices, and orchestration techniques.

Back to Blog
Share:

Related Posts