Docker sanallaştırma: kurulum ve temel kullanım
Docker'ın container mimarisini, temel komutlarını ve volume/network kavramlarını uygulamalı olarak anlatan bir başlangıç rehberi.
Docker’a ilk baktığımda kafamı karıştıran şey, sanallaştırma kelimesinin VM ile özdeşleşmiş olmasıydı. VMware ya da VirtualBox bağlamında sanallaştırma dendiğinde tam bir işletim sistemi imajı, ayrı bir çekirdek ve bunları ayakta tutan bir hypervisor akla geliyor. Docker farklı bir noktada duruyor: container mimarisini kullanıyor ve host işletim sisteminin çekirdeğini paylaşıyor. Bu paylaşım modeli, container’ları VM’lere kıyasla çok daha hafif ve hızlı başlatılabilir yapıyor.
Her container kendi bağımlılıklarını, kütüphanelerini ve çalışma ortamını kendi içinde taşır. Docker ise host çekirdeği ile container arasındaki iletişimi düzenleyen katman olarak işlev görür. Bu mimari fark, geliştirme ortamlarından production deployment’larına kadar bugün yaygın kullandığımız pek çok pratikle doğrudan ilgili.

Windows’ta Docker Kurulumu
Kuruluma geçmeden önce birkaç ön koşul var. Windows 11 Home üzerinde kurulum yapıyorum; diğer sürümlerde adımlar benzer.
BIOS ayarlarından donanım sanallaştırmayı açmanız gerekiyor. Anakart modeline göre ayar adı değişebilir, ama genellikle Hardware Assisted Virtualization ve Data Execution Protection aranacak iki seçenek. Hazır sistem aldıysanız genellikle açık geliyor.
Ardından Windows’un WSL2 desteğini etkinleştirin. Denetim Masası > Programlar > Windows Özelliklerini Aç veya Kapat üzerinden Linux için Windows Alt Sistemi ve Sanal Makine Platformu seçeneklerini işaretleyin, bilgisayarı yeniden başlatın. Yeniden başlatma sonrasında Windows Update’i çalıştırın; WSL2 çekirdeği güncelleme olarak geliyor.
WSL durumunu doğrulamak için:
wsl --status
Hata alırsanız Microsoft’un manual kurulum dökümanı adım adım anlatıyor.
Ortam hazırsa docker.com/get-started adresinden Docker Desktop’ı indirin ve yükleyin. Kurulum sırasında ek bir yapılandırma yapmanıza gerek yok; varsayılan seçenekler çalışır. Kurulum sonunda oturumu kapatıp açmanızı isteyecek, ardından Docker otomatik başlayacak.
Kurulumu doğrulamak için terminalde:
docker version
İstemci ve sunucu bilgilerini görüyorsanız Docker çalışıyor demektir. Docker Hub hesabı oluşturmanızı da öneririm; resmi image’lara erişmek ve kendi image’larınızı yayımlamak için gerekiyor: hub.docker.com.
Temel Kavramlar
Komutlara geçmeden önce üç terimi netleştirmek işleri kolaylaştırıyor.
Image, bir veya daha fazla bileşeni içinde barındıran paket yapısıdır. İşletim sistemi, kütüphane, uygulama — hepsi image içinde tanımlı. Docker Hub üzerinde yayımlanır ve dağıtılır. Kaynak koda benzetebilirsiniz.
Container, bir image’dan türetilmiş ve izole biçimde çalışan örnektir. Image kaynak kod, container o kodun çalışan hali. Aynı image’dan istediğiniz kadar container başlatabilirsiniz.
Docker Registry, image’ları saklayan ve dağıtan yazılım ya da servistir. Docker Hub en bilinen public registry; kendi private registry’nizi de kurabilirsiniz.
Temel Komutlar
Image İşlemleri
Docker Hub üzerinde image aramak için:
docker search php
Yalnızca resmi image’ları listelemek için:
docker search --filter is-official=true php
Bir image çekmek:
docker pull php
Belirli bir sürümü indirmek için etiket (tag) kullanılır:
docker pull php:7.4-cli
Yüklü image’ları listelemek:
docker images
Belirli bir image’ı filtrelemek:
docker images java:8
Image silmek:
docker rmi php
Container İşlemleri
Container oluşturmanın en yaygın yolu run komutudur. Tek seferde image çekme, container oluşturma ve başlatmayı birleştirir:
docker run --name dbserver mysql
mysql image daha önce çekilmemişse önce çeker, ardından dbserver adında bir container oluşturup başlatır.
Arka planda çalıştırmak (detach mode) için -d bayrağı:
docker run -d mysql
Container’ın interaktif terminaline bağlanmak için -it:
docker run -it --name dockerbash ubuntu

