Docker Nedir?

Docker, uygulamaları container'larda paketlemek ve çalıştırmak için kullanılan bir platformdur. Container'lar uygulamanızı tüm dependencies'leri ile birlikte paketler ve her ortamda tutarlı çalışmasını sağlar.

Docker'ın Avantajları

1. Docker Kurulumu

Windows

# Docker Desktop'ı indirin ve kurun
# https://www.docker.com/products/docker-desktop

# WSL 2 backend gerekli (Windows 10/11)
wsl --install
wsl --set-default-version 2

macOS

# Docker Desktop'ı indirin ve kurun
# https://www.docker.com/products/docker-desktop

# Homebrew ile
brew install --cask docker

Ubuntu/Linux

# Official Docker repository ekle
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Docker'ı kur
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io

# User'ı docker grubuna ekle
sudo usermod -aG docker $USER

Kurulum Testi

# Docker version kontrol
docker --version
docker-compose --version

# Test container çalıştır
docker run hello-world

2. Temel Docker Komutları

Image Yönetimi

# Image'leri listele
docker images
docker image ls

# Image indir
docker pull nginx:latest
docker pull python:3.9

# Image sil
docker rmi image_name:tag
docker rmi image_id

# Kullanılmayan image'leri temizle
docker image prune

Container Yönetimi

# Container çalıştır
docker run nginx
docker run -d nginx                    # Detached mode
docker run -p 8080:80 nginx           # Port mapping
docker run --name my-nginx nginx      # Container ismi ver

# Çalışan container'ları listele
docker ps
docker container ls

# Tüm container'ları listele (durmuş olanlar dahil)
docker ps -a

# Container durdur
docker stop container_name
docker stop container_id

# Container başlat
docker start container_name

# Container sil
docker rm container_name
docker rm container_id

# Çalışan container'ı sil
docker rm -f container_name

Container İnteraksiyon

# Container içine bash ile gir
docker exec -it container_name bash
docker exec -it container_name sh

# Container loglarını görüntüle
docker logs container_name
docker logs -f container_name  # Follow mode

# Container resource kullanımını görüntüle
docker stats
docker stats container_name

3. Dockerfile Yazma

Dockerfile, Docker image'ı nasıl oluşturacağınızı tanımlayan text dosyasıdır.

Basit Python Uygulaması

# app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello, Docker!'

@app.route('/health')
def health():
    return {'status': 'healthy'}

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
# requirements.txt
Flask==2.3.2
# Dockerfile
FROM python:3.9-slim

# Working directory ayarla
WORKDIR /app

# Requirements dosyasını kopyala ve install et
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Uygulama dosyalarını kopyala
COPY . .

# Port expose et
EXPOSE 5000

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

# Uygulama çalıştır
CMD ["python", "app.py"]

Image Build Etme

# Image build et
docker build -t my-flask-app .
docker build -t my-flask-app:v1.0 .

# Build cache kullanmadan
docker build --no-cache -t my-flask-app .

# Multi-stage build example
# Dockerfile.multi-stage

Multi-stage Build

# Multi-stage Dockerfile (Node.js örneği)
# Build stage
FROM node:16-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

COPY . .
RUN npm run build

# Production stage
FROM nginx:alpine

# Build stage'den sadece gerekli dosyaları kopyala
COPY --from=builder /app/dist /usr/share/nginx/html

# Nginx config
COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

4. Docker Compose

Docker Compose, multi-container uygulamaları tanımlamak ve çalıştırmak için kullanılır.

docker-compose.yml

# docker-compose.yml
version: '3.8'

services:
  web:
    build: .
    ports:
      - "5000:5000"
    depends_on:
      - db
      - redis
    environment:
      - DATABASE_URL=postgresql://user:password@db:5432/myapp
      - REDIS_URL=redis://redis:6379
    volumes:
      - .:/app
    networks:
      - app-network

  db:
    image: postgres:13
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - app-network

  redis:
    image: redis:6-alpine
    networks:
      - app-network

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - web
    networks:
      - app-network

volumes:
  postgres_data:

networks:
  app-network:
    driver: bridge

Docker Compose Komutları

# Servisleri başlat
docker-compose up
docker-compose up -d        # Detached mode
docker-compose up --build  # Build ile başlat

# Belirli servisi başlat
docker-compose up web

# Servisleri durdur
docker-compose down
docker-compose down -v      # Volume'leri de sil

# Logları görüntüle
docker-compose logs
docker-compose logs web
docker-compose logs -f web  # Follow mode

# Servislerin durumunu göster
docker-compose ps

# Servis scale et
docker-compose up --scale web=3

5. Docker Volumes

Volumes, container'lardaki veriyi persist etmek için kullanılır.

Volume Türleri

# Named Volume
docker volume create my-vol
docker run -d -v my-vol:/app/data nginx

# Bind Mount (Host path'i container'a mount et)
docker run -d -v /host/path:/container/path nginx
docker run -d -v $(pwd):/app python:3.9

# Anonymous Volume
docker run -d -v /app/data nginx

Volume Yönetimi

# Volume'leri listele
docker volume ls

# Volume detaylarını göster
docker volume inspect volume_name

# Volume oluştur
docker volume create my-data

# Volume sil
docker volume rm volume_name

# Kullanılmayan volume'leri temizle
docker volume prune

6. Docker Networks

Container'lar arası iletişimi sağlamak için network'ler kullanılır.

Network Türleri

