Docker'ın gereksiz yere karmaşık olduğunu düşünerek çok fazla zaman harcadım. Her eğitim container teorisiyle başlıyor, Linux namespace'leri ve cgroup'lara geçiyor ve üçüncü sayfada zaten kayboluyordum. Meğer fazla düşünüyormuşum. Docker aslında öğrenebileceğiniz en pratik araçlardan biri ve jargonu çıkarıp attığınızda temel kavramlar kafanıza sığıyor.
Yaşadığım kafa karışıklığından sizi kurtarayım.
"Benim Bilgisayarımda Çalışıyor" Problemi
Her geliştiricinin en az bir kez yaşadığı bir senaryo: laptopunuzda bir uygulama yapıyorsunuz ve her şey mükemmel çalışıyor. Testler geçiyor, API yanıt veriyor, frontend güzel render oluyor. Sunucuya deploy ediyorsunuz ve... bozuluyor.
Farklı işletim sistemi. Farklı Python versiyonu. Bilgisayarınızda global olarak kurulu ama sunucuda eksik olan bir kütüphane. Farklı konumdaki bir yapılandırma dosyası. Ayarlamayı unuttuğunuz bir ortam değişkeni.
İşte Docker'ın çözdüğü temel problem budur. Uygulamanızı ihtiyaç duyduğu her şeyle birlikte — doğru Java veya Node.js versiyonu, tam kütüphaneler, yapılandırma dosyaları, ortam değişkenleri, hepsi — container adı verilen kendi kendine yeten bir birime paketler. Bu container laptopunuzda, takım arkadaşınızın laptopunda ve üretim sunucusunda aynı şekilde çalışır.
Artık "ama benim bilgisayarımda çalışıyor" yok. Container'da çalışıyorsa, her yerde çalışır.
Container vs Sanal Makine: Daire Benzetmesi
Container'lardan önce sanal makinelerimiz vardı. İkisi de ortam tutarlılığı problemini çözer ama çok farklı şekillerde.
Sanal makine tam bir işletim sistemi çalıştırır — kendi çekirdeği, kendi dosya sistemi, kendi her şeyi. Bütün bir daire kiralamak gibidir. Tam izolasyon elde edersiniz ama tek ihtiyacınız çalışacak bir masa olsa bile mutfak, banyo ve oturma odası için de ödeme yaparsınız.
Container ana bilgisayarın işletim sistemi çekirdeğini paylaşır ve sadece uygulama seviyesindeki şeyleri paketler. Ortak çalışma alanında özel oda almak gibi — kendi alanınız ve eşyalarınız var ama binanın altyapısını paylaşıyorsunuz.
Bu container'ları:
- Çok daha küçük yapar — VM imajı 2-10 GB olabilir. Bir Java uygulaması için container imajı genellikle 200-400 MB'dir.
- Çok daha hızlı başlatır — VM'ler dakikalar alır. Container'lar saniyeler içinde başlar.
- Kaynaklarda çok daha hafif yapar — Laptopunuzda 3-5 VM çalıştırabilirsiniz. 20-30 container kolayca çalıştırabilirsiniz.
- Bir takımla çalışıyorsanız
- Üretime deploy ediyorsanız
- Uygulamanızda birden fazla servis varsa
- "Benim bilgisayarımda çalışıyor" konuşmalarından yorulduysanız
Üç Temel Kavram
Docker'ın birçok özelliği var ama verimli olmak için sadece üç şeyi anlamanız gerekir.
1. Dockerfile: Tarif
Dockerfile, uygulamanızın ortamını nasıl oluşturacağınızı açıklayan bir metin dosyasıdır. Bir tarif gibi düşünün:
# Java 21 ile bir temel imajdan başla FROM eclipse-temurin:21-jre-alpine# Container içindeki çalışma dizinini ayarla WORKDIR /app
# Derlenmiş JAR dosyasını container'a kopyala COPY target/myapp.jar app.jar
# Uygulamanın dinlediği portu belirt EXPOSE 8080
# Container başladığında ne olacağını tanımla ENTRYPOINT ["java", "-jar", "app.jar"]
Beş talimat. Bir üretim uygulaması için tam bir Dockerfile.
Node.js için şöyle görünür:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
package.json dosyasını önce kopyalayıp bağımlılıkları kaynak koddan önce kurduğumuza dikkat edin. Bu, katman önbellekleme adı verilen bir Docker en iyi uygulamasıdır.
2. Image: Anlık Görüntü
docker build çalıştırdığınızda Docker bir imaj oluşturur — uygulamanızın ve tüm ortamının salt okunur anlık görüntüsü.
docker build -t myapp:1.0 .
İmajlar değişmezdir. Bir kez oluşturulduğunda asla değişmez. Bu bir özelliktir — test ortamında test ettiğiniz imajın üretimde çalışanla tam olarak aynı olduğunu bilirsiniz.
3. Container: Çalışan Örnek
Container, bir imajın çalışan örneğidir. İmajı sınıf, container'ı nesne olarak düşünebilirsiniz.
docker run -d -p 8080:8080 --name myapp myapp:1.0
Aynı imajdan birden fazla container çalıştırabilirsiniz, her biri diğerlerinden izole.
Docker Compose: Birden Fazla Servisi Yönetmek
Gerçek uygulamalar nadiren tek bir servisten oluşur. Docker Compose hepsini tek bir YAML dosyasında tanımlamanızı sağlar:
services: backend: build: . ports: - "8080:8080" depends_on: postgres: condition: service_healthypostgres: image: postgres:16-alpine environment: POSTGRES_DB: myapp POSTGRES_PASSWORD: secret volumes: - pgdata:/var/lib/postgresql/data healthcheck: test: pg_isready -U postgres interval: 10s
nginx: image: nginx:1.27-alpine ports: - "80:80"
volumes: pgdata:
Tek komut her şeyi ayağa kaldırır:
docker compose up -d
Bu geliştirme için inanılmaz güçlüdür. Yeni takım üyesi mi katılıyor? Repoyu klonlar, docker compose up çalıştırır ve dakikalar içinde tüm uygulama stack'i çalışır.
Yaptığım Yaygın Hatalar
1. Dev Temel İmajlar Kullanmak
# Kötü: ubuntu 75MB, sonra her şeyi elle kurarsınız FROM ubuntu:22.04
# İyi: amaca yönelik, minimal imaj FROM eclipse-temurin:21-jre-alpine
Alpine tabanlı imajlar genellikle 5-10 kat daha küçüktür.
2. .dockerignore Unutmak
Dockeri gnore olmadan Docker tüm proje dizininizi kopyalar — node_modules, .git, test dosyaları dahil.
3. Root Olarak Çalıştırmak
Varsayılan olarak container'lar root olarak çalışır. Bu bir güvenlik riskidir.
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
4. Katman Önbelleklemeyi Kullanmamak
Nadiren değişen talimatları sık değişenlerden önce koyun.
5. Container'da Veri Depolamak
Container'lar geçicidir — durduğunda verileri kaybolur. Kalıcı olması gereken her şey için volume kullanın.
Her Gün Kullanacağınız Docker Komutları
docker ps # Çalışan container'ları gör
docker logs myapp --tail 50 -f # Logları gör
docker exec -it myapp /bin/sh # Container içinde komut çalıştır
docker stop myapp && docker rm myapp # Durdur ve kaldır
docker image prune -f # Kullanılmayan imajları temizle
Docker Ne Zaman Gereksizdir
Basit bir script, erken geliştirme aşamasındaki kişisel proje veya ödev için Docker ihtiyacınız olmayan karmaşıklık ekler.
Şu durumlarda Docker kullanmaya başlayın:
Sonuç
Docker sihir değildir ve ilk göründüğü kadar karmaşık değildir. Sadece yazılımı farklı ortamlarda tutarlı şekilde paketlemenin ve çalıştırmanın gerçekten iyi bir yoludur.
Dockerfile, imaj, container ve compose dosyalarını anladığınızda günlük geliştirme işleriniz için ihtiyacınızın yüzde doksanına sahipsiniz. Geri kalan yüzde onu — çok aşamalı build'ler, ağ modları, Kubernetes ile orkestrasyon — ihtiyaç duydukça öğrenebilirsiniz.
Docker'ı öğrenmenin en iyi yolu zaten sahip olduğunuz bir projeyi container'a almaktır. Çalışan bir uygulama alın, bir Dockerfile yazın, container'da çalıştırın, sonra veritabanı için compose dosyası ekleyin. Kavramların ne kadar hızlı oturduğuna şaşıracaksınız.

Yorumlar (