Next.js + Django'yu Aynı Origin'de, CORS Derdi Olmadan
Next.js frontend'i ile Django backend'ini ayrı servisler olarak çalıştırdığınızda karşınıza hemen CORS (Cross-Origin Resource Sharing) sorunu çıkar. localhost:3000 üzerinde çalışan frontend, localhost:8000'deki API'ye istek attığında tarayıcı bunu farklı bir origin olarak görür ve ekstra header yapılandırması gerektirir. Production'da bu daha da karmaşıklaşır: CORS ayarları, cookie'lerin SameSite davranışı, ve iki ayrı domain/subdomain yönetimi.
Çözüm: Tek origin, nginx ile
Bir havalimanı transfer sitesi için kurduğum mimaride bu sorunu kökten çözdüm: nginx'i tek giriş noktası yaparak hem Next.js'i hem Django'yu aynı origin üzerinden servis ettim.
server {
listen 80;
location /api/ {
proxy_pass http://backend:8000;
proxy_set_header Host $host;
}
location /custom-admin-path/ {
proxy_pass http://backend:8000;
}
location / {
proxy_pass http://frontend:3000;
}
}Tarayıcı açısından tek bir domain var: /api ile başlayan her şey Django'ya, admin path'i Django admin paneline, geri kalan her şey Next.js'e gidiyor. CORS header'ı yazmaya hiç gerek kalmıyor çünkü tarayıcı zaten hepsinin aynı origin'den geldiğini görüyor.
Admin path'ini gizlemek
Django admin panelinin varsayılan /admin/ yolunu kullanmak, botların brute-force denemeleri için ilk hedef oluyor. Bunun yerine tahmin edilemez bir path kullanıyorum:
# config/urls.py
urlpatterns = [
path("custom-admin-path/", admin.site.urls),
# ...
]Bu, gerçek bir güvenlik katmanı değil ama otomatik tarama botlarının büyük kısmını eleyen ucuz ve etkili bir önlem.
Docker Compose ile bir araya getirmek
Üç servis (frontend, backend, nginx) docker-compose.yml içinde tanımlanıyor; nginx dışarıya tek port açıyor, diğer ikisi sadece iç ağda konuşuyor. Bunun üzerine veritabanı ve sır yönetimi eklenmiş tam bir production kurulumu için Docker Compose ile Next.js + Django production kurulumu yazısına bakabilirsiniz:
services:
frontend:
build: ./frontend
expose:
- "3000"
backend:
build: ./backend
expose:
- "8000"
nginx:
image: nginx:alpine
ports:
- "80:80"
depends_on:
- frontend
- backendSonuç
Bu yaklaşımla CORS yapılandırması, cookie domain sorunları ve iki ayrı SSL sertifikası yönetimi gibi problemlerin hepsi ortadan kalkıyor. Geliştirme ortamında da production'da da aynı mimari çalışıyor, bu da "yerelde çalışıyordu" sürprizlerini büyük ölçüde azaltıyor. Bunu çalıştıracak bir sunucu arıyorsanız, AWS Lightsail'de Django deploy'u yazısı sıfırdan nginx ve HTTPS kurulumunu anlatıyor.