Docker ve Docker Compose Kurulumu: Ubuntu/Debian Rehberi
Docker ve Docker Compose kurulumu için Ubuntu veya Debian'da en doğru yol, dağıtımın eski docker.io paketi yerine Docker'ın kendi resmi apt deposunu kullanmaktır. Bu rehberde depoyu ekleyip docker-ce ile docker-compose-plugin paketlerini kuracak, ilk konteynerinizi çalıştıracak, compose ile küçük bir web uygulaması ayağa kaldıracak ve üretimde işinize yarayacak güvenlik ayarlarına bakacağız.
Komutlar Ubuntu 22.04/24.04 ve Debian 11/12 üzerinde root olmayan, sudo yetkili bir kullanıcıyla çalıştırılacak şekilde yazıldı. Sunucunuz yeniyse önce SSH ve güvenlik duvarı gibi temel ayarları tamamlamanız iyi olur.
Ön Hazırlık: Eski Paketleri Kaldırın
Daha önce dağıtım depolarından Docker benzeri paketler kurduysanız çakışmayı önlemek için kaldırın. Konteyner ve volume verileriniz /var/lib/docker altında olduğundan bu işlem onlara dokunmaz.
for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do
sudo apt-get remove -y $pkg
done
Paket yüklü değilse apt sadece bilgi verir, sorun değildir.
Resmi Docker Deposunu Ekleme
Ubuntu için
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Debian için
URL ve dağıtım adı değişir, geri kalanı aynıdır:
sudo apt-get update
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
Docker Engine ve Compose Eklentisini Kurma
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Kurulum bitince servis otomatik başlar ve açılışta çalışacak şekilde etkinleşir. Kontrol edin:
sudo systemctl status docker --no-pager
docker --version
docker compose version
Dikkat: Güncel kurulumda komut docker-compose (tire ile, eski Python sürümü) değil, docker compose (boşlukla, Compose v2 eklentisi) şeklindedir.
İlk Konteyner: hello-world ve Nginx
sudo docker run hello-world
Çıktıda "Hello from Docker!" görüyorsanız imaj indirme, konteyner oluşturma ve çalıştırma zinciri çalışıyor demektir. Şimdi gerçek bir servis deneyelim:
sudo docker run -d --name test-nginx -p 127.0.0.1:8080:80 nginx:stable-alpine
curl -I http://127.0.0.1:8080
sudo docker ps
sudo docker logs test-nginx
sudo docker rm -f test-nginx
-p 127.0.0.1:8080:80 ifadesine dikkat edin: portu sadece yerel arayüze bağlıyoruz. Nedenini güvenlik bölümünde açıklıyoruz.
Her seferinde sudo yazmamak için
sudo usermod -aG docker $USER
newgrp docker
docker ps
Uyarı: docker grubundaki bir kullanıcı fiilen root yetkisine eşdeğerdir. Bu gruba yalnızca güvendiğiniz hesapları ekleyin.
Docker Compose ile Web Uygulaması
Örnek olarak bir Nginx web sunucusu ve bir PostgreSQL veritabanından oluşan basit bir yapı kuralım. Önce klasör ve dosyaları hazırlayın:
mkdir -p ~/webapp/html && cd ~/webapp
echo '<h1>Merhaba, Docker Compose!</h1>' > html/index.html
.env dosyası (parolayı kendi değerinizle değiştirin):
cat > .env <<'EOF'
POSTGRES_DB=appdb
POSTGRES_USER=appuser
POSTGRES_PASSWORD=guclu-bir-parola-yazin
EOF
chmod 600 .env
compose.yaml dosyası:
services:
web:
image: nginx:1.27-alpine
ports:
- "127.0.0.1:8080:80"
volumes:
- ./html:/usr/share/nginx/html:ro
depends_on:
db:
condition: service_healthy
networks:
- frontend
- backend
restart: unless-stopped
db:
image: postgres:16-alpine
env_file: .env
volumes:
- dbdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
restart: unless-stopped
networks:
frontend:
backend:
internal: true
volumes:
dbdata:
Burada üç önemli nokta var: veritabanının hiçbir portu dışarı yayımlanmıyor, backend ağı internal olduğu için dış dünyaya çıkışı da yok ve veriler dbdata adlı volume'da kalıcı. Yeni Compose sürümlerinde dosyanın başına version: satırı yazmanıza gerek yoktur.
Başlatın ve doğrulayın:
docker compose config # yazım hatası kontrolü
docker compose up -d
docker compose ps
curl http://127.0.0.1:8080
Günlük işlemler için sık kullanılan komutlar:
| Komut | Ne yapar |
|---|---|
docker compose logs -f web |
Servisin canlı logları |
docker compose pull && docker compose up -d |
İmajları günceller, değişenleri yeniden oluşturur |
docker compose restart web |
Tek servisi yeniden başlatır |
docker compose down |
Konteyner ve ağları siler, volume'lar kalır |
docker compose down -v |
Volume'ları da siler (veri kaybı!) |
Siteyi internete açmak için 127.0.0.1:8080'e önünde bir ters vekil (reverse proxy) ve TLS ile erişmek en temiz yöntemdir. Nginx ve Certbot ayarı için ayrı rehberimize bakabilirsiniz.
Güvenlik İpuçları
1. Docker, UFW'yi atlar
En sık yapılan hata budur. -p 8080:80 ile yayımlanan bir port, Docker'ın eklediği iptables kuralları nedeniyle UFW'de "deny" olsa bile dışarıdan erişilebilir olabilir. Çözüm basit: dışarı açmanız gerekmeyen her portu 127.0.0.1: önekiyle yayımlayın ve dışarıya yalnızca ters vekil üzerinden 80/443 açın. Veritabanı, Redis gibi servislere hiç ports: yazmayın; aynı compose ağındaki servisler birbirine servis adıyla erişir.
Kontrol için dışarıdan bir nmap taraması ya da sunucuda şu komut işinize yarar:
sudo ss -tlnp | grep -E 'docker-proxy|:8080'
2. docker.sock'u konteynere bağlamayın
/var/run/docker.sock dosyasını bir konteynere mount etmek, o konteynere sunucunun tam kontrolünü vermek demektir. Gerçekten gerekiyorsa (örneğin bir izleme aracı) salt okunur bir socket vekili kullanın ve güvenilir imajlarla sınırlayın.
3. Konteyneri en az yetkiyle çalıştırın
Uygulama servisleriniz için uygun olduğu ölçüde şu ayarları ekleyin:
user: "1000:1000"
read_only: true
tmpfs:
- /tmp
cap_drop:
- ALL
security_opt:
- no-new-privileges:true
Her imaj bu kısıtlarla çalışmaz; hata alırsanız cap_add ile yalnızca gereken yetkiyi geri verin.
4. İmaj etiketlerini sabitleyin, güncel tutun
latest yerine nginx:1.27-alpine gibi belirli etiketler kullanın. Mümkünse resmi (Docker Official) veya doğrulanmış yayıncıların imajlarını tercih edin. Düzenli olarak docker compose pull yapıp yeniden oluşturun.
5. Gizli bilgileri imaja gömmeyin
Parolalar için .env (chmod 600) veya Compose secrets kullanın; .env dosyasını Git'e eklemeyin (.gitignore).
6. Log rotasyonunu ayarlayın
Varsayılan json-file sürücüsünde log boyutu sınırsızdır ve diski doldurabilir. /etc/docker/daemon.json dosyasını oluşturun:
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
sudo systemctl restart docker
Bu ayar yalnızca yeni oluşturulan konteynerlere uygulanır; mevcutları docker compose up -d --force-recreate ile yeniden oluşturun.
Yaygın Hatalar ve Çözümleri
permission denied while trying to connect to the Docker daemon socket: Kullanıcıdockergrubunda değil ya da oturumu yenilemediniz.usermod -aG docker $USERsonrası çıkış yapıp tekrar girin.docker-compose: command not found: Compose v2'de komutdocker composeşeklindedir.docker-compose-pluginpaketinin kurulu olduğunu kontrol edin.Package docker-ce has no installation candidate: Depo satırındaki dağıtım adı (codename) hatalı ya da sürümünüz desteklenmiyor.cat /etc/apt/sources.list.d/docker.listile çıktıyı kontrol edin.port is already allocated/address already in use: Port başka bir süreçte kullanımda.sudo ss -tlnp | grep :8080ile bulun, compose dosyasında portu değiştirin.- Disk doluyor:
docker system dfile durumu görün; kullanılmayan kaynaklarıdocker system pruneile temizleyin. Volume'ları silen--volumesbayrağını bilerek kullanın. - YAML hatası: Girintiler boşlukla olmalı, sekme (tab) kullanılmaz.
docker compose confighatayı satır numarasıyla gösterir. - Konteyner içinden DNS çözülmüyor: Sunucunun
/etc/resolv.confayarını ve güvenlik duvarının FORWARD zincirini kontrol edin; gerekirsedaemon.jsoniçine"dns": ["9.9.9.9"]gibi bir değer ekleyin.
Üretim İçin Altyapı Notu
Docker'ı geliştirme ortamında laptopta denemek kolaydır, ancak üretim için kaynakların size ayrılmış olması, ağ erişiminin öngörülebilir olması ve gerektiğinde saldırı trafiğinin filtrelenebilmesi önemlidir. Konteynerlerinizi, kendi kaynaklarınıza sahip bir VDS sunucuda çalıştırabilirsiniz. Herkese açık servisler barındırıyorsanız DDoS koruma ve firewall seçeneklerini de gözden geçirmenizi öneririz; çünkü Docker'ın yayımladığı portlar ağ katmanı saldırılarına karşı kendi başına bir koruma sağlamaz.
Özet
- Eski paketleri kaldırın, resmi Docker deposunu ekleyin.
docker-cevedocker-compose-pluginpaketlerini kurun;docker compose versionile doğrulayın.- Servisleri compose ile tanımlayın, veritabanı gibi servisleri dışarı açmayın.
- Portları
127.0.0.1ile sınırlayın, UFW'nin Docker'ı kısıtlamadığını unutmayın. - Log rotasyonu, sabit imaj etiketleri ve en az yetki ilkesini uygulayın.
Sık sorulan sorular
Docker ve Docker Compose'u ayrı ayrı kurmam gerekir mi?
Hayır. Resmi depodan docker-compose-plugin paketini kurduğunuzda Compose v2, docker komutuna eklenti olarak gelir ve docker compose şeklinde kullanılır. Ayrı bir docker-compose ikilisi kurmanız gerekmez.
docker.io paketi ile docker-ce arasındaki fark nedir?
docker.io, Ubuntu/Debian deposundaki dağıtım tarafından paketlenen sürümdür ve genelde daha eskidir. docker-ce, Docker'ın kendi deposundan gelen güncel Engine sürümüdür ve Compose ile Buildx eklentileri aynı depodan güncellenir.
UFW kuralları Docker konteyner portlarını neden engellemiyor?
Docker, yayımlanan portlar için doğrudan iptables kuralları ekler ve bu trafik UFW'nin zincirlerinden önce işlenebilir. En güvenli çözüm, gerekmeyen portları 127.0.0.1 ile yayımlamak ve dış erişimi bir ters vekil üzerinden vermektir.
Kullanıcıyı docker grubuna eklemek güvenli mi?
Docker grubu üyeleri fiilen root yetkisine sahip olur, çünkü konteyner içine sunucu dosya sistemini bağlayabilirler. Bu gruba yalnızca güvendiğiniz yönetici hesaplarını ekleyin; diğer kullanıcılar için sudo veya rootless Docker düşünün.