
Zelkulon19 Mart 20251 dk okuma
Microservisler için Docker ve Docker Compose'u doğru kullanmak: Çok aşamalı Build'ler, Servis Keşfi, Sağlık Kontrolleri ve eksiksiz bir yerel geliştirme ortamı.
Hedef Mimari
┌─────────────────────────────────────────────────────────────┐ │ docker-compose.yml │ │ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Next.js │ │ Order │ │ Payment │ │ │ │ :3000 │ │ Service │ │ Service │ │ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ └───────────────┴───────────────┘ │ │ Bridge-Network │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │PostgreSQL│ │ RabbitMQ │ │ Redis │ │ │ │ :5432 │ │ :5672 │ │ :6379 │ │ │ └──────────┘ └──────────┘ └──────────┘ │ └─────────────────────────────────────────────────────────────┘
Çok Aşamalı Dockerfile (Spring Boot)
# ─── Stage 1: Build ────────────────────────────────────────────
FROM eclipse-temurin:21-jdk-alpine AS build
WORKDIR /app
COPY pom.xml .
COPY .mvn .mvn
COPY mvnw .
RUN ./mvnw dependency:go-offline -B # Bağımlılıklar için katman önbelleği
COPY src src
RUN ./mvnw package -DskipTests -B
RUN java -Djarmode=layertools -jar target/*.jar extract --destination target/layers
# ─── Stage 2: Runtime (~600 MB yerine ~150 MB) ──────────────────
FROM eclipse-temurin:21-jre-alpine AS runtime
WORKDIR /app
COPY --from=build /app/target/layers/dependencies/ ./
COPY --from=build /app/target/layers/spring-boot-loader/ ./
COPY --from=build /app/target/layers/application/ ./
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
EXPOSE 8081
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s CMD wget -qO- http://localhost:8081/actuator/health || exit 1
ENTRYPOINT ["java", "org.springframework.boot.loader.launch.JarLauncher"]Docker Compose
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: ${DB_PASS:-secret}
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
retries: 5
rabbitmq:
image: rabbitmq:3.13-management-alpine
ports:
- "5672:5672"
- "15672:15672" # Yönetim Arayüzü
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "ping"]
interval: 30s
order-service:
build: ./order-service
environment:
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/orderdb
SPRING_RABBITMQ_HOST: rabbitmq
ports:
- "8081:8081"
depends_on:
postgres:
condition: service_healthy # Yalnızca DB hazır olduğunda başlat!
rabbitmq:
condition: service_healthy
restart: unless-stopped
volumes:
postgres_data:Kullanışlı Komutlar
# Tüm servisleri başlat
docker compose up -d
# Yalnızca altyapı (yerel geliştirme için)
docker compose up -d postgres rabbitmq redis
# Bir servisin logları
docker compose logs -f order-service
# Servisi yeniden derle
docker compose up -d --build order-service
# Tüm servislerin durumu
docker compose ps
# Container kabuğunu aç
docker compose exec order-service sh
# Her şeyi durdur + volume'leri sil (veritabanı verilerini sıfırla)
docker compose down -vSağlık Kontrolü ile Başlatma Sırası
1. postgres, rabbitmq, redis başlatılıyor
│
▼
2. Sağlık kontrolleri (pg_isready, rabbit ping, redis ping)
│ tümü sağlıklı
▼
3. order-service, payment-service başlatılıyor
│
▼
4. Sağlık kontrolleri (actuator/health)
│ tümü sağlıklı
▼
5. Frontend başlatılıyor
condition: service_healthy olmadan → Spring, PostgreSQL
hazır olmadan önce başlar → bağlantı hatası!Özet
- Tutarlılık: "Bende çalışıyor" dönemi kapandı
- İzolasyon: Servisler birbirinden bağımsız çalışır
- Hızlı başlangıç: docker compose up – hazır
- Üretim paritesi: Yerel ortam dağıtımla birebir eşleşir
- Ölçeklenebilirlik: docker compose up --scale order-service=3