Docker & Containerization

Uygulamalarınızı konteynerler içinde paketleyin, her yerde çalıştırın

docker run -d -p 80:80 nginx
# Dünya'nın en popüler web sunucusu

Docker Nedir?

Docker, uygulamalarınızı ve bağımlılıklarınızı hafif, taşınabilir ve kendi kendine yeten konteynerler içinde paketlemenizi sağlayan bir platformdur. Geleneksel sanal makinelerin aksine, konteynerler işletim sistemi seviyesinde sanallaştırma yapar ve çok daha verimlidir.

Tarihçe
Docker, 2013 yılında Solomon Hykes tarafından dotCloud şirketi tarafından geliştirildi. Linux konteyner teknolojisi (LXC) üzerine inşa edildi ve konteyner sanallaştırmasını kitlelere ulaştırdı. Bugün, yazılım geliştirme ve dağıtımın standart bir parçasıdır.
Docker'un Temel Bileşenleri:
  • Docker Engine: Konteynerleri oluşturan ve yöneten temel servis
  • Docker CLI: Komut satırı arayüzü
  • Docker Hub: Resmi ve topluluk konteyner resimleri
  • Docker Compose: Çoklu konteynerli uygulamalar için
  • Docker Swarm: Konteyner orkestrasyonu
Neden Docker?
• Tutarlılık: "Benim bilgisayarımda çalışıyordu" sorunu yok
• Taşınabilirlik: Geliştirme, test, üretim ortamları aynı
• Verimlilik: VM'lere göre daha az kaynak tüketir
• Hız: Saniyeler içinde başlatılır ve durdurulur

Docker, DevOps kültürünün ve mikroservis mimarisinin yükselişinde kritik bir rol oynamıştır. Günümüzde bulut bilişim, sürekli entegrasyon/sürekli dağıtım (CI/CD) ve modern uygulama mimarilerinin temel taşıdır.

Container Nedir?

Container (Konteyner), bir uygulamanın kodunu ve tüm bağımlılıklarını (kütüphaneler, sistem araçları, ayarlar) içeren, izole edilmiş ve taşınabilir bir yazılım birimidir. Konteynerler, herhangi bir Linux veya Windows tabanlı makinede tutarlı şekilde çalışır.

VM vs Container

Sanal Makine: Hypervisor → Guest OS → App → Libraries
Container: Host OS → Docker Engine → App + Libraries

Container Özellikleri
İzole: Her konteyner kendi dosya sistemi, ağ ve işlem alanına sahiptir
Hafif: Sadece uygulama ve bağımlılıkları, tam bir OS değil
Portatif: Herhangi bir Docker Engine olan makinede çalışır
Ölçeklenebilir: Saniyeler içinde çoğaltılabilir
Uyarı: Konteynerler sanal makineler DEĞİLdir. Güvenlik açısından, konteynerler host kernel'ı paylaşır. Bu nedenle, güvenlik duvarı ve izolasyon kuralları önemlidir.

Docker Image Nedir?

Docker Image, bir konteynerin sabit, salt okunur şablonudur. Bir image, bir uygulamanın nasıl çalıştırılacağını tanımlayan bir dizi katmandan (layer) oluşur. Image'ler, Dockerfile'lar kullanılarak veya mevcut konteynerlerden commit edilerek oluşturulur.

Image Katmanları
Her RUN, COPY, ADD komutu yeni bir katman oluşturur. Katmanlar önbelleğe alınır, bu da tekrar derleme işlemlerini hızlandırır. docker history komutu ile katmanları görebilirsiniz.
# Image listele
docker images

# Resmi Nginx image'ini indir
docker pull nginx

# Image detaylarını incele
docker inspect nginx

# Image geçmişini göster
docker history nginx
Image vs Container:
Image: Sınıf (Class) gibi düşünebilirsiniz — şablondur.
Container: Nesne (Object) gibidir — çalışan örnektir.

docker run komutu, bir image'den yeni bir container başlatır.

Dockerfile Nedir ve Nasıl Yazılır?

Dockerfile, bir Docker image'ini oluşturmak için kullanılan metin tabanlı bir betiktir. Adım adım talimatlar içerir ve docker build komutu ile image'e dönüştürülür.

# 1. Temel image
FROM python:3.9-slim

# 2. Çalışma dizini
WORKDIR /app

