0%

Docker ile Microservices: Container Tabanlı Geliştirme

Docker ve containerization kullanarak microservices mimarisini öğrenin ve modern uygulamalar geliştirin.

📅
👤CodeBros
⏱️8 dakikada okunur
DockerMicroservicesDevOpsContainerKubernetes
Docker ile Microservices: Container Tabanlı Geliştirme - Blog yazısı öne çıkan görseli

Docker ile Microservices: Container Tabanlı Geliştirme

Modern yazılım geliştirmede Docker ve containerization, microservices mimarisinin temel taşlarıdır. Bu kapsamlı rehberde, Docker ile microservices geliştirmeyi baştan sona öğreneceksiniz.

Docker Nedir?

Docker, uygulamaları containerlar içinde paketleyip çalıştıran bir platformdur.

Container vs Virtual Machine

**Container:**
✓ Lightweight (MB seviyesinde)
✓ Saniyeler içinde başlatılır
✓ OS kernel'ı paylaşır
✓ Daha az kaynak kullanır

**Virtual Machine:**
× Heavy (GB seviyesinde)
× Dakikalar içinde başlatılır
× Kendi OS'i var
× Daha çok kaynak kullanır

Docker Avantajları

  • Consistency: "Works on my machine" problemini çözer
  • Isolation: Her servis izole ortamda çalışır
  • Scalability: Kolayca ölçeklendirilebilir
  • Portability: Her yerde aynı şekilde çalışır

Docker Temelleri

Dockerfile Oluşturma

# Node.js uygulaması için Dockerfile
FROM node:18-alpine AS base

# Çalışma dizini oluştur
WORKDIR /app

# Package files kopyala
COPY package*.json ./

# Dependencies yükle
RUN npm ci --only=production

# Uygulama kodunu kopyala
COPY . .

# Port expose et
EXPOSE 3000

# Health check ekle
HEALTHCHECK --interval=30s --timeout=3s \
  CMD node healthcheck.js || exit 1

# Uygulamayı başlat
CMD ["node", "server.js"]

Multi-Stage Build

# Build stage
FROM node:18-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci

COPY . .
RUN npm run build

# Production stage
FROM node:18-alpine AS production

WORKDIR /app

# Sadece gerekli dosyaları kopyala
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./

ENV NODE_ENV=production
EXPOSE 3000

CMD ["node", "dist/server.js"]

.dockerignore

node_modules
npm-debug.log
.git
.env
.DS_Store
*.md
coverage
.vscode

Docker Compose ile Microservices

docker-compose.yml Örneği

version: '3.8'

services:
  # API Gateway
  api-gateway:
    build: ./api-gateway
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - REDIS_URL=redis://redis:6379
    depends_on:
      - redis
      - auth-service
      - user-service
    networks:
      - microservices

  # Auth Service
  auth-service:
    build: ./auth-service
    ports:
      - "3001:3001"
    environment:
      - DATABASE_URL=postgresql://postgres:password@postgres:5432/auth
      - JWT_SECRET=${JWT_SECRET}
    depends_on:
      - postgres
    networks:
      - microservices

  # User Service
  user-service:
    build: ./user-service
    ports:
      - "3002:3002"
    environment:
      - MONGO_URL=mongodb://mongo:27017/users
    depends_on:
      - mongo
    networks:
      - microservices

  # Database - PostgreSQL
  postgres:
    image: postgres:15-alpine
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=auth
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - microservices

  # Database - MongoDB
  mongo:
    image: mongo:6
    environment:
      - MONGO_INITDB_ROOT_USERNAME=admin
      - MONGO_INITDB_ROOT_PASSWORD=password
    volumes:
      - mongo-data:/data/db
    networks:
      - microservices

  # Cache - Redis
  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data
    networks:
      - microservices

  # Message Queue - RabbitMQ
  rabbitmq:
    image: rabbitmq:3-management-alpine
    ports:
      - "5672:5672"
      - "15672:15672"
    environment:
      - RABBITMQ_DEFAULT_USER=admin
      - RABBITMQ_DEFAULT_PASS=password
    volumes:
      - rabbitmq-data:/var/lib/rabbitmq
    networks:
      - microservices

volumes:
  postgres-data:
  mongo-data:
  redis-data:
  rabbitmq-data:

networks:
  microservices:
    driver: bridge

Docker Compose Komutları

# Tüm servisleri başlat
docker-compose up -d

# Belirli bir servisi başlat
docker-compose up -d auth-service

# Logları görüntüle
docker-compose logs -f

# Servisleri durdur ve kaldır
docker-compose down

# Volume'ları da kaldır
docker-compose down -v

# Servisleri yeniden build et
docker-compose build

