İçeriğe atla

Vercel Alternatifleri: Next.js Deployment Kapsamlı Rehberi

Vercel dışında Next.js deploy etmenin kapsamlı rehberi: her hedef platform için maliyet profili, implementasyon detayları ve migration yolu.

Ayhan Sipahi Ayhan Sipahi

Vercel, Next.js için en pürüzsüz deployment deneyimini sunar; ama fatura trafikten daha hızlı büyür. Bandwidth aşımları GB başına $0.15’e gelir ve function invocation’lar sessizce birikir; tek bir marketing zirvesi, tam da dönüşümlerin en kritik olduğu anda maliyeti katlayabilir. Deployment’ı kolaylaştıran platforma özel API’ler, aynı zamanda ileride taşınmayı zorlaştıran bir lock-in yaratır.

Çoğu Next.js uygulaması için ilk denenecek varsayılan, OpenNext adapter’ıyla Cloudflare Workers: bandwidth ölçülmüyor ve adapter uygulamayı taşınabilir tutuyor. Bu varsayılanın yetmediği durumları AWS üzerinde SST ve CDN arkasındaki Docker VPS karşılıyor. Her hedefin kendi maliyet profili ve dokümantasyonun atladığı kendi migration detayları var.

Ekipler Neden Vercel’in Ötesine Bakıyor#

Vercel mükemmel bir geliştirici deneyimi sunsa da birkaç faktör ekipleri alternatifleri keşfetmeye yönlendiriyor:

  1. Vendor Lock-in Endişeleri: Vercel’in platforma özel API’leri ve deployment pattern’leri gelecekteki migration’ları zorlaştıran bağımlılıklar yaratıyor. Ekipler kendilerini diğer platformlara tercüme edilemeyen proprietary özelliklere bağlı buluyor.

  2. Tek Nokta Bağımlılığı: Kritik altyapı için tek bir vendor’a güvenmek risk yaratıyor. Vercel kesinti yaşadığında veya fiyatlandırma modelini değiştirdiğinde, ekiplerin sınırlı seçenekleri oluyor.

  3. Ölçekte Maliyet: Dahil edilen kotanın üstündeki bandwidth GB başına $0.15 (terabayt başına $150) faturalanıyor ve function invocation’lar bunun üstüne ekleniyor. Trafik zirveleri bu yüzden hem faturayı hem de plan limitlerini aynı anda zorluyor. Planın nerede tavan yaptığını kampanya daha planlama aşamasındayken kontrol etmekte fayda var.

Kararı etkileyen ek faktörler:

  • Belirli bölgesel uyumluluk veya veri yerleşimi ihtiyacı
  • Mevcut cloud altyapı yatırımlarından yararlanma arzusu
  • Özel caching kuralları veya deployment yapılandırması gereksinimleri
  • Vercel’in fiyatlandırma kademelerine uymayan bütçe kısıtlamaları

Deployment Seçeneklerini Değerlendirme#

Hedefi dört eksen belirliyor: feature desteği, maliyet yapısı, performans ihtiyaçları ve kurulumu işletecek ekibin kapasitesi.

Deployment Gereksinimleri

Feature Destegi

Maliyet Yapisi

Performans Ihtiyaclari

Ekip Yetenekleri

SSR/ISR Destegi

API Routes

Middleware

Image Optimization

Sabit vs Kullanim

Bandwidth Maliyetleri

Compute Fiyatlandirma

Global Dagitim

Cold Start Sureleri

Cache Stratejisi

DevOps Deneyimi

Bakim Kapasitesi

Platform Asinaligi

Yönetilen Platform Alternatifleri#

AWS Amplify - Enterprise-Ready Seçim#

AWS Amplify, Next.js deployment’ları için önemli ölçüde olgunlaştı. İşte bir production yapılandırması:

# amplify.yml
version: 1
frontend:
  phases:
    preBuild:
      commands:
        - npm ci --cache .npm --prefer-offline
        # Sharp/image optimization için fix
        - npm install --os=linux --cpu=x64 sharp
    build:
      commands:
        - npm run build
  artifacts:
    baseDirectory: .next
    files:
      - '**/*'
  cache:
    paths:
      - .npm/**/*
      - node_modules/**/*

# Özel cache yapılandırması
customHeaders:
  - pattern: '**/*'
    headers:
      - key: 'Cache-Control'
        value: 'public, max-age=31536000, immutable'
  - pattern: '**/*.html'
    headers:
      - key: 'Cache-Control'
        value: 'public, max-age=0, must-revalidate'

