İlk Container'ın — docker run ile Tanışma
Docker kuruldu, her şey hazır. Şimdi Docker'ın en temel, en sık kullanılan, en güçlü komutunu öğrenme zamanı: docker run.
Bir otomat makinesi düşün. Para atarsın, buton seçersin, ürün düşer. İçeride kompresör mü çalışıyor, soğutma sistemi nasıl — bilmene gerek yok. Sen sadece butona basarsın. docker run da tam olarak bu. Tek bir komutla: image indirilir, container oluşturulur, network konfigüre edilir, dosya sistemi hazırlanır ve proses başlatılır. Sen sadece komutu yazarsın.
Bu derste docker run komutunu tüm detaylarıyla öğreneceğiz. Her parametresini, her davranışını, gerçek dünya örnekleriyle pratik yapacağız.
docker run — En Temel Komut
docker run [SEÇENEKLER] IMAGE [KOMUT] [ARGÜMANLAR]Bu komut aslında iki işlemi birlikte yapıyor: önce image'dan bir container oluşturuyor (docker create), sonra bu container'ı başlatıyor (docker start). Ama biz genellikle ikisini birden yapan docker run'ı kullanırız.
En basit haliyle:
docker run nginxBu komutu çalıştırdığında ne oluyor? Docker önce nginx:latest image'ını yerelde arıyor. Bulamazsa Docker Hub'dan indiriyor. Sonra image'dan bir container oluşturuyor. Container'ın varsayılan komutunu (CMD) çalıştırıyor. Ve container ön planda (foreground) çalışmaya başlıyor — terminali meşgul ediyor. Ctrl+C ile durdurabilirsin.
Ama pratikte container'ları genellikle arka planda çalıştırırız. Şimdi en sık kullanılan seçenekleri tek tek öğrenelim.
Arka Planda Çalıştır: -d (Detached Mode)
# Ön planda — terminal meşgul olur
docker run nginx
# Arka planda — terminal serbest kalır
docker run -d nginx
# Çıktı: a1b2c3d4e5f6... (container ID)-d flag'i container'ı arka plana gönderir. Container çalışmaya devam eder ama terminalin serbest kalır. Başka işler yapabilirsin. Çalışan container'ları görmek için docker ps kullanırsın.
Container'a İsim Ver: --name
Docker, isim vermediğin container'lara rastgele isimler atar: eager_einstein, silly_hawking gibi. Eğlenceli ama kafa karıştırıcı. Onun yerine her zaman anlamlı isimler ver:
docker run -d --name web-server nginxArtık bu container'a ismiyle erişebilirsin:
docker stop web-server
docker start web-server
docker logs web-server
docker rm web-server💡 Her zaman --name kullan. Rastgele isimlerle çalışmak, özellikle birden fazla container varken, çok karmaşıklaştırır.
Port Mapping: -p
Container'lar varsayılan olarak dış dünyadan erişilemez. İçeride bir web sunucusu çalışıyor olabilir ama sen tarayıcıdan ona ulaşamazsın. Port mapping ile container'ın portunu host'un portuna bağlarsın:
docker run -d -p 8080:80 nginxBu komut "host'un 8080 portuna gelen istekleri container'ın 80 portuna yönlendir" diyor. Şimdi tarayıcıda http://localhost:8080 açarsan Nginx'in karşılama sayfasını görürsün.
Birden fazla port da eşleyebilirsin:
docker run -d -p 8080:80 -p 8443:443 nginxEğer belirli bir IP'ye bağlamak istersen (mesela sadece localhost'tan erişilebilir olsun):
docker run -d -p 127.0.0.1:8080:80 nginxHangi portların eşlendiğini görmek için:
docker port web-server
# 80/tcp -> 0.0.0.0:8080İnteraktif Mod: -it
Bazen container'ın içine girip etkileşimli çalışmak istersin — bir shell açmak, komut denemek, debug yapmak gibi. Bunun için -it flag'lerini kullanıyoruz:
docker run -it ubuntu bash-i stdin'i açık tutar (klavyeden input girebilirsin), -t bir terminal emülatörü sağlar (renkler, satır düzeni doğru görünür). İkisi birlikte tam bir terminal deneyimi sunar.
Bu komutu çalıştırdığın anda kendini bir Ubuntu shell'inin içinde bulursun:
root@a1b2c3d4e5f6:/# whoami
root
root@a1b2c3d4e5f6:/# ls /
bin boot dev etc home lib ...
root@a1b2c3d4e5f6:/# exitexit yazınca container durur — çünkü container'ın ana prosesi bash'ti ve o kapandı.
Aynı şekilde Python veya Node.js REPL'ini de container içinde çalıştırabilirsin:
# Python REPL
docker run -it python:3.12
>>> print("Merhaba Docker!")
Merhaba Docker!
>>> exit()
# Node.js REPL
docker run -it node:20
> console.log("Docker'dan selam!")
Docker'dan selam!
> .exitOtomatik Temizlik: --rm
Normalde bir container durduğunda silinmez — docker ps -a ile hâlâ görürsün. Zamanla onlarca durmuş container birikir. --rm flag'i ile container durduğu anda otomatik silinir:
# --rm olmadan: container durmuş olarak kalır
docker run ubuntu echo "hello"
docker ps -a # Exited container görürsün
# --rm ile: container durduğu anda silinir
docker run --rm ubuntu echo "hello"
docker ps -a # Temiz — container yok💡 Tek seferlik komutlarda, test ve deneme amaçlı container'larda her zaman --rm kullan. Yoksa zamanla durmuş container çöplüğü oluşur.
Environment Variables: -e
Uygulamaları konfigüre etmenin en yaygın yolu environment variable'lar. -e flag'i ile container'a değişken geçirebilirsin:
docker run -d \
-e POSTGRES_USER=admin \
-e POSTGRES_PASSWORD=secret123 \
-e POSTGRES_DB=myapp \
postgres:16Çok sayıda değişken varsa dosyadan yüklemek daha temiz:
# .env dosyası oluştur
cat > .env << 'EOF'
POSTGRES_USER=admin
POSTGRES_PASSWORD=secret123
POSTGRES_DB=myapp
EOF
# Dosyadan yükle
docker run -d --env-file .env postgres:16Container'ın environment variable'larını kontrol etmek için:
docker exec my-container envEnvironment variable'ları Bölüm 4'te çok daha detaylı inceleyeceğiz.
Volume ve Bind Mount Temelleri
Container'lar geçici. Durdurduğunda veya sildiğinde içindeki veriler kaybolur. Ama veritabanı verisi, log dosyaları, kullanıcı yüklemeleri — bunlar kalıcı olmalı. İşte burada volume'lar devreye girer:
# Named volume: Docker-yönetimli kalıcı depolama
docker run -d \
-v pgdata:/var/lib/postgresql/data \
postgres:16
# pgdata volume'ü container silinse bile kalır!
# Bind mount: Host dizinini container'a bağla
docker run -d \
-v $(pwd)/html:/usr/share/nginx/html \
-p 8080:80 \
nginx
# Host'taki html/ dizini container'da görünür
# Dosyaları host'ta düzenlersin, container'da anında yansırVolume konusunu Bölüm 6'da derinlemesine ele alacağız. Şimdilik "veri kalıcı olsun istiyorsan volume kullan" kuralını hatırla.
Restart Policy — Container Çökerse Ne Olur?
Production'da container'lar çökebilir. Bir hata, bir memory leak, bir beklenmedik durum — ve container durur. Ne olacak? Elle mi başlatacaksın? Hayır. Restart policy ile otomatik yeniden başlatma tanımlarsın:
# Her zaman yeniden başlat
docker run -d --restart=always nginx
# Hata durumunda max 5 deneme
docker run -d --restart=on-failure:5 myapp
# Docker daemon restart'ında da başlat (elle durdurulmuşsa hariç)
docker run -d --restart=unless-stopped nginxProduction tavsiyesi: unless-stopped kullan. Container çökerse otomatik başlar, Docker servisi yeniden başlarsa da başlar. Ama sen docker stop ile durdurduysan, kendiliğinden başlamaz.
Kaynak Limitleri — Kontrolü Kaybetme
Bir container kontrolsüzce tüm CPU'yu veya RAM'i tüketebilir. Bu, aynı sunucudaki diğer container'ları ve hatta host sistemi çökertebilir. Kaynak limitleri ile bunu önlersin:
# Memory limiti — 256MB'ı aşarsa container durdurulur
docker run -d --memory=256m nginx
# CPU limiti — maksimum yarım CPU core
docker run -d --cpus=0.5 nginx
# İkisi birlikte
docker run -d --memory=512m --cpus=1 myappKaynak kullanımını izlemek için:
docker stats
# CONTAINER CPU % MEM USAGE / LIMIT MEM %
# web-server 0.05% 5.2MiB / 256MiB 2.03%Kaynak limitlerini Bölüm 4'te çok daha detaylı inceleyeceğiz.
Gerçek Dünya Örnekleri
Teoriyi yeterince konuştuk, şimdi gerçek uygulamalar çalıştıralım.
Örnek 1: PostgreSQL Veritabanı
Diyelim ki bir projede PostgreSQL lazım. Eskiden PostgreSQL'i indirip kurar, konfigüre eder, servis olarak ayarlardın. Docker ile:
docker run -d \
--name postgres \
-e POSTGRES_USER=admin \
-e POSTGRES_PASSWORD=supersecret \
-e POSTGRES_DB=myapp \
-v pgdata:/var/lib/postgresql/data \
-p 5432:5432 \
--restart=unless-stopped \
postgres:16Tek komutla PostgreSQL çalışıyor! Veritabanına bağlanmak için:
docker exec -it postgres psql -U admin -d myappBu seni PostgreSQL shell'ine düşürür. SQL yazabilir, tablo oluşturabilir, veri ekleyebilirsin:
myapp=# CREATE TABLE users (id SERIAL, name TEXT);
myapp=# INSERT INTO users (name) VALUES ('Docker Öğrencisi');
myapp=# SELECT * FROM users;
myapp=# \qÖrnek 2: Redis Cache
docker run -d \
--name redis \
-p 6379:6379 \
-v redis-data:/data \
--restart=unless-stopped \
redis:7 \
redis-server --appendonly yes --requirepass mypasswordBurada ilginç bir şey var — image adından sonra redis-server --appendonly yes --requirepass mypassword yazdık. Bu, container'ın varsayılan komutunu (CMD) override ediyor. Redis'e "kalıcı depolama aç ve şifre zorunlu tut" diyoruz.
docker exec -it redis redis-cli -a mypassword
127.0.0.1:6379> SET greeting "Merhaba Docker!"
127.0.0.1:6379> GET greeting
# "Merhaba Docker!"
127.0.0.1:6379> exitÖrnek 3: Node.js Geliştirme Ortamı
Bu örnek özellikle geliştirme sürecinde çok kullanışlı. Proje dizinini container'a bağlıyoruz — host'ta kodu düzenliyoruz, container'da çalışıyor:
mkdir myproject && cd myproject
# Basit bir Express server oluşturalım
cat > package.json << 'EOF'
{
"name": "docker-demo",
"version": "1.0.0",
"scripts": { "start": "node server.js", "dev": "node --watch server.js" },
"dependencies": { "express": "^4.18.0" }
}
EOF
cat > server.js << 'EOF'
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.json({ message: 'Merhaba Docker!', time: new Date() });
});
app.listen(3000, () => console.log('Server 3000 portunda çalışıyor'));
EOF
# Container'da çalıştır
docker run -it --rm \
--name node-dev \
-v $(pwd):/app \
-w /app \
-p 3000:3000 \
node:20 \
sh -c "npm install && npm run dev"Tarayıcıda http://localhost:3000 aç — JSON yanıtı göreceksin. En güzeli: server.js'i düzenle, kaydet — Node.js --watch modu sayesinde otomatik yeniden başlar!
Container Yönetim Komutları
Container çalıştırmayı öğrendik. Şimdi çalışan container'ları nasıl yöneteceğimize bakalım.
Listeleme
docker ps # Çalışan container'lar
docker ps -a # Tüm container'lar (durmuşlar dahil)
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" # Özel formatYaşam Döngüsü
docker start web-server # Durmuş container'ı başlat
docker stop web-server # Nazikçe durdur (SIGTERM → 10s → SIGKILL)
docker restart web-server # Yeniden başlat
docker kill web-server # Anında durdur (SIGKILL)İnceleme
docker logs web-server # Loglar
docker logs -f web-server # Canlı log takibi (tail -f gibi)
docker logs --tail 50 web-server # Son 50 satır
docker inspect web-server # Tüm detaylar (JSON)
docker stats web-server # Kaynak kullanımıContainer İçi İşlemler
docker exec -it web-server bash # Shell aç
docker exec web-server cat /etc/hosts # Tek komut çalıştır
docker cp web-server:/var/log/ ./logs/ # Container → Host dosya kopyala
docker cp ./config.txt web-server:/app/ # Host → Container dosya kopyalaTemizlik
docker rm web-server # Durmuş container'ı sil
docker rm -f web-server # Çalışıyorsa bile zorla sil
docker container prune # Tüm durmuş container'ları silEn Sık Karşılaşılan Hatalar
Container Hemen Duruyor
docker run -d ubuntu
docker ps # Boş! Container yok!
docker ps -a # STATUS: Exited (0) 1 second agoBu çok yaygın ve kafa karıştırıcı. Neden? Çünkü Ubuntu image'ının varsayılan komutu bash. Ama -it flag'leri olmadan bash'e input gönderemezsin, bash yapacak bir şey bulamayıp kapanır, ve container da onunla birlikte durur.
Çözümler:
# İnteraktif mod ile
docker run -it ubuntu bash
# Veya sürekli çalışan bir komut ver
docker run -d ubuntu sleep infinity
# Veya bir servis çalıştır
docker run -d ubuntu sh -c "while true; do echo 'alive'; sleep 60; done"Nginx, PostgreSQL gibi servis container'ları bu sorunu yaşamaz — çünkü zaten sürekli çalışan bir foreground prosesleri var.
Port Zaten Kullanımda
docker run -d -p 8080:80 nginx
# Error: port is already allocatedBaşka bir proses (veya başka bir container) 8080 portunu kullanıyor. Hangi proses olduğunu bulmak için:
sudo lsof -i :8080
# veya
sudo ss -tlnp | grep 8080Çözüm: farklı port kullan (-p 8081:80).
Volume İzin Sorunu
docker run -v $(pwd)/data:/data myapp
# Permission deniedContainer içindeki kullanıcı ile host'taki dosya izinleri uyuşmuyordur. Çözüm:
# Doğru kullanıcı ID ile çalıştır
docker run --user $(id -u):$(id -g) -v $(pwd)/data:/data myappdocker run Parametre Özeti
Bir container başlatırken en sık kullandığın parametreleri toparlayalım:
docker run \
-d # Arka planda çalıştır
--name mycontainer # İsim ver
-p 8080:80 # Port eşle
-v /host/path:/container/path # Bind mount
-v volume-name:/data # Named volume
-e KEY=VALUE # Environment variable
--env-file .env # Env dosyasından yükle
--restart=unless-stopped # Restart policy
--memory=512m # RAM limiti
--cpus=1 # CPU limiti
--rm # Durdurulunca otomatik sil
image:tag # Çalıştırılacak image
command args # Özel komut (opsiyonel)Bu parametrelerin hepsini ezberleme. İhtiyacın olduğunda docker run --help ile her zaman bakabilirsin. Ama en temel olanları — -d, --name, -p, -v, -e — zamanla parmağına oturacak.
Bu Derste Ne Öğrendik?
docker run, Docker'ın en temel komutu — bir image'dan container oluşturur ve başlatır.-darka planda çalıştırır,-itinteraktif mod açar,--rmotomatik temizlik yapar,-pport eşler,-vvolume bağlar.Her container'a anlamlı
--namever ve production'da kaynak limitleri (--memory,--cpus) belirle.--restartpolicy ile container çökme davranışını kontrol et — production'daunless-stoppedkullan.docker execile çalışan container'da komut çalıştır,docker logsile logları takip et.Container hemen duruyorsa, sürekli çalışan bir foreground process gerekli. Servis container'ları (Nginx, PostgreSQL) bunu otomatik sağlar.
Hands-On Pratik: Adım Adım Dene
Bu derste öğrendiklerini pekiştirmek için şu adımları sırayla uygula:
# 1. Docker versiyonunu kontrol et
docker version
# 2. Sistem bilgilerini gör
docker info
# 3. Hello World çalıştır
docker run --rm hello-world
# 4. İnteraktif Ubuntu shell aç
docker run -it --rm ubuntu bash
# İçeride: ls, pwd, whoami komutlarını dene
# exit ile çık
# 5. Arka planda Nginx başlat
docker run -d -p 8080:80 --name my-nginx nginx
# 6. Çalışan container'ları listele
docker ps
# 7. Container loglarını gör
docker logs my-nginx
# 8. Container'ın içine gir
docker exec -it my-nginx sh
# İçeride: cat /etc/nginx/nginx.conf dene
# exit ile çık
# 9. Container kaynak kullanımını gör
docker stats --no-stream my-nginx
# 10. Container'ı durdur ve sil
docker stop my-nginx
docker rm my-nginx
# 11. Tüm container'ları listele (durmuş olanlar dahil)
docker ps -a
# 12. Durmuş tüm container'ları temizle
docker container prune -f
# 13. PostgreSQL veritabanı başlat
docker run -d --name testdb \
-e POSTGRES_PASSWORD=test123 \
-p 5432:5432 \
postgres:16
# 14. Veritabanına bağlan ve SQL çalıştır
docker exec -it testdb psql -U postgres -c "SELECT version();"
# 15. Temizlik
docker stop testdb
docker rm testdb
docker system prune -fBu 15 adımı sorunsuz tamamladıysan, docker run komutunu ve temel container yönetimini öğrendin demektir. Her adımda ne olduğunu gözlemle — çıktılara dikkat et, hata alırsan yukarıdaki "Sık Karşılaşılan Hatalar" bölümüne bak.
Gelişmiş Seçenekler — İleride Lazım Olacak
Şu an için bunları bilmen yeterli ama referans olarak not et:
Hostname ve DNS
# Container'a özel hostname ver
docker run -d --hostname myserver nginx
# DNS sunucusu belirle
docker run -d --dns 8.8.8.8 nginx
# Hosts dosyasına kayıt ekle
docker run -d --add-host=api.local:192.168.1.100 myappHealthcheck
Container'ın sağlıklı çalışıp çalışmadığını izlemek için:
docker run -d \
--health-cmd="curl -f http://localhost/ || exit 1" \
--health-interval=30s \
--health-timeout=10s \
--health-retries=3 \
nginxdocker ps çıktısında STATUS sütununda (healthy) veya (unhealthy) görürsün.
Log Limitleri
Container loglarının disk'i doldurmasını önlemek için:
docker run -d \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginxHer container için maksimum 30MB log (3 dosya × 10MB).
Network Seçenekleri
# Host'un network'ünü doğrudan kullan (Linux only)
docker run -d --network host nginx
# Özel network oluştur ve kullan
docker network create mynet
docker run -d --network mynet --name web nginx
docker run -d --network mynet --name api myapp
# web ve api birbirini isimle bulabilir!
# Network erişimini tamamen kapat
docker run --network none alpine ping google.com
# ağ erişimi yokNetwork konusunu Bölüm 5'te derinlemesine ele alacağız.
Bölüm 1 tamamlandı! Container nedir, Docker ekosistemi ne içerir, nasıl kurulur ve nasıl container çalıştırılır — hepsini öğrendin. Bir sonraki bölümde Docker image kavramına derinlemesine dalacağız — image'lar nasıl çalışır, katmanlı dosya sistemi nedir, image'ları nasıl yönetirsin.
AI Asistan
Sorularını yanıtlamaya hazır