# Çalışan servisleri listele
docker-compose ps

Microservices Mimarisi

API Gateway Pattern

// api-gateway/server.js
const express = require('express');
const httpProxy = require('http-proxy');

const app = express();
const proxy = httpProxy.createProxyServer();

// Service discovery (basit versiyon)
const services = {
  auth: 'http://auth-service:3001',
  users: 'http://user-service:3002',
  products: 'http://product-service:3003'
};

// Rate limiting
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100
});

app.use(limiter);

// Routing middleware
app.use('/api/auth/*', (req, res) => {
  proxy.web(req, res, { target: services.auth });
});

app.use('/api/users/*', authenticate, (req, res) => {
  proxy.web(req, res, { target: services.users });
});

app.use('/api/products/*', (req, res) => {
  proxy.web(req, res, { target: services.products });
});

// Error handling
proxy.on('error', (err, req, res) => {
  res.status(502).json({ error: 'Service unavailable' });
});

app.listen(3000, () => {
  console.log('API Gateway running on port 3000');
});

Service Communication

REST API ile İletişim

// user-service: Başka servise HTTP isteği
const axios = require('axios');

async function getUserOrders(userId) {
  try {
    const response = await axios.get(
      `http://order-service:3004/api/orders/user/${userId}`,
      {
        headers: {
          'X-Service-Token': process.env.SERVICE_TOKEN
        },
        timeout: 5000
      }
    );
    
    return response.data;
  } catch (error) {
    console.error('Failed to fetch orders:', error.message);
    return []; // Graceful degradation
  }
}

Message Queue ile İletişim

// RabbitMQ kullanarak asenkron iletişim
const amqp = require('amqplib');

class MessageBroker {
  constructor() {
    this.connection = null;
    this.channel = null;
  }
  
  async connect() {
    this.connection = await amqp.connect(
      process.env.RABBITMQ_URL || 'amqp://localhost'
    );
    this.channel = await this.connection.createChannel();
  }
  
  async publish(queue, message) {
    await this.channel.assertQueue(queue, { durable: true });
    this.channel.sendToQueue(
      queue,
      Buffer.from(JSON.stringify(message)),
      { persistent: true }
    );
  }
  
  async subscribe(queue, callback) {
    await this.channel.assertQueue(queue, { durable: true });
    this.channel.consume(queue, async (msg) => {
      if (msg) {
        const content = JSON.parse(msg.content.toString());
        await callback(content);
        this.channel.ack(msg);
      }
    });
  }
}

// Kullanım - Order Service
const broker = new MessageBroker();
await broker.connect();

// Sipariş oluşturulduğunda event yayınla
app.post('/api/orders', async (req, res) => {
  const order = await Order.create(req.body);
  
  // Email servisine bildirim gönder
  await broker.publish('orders.created', {
    orderId: order.id,
    userId: order.userId,
    total: order.total
  });
  
  res.json(order);
});

// Kullanım - Email Service
await broker.subscribe('orders.created', async (data) => {
  await sendOrderConfirmationEmail(data.userId, data.orderId);
});

Docker Networking

Network Türleri

# Bridge network oluştur (default)
docker network create microservices-network

# Servisleri aynı network'e bağla
docker run --network microservices-network api-service

# Network'e bağlı containerları listele
docker network inspect microservices-network

Service Discovery

# docker-compose.yml - DNS tabanlı service discovery
services:
  api:
    networks:
      - backend
  
  database:
    networks:
      - backend

# API servisi, database'e 'database' hostname'i ile erişir
# DATABASE_URL=postgresql://database:5432/mydb

Volume Management

Named Volumes

services:
  postgres:
    image: postgres:15
    volumes:
      # Named volume
      - postgres-data:/var/lib/postgresql/data
      
      # Bind mount (development)
      - ./init-scripts:/docker-entrypoint-initdb.d
      
      # Anonymous volume
      - /var/lib/postgresql/data

volumes:
  postgres-data:
    driver: local

Volume Komutları

# Volume oluştur
docker volume create my-volume

# Volume'ları listele
docker volume ls

# Volume detaylarını görüntüle
docker volume inspect my-volume

# Kullanılmayan volume'ları temizle
docker volume prune

# Backup volume
docker run --rm -v my-volume:/data -v $(pwd):/backup \
  alpine tar czf /backup/my-volume-backup.tar.gz /data

# Restore volume
docker run --rm -v my-volume:/data -v $(pwd):/backup \
  alpine tar xzf /backup/my-volume-backup.tar.gz -C /data

Health Checks

Container Health Check

# Dockerfile
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

Health Endpoint

