"Bende çalışıyordu" cümlesi yazılım ekiplerinde sık duyulur; geliştirme bilgisayarındaki bir uygulama sunucuya taşındığında farklı bir ortamla karşılaşır ve orada beklenmedik hatalar verir. Bu farkın kaynağı genelde küçük bir ayrıntıdır: eksik bir kütüphane sürümü, farklı bir işletim sistemi ayarı, unutulmuş bir ortam değişkeni. Docker, uygulamayı ve çalışması için gereken her şeyi tek bir pakette bir araya getirerek bu sorunu ortadan kaldırır. Bu yazıda Docker'ın konteyner mantığını, sanal makineden farkını ve günlük kullanımda ihtiyaç duyacağınız temel komutları ele alıyorum.
Konteyner Tam Olarak Nedir?
Bir konteyner, bir uygulamayı, bu uygulamanın kütüphanelerini, bağımlılıklarını ve çalışma zamanı ayarlarını tek bir pakette toplayan izole bir ortamdır. Bu paket geliştirme bilgisayarında nasıl çalışıyorsa, test sunucusunda ve üretim ortamında da aynı şekilde çalışır. Taşınan şey kurulum talimatları değil, önceden hazırlanmış ve test edilmiş ortamın kendisidir. Bu sayede ekipler ortam kurulumuna daha az zaman harcar, yeni bir sunucuya geçiş de basitleşir.
Docker, bu konteynerleri oluşturmak, çalıştırmak ve yönetmek için kullanılan platformdur. Bir imaj (image), konteynerin salt okunur şablonudur. Bu şablondan bir konteyner başlattığınızda imajın üzerine yazılabilir bir katman eklenir; aynı imajdan istediğiniz kadar konteyner başlatabilirsiniz ve her biri birbirinden bağımsız çalışır. İmajlar katmanlı bir yapıda saklanır. Kopyalama, kurulum veya ayar gibi her komut yeni bir katman ekler; Docker bu katmanları yeniden kullanarak hem depolama alanından hem de inşa süresinden tasarruf sağlar.
docker pull nginx
docker run -d -p 8080:80 nginx
İlk komut Docker Hub'dan resmi nginx imajını indirir. İkinci komut bu imajdan bir konteyner başlatır. -d konteyneri arka planda çalıştırır, -p 8080:80 ise sunucunun 8080 portunu konteynerin 80 portuna bağlar. Tarayıcıdan localhost:8080 adresine gittiğinizde nginx'in karşılama sayfasını görürsünüz. Aynı sunucuda farklı portlara bağlı başka nginx konteynerleri de çalıştırabilirsiniz; her biri kendi dosyalarıyla çalışır, birbirine karışmaz.
Konteyner ile Sanal Makine Arasındaki Fark
Sanal makineler (VM), her biri kendi işletim sistemi çekirdeğini çalıştıran bağımsız sistemlerdir. Bir hipervizör donanımı sanallaştırır ve üzerinde birden fazla tam işletim sistemi çalıştırır. Konteynerler ise ana makinenin çekirdeğini paylaşır, yalnızca uygulama katmanını izole eder. Bu fark, performans ve kaynak kullanımında büyük sonuçlar doğurur.

| Özellik | Sanal Makine | Docker Konteyner |
|---|---|---|
| Başlatma süresi | Dakikalar | Saniyeler |
| Kaynak kullanımı | Yüksek (tam işletim sistemi) | Düşük (paylaşılan çekirdek) |
| İzolasyon seviyesi | Tam donanım seviyesi | Süreç seviyesi |
| Disk boyutu | Gigabaytlarca | Genelde yüz megabayt civarı |
| Taşınabilirlik | Sınırlı | Yüksek |
Bir sunucuda onlarca sanal makine çalıştırmak ciddi donanım kaynağı ister. Aynı sunucuda yüzlerce konteyner çalıştırmak mümkün olabilir, çünkü her konteyner kendi çekirdeğini taşımaz. Bu verimlilik, Docker'ın mikroservis mimarilerinde ve bulut ortamlarında bu kadar yaygınlaşmasının temel nedenidir. Sanal makineler bu yüzden ortadan kalkmadı; güçlü izolasyon gereken veya farklı bir işletim sistemi çekirdeği gereken senaryolarda VM hâlâ tercih edilir. Ama tek bir Linux sunucusunda birden fazla uygulama çalıştırmak isteyen çoğu ekip için konteyner daha hafif ve daha hızlı bir çözümdür.
Dockerfile ile Kendi İmajınızı Oluşturmak
Hazır imajları kullanmanın ötesinde, kendi uygulamanız için özel bir imaj da oluşturabilirsiniz. Bu iş Dockerfile adında bir metin dosyasıyla yapılır. Dosya, imajın nasıl inşa edileceğini adım adım tarif eder.

