Docker ve Container Mimarisi ile Web Uygulaması Dağıtım Rehberi
Modern web projelerinde Docker ve container mimarisi ile sıfır kesintili, güvenli ve ölçeklenebilir web uygulaması dağıtımı (deployment) adımları.
Sistem Yöneticisi
Kıdemli Yazılım Mimarı
Giriş: Modern Web Dağıtımında Container Standardı
Farklı sunucularda çalışan modern web uygulamalarında ortam uyuşmazlığı sorununu çözmenin kesin yolu container mimarisidir. Bir dijital ajans veya yazılım ekibi için geliştirme, test ve canlı sunucu paritesini sağlamak kritik gereksinimdir. Güncel DevOps trendleri, monolitik yapılardan izole container yapılarına geçişi zorunlu kılar. Bu rehber, Docker ile üretime hazır deployment adımlarını kapsar.
Adım 1: Optimize Edilmiş Dockerfile Hazırlığı
Gereksiz katmanları ve bağımlılıkları üretim imajından ayırmak için Multi-Stage Build kullanın. Boyut küçülür, güvenlik açıkları azalır.
# Build aşaması
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Üretim aşaması
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
USER node
EXPOSE 3000
CMD ["node", "dist/main.js"]Kritik kural: Container içinde uygulamayı kesinlikle root kullanıcısıyla çalıştırmayın. USER node veya özel kullanıcı tanımlayın.
Adım 2: docker-compose ile Servis Tanımlama
Web uygulaması, veritabanı ve reverse proxy (Nginx) servislerini tek dosyada izole ağ (bridge network) üzerinde yapılandırın.
version: '3.8'
services:
web:
build:
context: .
dockerfile: Dockerfile
restart: always
environment:
- PORT=3000
- DATABASE_URL=postgres://user:pass@db:5432/app_db
depends_on:
db:
condition: service_healthy
networks:
- internal_net
db:
image: postgres:16-alpine
restart: always
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: app_db
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d app_db"]
interval: 5s
timeout: 5s
retries: 5
networks:
- internal_net
volumes:
pgdata:
networks:
internal_net:
driver: bridgeAdım 3: Reverse Proxy ve SSL Konfigürasyonu
Trafik doğrudan uygulama portuna yönlendirilmez. Nginx veya Traefik reverse proxy arkasına alınır. Nginx konfigürasyon örneği:
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
location / {
proxy_pass http://web:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Adım 4: CI/CD Pipeline ile Otomatik Deployment
Sunucuya manuel SSH bağlantısı yerine GitHub Actions üzerinden otomatik build ve deploy adımı kurgulayın:
- Koddaki testleri çalıştır.
- Docker imajını derle ve Docker Registry (GHCR/Docker Hub) üzerine push et.
- Canlı sunucuya SSH ile bağlanıp yeni imajı çek ve container'ı güncelle:
docker compose pull web
docker compose up -d --no-deps --build web
docker image prune -fSıfır Kesinti (Zero-Downtime) İpucu: Tek sunucuda güncelleme yaparken kesintiyi önlemek için healthcheck mekanizması aktif edilmeli ve yeni container ayağa kalkmadan eskisi silinmemelidir.
Üretim Ortamı Kontrol Listesi
- Hassas Bilgiler:
.envdosyalarını git repolarına göndermeyin, Docker Secrets veya ortam değişkenleri kullanın. - Log Yönetimi: Disk dolmasını önlemek için Docker daemon'da
json-filelog rotasyonu tanımlayın (max-size: "10m",max-file: "3"). - Kaynak Sınırları: OOM (Out of Memory) çökmelerini engellemek için Compose içinde
cpusvememorylimitleri belirleyin. - İmaj Güvenliği: Trivy gibi araçlarla base imajdaki CVE güvenlik açıklarını düzenli tarayın.