Önemli Uygulama Detayları:

  • Build dakikaları her biri $0.01 (tipik build’ler: 2-4 dakika)
  • Bandwidth fiyatlandırması: 15GB ücretsiz katmandan sonra $0.15/GB
  • Çok sayıda redirect destekler, ancak binlerce kural ile konsol performansı düşüyor
  • Pull request’ler için otomatik branch deployment’ları

Pratikte Karşılaşılan Tuzak: Redirect konsol performans sorunu dokümante edilmemiş. Bu, 2.000+ redirect’li eski uygulamaları migrate ederken belirgin hale geliyor. Çözüm? Redirect’leri middleware kullanarak uygulama seviyesinde gerçekleştirmek:

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

// Redirect'leri JSON dosyasından veya veritabanından yükle
import redirects from './redirects.json';

export function middleware(request: NextRequest) {
  const pathname = request.nextUrl.pathname;

  // Pathname'in redirect'e ihtiyacı var mı kontrol et
  const redirect = redirects[pathname];
  if (redirect) {
    return NextResponse.redirect(
      new URL(redirect.destination, request.url),
      redirect.permanent ? 308 : 307
    );
  }

  return NextResponse.next();
}

export const config = {
  matcher: '/((?!api|_next/static|_next/image|favicon.ico).*)',
};

Cloudflare Workers - Düşük Maliyetli Varsayılan#

OpenNext adapter’ıyla Cloudflare şaşırtıcı derecede yetenekli hale geldi. Uygulama için iki yaklaşım var ve ikisi farklı ürünü hedefliyor:

Seçenek 1: Pages’te Sadece Edge Runtime (Sınırlı ama Hızlı)

npm install @cloudflare/next-on-pages

Seçenek 2: Workers’ta Tam Node.js Desteği (Önerilen)

npm install @opennextjs/cloudflare

OpenNext kullanarak production-ready yapılandırma:

// next.config.mjs
import { initOpenNextCloudflareForDev } from '@opennextjs/cloudflare';

const nextConfig = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**.cloudinary.com',
      },
    ],
  },
};

export default nextConfig;

// Cloudflare binding'lerini `next dev` için erişilebilir yapar
initOpenNextCloudflareForDev();
# wrangler.toml
name = "nextjs-production"
main = ".open-next/worker.js"
# nodejs_compat için compatibility date 2024-09-23 veya sonrası olmalı
compatibility_date = "2024-09-23"
compatibility_flags = ["nodejs_compat"]

[assets]
directory = ".open-next/assets"
binding = "ASSETS"

[vars]
ENVIRONMENT = "production"

[[d1_databases]]
binding = "DB"
database_name = "production"
database_id = "your-database-id"

[[kv_namespaces]]
binding = "CACHE"
id = "your-kv-namespace-id"

Adapter bir Pages projesi değil, bir Worker üretiyor. Deployment opennextjs-cloudflare build ve opennextjs-cloudflare deploy üzerinden yürüyor.

Maliyet Analizi:

  • Bandwidth: hacimden bağımsız olarak ölçülmüyor
  • Request’ler: Workers ücretsiz katmanında günde 100.000
  • Bu sınırın üstünde: aylık $5’ten başlayan Workers Paid planı
  • Düşük trafikli bir uygulama için toplam aylık maliyet: $0

Netlify - Geliştirici Dostu Orta Yol#

Netlify’ın Next.js desteği önemli ölçüde gelişti. Karmaşık gereksinimleri ele alan bir yapılandırma:

# netlify.toml
[build]
  command = "npm run build"
  publish = ".next"

[[plugins]]
  package = "@netlify/plugin-nextjs"

[build.environment]
  NEXT_USE_NETLIFY_EDGE = "true"
  NETLIFY_NEXT_PLUGIN_SKIP = "false"

# API route'lar için function yapılandırması
[functions]
  directory = "netlify/functions"
  included_files = ["data/**"]

# Splat destekli redirect kuralları
[[redirects]]
  from = "/old-blog/*"
  to = "/posts/:splat"
  status = 301
  force = true

# Güvenlik için özel header'lar
[[headers]]
  for = "/*"
  [headers.values]
    X-Frame-Options = "DENY"
    X-Content-Type-Options = "nosniff"
    X-XSS-Protection = "1; mode=block"