// Express health endpoint
app.get('/health', async (req, res) => {
  const health = {
    uptime: process.uptime(),
    message: 'OK',
    timestamp: Date.now()
  };
  
  try {
    // Database connection check
    await db.ping();
    health.database = 'connected';
    
    // Redis connection check
    await redis.ping();
    health.cache = 'connected';
    
    res.status(200).json(health);
  } catch (error) {
    health.message = error.message;
    health.database = 'disconnected';
    res.status(503).json(health);
  }
});

Logging ve Monitoring

Centralized Logging

# docker-compose.yml - ELK Stack
services:
  # Elasticsearch
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.8.0
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ports:
      - "9200:9200"
    volumes:
      - elasticsearch-data:/usr/share/elasticsearch/data

  # Logstash
  logstash:
    image: docker.elastic.co/logstash/logstash:8.8.0
    volumes:
      - ./logstash/config:/usr/share/logstash/pipeline
    depends_on:
      - elasticsearch

  # Kibana
  kibana:
    image: docker.elastic.co/kibana/kibana:8.8.0
    ports:
      - "5601:5601"
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
    depends_on:
      - elasticsearch

Application Logging

const winston = require('winston');
require('winston-elasticsearch');

const esTransport = new winston.transports.ElasticsearchTransport({
  level: 'info',
  clientOpts: { node: 'http://elasticsearch:9200' },
  index: 'logs'
});

const logger = winston.createLogger({
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.json()
  ),
  transports: [
    esTransport,
    new winston.transports.Console()
  ]
});

// Kullanım
logger.info('User logged in', {
  userId: user.id,
  service: 'auth-service',
  action: 'login'
});

Security Best Practices

Dockerfile Security

# ❌ YANLIŞ: root user
FROM node:18
WORKDIR /app
COPY . .
RUN npm install
CMD ["node", "server.js"]

# ✅ DOĞRU: non-root user
FROM node:18-alpine

# Non-root user oluştur
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001

WORKDIR /app

# Dependencies önce
COPY package*.json ./
RUN npm ci --only=production

# Uygulama kodu
COPY --chown=nodejs:nodejs . .

# Non-root user'a geç
USER nodejs

EXPOSE 3000
CMD ["node", "server.js"]

Secret Management

# docker-compose.yml - Secrets kullanımı
version: '3.8'

services:
  api:
    image: my-api
    secrets:
      - db_password
      - jwt_secret
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password
      - JWT_SECRET_FILE=/run/secrets/jwt_secret

secrets:
  db_password:
    file: ./secrets/db_password.txt
  jwt_secret:
    file: ./secrets/jwt_secret.txt

Image Scanning

# Trivy ile image taraması
trivy image my-app:latest

# Snyk ile tarama
snyk container test my-app:latest

# Docker Scout
docker scout cves my-app:latest

Production Deployment

Docker Swarm

# Swarm başlat
docker swarm init

# Service deploy et
docker stack deploy -c docker-compose.yml myapp

# Service'leri listele
docker service ls

# Service ölçeklendir
docker service scale myapp_api=5

# Service logları
docker service logs myapp_api

Kubernetes Basics

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: api
        image: myregistry/api:latest
        ports:
        - containerPort: 3000
        env:
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: url
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5

CI/CD Pipeline

# .github/workflows/deploy.yml
name: Build and Deploy

on:
  push:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Build Docker image
        run: docker build -t myapp:${{ github.sha }} .
      
      - name: Run tests
        run: docker run myapp:${{ github.sha }} npm test
      
      - name: Push to registry
        run: |
          echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
          docker push myapp:${{ github.sha }}
      
      - name: Deploy to production
        run: |
          docker-compose -f docker-compose.prod.yml pull
          docker-compose -f docker-compose.prod.yml up -d

CodeBros Docker Hizmetleri

CodeBros olarak containerization ve microservices konusunda:

Architecture Design: Microservices mimarisi tasarımı ✅ Docker Setup: Dockerfile ve Compose yapılandırması ✅ CI/CD Pipeline: Otomatik build ve deployment ✅ Kubernetes: Production-ready K8s cluster'ları ✅ Monitoring: Logging ve monitoring altyapısı ✅ Security: Container güvenliği ve best practices

Sonuç

Docker ve containerization, modern uygulama geliştirmede temel bir beceridir. Bu rehberdeki bilgilerle, production-ready microservices uygulamaları geliştirebilirsiniz.

Docker ve DevOps hizmetlerimiz için iletişime geçin!


Etiketler: #Docker #Microservices #DevOps #Containers #Kubernetes #CloudNative #CodeBros

K
CodeBros
CodeBros - Profesyonel Yazılım Geliştirme Şirketi
Paylaş:
WhatsApp
WhatsApp