FROM node:20-alpine
WORKDIR /app
COPY package.json .
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
FROM satırı hangi temel imajdan başlanacağını belirtir; burada Node.js'in hafif bir sürümü (alpine) seçilmiş. WORKDIR konteyner içinde çalışma dizinini ayarlar. COPY dosyaları imaja kopyalar, RUN ise imaj inşa edilirken bir komut çalıştırır; burada bağımlılıklar kurulur.
EXPOSE satırı konteynerin hangi portu dinlediğini belgeleyen bir bilgi notudur, gerçek port yönlendirmesini yapmaz. Bu iş docker run sırasında -p bayrağıyla yapılır. CMD ise konteyner başlatıldığında çalışacak asıl komutu belirtir.
Bu dosyayı docker build -t benim-uygulamam . komutuyla inşa edip kendi imajınızı oluşturabilirsiniz. package.json dosyasının kaynak kodun geri kalanından önce kopyalanması tesadüf değildir: Docker her satırı ayrı bir katman olarak önbelleğe alır. Bağımlılıklar değişmediği sürece npm install adımı tekrar çalışmaz, inşa süresi de bu sayede kısalır.
Konteynerleri Günlük Kullanımda Yönetmek
Bir konteyner çalıştırdıktan sonra onunla etkileşim kurmanın birkaç temel yolu vardır. Çalışan konteynerleri listelemek, loglarına bakmak ve içine girmek en sık ihtiyaç duyacağınız işlemlerdir.
docker ps
docker logs -f benim-uygulamam
docker exec -it benim-uygulamam sh
docker ps o an çalışan tüm konteynerleri listeler; durdurulmuş olanları da görmek için -a bayrağıyla kullanılır. docker logs -f konteynerin çıktısını canlı olarak takip etmenizi sağlar; bir uygulama hata veriyorsa ilk bakılacak yer burasıdır. docker exec -it ... sh ise çalışan bir konteynerin içine terminal açar, dosya sistemini ve süreçleri doğrudan inceleyebilirsiniz.
Günlük kullanımda en sık başvurulan komutlar şunlardır:
docker stop: konteyneri düzgün biçimde durdururdocker start: durdurulmuş bir konteyneri yeniden başlatırdocker rm: konteyneri tamamen silerdocker images: indirilmiş tüm imajları listelerdocker rmi: kullanılmayan bir imajı siler
Kullanılmayan imajlar ve konteynerler zamanla disk alanı tüketir. docker system prune komutu, artık hiçbir konteyner tarafından kullanılmayan imajları ve önbellekleri temizler.
docker ps çıktısındaki otomatik üretilmiş isimleri hatırlamaya çalışmak yerine, docker run --name benim-uygulamam şeklinde kendi isminizi verin; bu, günlük kullanımda işleri kolaylaştırır. Aynı ismi taşıyan bir konteyner zaten varsa Docker hata verir, bu da aynı servisi yanlışlıkla iki kez başlatmanızı önler.
Docker Compose ile Çoklu Servis Yönetimi
Gerçek uygulamalar nadiren tek bir konteynerden ibarettir; bir web uygulaması genelde bir veritabanı, belki bir önbellek servisi ve uygulamanın kendisinden oluşur. Docker Compose bu servisleri tek bir YAML dosyasında tanımlamanızı ve hepsini birlikte başlatmanızı sağlar.

version: "3.9"
services:
web:
build: .
ports:
- "3000:3000"
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: gizli
Bu dosyayı docker-compose up komutuyla çalıştırdığınızda hem uygulama hem veritabanı servisi aynı anda ayağa kalkar ve birbiriyle konuşacak şekilde aynı ağa bağlanır. Servisler arası iletişimde IP adresi yerine servis adı kullanılır: web servisi veritabanına db:5432 adresinden ulaşır, çünkü Compose dahili bir DNS çözümlemesi sağlar.
Geliştirme ortamında tüm bağımlılıkları tek komutla ayağa kaldırmak, yeni bir ekip üyesinin projeye başlaması için gereken süreyi saatlerden dakikalara indirir; kurulum talimatları belgesi yerine docker-compose up çalıştırmak yeterli olur. Servisleri durdurmak için docker-compose down kullanılır. Bu komut varsayılan olarak volume'lere dokunmaz, sadece konteynerleri ve ağı kaldırır.
Verinin Kalıcılığı: Volume Kullanımı
Bir konteyner silindiğinde içindeki tüm veriler de silinir. Bu, veritabanı gibi kalıcı veri tutması gereken servisler için ciddi bir sorundur. Docker bu sorunu volume (birim) kavramıyla çözer. Volume, konteynerin dışında ana makinede duran ve konteyner silinse bile kalan bir depolama alanıdır.
docker volume create veritabani_verisi
docker run -d -v veritabani_verisi:/var/lib/postgresql/data postgres:16
Bu komut veritabani_verisi adında bir volume oluşturur ve konteynerin veritabanı dizinini bu volume'a bağlar. Konteyneri durdurup silseniz bile, aynı volume'u yeni bir konteynere bağladığınızda veriler yerinde durur. Üretim ortamındaki her veritabanı konteyneri için volume kullanmak neredeyse zorunlu bir alışkanlıktır. Aksi hâlde bir güncelleme sırasında konteyneri yeniden oluşturmak tüm verinin kaybolmasına yol açabilir.
Docker ayrıca bind mount adı verilen ikinci bir depolama yöntemi sunar. Bu yöntemde ana makinedeki belirli bir klasör doğrudan konteynere bağlanır. Geliştirme sırasında kaynak kodu bu şekilde bağlamak, kodu her değiştirdiğinizde imajı yeniden inşa etmeden değişikliği konteyner içinde görmenizi sağlar.
Docker'ı Linux dosya sistemi yapısını anlayarak kullanmak, volume'lerin ana makinede nerede saklandığını ve disk kullanımını takip etmeyi kolaylaştırır. Resmi Docker belgelerine docs.docker.com üzerinden ulaşabilir, komut referansını ve Compose sözdizimini oradan doğrulayabilirsiniz.
Henüz yorum yok.
Sohbete katıl. Yorumlar yayınlanmadan önce moderasyondan geçer.