Netlify’ın yerleşik form handling özelliği Next.js ile üçüncü parti bir servise ihtiyaç duymadan çalışır; lead toplayan sitelerde bu bir hareketli parçayı ortadan kaldırır. Diğer platformlarda aynı iş için dışarıda bir endpoint gerekir.

Self-Hosting Çözümleri - Maksimum Kontrol#

AWS’de SST - Tam AWS Erişimiyle Serverless#

SST (eskiden Serverless Stack), Next.js için en iyi serverless deployment deneyimini sağlar. Tam bir production kurulumu:

// sst.config.ts
import { SSTConfig } from "sst";
import { NextjsSite, Bucket, Table } from "sst/constructs";

export default {
  config(_input) {
    return {
      name: "nextjs-production",
      region: "us-east-1",
    };
  },
  stacks(app) {
    app.stack(function Site({ stack }) {
      // Session storage için DynamoDB
      const table = new Table(stack, "sessions", {
        fields: {
          sessionId: "string",
        },
        primaryIndex: { partitionKey: "sessionId" },
      });

      // Upload'lar için S3
      const bucket = new Bucket(stack, "uploads", {
        cors: [
          {
            maxAge: "1 day",
            allowedOrigins: ["*"],
            allowedHeaders: ["*"],
            allowedMethods: ["GET", "PUT", "POST", "DELETE", "HEAD"],
          },
        ],
      });

      // Next.js sitesi
      const site = new NextjsSite(stack, "site", {
        customDomain: {
          domainName: "example.com",
          hostedZone: "example.com",
        },
        environment: {
          DATABASE_URL: process.env.DATABASE_URL,
          SESSION_TABLE_NAME: table.tableName,
          UPLOAD_BUCKET_NAME: bucket.bucketName,
        },
        bind: [table, bucket],
        // Performans optimizasyonları
        memorySize: 1024,
        timeout: "30 seconds",
        // Bölgesel yapılandırma
        regional: {
          enableServerUrlIamAuth: true,
        },
      });

      stack.addOutputs({
        SiteUrl: site.url,
        CloudFrontUrl: site.cdk.distribution.distributionDomainName,
      });
    });
  },
} satisfies SSTConfig;

Ayda 1M request için maliyet dağılımı:

  • Lambda: ~$20 (free tier dahil)
  • CloudFront: Bandwidth için ~$10
  • S3: Storage için ~$1
  • Toplam: ~$31/ay

Docker + VPS - Sabit Maliyetli Kurulum#

Sunucu yönetiminde rahat olan ekipler için, Hetzner veya DigitalOcean’da self-hosting rakipsiz değer sağlar. Production-grade Docker kurulumu:

# Dockerfile
# Dependencies
FROM node:20-alpine AS deps
RUN apk add --no-cache libc6-compat
WORKDIR /app

# Lockfile'a göre dependency'leri yükle
COPY package.json package-lock.json* ./
RUN \
  if [ -f package-lock.json ]; then npm ci --omit=dev; \
  else echo "Lockfile bulunamadı." && exit 1; \
  fi

# Builder
FROM node:20-alpine AS builder
RUN apk add --no-cache libc6-compat
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .

# Uygulamayı build et
ENV NEXT_TELEMETRY_DISABLED 1
RUN npm run build

# Runner
FROM node:20-alpine AS runner
WORKDIR /app

ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1

# Non-root kullanıcı oluştur
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs

# Build edilmiş uygulamayı kopyala
COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs
EXPOSE 3000
ENV PORT 3000

CMD ["node", "server.js"]
# docker-compose.yml
version: '3.8'

services:
  nextjs:
    build: .
    restart: unless-stopped
    environment:
      - NODE_ENV=production
      - DATABASE_URL=${DATABASE_URL}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - app-network

  nginx:
    image: nginx:alpine
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro
      - ./nginx/ssl:/etc/nginx/ssl:ro
      - ./nginx/cache:/var/cache/nginx
    depends_on:
      - nextjs
    networks:
      - app-network

  # Opsiyonel: Caching için Redis
  redis:
    image: redis:alpine
    restart: unless-stopped
    command: redis-server --appendonly yes
    volumes:
      - redis-data:/data
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  redis-data:

Production için Nginx Yapılandırması:

# nginx.conf
upstream nextjs {
    server nextjs:3000;
}