# 3. Bağımlılıkları kopyala ve yükle
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 4. Uygulama kodunu kopyala
COPY . .

# 5. Uygulamayı çalıştır
CMD ["python", "app.py"]
Temel Dockerfile Komutları:
  • FROM: Temel image
  • RUN: Image içinde komut çalıştır
  • COPY: Dosya/dizin kopyala
  • ADD: COPY + URL ve arşiv desteği
  • WORKDIR: Çalışma dizini belirle
  • ENV: Ortam değişkeni tanımla
  • EXPOSE: Port aç (belgeleme amaçlı)
  • CMD: Konteyner başlangıç komutu
  • ENTRYPOINT: CMD gibi ama override edilemez
Best Practice:
• Temel image olarak alpine gibi hafif image'leri tercih edin
• .dockerignore dosyası kullanarak gereksiz dosyaları kopyalamayın
• Katman sayısını azaltmak için RUN komutlarını birleştirin
• Multi-stage build kullanarak production image boyutunu küçültün
# Multi-stage build örneği
# 1. Aşama: Derleme
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o myapp .

# 2. Aşama: Production image
FROM alpine:3.18
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/myapp .
CMD ["./myapp"]

Docker CLI Temel Komutları

Docker CLI, konteynerleri yönetmek için kullandığınız komut satırı arayüzüdür. En sık kullanılan komutları aşağıda bulabilirsiniz.

# Konteynerleri listele (çalışanlar)
docker ps

# Tüm konteynerleri listele (durdurulanlar dahil)
docker ps -a

# Image'leri listele
docker images

# Konteyner başlat
docker run -d --name my-nginx -p 8080:80 nginx

# Konteyneri durdur
docker stop my-nginx

# Konteyneri sil
docker rm my-nginx

# Image sil
docker rmi nginx

# Konteyner loglarını göster
docker logs my-nginx

# Konteyner içine bağlan
docker exec -it my-nginx /bin/bash
Kullanışlı Kısayollar
-d: Detached mod (arka planda çalıştır)
-it: Interactive + TTY (etkileşimli terminal)
-p 8080:80: Port mapping (host:container)
--rm: Konteyner durduğunda otomatik sil
-v /host/path:/container/path: Volume mount
Temizlik: Durdurulmuş konteynerler, kullanılmayan image'ler ve volume'ler disk alanını doldurur. docker system prune komutu ile temizlik yapabilirsiniz.

Docker Compose: Çoklu Konteyner Yönetimi

Docker Compose, tek bir YAML dosyası (docker-compose.yml) kullanarak birden fazla konteynerden oluşan uygulamaları tanımlamanıza ve yönetmenize olanak tanır. Özellikle geliştirme ortamlarında çok kullanışlıdır.

docker-compose.yml Örneği

version: '3.8'

services:
  web:
    build: .
    ports:
      - "5000:5000"
    depends_on:
      - redis
    environment:
      - REDIS_HOST=redis

  redis:
    image: "redis:alpine"
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data

volumes:
  redis-data:
    driver: local

Docker Compose CLI Komutları

# Tüm servisleri başlat
docker-compose up -d

# Servisleri durdur ve konteynerleri sil
docker-compose down

# Sadece durdur
docker-compose stop

# Logları izle
docker-compose logs -f

# Belirli bir servisi yeniden başlat
docker-compose restart web

# Servis durumunu göster
docker-compose ps
Avantajlar
Basitlik: Tek komutla tüm uygulama ayağa kalkar
Yapılandırma: Network, volume, environment değişkenleri tek dosyada
Reprodüktibilite: Ekip üyeleri aynı ortamı kolayca kurabilir

Volume ve Persistent Storage

Konteynerler geçicidir (ephemeral). Konteyner silindiğinde içindeki veriler de silinir. Volume ve Bind Mount, verilerin kalıcı olarak saklanmasını sağlar.

Volume Türleri:
  • Named Volume: Docker tarafından yönetilen, en güvenli ve taşınabilir yol. docker volume create my_volume
  • Bind Mount: Host makinedeki bir dizini konteyner içine bağlar. Geliştirme için kullanışlı. -v /host/path:/container/path
  • tmpfs Mount: Bellekte tutulan geçici veri. Güvenlik için kullanılır.
# Named volume oluştur ve kullan
docker volume create postgres_data
docker run -d --name postgres -v postgres_data:/var/lib/postgresql/data postgres

