Docker'a Giriş: Container'lar Neden Bu Kadar Önemli?
"Benim makinemde çalışıyordu" cümlesini duymayan DevOps mühendisi yoktur. Docker'ın çözdüğü temel problem tam olarak bu: uygulamanızı, çalışması için gereken her şeyle (kütüphaneler, bağımlılıklar, ortam değişkenleri) birlikte paketleyip her ortamda aynı şekilde çalışmasını sağlamak.
Container vs Virtual Machine
Sanal makineler (VM) her biri kendi işletim sistemini çalıştırır — ağır ve yavaştır. Container'lar ise host'un kernel'ini paylaşır, sadece uygulama ve bağımlılıklarını izole eder. Bu yüzden çok daha hafif ve hızlıdır.
# VM: dakikalar içinde ayağa kalkar, GB'larca yer kaplar
# Container: saniyeler içinde ayağa kalkar, MB'larca yer kaplar
Image vs Container
Bu ikisini karıştırmak yeni başlayanların en sık yaptığı hata:
- Image: Değişmez (immutable) bir şablon. Uygulamanın ve bağımlılıklarının dondurulmuş hali.
- Container: Image'ın çalışan bir örneği (instance).
docker build -t myapp:1.0 . # Dockerfile'dan image oluştur
docker run -d -p 8080:8080 myapp:1.0 # image'dan container çalıştır
docker ps # çalışan container'ları listele
docker logs -f <container_id> # container loglarını canlı izle
docker exec -it <container_id> sh # container içine gir
Basit Bir Dockerfile
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY target/app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
Her satır bir layer oluşturur ve Docker bu layer'ları cache'ler. Değişmeyen katmanları üstte tutmak (FROM, WORKDIR) build sürelerini ciddi şekilde kısaltır.
Volume ve Network
Container'lar durumsuzdur (stateless) — silindiğinde içindeki veri de gider. Kalıcı veri için volume kullanılır:
docker volume create pgdata
docker run -d -v pgdata:/var/lib/postgresql/data postgres
Birden fazla container'ın birbirini bulabilmesi için network tanımlanır:
docker network create app-net
docker run -d --network app-net --name db postgres
docker run -d --network app-net --name api myapp # 'db' hostname'i ile erişebilir
Docker Compose
Tek bir servisi docker run ile ayağa kaldırmak kolay, ama birden fazla servisi (API, veritabanı, cache) birlikte yönetmek için docker-compose.yml kullanılır:
services:
api:
build: .
ports:
- "8080:8080"
depends_on:
- db
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: secret
docker compose up -d
Kapanış
Docker, tek başına bir araç olmaktan çıkıp modern DevOps'un temel yapı taşı haline geldi. Bir sonraki yazıda bu container'ları production'da ölçeklemek için Kubernetes'e nasıl geçtiğimizi anlatacağım.