server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com;

    ssl_certificate /etc/nginx/ssl/cert.pem;
    ssl_certificate_key /etc/nginx/ssl/key.pem;

    # Güvenlik header'ları
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-XSS-Protection "1; mode=block" always;

    # Statik asset'leri cache'le
    location /_next/static {
        proxy_pass http://nextjs;
        proxy_cache_valid 365d;
        add_header Cache-Control "public, immutable";
    }

    # Image'leri cache'le
    location /_next/image {
        proxy_pass http://nextjs;
        proxy_cache_valid 365d;
        add_header Cache-Control "public, max-age=31536000, immutable";
    }

    # Geri kalan her şey
    location / {
        proxy_pass http://nextjs;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        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;
    }
}

Platform-as-a-Service - Coolify ve Alternatifler#

Coolify, Vercel’e güçlü bir self-hosted alternatif olarak ortaya çıktı. Temiz bir VPS’e kurulum:

# Ubuntu/Debian'a Coolify kurulumu
curl -fsSL https://coolify.io/install.sh | bash

Repoya eklenecek bir yapılandırma dosyası yok. Coolify repoyu okuyor; build komutunu, start komutunu, açılacak portu, health-check yolunu ve environment değişkenlerini kendi arayüzünden soruyor. Uygulama başına CPU ve bellek limitleri de aynı yerden ayarlanıyor; tek bir VPS’in birden fazla müşteri projesini, yoğun bir site makineyi devirmeden barındırmasını sağlayan şey bu.

Maliyet Karşılaştırması#

Platformların yayımlanmış fiyatlarına göre üç trafik seviyesindeki aylık maliyet profili:

Note

Bunlar liste fiyatlarından çıkarılmış tahminlerdir. Gerçek fatura ayrıca request hacmi, function süresi ve bölgeye göre değişir.

PlatformKüçük Uygulama (10GB/ay)Orta Uygulama (500GB/ay)Büyük Uygulama (2TB/ay)Notlar
Vercel$20$80$320Tahmin edilebilir ama ölçekte pahalı
Netlify$0 (free tier)$20$95+Vercel’den daha iyi tahmin edilebilirlik
Cloudflare Workers$0$0~$5Bandwidth ölçülmüyor; ücretsiz request sınırının üstünde Workers Paid
AWS Amplify~$5~$30~$70Kullandıkça öde modeli
Hetzner + CloudflareEUR3.79EUR3.79EUR3.79Trafikten bağımsız sabit maliyet
AWS’de SST~$10~$20-40~$50-100Kullanım paternlerine göre değişir
DigitalOcean Apps$5$25$100Basit fiyatlandırma yapısı

Migration Stratejisi - Hafta Hafta Geçiş Planı#

Hafta 1 - Değerlendirme ve Planlama#

Vercel panelindeki kullanım sayfasından başlayın ve aylık üç sayıyı kaydedin: sunulan bandwidth, function invocation sayısı ve build dakikası. Faturanın büyük kısmını bu üçü belirliyor; alternatif platformların fiyatlandırdığı girdiler de aynı. Sakin bir ayın baseline’ı belirlememesi için son bir ayı değil son üç ayı alın. Zirve günü ayrıca not edin; ücretsiz request sınırının yetip yetmeyeceğine zirve karar veriyor.

Hafta 2 - Proof of Concept#

Seçtiğiniz platforma minimal bir versiyon deploy edin:

# Örnek: Cloudflare Workers deployment'ını test etme
npx create-next-app@latest test-deployment
cd test-deployment

# OpenNext adapter'ı ekle
npm install @opennextjs/cloudflare

# Yapılandır, build al ve deploy et
npx opennextjs-cloudflare build
npx opennextjs-cloudflare deploy

Hafta 3 - Production Hazırlığı#

Monitoring ve observability’yi uygulayın:

// lib/monitoring.ts
import { metrics } from '@opentelemetry/api-metrics';

const meter = metrics.getMeter('nextjs-app', '1.0.0');

// Özel metrikler oluştur
const requestDuration = meter.createHistogram('http_request_duration', {
  description: 'HTTP request süresi milisaniye cinsinden',
  unit: 'ms',
});

const deploymentCost = meter.createGauge('deployment_cost', {
  description: 'Tahmini deployment maliyeti USD cinsinden',
  unit: 'USD',
});

export function trackRequest(route: string, duration: number) {
  requestDuration.record(duration, { route });
}

export function updateCost(platform: string, cost: number) {
  deploymentCost.record(cost, { platform });
}

Hafta 4 - Migration ve Doğrulama#