# Bind mount ile geliştirme
docker run -d --name dev-app -v $(pwd):/app -p 3000:3000 node:18

# Volume'leri listele
docker volume ls

# Volume sil
docker volume rm postgres_data
Uyarı: Production ortamlarında bind mount kullanmaktan kaçının. Güvenlik ve taşınabilirlik sorunlarına yol açabilir. Named volume veya cloud storage çözümleri tercih edin.

Docker Network

Docker, konteynerlerin birbirleriyle ve dış dünya ile iletişim kurmasını sağlayan ağ yapıları sunar. Varsayılan olarak üç ağ tipi gelir: bridge, host, none.

Varsayılan Ağlar:
  • bridge: Varsayılan. Konteynerler birbirini IP ile görür, port mapping gerekir.
  • host: Konteyner, host'un ağ stack'ini kullanır. Performanslı ama izolasyon yok.
  • none: Hiçbir ağ erişimi yok.
# Özel bridge network oluştur
docker network create my_network

# Konteynerleri bu ağa bağla
docker run -d --name app1 --network my_network nginx
docker run -d --name app2 --network my_network redis

# app1 içinden app2'ye ping atabilirsiniz (DNS çözümleme)
docker exec -it app1 ping app2

# Ağları listele
docker network ls

# Ağ detaylarını göster
docker network inspect my_network
Compose ile Network: Docker Compose otomatik olarak özel bir bridge network oluşturur. Bu sayede servisler birbirlerini servis isimleriyle (redis, db) çözebilir.

Docker Hub ve Registry

Docker Hub, Docker'ın resmi konteyner resmi deposudur. Milyonlarca resmi ve topluluk image'ine erişebilir, kendi image'lerinizi paylaşabilirsiniz.

# Docker Hub'a giriş yap
docker login

# Image tag'le
docker tag my-app username/my-app:latest

# Image'i push et
docker push username/my-app:latest

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

Private Registry

Şirketler için: Hassas image'leri Docker Hub'da paylaşmak istemeyebilirsiniz. Kendi private registry'nizi kurabilirsiniz:
# Resmi Docker registry image'ini çalıştır
docker run -d -p 5000:5000 --name registry registry:2

# Image'i private registry'e push et
docker tag my-app localhost:5000/my-app
docker push localhost:5000/my-app
Resmi Image'ler
Resmi Image'ler: nginx, redis, postgres, python, node
Bunlar Docker tarafından veya orijinal yazılım üreticileri tarafından sağlanır ve güvenlidir.

Docker Güvenliği

Docker konteynerleri, sanal makineler kadar izole değildir. Host kernel'ı paylaşıldığı için güvenlik kritik öneme sahiptir.

Temel Güvenlik Önlemleri:
  • Root Olmadan Çalıştır: USER komutu ile non-root kullanıcı oluşturun.
  • En Küçük Yetki: Konteynerin sadece ihtiyaç duyduğu yetkilere sahip olmasına izin verin.
  • Güncel Image'ler: Temel image'leri ve bağımlılıkları güncel tutun.
  • Read-Only Filesystem: --read-only flag'i ile dosya sistemini salt okunur yapın.
  • Security Scanning: Docker Scout, Trivy gibi araçlarla image'leri tarayın.
# Güvenli bir Dockerfile örneği
FROM python:3.9-slim

# Non-root kullanıcı oluştur
RUN useradd --create-home appuser
WORKDIR /home/appuser
COPY --chown=appuser:appuser . .
USER appuser

CMD ["python", "app.py"]
Araçlar:
• docker scan : Zafiyet taraması
• trivy image : Açık kaynak güvenlik tarayıcı
• docker bench security: Docker kurulumunuzu güvenlik için denetler

Docker Swarm: Konteyner Orkestrasyonu

Docker Swarm, Docker'ın kendi içinde gelen konteyner orkestrasyon aracıdır. Birden fazla Docker node'undan oluşan bir cluster oluşturup, servisleri bu cluster üzerinde dağıtabilirsiniz.

Swarm Bileşenleri
Manager Node: Cluster'ı yönetir, servisleri dağıtır
Worker Node: Konteynerleri çalıştırır
Service: Aynı image'den oluşan konteyner koleksiyonu
Stack: compose dosyası ile tanımlanan çoklu servisler
# Swarm modunu başlat (manager)
docker swarm init

# Worker node ekleme komutu (manager'da çalıştır)
docker swarm join-token worker

