Docker Nedir, Neden VPS'te Kullanılır?

Docker, uygulamaları konteyner adı verilen hafif, taşınabilir ve izole birimlerde paketleyip çalıştıran bir platformdur. Bir konteyner; uygulamanızı, bağımlılıklarını, kütüphanelerini ve yapılandırmasını tek bir görüntü (image) içinde barındırır. Böylece geliştirme, test ve üretim ortamları arasında birebir aynı davranışı garanti eder.

Sanal makinelerden (VM) farkı: Konteynerler işletim sistemi çekirdeğini (kernel) paylaşır, kendi çekirdeğini önyüklemez. Bu sayede bir VM saniyeler yerine milisaniyeler içinde başlar ve yüzlerce MB yerine onlarca MB yer kaplar. Tek bir VPS üzerinde onlarca konteyner rahatça çalışabilir.

VPS'te Docker kullanmanın somut avantajları:

  • 🔁 Taşınabilirlik: Aynı görüntü yerel bilgisayarınızda da, VPS'te de, farklı bir sağlayıcıda da aynı çalışır.
  • 📦 İzolasyon: Bir uygulamanın PHP 8.3, diğerinin PHP 7.4 istemesi sorun değil; her biri kendi konteynerinde.
  • Hızlı dağıtım: docker compose up -d ile tüm yığın (stack) saniyeler içinde ayağa kalkar.
  • ♻️ Kolay geri alma: Yeni sürüm sorun çıkarırsa eski görüntüye tek komutla dönebilirsiniz.
💡 Bilgi: Paylaşımlı hosting üzerinde Docker çalıştıramazsınız çünkü root erişimi ve kernel özellikleri gerekir. Docker için en az bir VPS veya dedicated sunucu gerekir. VDS ve VPS farkları için VDS karşılaştırma sayfamıza bakabilirsiniz.

VPS'e Docker Kurulumu (Ubuntu 22.04/24.04)

Aşağıdaki adımlar Ubuntu 22.04 ve 24.04 için Docker'ın resmi deposundan güncel sürümü kurar. Komutları root veya sudo yetkili bir kullanıcıyla çalıştırın.

1. Eski sürümleri temizleyin ve sistemi güncelleyin:

# Varsa çakışan eski paketleri kaldır
sudo apt-get remove -y docker docker-engine docker.io containerd runc

# Sistem paketlerini güncelle
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release

2. Docker'ın resmi GPG anahtarını ve deposunu ekleyin:

# GPG anahtar dizinini oluştur
sudo install -m 0755 -d /etc/apt/keyrings

# Docker GPG anahtarını indir
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
  sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

# Depoyu kaynak listesine ekle
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

3. Docker Engine ve Compose eklentisini kurun:

sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin

# Kurulumu doğrula
sudo docker --version
sudo docker compose version

4. Kullanıcınızı docker grubuna ekleyin (böylece her komutta sudo yazmanız gerekmez):

sudo usermod -aG docker $USER

# Değişikliğin geçerli olması için oturumu kapatıp açın veya:
newgrp docker

# Test: sudo olmadan çalışmalı
docker run hello-world
⚠️ Güvenlik uyarısı: docker grubuna eklenen kullanıcı, pratikte root yetkisine sahip olur (konteynerlerle host dosya sistemine erişebilir). Bu kullanıcı için mutlaka SSH anahtarı kullanın ve parola girişini kapatın.

İlk Konteynerinizi Çalıştırma

Bir Nginx web sunucusunu tek komutla ayağa kaldıralım. Bu, portların ve kalıcı veri (volume) mantığının nasıl çalıştığını gösterir:

# -d: arka planda çalıştır, --name: konteyner adı
# -p: host_portu:konteyner_portu, -v: kalıcı dosya bağlama
docker run -d \
  --name web \
  -p 80:80 \
  -v /var/www/site:/usr/share/nginx/html:ro \
  nginx:latest

# Çalışan konteynerleri listele
docker ps

# Logları izle
docker logs -f web

# Konteynerin içine gir (hata ayıklama için)
docker exec -it web /bin/bash

