Docker Nedir? Container Mantığı ve İlk Uygulamanızı Çalıştırma

Docker Nedir? Container Mantığı ve İlk Uygulamanızı Çalıştırma

"Benim bilgisayarımda çalışıyordu" cümlesini duyduysanız Docker'ın çözdüğü problemi zaten biliyorsunuz. Bir uygulama sizin makinenizde sorunsuz çalışır, ama arkadaşınızın bilgisayarında ya da sunucuda farklı bir sürüm, eksik bir kütüphane veya yanlış bir ayar yüzünden hata verir. Bu yazıda Docker'ın ne olduğunu, image ve container kavramlarını ve Docker'ın bu problemi nasıl çözdüğünü anlatacağız. Sonunda da kendi yazdığınız küçük bir uygulamayı Docker ile paketleyip çalıştırmış olacaksınız.

Bu yazıda ne öğreneceğiz?

  • Docker'ın ne olduğunu ve hangi problemi çözdüğünü
  • Image, container, Dockerfile ve registry kavramlarını
  • Container ile sanal makine arasındaki farkı
  • Hazır bir image'ı indirip çalıştırmayı
  • Kendi uygulamanız için Dockerfile yazıp image oluşturmayı
  • Yeni başlayanların en sık karşılaştığı Docker hatalarını ve çözümlerini

Docker nedir?

Docker, uygulamaları çalışması için gereken her şeyle birlikte paketleyip her ortamda aynı şekilde çalıştırmayı sağlayan açık kaynaklı bir platformdur.

"Gereken her şey" derken şunları kastediyoruz:

  • Uygulamanın kodu
  • Programlama dilinin çalışma ortamı (örneğin Python 3.13 ya da .NET 8)
  • Kullandığı kütüphaneler
  • Gerekli sistem araçları ve ayarlar

Bu paketin adı image, bu paketten çalıştırılan uygulamanın adı ise container'dır. Container (konteyner), uygulamanın bilgisayarın geri kalanından yalıtılmış biçimde çalıştığı kapalı bir ortamdır.

Docker'ın logosundaki gemi de bu fikirden gelir: Yük gemilerinde kullanılan standart konteynerler, içinde ne olursa olsun her gemiye, her vince ve her tıra uyar. Docker container'ları da içinde hangi uygulama olursa olsun Docker'ın kurulu olduğu her makinede aynı şekilde çalışır.

Docker neden kullanılır?

Docker'ın günlük hayatta sağladığı faydalar somut olarak şunlardır:

  1. Ortam farklılıklarını ortadan kaldırır. Uygulama, ihtiyaç duyduğu sürümlerle birlikte paketlendiği için geliştiricinin bilgisayarında, test sunucusunda ve canlı sunucuda aynı şekilde çalışır.
  2. Kurulumu kısaltır. Bilgisayarınıza PostgreSQL, Redis veya Nginx kurmak yerine tek bir komutla bunları container olarak çalıştırabilirsiniz. İşiniz bitince container'ı silersiniz, sisteminizde iz kalmaz.
  3. Uygulamaları birbirinden ayırır. Bir projede Python 3.10, diğerinde Python 3.13 kullanmanız gerekiyorsa ikisini de ayrı container'larda sorunsuz çalıştırabilirsiniz.
  4. Yeni ekip üyelerinin işe başlamasını hızlandırır. "Şu 15 adımı sırayla uygula" yerine "Docker'ı kur ve şu komutu çalıştır" demek yeterli olur.
  5. Yayına alma (deployment) sürecini sadeleştirir. Sunucuya kod yerine hazır image gönderilir. Coolify, Kubernetes ve bulut servislerinin çoğu doğrudan Docker image'larıyla çalışır.

Temel kavramlar: image, container, Dockerfile ve registry

Docker'ı anlamak için dört kavramı birbirinden ayırmak yeterli.

KavramNe işe yarar?Benzetme
DockerfileImage'ın nasıl oluşturulacağını adım adım tarif eden metin dosyasıYemek tarifi
ImageUygulamanın ve tüm bağımlılıklarının bulunduğu, değiştirilemeyen paketTariften hazırlanıp dondurulmuş yemek
ContainerBir image'ın çalışan haliIsıtılıp servis edilen porsiyon
RegistryImage'ların saklandığı ve paylaşıldığı depo (en bilineni Docker Hub)Market rafı

En çok karıştırılan nokta image ile container arasındaki farktır:

  • Image bir şablondur. Kendi başına çalışmaz ve değişmez.
  • Container o şablondan oluşturulmuş, çalışan bir kopyadır. Aynı image'dan istediğiniz kadar container başlatabilirsiniz.