İşi bitince kendini silmesini istediğiniz tek seferlik container’lar için --rm:
docker run --rm php php -v
Çalışan container’ları listelemek:
docker ps
Tüm container’ları (durmuşlar dahil) listelemek:
docker ps -a
Container durdurmak:
docker stop dbserver
Container silmek:
docker rm dbserver
Container yeniden adlandırmak:
docker container rename dbserver mysqlserver
Container loglarını görmek:
docker container logs dbserver
Container detaylarını incelemek:
docker container inspect dbserver
Container’ın dosya sistemini tar olarak dışa aktarmak:
docker container export -o /backup/db.tar dbserver
Port yönlendirmesi (port mapping) için -p bayrağı — dış port:iç port sırasıyla:
docker container create -p 3333:3306 mysql
Ortam değişkeni geçmek için -e:
docker run -e MYSQL_ROOT_PASSWORD=123456 mysql
Arka planda çalışan bir container’a terminalden bağlanmak:
docker attach dbserver
Volume Mapping
Container’ı sildiğinizde içinde yaptığınız değişiklikler varsayılan olarak kaybolur; yerine oluşturduğunuz container, image’dan her seferinde temiz başlar. Veriyi kalıcı tutmak için host üzerindeki bir dizin ile container içindeki bir dizini eşleştirirsiniz. -v bayrağı ile dışDizin:içDizin biçiminde belirtilir:
docker run -v /opt/datadir:/var/lib/mysql mysql
Terim konusunda bir düzeltme borçluyum: burada yaptığım şey Docker’ın sözlüğünde volume değil, bind mount. Dokümanın tanımıyla bind mount’ta “host makinedeki bir dosya ya da dizin host’tan container’a mount edilir”; volume’da ise Docker host üzerinde kendi depolama dizini içinde yeni bir dizin oluşturur ve onu kendisi yönetir. İkisi farklı mekanizma — aşağıdaki örnek bir bind mount.
Bu örnekte MySQL’in veri dizini host üzerindeki /opt/datadir’a bağlanıyor. Container yeniden başladığında veri orada duruyor, kaybolmuyor. Geliştirme ortamında proje klasörünüzü container’a bağlamak da aynı mekanizma üzerinden işliyor.
Network Türleri
Docker’da üç varsayılan network türü var:
Bridge: Her container’ın ayrı bir yerel IP adresi (genellikle 172.17.0.*) aldığı varsayılan network türü. Doküman şöyle diyor: Docker başladığında varsayılan bir bridge ağı otomatik oluşturulur ve aksi belirtilmedikçe yeni container’lar ona bağlanır. Container’lar arasında izolasyon sağlar, yine de birbirleriyle iletişim kurabilirler. Aynı doküman bir uyarı da düşüyor: varsayılan bridge ağı Docker’ın eski bir ayrıntısı sayılıyor ve production’da kullanılması önerilmiyor — orada kendi kullanıcı-tanımlı ağınızı oluşturun.
docker run --network=bridge mysql
None: Tamamen izole, dışarıyla hiçbir network bağlantısı olmayan container’lar için.
docker run --network=none mysql
Host: Container’ın host’un network yığınını doğrudan kullandığı mod. Port yönlendirmesine gerek kalmaz ama izolasyon da ortadan kalkar.
docker run --network=host mysql
Özel Network Oluşturma
Aynı network üzerinde container’ların birbirine ismiyle erişmesini istiyorsanız kullanıcı tanımlı network oluşturun:
docker network create --driver bridge --subnet 182.18.0.1/24 --gateway 182.18.0.1 wordpress-network
Network’leri listelemek:
docker network ls
Network silmek:
docker network rm wordpress-network
Network detaylarını görmek:
docker inspect wordpress-network
Belirli bir network üzerinde container başlatmak:
docker run --net wordpress-network mysql
Docker’ın gerçek gücü burada anlattığım tekil komutların ötesinde — birden fazla container’ı birlikte yönetmek için Docker Compose, production ortamları için Kubernetes gibi araçlar var. Ama bu temel komutları kavramadan o adımlara geçmek zorlaşıyor. Geliştirme ortamında Docker kullanmaya başlamanın en iyi yolu genellikle mevcut bir projeye docker-compose.yml ekleyip servisleri birer container olarak tanımlamak; bu deneyim Docker’ın nasıl çalıştığını kısa sürede netleştiriyor.
Kaynaklar
Bu konuda sorulanlar
Docker imaj boyutunu multi-stage build ve distroless ile nasıl küçültürüm?
Build araçlarını builder aşamasında bırakın: final aşama Go için distroless ya da scratch, PHP için fpm-alpine olsun; container'ı non-root çalıştırın.
Self-hosted CI/CD runner'larını nasıl izole eder, her çalışmadan sonra temizlenen (ephemeral) ortamı nasıl kurarım?
Runner'ı kaydol-çalış-yok ol modeline geçirip job'ları unprivileged çalıştırın; Docker soketini vermeyin ve fork PR'larını bu runner'da hiç koşturmayın.
WireGuard ile Docker ağları çakışıyor; routing'i nasıl stabilize ederim?
Çakışma runtime hatası değil adresleme planı sorunudur: Docker havuzunu daemon.json'da pinleyin, AllowedIPs'i DB subnet'ine kısın, rotaları kalıcı yapın.
Bu konudaki deneyler
Üretim veritabanına giden ad-hoc SQL'i onaya, maskelemeye ve değiştirilemez bir ize bağlayan self-hosted portal; QueryProxy ürününe dönüştü.
Şu an ne yapıyor
Geliştiricinin yazdığı SQL'i üretim veritabanında doğrudan değil, bir onaydan geçirerek çalıştırıyor; sonuçlar diske yazılırken maskeleniyor ve her istek değiştirilemez bir kayda düşüyor. Prod erişimi tek kişide toplanmış ekipler kurabilir.
Yorumlar
Yorum yapmak için GitHub hesabınızla giriş yapmanız yeterli. Yorumlar GitHub Discussions üzerinde saklanır.