# Durdur ve sil
docker stop web && docker rm web

Burada -p 80:80 VPS'in 80 numaralı portunu konteynerin 80 portuna yönlendirir. -v ise VPS'teki /var/www/site klasörünü konteynere bağlar; böylece konteyneri silseniz bile dosyalarınız kaybolmaz. Kalıcı veri yönetimi Docker'ın en kritik konusudur — veritabanı verilerini mutlaka bir volume üzerinde tutun.

docker-compose ile Çoklu Servis

Gerçek projeler tek konteynerden ibaret değildir: bir web uygulaması, bir veritabanı, belki bir önbellek (Redis) birlikte çalışır. docker-compose, tüm bu servisleri tek bir docker-compose.yml dosyasında tanımlayıp tek komutla yönetmenizi sağlar.

Aşağıda WordPress + MySQL yığını örneği. Bir dizin oluşturup içine docker-compose.yml kaydedin:

services:
  db:
    image: mysql:8.0
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: wordpress
      MYSQL_USER: wp_user
      MYSQL_PASSWORD: guclu_bir_sifre_123
      MYSQL_ROOT_PASSWORD: cok_daha_guclu_root_456
    volumes:
      - db_data:/var/lib/mysql
    networks:
      - internal

  wordpress:
    image: wordpress:php8.3-apache
    restart: unless-stopped
    depends_on:
      - db
    environment:
      WORDPRESS_DB_HOST: db:3306
      WORDPRESS_DB_USER: wp_user
      WORDPRESS_DB_PASSWORD: guclu_bir_sifre_123
      WORDPRESS_DB_NAME: wordpress
    ports:
      - "8080:80"
    volumes:
      - wp_data:/var/www/html
    networks:
      - internal

volumes:
  db_data:
  wp_data:

networks:
  internal:

Yığını yönetme komutları:

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

# Durumu gör
docker compose ps

# Tüm servislerin loglarını canlı izle
docker compose logs -f

# Sadece imajları güncelle ve yeniden başlat
docker compose pull && docker compose up -d

# Yığını tamamen durdur (volume'ler korunur)
docker compose down

# DİKKAT: -v ile volume'ler de silinir (veri kaybı!)
# docker compose down -v

Dikkat edin: db ve wordpress servisleri aynı internal ağında olduğu için birbirlerine servis adıyla (örneğin db:3306) erişebilir. Veritabanının portunu dışarıya (ports) açmadık; bu bilinçli bir güvenlik tercihidir — MySQL yalnızca iç ağdan erişilebilir.

Nginx ile Ters Proxy Kurulumu

Birden fazla uygulamayı tek IP ve 80/443 portları üzerinden yayınlamak için bir ters proxy (reverse proxy) gerekir. Ters proxy, gelen isteği alan adına göre doğru konteynere yönlendirir. İlk yöntem klasik Nginx yapılandırmasıdır.

Örnek: app1.siteniz.com isteğini 8080 portundaki konteynere, app2.siteniz.com isteğini 8090'a yönlendiren bir Nginx bloğu:

