Docker, yazilim olusturma, dagitma ve calistirma yontemimizi degistirdi. "Benim makinemde calisiyor" yerine Docker, uygulamanizin her yerde ayni sekilde calismasini garanti eder - dizustu bilgisayarinizda, bir meslektasinizin makinesinde, CI/CD'de ve production'da. Bu rehberde, sifirdan gercek bir uygulamayi deploy etmeye kadar gidecegiz.
Docker Nedir?
Docker, uygulamanizi ve tum bagimliklarini container adinda standart bir birime paketleyen bir platformdur. Container, ana bilgisayar isletim sistemi cekirdegini paylasan ancak kendi dosya sistemi, agi ve islem alanina sahip izole, hafif bir islemdir.
Container-lar vs Sanal Makineler
| Ozellik | Container-lar | Sanal Makineler |
|---|---|---|
| Baslatma | Saniyeler | Dakikalar |
| Boyut | MB | GB |
| Isletim Sistemi | Ana bilgisayar cekirdegini paylasiyor | Tam misafir IS |
| Izolasyon | Islem duzeyi | Donanim duzeyi |
| Performans | Neredeyse yerel | Hypervisor ek yuku |
| Yogunluk | Ana bilgisayar basina yuzlerce | Ana bilgisayar basina onlarca |
Docker'i Kurmak
# macOS brew install --cask docker # Ubuntu/Debian curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER # Verify installation docker --version docker run hello-world
Temel Kavramlar
Image-lar
Bir image, container olusturmak icin talimatlari iceren salt okunur bir sablondur. Uygulamanizin ve ortaminin bir anllik goruntusu olarak dusunun.
# Pull an image from Docker Hub docker pull node:20-alpine # List local images docker images # Remove an image docker rmi node:20-alpine
Container-lar
Container, bir image'in calisan bir ornegi-dir. Container olusturabilir, baslatabilir, durdurabilir ve silebilirsiniz.
# Run a container docker run -d --name my-app -p 3000:3000 node:20-alpine # List running containers docker ps # List all containers (including stopped) docker ps -a # Stop a container docker stop my-app # Remove a container docker rm my-app # View logs docker logs my-app # Execute a command inside a running container docker exec -it my-app sh
Dockerfile Yazmak
Dockerfile, bir image olusturmak icin talimatlar iceren bir metin dosyasidir. Her talimat bir katman olusturur.
Node.js Uygulamasi icin Temel Dockerfile
# Use an official Node.js runtime as base image FROM node:20-alpine # Set working directory WORKDIR /app # Copy package files first (better caching) COPY package.json package-lock.json ./ # Install dependencies RUN npm ci --only=production # Copy application code COPY . . # Expose the port the app runs on EXPOSE 3000 # Command to run the application CMD ["node", "server.js"]
Olusturma ve Calistirma
# Build the image docker build -t my-node-app . # Run the container docker run -d -p 3000:3000 my-node-app # Visit http://localhost:3000
Multi-Stage Build-ler
Multi-stage build-ler, build ortamini runtime'dan ayirarak production image-larinizi kucuk tutar.
# Stage 1: Build FROM node:20-alpine AS builder WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci COPY . . RUN npm run build # Stage 2: Production FROM node:20-alpine AS runner WORKDIR /app COPY /app/dist ./dist COPY /app/node_modules ./node_modules COPY /app/package.json ./ EXPOSE 3000 CMD ["node", "dist/server.js"]
Bu, yalnizca derlenenmis ciktiyi ve production bagimliklarini iceren bir image uretir - kaynak kodu yok, gelistirme bagimliliklari yok, build araclari yok.
Next.js Multi-Stage Ornegi
FROM node:20-alpine AS deps WORKDIR /app COPY package.json package-lock.json ./ RUN npm ci FROM node:20-alpine AS builder WORKDIR /app COPY /app/node_modules ./node_modules COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app ENV NODE_ENV=production COPY /app/public ./public COPY /app/.next/standalone ./ COPY /app/.next/static ./.next/static EXPOSE 3000 CMD ["node", "server.js"]
Volume-ler: Kalici Veri
Varsayilan olarak, container icindeki veriler container kaldirildiginda kaybolur. Volume-ler bu sorunu cozer.
# Create a named volume docker volume create my-data # Run with a volume docker run -d -v my-data:/app/data my-app # Bind mount (map host directory to container) docker run -d -v $(pwd)/data:/app/data my-app # List volumes docker volume ls
Ag Yapisi
Docker, container-larin iletisim kurmasi icin izole aglar olusturur.
# Create a custom network docker network create my-network # Run containers on the same network docker run -d --name api --network my-network my-api docker run -d --name db --network my-network postgres:16 # Containers can reach each other by name # From "api" container: postgres://db:5432
Docker Compose
Docker Compose, tek bir YAML dosyasiyla coklu container uygulamalarini tanimlamanizi ve calistirmanizi saglar.
docker-compose.yml
services: api: build: ./api ports: - "3000:3000" environment: - DATABASE_URL=postgres://user:pass@db:5432/mydb depends_on: - db db: image: postgres:16-alpine environment: - POSTGRES_USER=user - POSTGRES_PASSWORD=pass - POSTGRES_DB=mydb volumes: - pgdata:/var/lib/postgresql/data ports: - "5432:5432" redis: image: redis:7-alpine ports: - "6379:6379" volumes: pgdata:
Komutlar
# Start all services docker compose up -d # View logs docker compose logs -f # Stop all services docker compose down # Rebuild and restart docker compose up -d --build # Scale a service docker compose up -d --scale api=3
.dockerignore
.gitignore gibi, bu dosya gereksiz dosyalarin image'a kopyalanmasini onler.
node_modules .git .env *.md .next dist coverage
Production En Iyi Uygulamalari
1. Kucuk Temel Image-lar Kullanin
# Bad: 1GB+ FROM node:20 # Good: ~180MB FROM node:20-alpine
2. Root Olarak Calistirmayin
FROM node:20-alpine RUN addgroup -S app && adduser -S app -G app USER app WORKDIR /home/app COPY . .
3. Belirli Image Tag-leri Kullanin
# Bad: can change unexpectedly FROM node:latest # Good: pinned version FROM node:20.11-alpine3.19
4. Build Onbellegini Kullanin
Dockerfile talimatlarinizi en az degisenden en cok degisene dogru sirayin:
FROM node:20-alpine WORKDIR /app # These change rarely - cached COPY package.json package-lock.json ./ RUN npm ci --only=production # This changes often - not cached COPY . .
5. Saglik Kontrolleri
HEALTHCHECK \ CMD wget -qO- http://localhost:3000/health || exit 1
6. Ortam Degiskenleri Kullanin
ENV NODE_ENV=production ENV PORT=3000
Yaygin Docker Komutlari Hizli Basvuru
# Images docker build -t name:tag . # Build image docker images # List images docker rmi image_name # Remove image docker image prune # Remove unused images # Containers docker run -d -p 3000:3000 image # Run detached docker ps # List running docker stop container_name # Stop docker rm container_name # Remove docker logs -f container_name # Follow logs docker exec -it container sh # Shell into container # Compose docker compose up -d # Start services docker compose down # Stop services docker compose logs -f # Follow all logs docker compose ps # List services # Cleanup docker system prune -a # Remove everything unused
Docker'dan Kubernetes'e
Docker bireysel container-lari yonetir. Birden fazla sunucuda yuzlerce container-i orkestre etmeniz gerektiginde Kubernetes'e ihtiyaciniz vardir. Docker ve Kubernetes birbirini tamamlar:
- Docker: container-lari olusturur ve calistirir
- Kubernetes: container-lari buyuk olcekte orkestre eder (zamanlama, olceklendirme, iyilestirme)
Sonraki adimla ilgileniyorsaniz, Kubernetes'e Giris hakkindaki makaleme goz atin.
Sonuc
Docker, modern gelisimciler icin temel bir beceridir. Ortam tutarsizliklarini ortadan kaldirir, deploy'u basitlestirir ve Kubernetes ile container orkestrasyonunun temelidir. Basit bir Dockerfile ile baslayin, coklu hizmet uygulamalari icin Docker Compose'a gecin ve buyudukce multi-stage build-leri ve guvenlik en iyi uygulamalarini benimseyin.
Docker'i ogrenmenin en iyi yolu, halihazirda uzerinde calistiginiz bir projeyi containerize etmektir. Bugun baslayin.