# Bridge Network (default)
docker network create my-bridge-network
docker run -d --network my-bridge-network --name web1 nginx
docker run -d --network my-bridge-network --name web2 nginx

# Host Network
docker run -d --network host nginx

# None Network (no networking)
docker run -d --network none nginx

Network Yönetimi

# Network'leri listele
docker network ls

# Network detaylarını göster
docker network inspect network_name

# Network oluştur
docker network create --driver bridge my-network

# Container'ı network'e bağla
docker network connect network_name container_name

# Container'ı network'ten ayır
docker network disconnect network_name container_name

# Network sil
docker network rm network_name

7. Docker Registry

Docker Hub

# Docker Hub'a login
docker login

# Image'ı tag'le
docker tag my-app:latest username/my-app:latest
docker tag my-app:latest username/my-app:v1.0

# Image'ı push et
docker push username/my-app:latest
docker push username/my-app:v1.0

# Image'ı pull et
docker pull username/my-app:latest

Private Registry

# Local registry çalıştır
docker run -d -p 5000:5000 --restart=always --name registry registry:2

# Image'ı local registry'ye push et
docker tag my-app:latest localhost:5000/my-app:latest
docker push localhost:5000/my-app:latest

# Local registry'den pull et
docker pull localhost:5000/my-app:latest

8. Docker Best Practices

Dockerfile Best Practices

# ✅ İyi practices
FROM python:3.9-slim

# Non-root user oluştur
RUN groupadd -r appuser && useradd -r -g appuser appuser

# Working directory
WORKDIR /app

# Dependencies'leri önce kopyala (cache için)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Uygulama dosyalarını kopyala
COPY . .

# Ownership değiştir
RUN chown -R appuser:appuser /app
USER appuser

# Specific port expose et
EXPOSE 8000

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

# Signal handling için exec form kullan
CMD ["python", "-m", "uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]

.dockerignore

# .dockerignore
node_modules
npm-debug.log
Dockerfile
.dockerignore
.git
.gitignore
README.md
.env
.nyc_output
coverage
.nyc_output
.coverage
.pytest_cache
__pycache__

Security Best Practices

# ❌ Root user kullanma
USER root

# ✅ Non-root user kullan
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

# ❌ Latest tag kullanma
FROM python:latest

# ✅ Specific version kullan
FROM python:3.9.16-slim

# ❌ Tüm port'ları expose etme
EXPOSE 0-65535

# ✅ Sadece gerekli port'u expose et
EXPOSE 8000

9. Container Monitoring

Resource Monitoring

# Container resource kullanımı
docker stats

# Belirli container
docker stats container_name

# Memory limit koy
docker run -d --memory="256m" nginx

# CPU limit koy
docker run -d --cpus="1.5" nginx

# Container processes
docker exec container_name ps aux

Logging

# Log driver ayarla
docker run -d --log-driver json-file --log-opt max-size=10m --log-opt max-file=3 nginx

# Log görüntüle
docker logs container_name
docker logs --tail 50 container_name
docker logs --since="2023-01-01T00:00:00" container_name

# Log export et
docker logs container_name > container_logs.txt

10. Production Ready Setup

Multi-stage Production Build

# Dockerfile.prod
FROM python:3.9-slim as builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

FROM python:3.9-slim

# Security: non-root user
RUN groupadd -r appuser && useradd -r -g appuser appuser

# Copy dependencies from builder
COPY --from=builder /root/.local /home/appuser/.local

WORKDIR /app
COPY . .
RUN chown -R appuser:appuser /app

USER appuser

# Make sure scripts in .local are usable
ENV PATH=/home/appuser/.local/bin:$PATH

EXPOSE 8000

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

CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

Production docker-compose.yml

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

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile.prod
    restart: unless-stopped
    expose:
      - "8000"
    depends_on:
      - db
      - redis
    environment:
      - DATABASE_URL=${DATABASE_URL}
      - REDIS_URL=${REDIS_URL}
      - SECRET_KEY=${SECRET_KEY}
    networks:
      - app-network
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"

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

  db:
    image: postgres:13
    restart: unless-stopped
    environment:
      - POSTGRES_DB=${POSTGRES_DB}
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    networks:
      - app-network

volumes:
  postgres_data:
    driver: local

networks:
  app-network:
    driver: bridge

11. Troubleshooting

Yaygın Problemler ve Çözümleri

# Container başlamıyor
docker logs container_name
docker exec -it container_name sh

# Port conflicts
docker ps -a  # Kullanılan port'ları kontrol et
docker run -p 8080:80 nginx  # Farklı port kullan

# Volume mount problems
docker inspect container_name  # Volume mount'ları kontrol et
docker run -v $(pwd):/app alpine ls /app  # Mount test et

# Network connectivity
docker network inspect bridge
docker exec container1 ping container2

# Resource issues
docker system df  # Disk usage
docker system prune  # Cleanup unused resources

Debug Commands

# Container içindeki processes
docker exec container_name ps aux

# Container file system
docker exec container_name ls -la
docker exec container_name df -h

# Network test
docker exec container_name ping google.com
docker exec container_name netstat -tuln

# Environment variables
docker exec container_name env

Sonuç

Bu tutorial'da Docker'ın temellerinden production-ready deployment'a kadar geniş bir yelpazede konuları ele aldık. Docker modern yazılım geliştirmenin vazgeçilmez bir parçası haline gelmiştir.

Önemli Noktalar:

Docker'ı öğrenmek için en iyi yol practice yapmaktır. Kendi uygulamalarınızı containerize ederek deneyim kazanın!