Şimdiye kadar Dockerfile yazmayı, Compose ile çoklu servis yönetmeyi, volume’leri, networking’i, registry’i, CI/CD’yi ve izlemeyi tek tek gördük. Bu yazıda hepsini bir araya getirip, basit bir Node.js API’sini sıfırdan alıp gerçekçi bir production kurulumuna taşıyoruz — bu portaldaki tüm konuların birleştiği uçtan uca bir referans.

Proje: küçük bir görev listesi API’si

Node.js/Express ile yazılmış, PostgreSQL’e bağlanan basit bir REST API’miz olduğunu varsayalım. Klasör yapımız şöyle:

benim-api/
├── src/
│   └── server.js
├── package.json
├── Dockerfile
├── .dockerignore
└── docker-compose.yml

1. Adım: Multi-stage, güvenli bir Dockerfile

Önceki yazılarda gördüğümüz iyi pratikleri (küçük taban imaj, root olmayan kullanıcı, sabit sürüm etiketi, health check) tek bir Dockerfile’da birleştiriyoruz:

FROM node:20.15.1-alpine3.20 AS base
WORKDIR /app
COPY package*.json ./

FROM base AS deps
RUN npm ci --production

FROM base AS runtime
COPY --from=deps /app/node_modules ./node_modules
COPY src/ ./src

RUN addgroup -S uygulama && adduser -S uygulama -G uygulama
USER uygulama

EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD wget -q -O- http://localhost:3000/saglik || exit 1

CMD ["node", "src/server.js"]
# .dockerignore
node_modules
.git
.env
*.log

2. Adım: Compose ile API + veritabanı + reverse proxy

Volume’ler kalıcı veriyi, servis isimleri (network) container’lar arası iletişimi, depends_on başlatma sırasını yönetir:

services:
  api:
    build: .
    environment:
      DB_HOST: db
      DB_PASSWORD: ${DB_PASSWORD}
    depends_on:
      - db
    restart: unless-stopped

  db:
    image: postgres:16.3-alpine
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - pg_data:/var/lib/postgresql/data
    restart: unless-stopped

  proxy:
    image: nginx:1.27-alpine
    ports:
      - "443:443"
      - "80:80"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - api
    restart: unless-stopped

volumes:
  pg_data:

Veritabanı portu (5432) dışarıya hiç açılmıyor — sadece api servisi, aynı Compose ağı üzerinden db ismiyle erişebiliyor. Dışarıdan gelen tüm trafik proxy (Nginx) üzerinden geçiyor; bu hem TLS sonlandırmayı tek yerde toplar hem de API’yi doğrudan internete açmaz.

✓

Şifreler ve gizli değerler (DB_PASSWORD) doğrudan docker-compose.yml‘a yazılmadı — bir .env dosyasından okunuyor (${DB_PASSWORD}). .env dosyasını .gitignore‘a eklemeyi unutmayın.

3. Adım: CI/CD ile otomatik build, tarama ve push

Önceki “CI/CD ile Docker” yazımızdaki pipeline’ı bu projeye uygularsak: kod main‘e push edilince imaj build edilir → Trivy ile taranır → geçerse çok mimarili (amd64 + arm64) olarak registry’e gönderilir → sunucuda otomatik çekilip devreye alınır. Tüm bu adımlar tek bir .github/workflows/deploy.yml dosyasında birleşir; her adımın detayını ilgili yazılarımızda bulabilirsiniz.

4. Adım: Sunucuda devreye alma

# Sunucuda ilk kurulum
git clone https://github.com/kullanici-adi/benim-api.git
cd benim-api
echo "DB_PASSWORD=guclu-bir-parola" > .env
docker compose up -d

# CI/CD her yeni sürümde bu adımı otomatik çalıştırır
docker compose pull
docker compose up -d --no-deps --build api

5. Adım: Sağlığı ve kaynak kullanımını izleme

# Hızlı, tek sunuculuk kontrol
docker compose ps        # health check durumları burada görünür
docker stats
docker compose logs -f api

Trafik büyüdükçe, “Container İzleme ve Loglama” yazımızda anlattığımız cAdvisor + Prometheus + Grafana üçlüsünü aynı docker-compose.yml‘a birer servis olarak eklemek, tek komutla (docker compose up -d) tüm izleme yığınını da ayağa kaldırır.

Tüm parçaların birbirine bağlandığı yer

İhtiyaç Kullanılan araç/kavram
Küçük, güvenli imaj Multi-stage Dockerfile, alpine taban imaj, USER, HEALTHCHECK
Kalıcı veri Named volume (pg_data)
Servisler arası iletişim Compose’un otomatik oluşturduğu ağ, servis ismiyle DNS
Dış dünyaya güvenli erişim Nginx reverse proxy, sadece 80/443 dışarı açık
İmaj dağıtımı GitHub Container Registry / Docker Hub
Otomasyon GitHub Actions: build → tara → push → deploy
Çoklu donanım desteği Buildx ile linux/amd64,linux/arm64
Sağlık ve gözlemlenebilirlik HEALTHCHECK, docker stats, Prometheus + Grafana

Bu portaldaki her yazı, burada bir araya gelen parçalardan birini derinlemesine ele alıyor. Kendi projeniz için bu şablonu başlangıç noktası olarak kullanabilir, ihtiyacınıza göre (Kubernetes’e geçiş, çoklu bölge dağıtımı, otomatik ölçekleme gibi) üzerine katman katman ekleyebilirsiniz.