Docker Compose ile Nginx Proxy Kurulumu 2026 Rehberi
Docker Compose ile Nginx Proxy Kurulumu 2026 Rehberi
Docker Compose ile Nginx proxy kurmak, aynı sunucuda birden fazla web uygulamasını düzgün, temiz ve yönetilebilir şekilde yayınlamanın en pratik yollarından biri. Tek bir VPS üzerinde WordPress, Node.js API, Laravel paneli, statik site veya küçük bir admin aracı çalıştırıyorsanız, hepsine ayrı ayrı port açmak yerine Nginx’i kapıdaki karşılama noktası gibi kullanırsınız. Kullanıcı alanadiniz.com adresine gelir, Nginx isteği alır ve arka tarafta hangi container’a gitmesi gerekiyorsa oraya yönlendirir. Bu yüzden konu sadece “bir proxy kuralı yazalım” meselesi değil; domain, SSL, container ağı, log, güvenlik ve bakım alışkanlığıyla birlikte düşünülmesi gereken küçük ama önemli bir mimari karardır.
En basit anlatımla Nginx reverse proxy, dış dünyadan gelen HTTP ve HTTPS isteklerini içeride çalışan servislere dağıtır. Docker Compose ise bu servisleri tek bir dosyada tarif etmenizi sağlar. Böylece “nginx container’ı nerede çalışacak, uygulama hangi portu dinleyecek, iki container aynı network üzerinde mi, volume nereye bağlanacak?” gibi ayrıntılar dağınık komutlar yerine docker-compose.yml içinde kalır. Linux tarafına yeni giriyorsanız önce terminal, servis mantığı ve dosya izinleriyle rahat etmek işinizi kolaylaştırır; bunun için Linux komutlarını öğrenmek için başlangıç rehberi iyi bir temel sağlar.
Bu rehberde klasik ve anlaşılır bir kurulum üzerinden gideceğiz: Bir Nginx container’ı reverse proxy olarak çalışacak, arkada örnek bir web uygulaması olacak ve dışarıya yalnızca 80 ile 443 portları açılacak. 2026’da da mantık hâlâ aynı: Gereksiz portları internete açma, container’ları aynı Docker network içine al, domain bazlı yönlendirmeyi Nginx ile yap, SSL sertifikasını otomatik yenilenebilir şekilde planla. Sunucu olarak Ubuntu veya Debian kullanıyorsanız önce sistemin güncel olduğundan, Docker ve Docker Compose eklentisinin kurulu olduğundan emin olun. Yeni bir Ubuntu kurulumu yaptıysanız Ubuntu 26.04 LTS kurulumdan sonra yapılacak ayarlar yazısındaki temel bakım adımları bu işe başlamadan önce iyi bir kontrol listesi gibi düşünülebilir.
Örnek klasör yapısını sade tutalım. Sunucuda /opt/nginx-proxy gibi bir dizin oluşturup içine docker-compose.yml, nginx.conf ve certbot için birkaç klasör koyabilirsiniz. Üretim ortamında her şeyi root dizinine rastgele atmak yerine uygulama bazlı klasörler kullanmak ileride büyük rahatlık sağlar. Mesela /opt/nginx-proxy/nginx/conf.d içine site yapılandırmalarını, /opt/nginx-proxy/certbot/www içine Let’s Encrypt doğrulama dosyalarını, /opt/nginx-proxy/certbot/conf içine sertifikaları koymak mantıklı bir düzen olur.
Başlangıç için docker-compose.yml dosyanız şöyle olabilir:
`yaml services: nginx: image: nginx:stable-alpine container_name: nginx_proxy restart: unless-stopped ports:
- "80:80"
- "443:443" volumes:
- ./nginx/conf.d:/etc/nginx/conf.d:ro
- ./certbot/www:/var/www/certbot:ro
- ./certbot/conf:/etc/letsencrypt:ro networks:
-
proxy
app: image: nginx:stable-alpine container_name: demo_app restart: unless-stopped volumes:
- ./app:/usr/share/nginx/html:ro networks:
- proxy
networks: proxy: driver: bridge `
Burada iki ayrı Nginx var gibi görünmesi kafanızı karıştırmasın. Birincisi dış dünyaya bakan proxy. İkincisi sadece örnek web uygulamasını temsil ediyor. Gerçek hayatta bu app servisi bir Node.js container’ı, PHP-FPM ile çalışan bir Laravel uygulaması, Python FastAPI servisi ya da başka bir şey olabilir. Önemli nokta şu: app servisini host makinede 3000, 8080, 5000 gibi portlarla dışarı açmak zorunda değilsiniz. Aynı Docker network içinde olduğu için proxy container’ı ona servis adıyla, yani app:80 gibi erişebilir.
Nginx site yapılandırması için ./nginx/conf.d/demo.conf dosyasını oluşturabilirsiniz. İlk aşamada SSL’siz, sadece HTTP üzerinden test etmek en temiz yöntemdir. Domain DNS kaydınız sunucunun IP adresine yönlendirilmiş olmalı. Ardından şu yapılandırma işinizi görür:
`nginx server { listen 80; server_name example.com www.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
proxy_pass http://app:80;
proxy_http_version 1.1;
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;
}
} `
example.com kısmını kendi domaininizle değiştirin. Sonra klasöre basit bir index.html koyup docker compose up -d komutunu çalıştırın. Tarayıcıdan domaininizi açtığınızda örnek uygulama görünüyorsa temel proxy hattı çalışıyor demektir. Burada en sık yapılan hata, uygulama container’ının sadece localhost üzerinde dinlemesidir. Container içindeki servis 127.0.0.1’e bağlı kalırsa diğer container’lar ona erişemez. Node.js için 0.0.0.0, Python uygulamalarında yine 0.0.0.0 bind adresi kullanmak genellikle gerekir.
SSL tarafında iki yaklaşım var. Birincisi certbot container’ını elle çalıştırıp sertifika almak, sonra Nginx yapılandırmasını HTTPS’e geçirmek. İkincisi nginx-proxy-manager veya Traefik gibi daha otomatik araçlara yönelmek. Bu yazıda kontrol sizde kalsın diye klasik Nginx + Certbot yönteminden ilerlemek daha öğretici. docker-compose.yml içine certbot servisini ekleyebilirsiniz:
`yaml certbot: image: certbot/certbot container_name: certbot volumes:
- ./certbot/www:/var/www/certbot
- ./certbot/conf:/etc/letsencrypt `
İlk sertifikayı almak için şu komutu kullanırsınız:
bash docker compose run --rm certbot certonly --webroot --webroot-path /var/www/certbot -d example.com -d www.example.com
Sertifika başarıyla oluştuğunda Nginx dosyasına 443 bloğu eklenir ve 80 trafiği HTTPS’e yönlendirilir. Yapılandırma şu hâle gelebilir:
`nginx server { listen 80; server_name example.com www.example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server { listen 443 ssl http2; server_name example.com www.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://app:80;
proxy_http_version 1.1;
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 https;
}
} `
Bu dosyayı kaydettikten sonra docker compose exec nginx nginx -t ile yapılandırmayı test edin. Hata yoksa docker compose exec nginx nginx -s reload komutuyla Nginx’i yeniden yükleyebilirsiniz. Container’ı tamamen kapatıp açmak çoğu zaman gerekmez. Küçük ama önemli bir alışkanlık: Nginx dosyasını değiştirdikten sonra doğrudan restart yapmak yerine önce nginx -t ile test edin. Yanlış yazılmış tek bir noktalı virgül bile yayındaki tüm siteleri etkileyebilir.
Birden fazla site yayınlamak istediğinizde her site için ayrı conf dosyası oluşturmak yeterlidir. Örneğin api.example.com için api.conf, panel.example.com için panel.conf yazarsınız. docker-compose.yml içinde app, api, panel gibi servisler aynı proxy network’e bağlı olursa Nginx her domaini ilgili servise aktarır. Bu düzen küçük VPS’lerde gayet verimlidir. Yine de her şeyi tek sunucuya yığarken log boyutlarını, disk doluluğunu ve yedekleri takip etmeyi ihmal etmemek gerekir. Web sunucusu yayınlamak sadece uygulamayı ayağa kaldırmak değildir; firewall ve SSH güvenliği de aynı resmin parçasıdır. Özellikle internete açık bir VPS kullanıyorsanız UFW kurulumu ve temel firewall ayarları ile yalnızca gerekli portları açık bırakmanız iyi olur.
Güvenlik tarafında 80 ve 443 dışında uygulama portlarını host’a açmamak en temiz başlangıçtır. Docker Compose dosyasında app servisi için ports yazmazsanız dış dünya ona doğrudan erişemez, sadece aynı Docker network içindeki Nginx erişir. Bu, özellikle admin panelleri ve API servisleri için önemlidir. Eğer veritabanı da Compose içinde çalışıyorsa MySQL veya PostgreSQL portunu internete açmayın. Uygulama container’ı veritabanına servis adıyla erişsin, dışarıdan bağlantı gerekiyorsa bunu geçici, sınırlı ve güvenli bir yöntemle çözün.
Performans için ilk gün karmaşık ayarlara boğulmaya gerek yok. Nginx zaten statik dosya sunma ve proxy yönlendirme konusunda hafif bir araçtır. Buna rağmen büyük dosya yükleyen uygulamalarda client_max_body_size değerini artırmanız gerekebilir. WebSocket kullanan servislerde Upgrade ve Connection başlıklarını eklemelisiniz. Gerçek kullanıcı IP’sini uygulamada görmek istiyorsanız X-Forwarded-For ve X-Real-IP başlıklarını doğru göndermek şarttır. Uygulama framework’ünüz proxy arkasında çalıştığını bilmiyorsa HTTPS yönlendirme döngüsü, yanlış callback URL’leri veya güvenli cookie sorunları yaşayabilirsiniz.
Sertifika yenileme için certbot renew komutunu düzenli çalıştırmanız gerekir. Bunu host üzerinde cron ile yapabilir veya basit bir systemd timer kullanabilirsiniz. Yenilemeden sonra Nginx’in yeni sertifikayı okuması için reload edilmesi gerekir. Pratik bir cron satırı şu mantıkta olabilir: certbot renew çalışır, başarılıysa nginx reload edilir. Üretim sunucusunda komutu önce elle test edip sonra otomasyona bağlamak daha sağlıklı olur. Sertifika süresi dolmadan yenilendiği için kullanıcılar genelde hiçbir kesinti hissetmez.
Sorun yaşarsanız ilk bakılacak yerler bellidir: docker compose ps ile container’lar ayakta mı, docker compose logs nginx ile Nginx ne diyor, nginx -t yapılandırmayı kabul ediyor mu, DNS gerçekten doğru IP’ye gidiyor mu, firewall 80 ve 443 portlarını açık bırakıyor mu? “502 Bad Gateway” çoğunlukla Nginx’in arkadaki servise ulaşamadığını söyler. Servis adı yanlış yazılmış olabilir, uygulama farklı portta dinliyor olabilir veya container aynı network’e bağlı değildir. “SSL certificate not found” hatası ise genellikle sertifika yolu ile domain adının uyuşmamasından çıkar.
Docker Compose ile Nginx proxy kurulumunun güzel tarafı, sistemin büyüdükçe bozulmadan genişleyebilmesidir. Bugün tek bir statik siteyle başlarsınız, yarın yanına API eklersiniz, sonra admin panelini ayrı container’a taşırsınız. Nginx dışarıya aynı sakin kapıyı gösterir, içeride servisleri siz istediğiniz gibi düzenlersiniz. 2026’da küçük ve orta ölçekli projeler için hâlâ en mantıklı kurulumlardan biri bu: sade bir Compose dosyası, okunabilir Nginx kuralları, otomatik yenilenen SSL, kapalı uygulama portları ve düzenli log takibi. Fazla gösterişli değil ama düzgün kurulduğunda uzun süre baş ağrıtmadan çalışır.