# Servis oluştur
docker service create --name web --replicas 3 -p 80:80 nginx

# Servis durumunu göster
docker service ls
docker service ps web

# Stack deploy (compose dosyası)
docker stack deploy -c docker-compose.yml my_stack
Swarm vs Kubernetes:
Swarm: Kurulumu ve kullanımı kolay, Docker entegrasyonu mükemmel
Kubernetes: Daha güçlü, esnek ve ölçeklenebilir, öğrenme eğrisi dik

Docker & Kubernetes

Kubernetes (K8s), Google'ın geliştirdiği, endüstri standardı haline gelmiş açık kaynaklı konteyner orkestrasyon sistemidir. Docker, Kubernetes'in altında çalışan konteyner çalışma zamanıdır (runtime).

Nasıl Çalışır?
Kubernetes, Docker konteynerlerinizi podlar içinde çalıştırır. Deployment, Service, ConfigMap, Secret gibi nesnelerle uygulamanızı tanımlarsınız. Kubernetes, konteynerlerinizi otomatik olarak ölçeklendirir, yeniden başlatır ve yönetir.
# Basit bir pod tanımı (pod.yaml)
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
  - name: nginx-container
    image: nginx:latest
    ports:
    - containerPort: 80

# Pod'u başlat
kubectl apply -f pod.yaml

# Pod durumunu kontrol et
kubectl get pods
kubectl logs nginx-pod
Not: Kubernetes, Docker CLI komutlarını doğrudan kullanmaz. kubectl komutu ile iletişim kurar. Docker, sadece konteynerleri çalıştıran alt seviye teknolojidir.

Docker Best Practices

Docker ile profesyonelce çalışmak için aşağıdaki en iyi uygulamaları benimseyin.

Image Boyutu:
  • Temel image olarak alpine veya -slim tag'leri kullanın.
  • Multi-stage build kullanarak derleme bağımlılıklarını production image'den çıkarın.
  • .dockerignore ile gereksiz dosyaları kopyalamayın.
Güvenlik:
  • Root kullanıcı ile çalıştırmayın.
  • Image'leri sık sık güncelleyin ve güvenlik taraması yapın.
  • Secret'leri environment variable'ı olarak vermeyin, Docker Secret veya Kubernetes Secret kullanın.
Yapılandırma:
  • Portları ve environment variable'ları Dockerfile'da belgeleyin.
  • Healthcheck ekleyin: HEALTHCHECK --interval=30s CMD curl -f http://localhost/ || exit 1
  • Log'ları STDOUT/STDERR'e yazdırın.
Pro İpucu: docker buildx ile multi-platform image'leri oluşturabilirsiniz (linux/amd64, linux/arm64). Bu, Raspberry Pi gibi cihazlarda da çalışmanızı sağlar.

Docker ile Mikroservis Mimari

Mikroservis mimarisi, bir uygulamayı küçük, bağımsız ve gevşek bağlı servisler halinde geliştirmeyi önerir. Docker, bu mimarinin doğal ortağıdır.

Mikroservis Yapısı

API Gateway → User Service → Product Service → Order Service → Database

Avantajlar
Ölçeklenebilirlik: Sadece yoğun kullanılan servisleri ölçeklendirin
Esneklik: Her servis farklı teknolojiyle yazılabilir
Dayanıklılık: Bir servis çökerse, diğerleri çalışmaya devam eder
Dağıtık Geliştirme: Farklı ekipler farklı servisler üzerinde çalışabilir
Zorluklar: Dağıtık sistemlerin karmaşıklığı, ağ gecikmeleri, veri tutarlılığı ve monitoring zorlukları.

CI/CD Entegrasyonu

Docker, sürekli entegrasyon ve sürekli dağıtım (CI/CD) pipeline'larının vazgeçilmez bir parçasıdır. Her commit'te otomatik olarak image oluşturulup test ortamına veya üretime deploy edilebilir.

Temel CI/CD Akışı:
  1. Kod commit edilir (GitHub, GitLab)
  2. CI sunucusu (Jenkins, GitHub Actions) tetiklenir
  3. Testler çalıştırılır
  4. Docker image oluşturulur ve taglenir
  5. Image private registry'e push edilir
  6. Orkestrasyon aracı (K8s, Swarm) yeni image ile rollout yapar