Rollback stratejisiyle migration’ı gerçekleştirin:

# .github/workflows/deploy-with-rollback.yml
name: Deploy with Rollback

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3

      - name: Mevcut deployment'ı yedekle
        run: |
          # Rollback için mevcut deployment bilgisini kaydet
          echo ${{ github.sha }} > .last-known-good

      - name: Yeni platforma deploy et
        run: |
          # Deployment komutlarınız burada
          npm run deploy:production

      - name: Health check
        id: health
        run: |
          # Deployment'ın sağlıklı olduğunu doğrula
          curl -f https://your-app.com/api/health || exit 1

      - name: Başarısızlıkta rollback
        if: failure()
        run: |
          # Önceki versiyona geri dön
          LAST_GOOD=$(cat .last-known-good)
          npm run deploy:rollback $LAST_GOOD

Yaygın Tuzaklar ve Çözümler#

Sharp/Image Optimization Zorluğu#

Neredeyse her platform Next.js image optimization ile zorlanıyor. Evrensel çözüm:

// next.config.js
module.exports = {
  images: {
    loader: 'custom',
    loaderFile: './lib/image-loader.js',
  },
};

// lib/image-loader.js
export default function cloudinaryLoader({ src, width, quality }) {
  const params = ['f_auto', 'c_limit', `w_${width}`, `q_${quality || 'auto'}`];
  const paramsString = params.join(',');
  return `https://res.cloudinary.com/your-cloud-name/image/upload/${paramsString}/${src}`;
}

Environment Variable Yönetimi#

Farklı platformlar environment variable’ları farklı şekilde ele alır. Birleşik bir yaklaşım:

// lib/config.ts
interface Config {
  database: {
    url: string;
    poolSize: number;
  };
  redis: {
    url: string;
  };
  platform: 'vercel' | 'amplify' | 'cloudflare' | 'self-hosted';
}

function detectPlatform(): Config['platform'] {
  if (process.env.VERCEL) return 'vercel';
  if (process.env.AWS_REGION) return 'amplify';
  if (globalThis.navigator?.userAgent === 'Cloudflare-Workers') return 'cloudflare';
  return 'self-hosted';
}

export const config: Config = {
  database: {
    url: process.env.DATABASE_URL!,
    poolSize: detectPlatform() === 'self-hosted' ? 20 : 1,
  },
  redis: {
    url: process.env.REDIS_URL || 'redis://localhost:6379',
  },
  platform: detectPlatform(),
};

ISR Cache Davranış Farklılıkları#

Incremental Static Regeneration platformlar arasında farklı davranır:

// pages/api/revalidate.ts
import { NextApiRequest, NextApiResponse } from 'next';

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse
) {
  const { path, platform } = req.query;

  try {
    switch (platform) {
      case 'vercel':
        await res.revalidate(path as string);
        break;

      case 'cloudflare':
        // Cloudflare KV-tabanlı revalidation
        await fetch(`https://api.cloudflare.com/client/v4/zones/${process.env.CF_ZONE}/purge_cache`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${process.env.CF_TOKEN}`,
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            files: [`https://example.com${path}`],
          }),
        });
        break;

      case 'aws':
        // CloudFront invalidation
        const cloudfront = new AWS.CloudFront();
        await cloudfront.createInvalidation({
          DistributionId: process.env.CF_DISTRIBUTION_ID,
          InvalidationBatch: {
            CallerReference: Date.now().toString(),
            Paths: {
              Quantity: 1,
              Items: [path as string],
            },
          },
        }).promise();
        break;
    }

    res.status(200).json({ revalidated: true });
  } catch (err) {
    res.status(500).json({ error: 'Revalidation başarısız' });
  }
}

Performans Dengeleri#

Gecikmeyi platformun pazarlama dili değil, kodun nerede çalıştığı belirliyor. Edge lokasyonunda yanıtlanan bir request, tek bir origin bölgesine giden request’i geçer. Sıfıra inmeyen bir container’ın ödeyeceği cold start yoktur. Önünde CDN olmayan bir VPS ise sunucudan uzaktaki kullanıcılar için en yavaş seçenektir ve bu fark yükle değil mesafeyle birlikte açılır.