# /etc/nginx/sites-available/app1.conf
server {
    listen 80;
    server_name app1.siteniz.com;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Yapılandırmayı etkinleştirip Let's Encrypt ile ücretsiz SSL sertifikası alalım. Certbot bu işi otomatikleştirir:

# Yapılandırmayı etkinleştir ve test et
sudo ln -s /etc/nginx/sites-available/app1.conf \
  /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

# Certbot kur ve SSL sertifikası al (otomatik yenilenir)
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d app1.siteniz.com

# Otomatik yenilemeyi test et
sudo certbot renew --dry-run

Bu yaklaşımda Nginx doğrudan VPS'te (konteyner dışında) çalışır. Basit senaryolar için gayet iyidir, ancak her yeni alan adında elle yapılandırma dosyası oluşturmanız gerekir.

Traefik ile Otomatik SSL Yönetimi

Traefik, Docker için tasarlanmış modern bir ters proxydir. En büyük avantajı: konteyner etiketlerini (labels) okuyarak yönlendirmeyi otomatik yapar ve Let's Encrypt sertifikalarını kendisi alıp yeniler. Yeni bir uygulama eklediğinizde tek satır etiket yeterlidir.

Aşağıda Traefik + örnek bir web uygulaması içeren docker-compose.yml. E-posta adresini kendinizinkiyle değiştirin:

services:
  traefik:
    image: traefik:v3.1
    restart: unless-stopped
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      # HTTP'yi otomatik HTTPS'e yönlendir
      - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
      - "--entrypoints.web.http.redirections.entrypoint.scheme=https"
      # Let's Encrypt otomatik sertifika
      - "--certificatesresolvers.le.acme.email=siz@siteniz.com"
      - "--certificatesresolvers.le.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.le.acme.tlschallenge=true"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./letsencrypt:/letsencrypt

  app:
    image: nginx:latest
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app.rule=Host(`app.siteniz.com`)"
      - "traefik.http.routers.app.entrypoints=websecure"
      - "traefik.http.routers.app.tls.certresolver=le"
      - "traefik.http.services.app.loadbalancer.server.port=80"

Yığını başlatın; Traefik app.siteniz.com için SSL sertifikasını otomatik alıp HTTPS'e yönlendirecektir:

docker compose up -d

# Traefik loglarında sertifika alımını izle
docker compose logs -f traefik

Yeni bir uygulama eklemek için tek yapmanız gereken, o servise labels bölümündeki dört satırı (kendi alan adıyla) eklemek. Traefik gerisini halleder.

✅ Karşılaştırma: Az sayıda site ve elle kontrol isteyen sabit yapılar için Nginx + Certbot yeterlidir. Sık değişen, çok sayıda konteyner çalıştıran, "sıfır dokunuş" SSL isteyen dinamik ortamlar için Traefik çok daha pratiktir.

Aşağıdaki tablo iki yaklaşımı hızlıca karşılaştırır:

Özellik Nginx + Certbot Traefik
Yapılandırma Her site için elle dosya Konteyner etiketi (otomatik)
SSL yenileme Certbot cron ile Tamamen otomatik
Öğrenme eğrisi Düşük (klasik) Orta
Dinamik ortam Zayıf Çok güçlü

Güvenlik ve Kaynak Yönetimi

Docker güçlüdür ama yanlış yapılandırılırsa güvenlik açığına dönüşür. Üretim ortamında dikkat edilmesi gerekenler:

  • 🔒 Gereksiz port açmayın: Sadece 80 ve 443'ü dışarıya açın. Veritabanı ve iç servisler yalnızca Docker ağında kalsın (yukarıdaki örnekte MySQL portu dışarı açılmadı).
  • 🧱 Güvenlik duvarı (UFW): sudo ufw allow 22,80,443/tcp ile yalnızca gerekli portlara izin verin. Docker'ın UFW ile birlikte doğru çalışması için ek yapılandırma gerekebilir.
  • 📉 Kaynak sınırı koyun: Bir konteynerin tüm RAM'i tüketip VPS'i çökertmesini önleyin. compose'da servise mem_limit: 512m ve cpus: "0.5" ekleyin.
  • 🔄 İmajları güncel tutun: docker compose pull ile güvenlik yamalarını düzenli alın. Sabitlenmiş sürüm etiketleri (örn. mysql:8.0) kullanın, latest'e körü körüne güvenmeyin.
  • 🧹 Disk temizliği: Kullanılmayan imaj ve volume'ler disk şişirir.

Kaynak kullanımını izleme ve temizlik komutları:

# Konteynerlerin canlı CPU/RAM kullanımı
docker stats

# Disk kullanımını gör
docker system df

# Kullanılmayan imaj, konteyner ve ağları temizle (dikkatli)
docker system prune -a

# Sadece asılı (dangling) imajları temizle
docker image prune
⚠️ Yedekleme: Volume içindeki veritabanı verileri konteyner silinse bile kalır, ama VPS'in kendisi çökerse gider. Kritik verileri düzenli olarak VPS dışına yedekleyin. Yedekleme stratejisi için VPS yönetimi rehberimize göz atabilirsiniz.

Docker İçin Hangi VPS'i Seçmeli?

Docker'ın kendisi çok az kaynak tüketir; asıl yükü çalıştıracağınız uygulamalar oluşturur. Yine de sağlıklı bir başlangıç için kabaca şu değerleri hedefleyin:

  • Deneme / küçük projeler: 1 vCPU, 2 GB RAM, 40 GB NVMe SSD. Birkaç hafif konteyner (statik site, küçük API) için yeterli. Türkiye'de aylık ~₺200-350 bandında bulunur.
  • WordPress + MySQL + Redis yığını: 2 vCPU, 4 GB RAM, 80 GB NVMe. Orta trafikli tek projeye rahat yeter; aylık ~₺400-600 aralığında.
  • Birden fazla proje / Traefik + çok servis: 4 vCPU, 8 GB RAM, 160 GB NVMe. Aylık ~₺750-1.200 bandını hedefleyin.

NVMe SSD disk, Docker imaj çekme ve konteyner başlatma hızını gözle görülür şekilde iyileştirir. RAM'i cömert tutmak, aynı anda çok sayıda konteyner çalıştırdığınızda kritik olur. Güncel fiyat ve özellikleri VPS karşılaştırma ve daha güçlü ihtiyaçlar için VDS karşılaştırma sayfalarımızdan inceleyebilir, farklı sağlayıcıları karşılaştır aracıyla yan yana koyabilirsiniz.

💡 İpucu: Docker öğrenirken en ucuz VPS'i alıp bolca deneme yapın. Bir şeyi bozarsanız konteyneri silip docker compose up -d ile saniyeler içinde temiz bir kopya başlatabilirsiniz — bu, Docker'ın en büyük öğrenme kolaylığıdır.

Sıkça Sorulan Sorular

Docker ile sanal makine (VM) arasındaki fark nedir?

Sanal makine, tam bir işletim sistemini kendi çekirdeğiyle sanallaştırır; ağır ve yavaş başlar. Docker konteyneri ise host'un çekirdeğini paylaşır, yalnızca uygulama ve bağımlılıklarını paketler. Bu yüzden konteynerler milisaniyeler içinde başlar, çok daha az RAM ve disk kullanır. Tek bir VPS'te düzinelerce konteyner rahatça çalışabilir.

Docker için ne kadar RAM gerekir?

Docker'ın kendisi birkaç yüz MB'la yetinir; asıl belirleyici çalıştıracağınız uygulamalardır. Tek bir WordPress + MySQL yığını için 2 GB RAM makuldür, ancak rahat bir kullanım için 4 GB önerilir. Birden fazla proje veya bellek yoğun servisler (Elasticsearch gibi) için 8 GB ve üzeri hedefleyin.

docker-compose ve Docker Compose aynı şey mi?

Eski docker-compose (tireli) ayrı bir Python aracıydı. Yeni sürümlerde bu işlev Docker'ın içine bir eklenti olarak gömüldü ve docker compose (boşluklu) komutuyla çağrılır. Bu rehberdeki kurulumda docker-compose-plugin paketiyle güncel sürümü kurduk; ikisinin de YAML söz dizimi aynıdır.

Ters proxy olmadan konteynerleri yayınlayabilir miyim?

Teknik olarak evet — her konteyneri farklı bir porta (8080, 8090...) bağlayıp o portlardan erişebilirsiniz. Ancak kullanıcılar temiz alan adları (app.siteniz.com) ve HTTPS bekler. Tek IP üzerinden birden fazla siteyi 443 portundan yayınlamak, SSL sertifikalarını merkezi yönetmek için Nginx veya Traefik gibi bir ters proxy neredeyse zorunludur.

Konteyneri silince verilerim gider mi?

Konteynerin kendi katmanındaki geçici veriler gider, ancak volume ile bağladığınız veriler (örneğin MySQL veritabanı) korunur. Bu yüzden kalıcı olması gereken her şeyi mutlaka bir named volume veya host dizini üzerinde tutun. Yine de VPS'in tamamen çökme ihtimaline karşı düzenli olarak VPS dışına yedek almayı ihmal etmeyin.