Programlamaya aşinaysanız şöyle düşünebilirsiniz: Image bir sınıf (class), container ise o sınıftan oluşturulan bir nesne (object) gibidir.

Container ile sanal makine arasındaki fark

Docker'ı ilk duyan birçok kişi "Bu bir sanal makine mi?" diye sorar. Hayır, ama amaçları benzer: ikisi de uygulamayı yalıtılmış bir ortamda çalıştırır. Fark, bu yalıtımın nasıl yapıldığındadır.

Sanal makine (Virtual Machine, VM), donanımı taklit eden ve içinde tam bir işletim sistemi çalıştıran bir bilgisayardır. Her sanal makinenin kendi işletim sistemi çekirdeği (kernel) vardır.

Container ise ayrı bir işletim sistemi çalıştırmaz. Ana makinenin işletim sistemi çekirdeğini paylaşır, yalnızca uygulamanın ihtiyaç duyduğu dosyaları ve kütüphaneleri içerir.

ÖzellikSanal makineContainer
İçinde tam işletim sistemi var mı?EvetHayır, ana makinenin çekirdeğini kullanır
Tipik boyutBirkaç GBBirkaç MB ile birkaç yüz MB arası
Başlama süresiGenellikle dakikalarGenellikle saniyeler veya daha kısa
Yalıtım seviyesiDaha güçlü (ayrı çekirdek)Daha hafif (çekirdek paylaşılır)
Farklı işletim sistemi çalıştırmaLinux üzerinde Windows çalıştırabilirLinux container'ı Linux çekirdeği ister