Hedefleri karşılaştırırken akılda tutulacak üç nokta var:

  • Self-hosted her kurulumun önüne CDN koyun. CDN yoksa sabit maliyet avantajı, uzak kullanıcılar için gecikme cezasıyla birlikte gelir.
  • “Sıfır cold start” iddiaları runtime’ın isolate başlangıcını anlatır, uygulamanın kendi başlatma süresini değil. Ağır bir modül grafiği ve yeni bir veritabanı bağlantısı ilk request’te hâlâ zaman harcar.
  • Cold start en çok, düşük trafikli ama gecikmeye duyarlı route’larda hissedilir. Uygulamada böyle route’lar varsa sürekli sıcak bir container bu değişkeni ayarlamak yerine tamamen ortadan kaldırır.

Karar vermeden önce adayı kendi route’larınızla ölçün. Yayımlanan sayılar başkasının modül grafiğini anlatır.

Use Case’e Göre Öneriler#

Startup’lar ve MVP’ler için#

Öneri: OpenNext ile Cloudflare Workers

  • Sıfır bandwidth maliyeti büyük bir ölçekleme endişesini ortadan kaldırır
  • Free tier çoğu startup trafiğini karşılar
  • Ek kurulum gerektirmeyen global performans

Enterprise Uygulamalar için#

Öneri: AWS’de SST

  • Tam AWS servis entegrasyonu
  • Uyumluluk için infrastructure as code
  • Reserved capacity ile tahmin edilebilir maliyetler

Yüksek Trafikli İçerik Siteleri için#

Öneri: Cloudflare CDN ile self-hosted

  • Trafikten bağımsız sabit aylık maliyetler
  • Caching stratejisi üzerinde tam kontrol
  • Vendor lock-in yok

Ajanslar ve Freelancer’lar için#

Öneri: Hetzner’da Coolify

  • Bir VPS’te sınırsız müşteri projesi barındırın
  • Müşteriler için basit deployment arayüzü
  • Sunucu başına EUR3.79/ay ile uygun maliyetli

Migration Dersleri#

İleride platform değiştirmeyi ucuz tutan dört alışkanlık:

OpenNext Uyumluluğu ile Başlayın: Uygulamanızı ilk günden OpenNext ile çalışacak şekilde tasarlayın. Bu, kod değişikliği olmadan platform geçişleri için maksimum esneklik sağlar.

Platform-Agnostic Monitoring Uygulayın: Platform-specific çözümler yerine OpenTelemetry veya benzer vendor-neutral observability araçlarını kullanın. Bu, migration’ları çok daha sorunsuz hale getirir.

Maliyet Takibini Erken Oluşturun: Baştan itibaren maliyet takibi uygulayın:

// lib/cost-tracker.ts
class DeploymentCostTracker {
  private costs: Map<string, number> = new Map();

  track(service: string, amount: number) {
    const current = this.costs.get(service) || 0;
    this.costs.set(service, current + amount);
  }

  async reportDaily() {
    const total = Array.from(this.costs.values()).reduce((a, b) => a + b, 0);

    // Monitoring servisine gönder
    await fetch('/api/metrics', {
      method: 'POST',
      body: JSON.stringify({
        date: new Date().toISOString(),
        costs: Object.fromEntries(this.costs),
        total,
      }),
    });

    // Sonraki gün için sıfırla
    this.costs.clear();
  }
}

Multi-Platform Deployment için Tasarlayın: Birden fazla platform için deployment yapılandırmalarını koruyun. Bu, vendor’larla pazarlık gücü ve hızlı disaster recovery seçenekleri sağlar.

Varsayılanı Seçmek#

İlk denenmeye değer seçenek, OpenNext ile Cloudflare Workers. Bandwidth ölçülmüyor, ücretsiz request sınırı çoğu lansmanı karşılıyor ve adapter uygulamayı taşınabilir tutuyor.

Bu varsayılanı iki durum geçersiz kılıyor. Uygulama, aynı hesap ve IAM sınırı içinde durması gereken AWS servislerine yaslanıyorsa SST siteyi ve bağımlılıklarını tek bir deployment’ta topluyor. Trafik, sabit sunucu faturasını request başına fiyatlandırmanın önüne geçirecek kadar yoğun ve düzenliyse CDN arkasındaki Docker VPS hem maliyette hem kontrolde kazanıyor.

Vercel’de kalmak da savunulabilir bir karar. Operasyon bütçesi yoksa ve trafik plana sığıyorsa migration işi faturadan daha pahalıya geliyor. Hesap, bandwidth ve invocation’lar dahil kotanın dışına çıktığında değişiyor; kararı o noktada yeniden gözden geçirin.

Kaynaklar#

İlgili yazılar