DEVOPS12m READ2 Haziran 2026

Docker ile Takım Geliştirme Ortamı Kurulumu

Fullstack proje için Docker Compose ve layer cache optimizasyonu.

Docker, geliştirme ortamını ekip genelinde standartlaştırmanın en etkili yoludur. "Bende çalışıyordu" sorununun kalıcı çözümüdür. Bu makalede gerçek bir fullstack proje için tam geliştirme ortamı kuruyoruz.

Neden Docker ile Geliştirme?

Klasik sorunlar:

  • Farklı Node.js sürümleri (14, 18, 20, 22...)
  • PostgreSQL'in local kurulumu vs. container davranış farkı
  • "Ben Windows'tayım, o Mac'te" uyumsuzlukları
  • CI'da çalışıyor, local'de çalışmıyor

Docker bu sorunları kökten çözer.

Proje Yapısı

// PLAINTEXT //
blog-projesi/
├── backend/
│   ├── src/
│   ├── Dockerfile
│   └── package.json
├── frontend/
│   ├── src/
│   ├── Dockerfile
│   └── package.json
├── nginx/
│   └── default.conf
├── docker-compose.yml
├── docker-compose.dev.yml
└── .env.example

Production Dockerfile (Node.js)

// DOCKERFILE //
# backend/Dockerfile
FROM node:22-alpine AS base
WORKDIR /app
COPY package*.json ./
 
FROM base AS deps
RUN npm ci --only=production
 
FROM base AS build
RUN npm ci
COPY . .
RUN npm run build
 
FROM node:22-alpine AS runner
WORKDIR /app
RUN addgroup -S app && adduser -S app -G app
COPY --from=deps  /app/node_modules ./node_modules
COPY --from=build /app/dist         ./dist
COPY --from=build /app/package.json ./
USER app
EXPOSE 3000
CMD ["node", "dist/server.js"]

Geliştirme Compose

// YAML //
# docker-compose.dev.yml
services:
  backend:
    build:
      context: ./backend
      target: build          # Dev bağımlılıkları yükle
    command: npm run dev      # ts-node-dev ile hot reload
    volumes:
      - ./backend/src:/app/src  # Kaynak bind mount
      - /app/node_modules       # Container'ın kendi node_modules
    environment:
      NODE_ENV: development
      DATABASE_URL: postgresql://dev:dev@db:5432/blogdev
      REDIS_URL:    redis://cache:6379
    ports:
      - "3000:3000"
      - "9229:9229"  # Debugger
    depends_on:
      db:
        condition: service_healthy
 
  frontend:
    build:
      context: ./frontend
      target: build
    command: npm run dev
    volumes:
      - ./frontend/src:/app/src
      - /app/node_modules
    environment:
      NEXT_PUBLIC_API_URL: http://localhost:3000
    ports:
      - "3001:3000"
 
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER:     dev
      POSTGRES_PASSWORD: dev
      POSTGRES_DB:       blogdev
    volumes:
      - postgres-dev:/var/lib/postgresql/data
      - ./backend/prisma/seed.sql:/docker-entrypoint-initdb.d/seed.sql
    ports:
      - "5432:5432"  # Local DB araçları için
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U dev -d blogdev"]
      interval: 5s
      timeout: 3s
      retries: 10
 
  cache:
    image: redis:7-alpine
    ports:
      - "6379:6379"
 
  mailpit:
    image: axllent/mailpit
    ports:
      - "1025:1025"  # SMTP
      - "8025:8025"  # Web UI
 
volumes:
  postgres-dev:

Makefile ile Kısayollar

// MAKEFILE //
# Makefile
.PHONY: dev prod down logs shell db-cli
 
dev:
	docker compose -f docker-compose.yml -f docker-compose.dev.yml up
 
prod:
	docker compose up -d
 
down:
	docker compose down
 
logs:
	docker compose logs -f backend
 
shell:
	docker compose exec backend sh
 
db-cli:
	docker compose exec db psql -U dev -d blogdev
 
db-reset:
	docker compose down -v
	docker compose -f docker-compose.yml -f docker-compose.dev.yml up db -d
	sleep 5
	docker compose exec backend npx prisma db push
	docker compose exec backend npx prisma db seed
 
test:
	docker compose exec backend npm test

Ortam Değişkenleri Yönetimi

// BASH //
# .env.example — commit'lenir, değerler gizlenmez
DATABASE_URL=postgresql://user:password@db:5432/blogdb
REDIS_URL=redis://cache:6379
JWT_SECRET=your-super-secret-jwt-key-here
CORS_ORIGIN=http://localhost:3001
NODE_ENV=development
 
# .env — commit'lenmez (.gitignore'da)
DATABASE_URL=postgresql://dev:dev@localhost:5432/blogdev
JWT_SECRET=localdevelopmentonly-change-in-prod
// YAML //
# docker-compose.yml — ortam dosyasını kullan
services:
  backend:
    env_file:
      - .env
    # veya tekil değişkenler
    environment:
      - NODE_ENV=${NODE_ENV:-development}

Layer Cache Optimizasyonu

// DOCKERFILE //
# KÖTÜ — her değişiklikte npm install çalışır
COPY . .
RUN npm install
 
# İYİ — package.json değişmediğinde cache'den alır
COPY package*.json ./
RUN npm ci           # Cache katmanı
COPY . .            # Kaynak kod (sık değişir)
RUN npm run build

Bu optimizasyon, kaynak değiştikçe npm install'ın tekrar çalışmasını engeller. Büyük projelerde dakikalarca zaman kazandırır.

Production için Güvenlik Kontrol Listesi

// BASH //
# Image'ı güvenlik açıkları için tara
docker scout cves myapp:latest
# veya
trivy image myapp:latest
 
# Root olmayan kullanıcı kontrolü
docker inspect myapp:latest | jq '.[0].Config.User'
# "app" çıkmalı, "" (root) değil
 
# Gereksiz kapı açık mı?
docker inspect mycontainer | jq '.[0].NetworkSettings.Ports'
 
# Read-only filesystem
docker run --read-only --tmpfs /tmp myapp:latest

CI/CD Entegrasyonu

// YAML //
# .github/workflows/docker.yml
name: Docker Build & Push
 
on:
  push:
    branches: [main]
 
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - name: Docker meta
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ghcr.io/${{ github.repository }}
          tags: |
            type=sha
            type=raw,value=latest,enable=${{ github.ref == 'refs/heads/main' }}
 
      - name: Build ve Push
        uses: docker/build-push-action@v5
        with:
          context: ./backend
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          cache-from: type=gha
          cache-to:   type=gha,mode=max

Sonuç

Docker ile geliştirme ortamı; yeni bir ekip üyesinin dakikalar içinde çalışmaya başlamasını, "bende çalışıyor" sorununu yok etmeyi ve production ile geliştirme arasındaki uçurumu kapatmayı sağlar. Makefile kısayolları ile günlük komutları sadeleştirebilir, layer cache optimizasyonu ile build sürelerini dramatik biçimde kısaltabilirsiniz.