Son satır önemli: Linux container'ları bir Linux çekirdeğine ihtiyaç duyar. Windows ve macOS'ta Docker Desktop bu yüzden arka planda hafif bir Linux sanal makinesi çalıştırır (Windows'ta bu genellikle WSL 2 üzerinden yapılır). Kullanıcı olarak bunu fark etmezsiniz, ama Docker'ın Windows ve Mac'te neden biraz daha fazla bellek kullandığını açıklar.

Docker nasıl kurulur?

Kurulum işletim sistemine göre değişir:

  • Windows ve macOS: Docker Desktop uygulamasını resmi siteden indirip kurun. Windows'ta kurulum sırasında WSL 2 kullanılması önerilir.
  • Linux (Ubuntu, Debian vb.): Sunucularda genellikle yalnızca Docker Engine kurulur. Dağıtımınıza özel adımlar için resmi kurulum sayfasını takip edin. Masaüstü Linux'ta isterseniz Docker Desktop da kullanabilirsiniz.

Kurulumdan sonra terminali açıp şu komutu çalıştırın:

docker version

Çıktıda hem Client hem de Server bölümlerini görüyorsanız Docker çalışıyor demektir. Yalnızca Client görünüp bir hata alıyorsanız aşağıdaki "Sık karşılaşılan hatalar" bölümüne bakın.

Kurulumu test etmenin klasik yolu ise şudur:

docker run hello-world

Bu komut Docker Hub'dan hello-world adlı küçük bir image indirir, ondan bir container oluşturur ve ekrana bir karşılama mesajı yazdırır. Mesajı görüyorsanız Docker image indirebiliyor ve container çalıştırabiliyor demektir.

Uygulamalı örnek: Kendi uygulamanızı Docker ile çalıştırın

Şimdi asıl işe geçelim. Python ile yazılmış, tarayıcıdan gelen isteğe metinle cevap veren küçük bir web sunucusunu Docker ile paketleyeceğiz. Bilgisayarınızda Python kurulu olmasına gerek yok; Python'u container içinde Docker sağlayacak.

Bu örneği Linux üzerinde Docker Engine 29.6 ile çalıştırarak test ettik. Windows ve macOS'ta Docker Desktop ile de aynı komutlar kullanılır.

Adım 1: Proje klasörünü oluşturun

mkdir ilk-docker-uygulamam
cd ilk-docker-uygulamam

Adım 2: Uygulama kodunu yazın

Klasörün içinde app.py adlı bir dosya oluşturun ve şu kodu yapıştırın:

from http.server import HTTPServer, BaseHTTPRequestHandler

class Handler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-Type", "text/plain; charset=utf-8")
        self.end_headers()
        self.wfile.write("Merhaba! Bu yanıt bir Docker container'ından geliyor.\n".encode("utf-8"))

print("Sunucu 8000 portunda çalışıyor...", flush=True)
HTTPServer(("0.0.0.0", 8000), Handler).serve_forever()

Bu kod Python'un kendi standart kütüphanesindeki http.server modülünü kullanır, yani ek paket kurmaya gerek yoktur. Önemli satırlar:

  • do_GET metodu, sunucuya her GET isteği geldiğinde çalışır ve "Merhaba!" mesajını döndürür.
  • HTTPServer(("0.0.0.0", 8000), Handler) sunucuyu 8000 portunda başlatır. Buradaki 0.0.0.0 önemlidir: Sunucunun yalnızca container'ın kendi içinden değil, dışarıdan gelen bağlantıları da kabul etmesini sağlar. 127.0.0.1 yazsaydık container dışından erişemezdik.
  • flush=True, mesajın hemen yazdırılmasını sağlar. Böylece docker logs komutuyla bu satırı anında görebiliriz.

Adım 3: Dockerfile'ı yazın

Aynı klasörde, uzantısı olmayan Dockerfile adlı bir dosya oluşturun:

FROM python:3.13-slim

WORKDIR /app

COPY app.py .

EXPOSE 8000

CMD ["python", "app.py"]

Her satır image'a bir adım ekler:

SatırNe yapar?
FROM python:3.13-slimTemel olarak Python 3.13 kurulu, küçültülmüş (slim) bir Linux image'ı kullanır. Her Dockerfile bir FROM satırıyla başlar.
WORKDIR /appContainer içindeki çalışma klasörünü /app yapar. Klasör yoksa oluşturur.
COPY app.py .Bilgisayarınızdaki app.py dosyasını container içindeki /app klasörüne kopyalar.
EXPOSE 8000Uygulamanın 8000 portunu kullandığını belgeler. Tek başına portu dışarı açmaz; bu iş docker run sırasında yapılır.
CMD ["python", "app.py"]Container başladığında çalışacak komutu belirtir.

Adım 4: Image'ı oluşturun

docker build -t ilk-uygulamam .
  • docker build, Dockerfile'ı okuyup image oluşturur.
  • -t ilk-uygulamam, image'a bir isim (tag) verir.
  • Sondaki . ise "Dockerfile ve dosyalar bu klasörde" anlamına gelir. Bu noktayı unutmak yeni başlayanların sık yaptığı bir hatadır.

İlk çalıştırmada Docker, python:3.13-slim image'ını indireceği için işlem biraz sürebilir. Sonraki build'ler önbellek sayesinde çok daha hızlıdır.

Image'ın oluştuğunu kontrol edin:

docker images ilk-uygulamam

Listede ilk-uygulamam adlı image'ı görmelisiniz. Bizim testimizde image'ın diskte kapladığı alan yaklaşık 187 MB idi. Bu boyutun neredeyse tamamı Python çalışma ortamından gelir, bizim kodumuz yalnızca birkaç yüz bayttır.

Adım 5: Container'ı çalıştırın

docker run -d -p 8080:8000 --name benim-uygulamam ilk-uygulamam

Bu komuttaki parametreler:

  • -d (detached): Container'ı arka planda çalıştırır, terminaliniz serbest kalır.
  • -p 8080:8000: Bilgisayarınızın 8080 portunu container'ın 8000 portuna bağlar. Biçim her zaman bilgisayar_portu:container_portu şeklindedir.
  • --name benim-uygulamam: Container'a hatırlanabilir bir isim verir. Vermezseniz Docker rastgele bir isim atar.
  • ilk-uygulamam: Hangi image'dan container oluşturulacağı.

Şimdi tarayıcınızda http://localhost:8080 adresini açın veya terminalde şunu çalıştırın:

curl http://localhost:8080

Şu yanıtı görmelisiniz:

Merhaba! Bu yanıt bir Docker container'ından geliyor.

Tebrikler, ilk uygulamanızı Docker ile paketleyip çalıştırdınız.

Adım 6: Container'ı yönetin

Günlük kullanımda en çok ihtiyaç duyacağınız komutlar şunlardır:

# Çalışan container'ları listele
docker ps

# Durmuş olanlar dahil tüm container'ları listele
docker ps -a

# Container'ın çıktısını (loglarını) gör
docker logs benim-uygulamam

# Container'ı durdur
docker stop benim-uygulamam

# Durmuş container'ı tekrar başlat
docker start benim-uygulamam

# Container'ı sil (önce durdurulmuş olmalı)
docker rm benim-uygulamam

# Image'ı sil
docker rmi ilk-uygulamam

docker logs benim-uygulamam komutunu çalıştırdığınızda hem "Sunucu 8000 portunda çalışıyor..." satırını hem de tarayıcıdan yaptığınız isteklerin kaydını görürsünüz.

Kodda bir değişiklik yaptığınızda çalışan container kendiliğinden güncellenmez. Çünkü container, build anındaki image'dan oluşturulmuştur. Değişikliği görmek için image'ı yeniden build edip container'ı yeniden oluşturmanız gerekir:

docker stop benim-uygulamam
docker rm benim-uygulamam
docker build -t ilk-uygulamam .
docker run -d -p 8080:8000 --name benim-uygulamam ilk-uygulamam

Bu adımları her seferinde elle yazmak zahmetli gelebilir. İleride Docker Compose ile bunun nasıl kolaylaştığını göreceğiz.

Gerçek kullanım senaryosu: Bilgisayarınıza kurmadan veritabanı çalıştırmak

Docker'ın en pratik kullanımlarından biri, geliştirme sırasında ihtiyaç duyduğunuz servisleri bilgisayarınıza kurmadan çalıştırmaktır. Örneğin bir proje için PostgreSQL gerekiyorsa:

docker run -d --name test-db -e POSTGRES_PASSWORD=gizli123 -p 5432:5432 postgres:17

Bu tek komut PostgreSQL 17'yi indirir ve 5432 portunda çalıştırır. -e parametresi container'a bir ortam değişkeni (environment variable) gönderir. PostgreSQL image'ı, yönetici şifresini POSTGRES_PASSWORD değişkeninden okur.

Bu yöntem geliştirme ve test için uygundur. Canlı ortamda şifreyi komut satırına açıkça yazmak yerine daha güvenli yöntemler kullanmalı ve verilerin kalıcı olması için volume tanımlamalısınız. Volume konusu ayrı bir yazının konusu.

Sık karşılaşılan hatalar ve çözümleri

"Cannot connect to the Docker daemon"

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

Neden olur: docker komutu bir istemcidir (client). Asıl işi arka planda çalışan Docker servisi (daemon) yapar. Bu hata, servisin çalışmadığını gösterir.

Çözüm:

  • Windows ve macOS'ta Docker Desktop uygulamasını açın ve tamamen başlamasını bekleyin.
  • Linux'ta servisi başlatın:
sudo systemctl start docker

"permission denied while trying to connect to the Docker daemon socket"

Neden olur: Linux'ta Docker komutlarını varsayılan olarak root kullanıcısı veya docker grubundaki kullanıcılar çalıştırabilir.

Çözüm: Komutun başına sudo ekleyebilir ya da kullanıcınızı docker grubuna ekleyebilirsiniz:

sudo usermod -aG docker $USER

Değişikliğin geçerli olması için oturumu kapatıp yeniden açmanız gerekir.

Güvenlik notu: docker grubundaki bir kullanıcı pratikte root yetkisine yakın yetkiye sahip olur. Bu yüzden bu gruba yalnızca güvendiğiniz kullanıcıları ekleyin, özellikle paylaşılan sunucularda dikkatli olun.

"port is already allocated"

Bind for 0.0.0.0:8080 failed: port is already allocated

Neden olur: Bilgisayarınızın 8080 portunu başka bir container veya program zaten kullanıyor.

Çözüm: docker ps ile bu portu kullanan container'ı bulup durdurun ya da farklı bir port seçin:

docker run -d -p 8081:8000 --name benim-uygulamam ilk-uygulamam

Bu durumda uygulamaya http://localhost:8081 adresinden erişirsiniz. Container içindeki port (8000) değişmez.

"The container name is already in use"

Conflict. The container name "/benim-uygulamam" is already in use by container "..."

Neden olur: Aynı isimde bir container zaten var. Durdurulmuş container'lar da silinene kadar ismini korur.

Çözüm: Eski container'ı silin veya farklı bir isim kullanın:

docker rm -f benim-uygulamam

-f parametresi container çalışıyor olsa bile önce durdurup sonra siler.

Tarayıcıda sayfa açılmıyor ama container çalışıyor

İki yaygın sebep vardır:

  1. -p parametresi unutulmuştur. EXPOSE satırı portu dışarı açmaz, docker run komutunda -p 8080:8000 yazmak gerekir.
  2. Uygulama 127.0.0.1 adresini dinliyordur. Container içindeki uygulama yalnızca 127.0.0.1'i dinlerse dışarıdan erişilemez. Örneğimizdeki gibi 0.0.0.0 kullanılmalıdır.

Sık sorulan sorular

Docker ücretsiz mi?

Docker Engine açık kaynaklıdır ve ücretsizdir. Docker Desktop ise kişisel kullanım, eğitim, ticari olmayan açık kaynak projeler ve küçük işletmeler için ücretsizdir. Docker'ın lisans sayfasına göre küçük işletme, 250'den az çalışanı ve 10 milyon dolardan az yıllık geliri olan şirket anlamına gelir. Bu sınırların üzerindeki şirketlerde Docker Desktop'ın ticari kullanımı ücretli abonelik gerektirir. Lisans koşulları değişebileceği için güncel bilgi için resmi lisans sayfasını kontrol edin.

Docker bilgisayarı yavaşlatır mı?

Container'lar sanal makinelere göre çok daha hafiftir. Ancak Windows ve macOS'ta Docker Desktop arka planda bir Linux sanal makinesi çalıştırdığı için açık olduğu sürece bir miktar bellek kullanır. Kullanmadığınızda Docker Desktop'ı kapatabilir veya ayarlar bölümünden kullanabileceği bellek ve işlemci miktarını sınırlayabilirsiniz.

Container silinince içindeki veriler ne olur?

Container içinde oluşturulan dosyalar container silindiğinde kaybolur. Veritabanı gibi kalıcı veri tutan uygulamalarda verileri volume adı verilen, container'dan bağımsız depolama alanlarında saklamak gerekir.

Docker ile Windows uygulaması çalıştırabilir miyim?

Docker'da kullanılan container'ların büyük çoğunluğu Linux container'larıdır. Windows Server ve Windows üzerinde Windows container'ları da çalıştırılabilir, ancak bunlar yalnızca Windows çekirdeği olan makinelerde çalışır ve kullanım alanları daha dardır. Masaüstü programlarını (grafik arayüzlü Windows uygulamalarını) Docker ile çalıştırmak pratik bir kullanım değildir.

Docker öğrenmek için Linux bilmem gerekir mi?

Başlamak için gerekmez, bu yazıdaki örneklerin tamamını Windows veya macOS'ta da yapabilirsiniz. Ancak container'ların çoğu Linux tabanlı olduğu için temel Linux komutlarını (ls, cd, cat gibi) bilmek, container içinde sorun ararken işinizi kolaylaştırır.

Docker ile Kubernetes aynı şey mi?

Hayır. Docker container oluşturmanızı ve çalıştırmanızı sağlar. Kubernetes ise çok sayıda container'ın birden fazla sunucu üzerinde yönetilmesi, ölçeklenmesi ve çökenlerin yeniden başlatılması için kullanılan bir orkestrasyon sistemidir. Kubernetes'e geçmeden önce Docker'ı rahat kullanabiliyor olmak gerekir.

Özet

  • Docker, uygulamayı ihtiyaç duyduğu her şeyle birlikte paketleyip her ortamda aynı şekilde çalıştırmayı sağlar.
  • Dockerfile tarif, image bu tariften oluşan değişmez paket, container ise image'ın çalışan halidir.
  • Container'lar ana makinenin çekirdeğini paylaştığı için sanal makinelerden çok daha hafiftir.
  • docker build ile image oluşturulur, docker run ile container başlatılır. -p parametresi olmadan uygulamanıza dışarıdan erişemezsiniz.
  • Kodda değişiklik yaptığınızda image'ı yeniden build etmeniz gerekir.

Sonraki adımlar

Bu yazıda tek bir container çalıştırdık. Gerçek projelerde çoğu zaman bir web uygulaması, bir veritabanı ve belki bir önbellek servisi birlikte çalışır. Bunları tek tek docker run komutlarıyla yönetmek yerine Docker Compose kullanılır. Bir sonraki adım olarak Docker Compose'u, ardından Docker ile PostgreSQL kurulumunu ve bir ASP.NET Core uygulamasını Docker ile çalıştırmayı öğrenebilirsiniz.

Kaynaklar

  • Docker resmi dokümantasyonu, "What is Docker?": https://docs.docker.com/get-started/docker-overview/
  • Docker Engine kurulum rehberi: https://docs.docker.com/engine/install/
  • Dockerfile referansı: https://docs.docker.com/reference/dockerfile/
  • Linux'ta Docker'ı root olmadan kullanma (docker grubu ve güvenlik notu): https://docs.docker.com/engine/install/linux-postinstall/
  • Docker Desktop lisans sözleşmesi: https://docs.docker.com/subscription/desktop-license/
  • Python resmi Docker image'ı: https://hub.docker.com/_/python
  • PostgreSQL resmi Docker image'ı: https://hub.docker.com/_/postgres

Paylaş

MMUTLU.CMS

Kurumsal web siteleri için içerik yönetim sistemi.

© 2026 Mutlu DoğruBu site MUTLU.CMS ile yayınlanmaktadır.

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.