# GitHub Actions örneği (.github/workflows/docker.yml)
name: Docker Build and Push

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    - name: Build Docker image
      run: docker build -t my-app:${{ github.sha }} .
    - name: Login to Docker Hub
      run: echo "${{ secrets.DOCKER_PASSWORD }}" | docker login -u "${{ secrets.DOCKER_USERNAME }}" --password-stdin
    - name: Push to Docker Hub
      run: |
        docker tag my-app:${{ github.sha }} username/my-app:latest
        docker push username/my-app:latest

Monitoring ve Logging

Konteynerler geçici olduğu için geleneksel monitoring yöntemleri yetersiz kalır. Docker'a özel araçlar kullanmanız gerekir.

Temel Araçlar:
  • Docker Stats: docker stats ile canlı kaynak kullanımı
  • Logs: docker logs ve log driver'ları (json-file, syslog, fluentd)
  • Prometheus + Grafana: Metrik toplama ve görselleştirme
  • ELK Stack (Elasticsearch, Logstash, Kibana): Log yönetimi
  • cAdvisor: Konteyner kaynak kullanımını izleme
Orkestrasyon ile: Kubernetes'te kubectl top pods ve kubectl logs komutları ile temel monitoring yapılabilir. Prometheus Operator ve Loki gibi araçlarla profesyonel çözümler kurulabilir.

Docker Desktop

Docker Desktop, Windows ve macOS kullanıcıları için Docker Engine, CLI, Docker Compose, Kubernetes ve GUI arayüzünü tek bir uygulamada sunar. Geliştirme için idealdir.

GUI Özellikleri
Konteyner/İmaj Listesi: Görsel olarak yönetin
Log Görüntüleme: Tıkla, logları gör
Kaynak Kullanımı: CPU, RAM, Disk kullanımı
Ayarlar: Proxy, network, disk alanı ayarları
Lisans: Docker Desktop, büyük şirketler için ücretlidir. Küçük şirketler ve bireysel geliştiriciler ücretsiz kullanabilir. Alternatif olarak Colima (macOS) veya doğrudan Linux kurulumu tercih edilebilir.

Docker Alternatifleri

Docker, konteyner dünyasının en popüler aracıdır ama tek seçeneğiniz değildir. Bazı alternatifler:

Podman: Red Hat tarafından geliştirilen, rootless ve daemon-less bir konteyner motorudur. Docker CLI ile uyumludur. alias docker=podman ile geçiş kolaydır.

containerd: Docker'ın alt yapısında da kullanılan CNCF projesi. Yüksek performanslı, minimalist bir container runtime'dır.

LXC/LXD: Docker'dan önceki nesil konteyner teknolojisi. Tam bir OS sanallaştırma sunar (system container).

CRI-O: Kubernetes için optimize edilmiş, OCI uyumlu container runtime.
Gelecek: Kubernetes, Docker'ı runtime olarak kullanmaktan vazgeçti (dockershim kaldırıldı). Artık containerd veya CRI-O gibi CRI uyumlu runtime'lar tercih ediliyor. Ancak, geliştirme için Docker hâlâ birinci sınıf bir araçtır.

Docker'un Geleceği

Docker, konteyner devrimini başlatan araç olarak tarihe geçti. Gelecekte, geliştirici deneyimi ve entegrasyonlar üzerinde odaklanmaya devam edecek.

Gelecek Trendler

WebAssembly (WASM): Docker, WASM modüllerini konteynerler içinde çalıştırma desteği sunuyor.
AI/ML Workload'lar: Büyük modellerin konteynerler içinde dağıtımı.
Geliştirici Araçları: Docker Desktop ve Docker Init gibi araçlarla geliştirici deneyimi iyileştiriliyor.

Son Söz: Docker, konteyner teknolojisinin standartlaşmasında ve demokratikleşmesinde kilit rol oynadı. Gelecekte de modern yazılım geliştirme ve dağıtımın merkezinde olmaya devam edecek.

Docker Yolculuğunuza Başlayın!

Nasıl Başlayabilirsiniz?
Yükleme: Docker Desktop (Windows/Mac) veya Docker Engine (Linux)
İlk Adım: docker run hello-world
Öğrenin: Dockerfile, Compose, CLI komutları
Pratik Yapın: Basit bir web uygulamasını konteynerize edin
Topluluk: Docker Forum, Stack Overflow, GitHub

docker build -t future .
docker run future

Konteynerlerle geleceği inşa edin!