Bu rehber gerçek Ubuntu 24.04 self-hosted AI stack kurulumumuzdaki en önemli güvenlik desenlerinden birini ayrı olarak ele alıyor: Docker uygulama portlarını 0.0.0.0 üzerinde public yayınlamak yerine 127.0.0.1 üzerinde tutmak ve public erişimi Nginx + HTTPS üzerinden vermek. Portainer 9443, Ollama 11434, Open WebUI 3000 ve n8n 5678 portlarını bu mimariyle kontrol ettik.
Internet :443
↓
Nginx + TLS
├─ 127.0.0.1:9443 → Portainer
├─ 127.0.0.1:3000 → Open WebUI
├─ 127.0.0.1:5678 → n8n
└─ Ollama 127.0.0.1:11434 + private Docker networkDocker'da -p 8080:80 gibi host IP belirtilmeden yapılan publish işlemi portu varsayılan olarak hostun tüm adreslerinde yayınlayabilir. Bu nedenle uygulamanın kendi yönetim veya API portunu farkında olmadan dış ağa açmak mümkündür.
Host IP'yi açıkça 127.0.0.1 olarak verdiğinizde published port yalnız Docker host üzerinden erişilebilir olur. Bizim self-hosted AI stack mimarimizin temel güvenlik kararı budur.
docker run -p 8080:80 nginxdocker run -p 127.0.0.1:8080:80 nginxGerçek Ubuntu 24.04 yapımızda Portainer 9443, Ollama 11434, Open WebUI 3000 ve n8n 5678 host portları yalnız 127.0.0.1 üzerinde bind edildi. Dış dünyaya doğrudan bu portları yayınlamadık.
Public erişim gereken web uygulamalarını Nginx üzerinden 80/443 portlarına taşıdık. Ollama API ise public domain olmadan local host ve private Docker network üzerinde kaldı.
127.0.0.1:9443 → Portainer127.0.0.1:11434 → Ollama127.0.0.1:3000 → Open WebUI127.0.0.1:5678 → n8n0.0.0.0:80 / :443 → Nginxdocker ps çıktısındaki Ports sütunu hızlı güvenlik kontrolüdür. 127.0.0.1:5678->5678/tcp gibi bir mapping yalnız loopback bindini gösterir. 0.0.0.0:5678->5678/tcp ise portun tüm IPv4 host interface'lerinde publish edildiğini gösterir.
Özellikle yönetim panelleri, veritabanları, local LLM API'leri ve otomasyon editörlerinde bu kontrolü deployment sonrası rutin hale getirin.
docker ps --format 'table {{.Names}}\t{{.Ports}}'Docker çıktısına ek olarak Linux socket tablosunu da kontrol etmek savunma açısından faydalıdır. ss -lntp ile local uygulama portlarının 127.0.0.1, Nginx'in ise 80/443 üzerinde public interface'lerde dinlediğini doğruladık.
Bu iki kontrol birlikte Docker publish ayarı ile işletim sistemi socket görünümünün aynı mimariyi yansıttığını gösterir.
ss -lntp | grep -E ':80|:443|:9443|:11434|:3000|:5678'Uygulama localhost üzerinde dinlerken Nginx public 443 isteğini local upstream'e aktarabilir. n8n için gerçek mimarimizde proxy_pass http://127.0.0.1:5678 kullanıldı; Open WebUI için aynı yaklaşım 127.0.0.1:3000 üzerinde uygulandı.
Bu model TLS, domain, access log, rate limit veya ek authentication gibi kontrolleri tek public giriş katmanında toplamanızı sağlar.
location / {
proxy_pass http://127.0.0.1:5678;
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;
}WebSocket protokol yükseltmesinde Upgrade ve Connection başlıkları hop-by-hop oldukları için reverse proxy tarafında açıkça iletilmeleri gerekir. n8n ve Open WebUI gibi gerçek zamanlı web uygulamalarında bu ayar bağlantı sorunlarını önlemek için önemlidir.
Biz Nginx map kullanarak connection_upgrade değerini ürettik ve location içinde HTTP/1.1, Upgrade ve Connection headerlarını upstream'e geçirdik.
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;Localhost-only port mimarisi tek başına public kullanıcı erişimi sağlamaz; domain katmanında Nginx ve TLS gerekir. Nginx config testi sonrası Certbot ile domain sertifikalarını kurduk ve HTTPS isteklerinin HTTP 200 döndüğünü doğruladık.
certbot renew --dry-run testi sertifika yenileme zincirini canlı sertifikayı değiştirmeden kontrol etmenin pratik yoludur.
nginx -tcurl -I https://n8n.ekasunucu.comcertbot renew --dry-runDocker port publishing kendi firewall/NAT kurallarını yönetir. Resmî Docker dokümantasyonu, host IP belirtmeden publish edilen portların dışarıdan erişilebilir olabileceğini ve Docker'ın iptables kuralları nedeniyle yalnız UFW beklentisine güvenmenin yeterli olmayabileceğini açıkça belirtir.
Bu nedenle uygulama portunda temel kontrolü doğrudan publish ifadesinde yapın: -p 127.0.0.1:HOST:CONTAINER. Firewall ise bunun üzerine ek savunma katmanı olsun.
-p 5678:5678-p 127.0.0.1:5678:5678Portainer, Open WebUI ve n8n tarayıcıdan erişilmesi gereken servisler olduğu için localhost uygulama portu + Nginx domain + HTTPS modeli kullandık. Böylece public kullanıcı yalnız TLS giriş noktasını görür.
Ollama ise backend API olarak kaldı. Hostta 127.0.0.1:11434 ve Docker içinde ollama:11434 adresleri kullanıldı; public bir 11434 socket açılmadı.
portainer.ekasunucu.com → Nginx → 127.0.0.1:9443openwebui.ekasunucu.com → Nginx → 127.0.0.1:3000n8n.ekasunucu.com → Nginx → 127.0.0.1:5678Ollama → 127.0.0.1:11434 + eka-ai private networkDocker containerın published port mapping'i çalışan container üzerinde normal docker network connect gibi değiştirilemez; güvenli bind için containerı aynı volume ve environment ile yeniden oluşturmanız gerekir. Önce mevcut inspect ve volume bilgilerini kaydedin.
Container recreate sırasında -p 127.0.0.1:... mapping kullanın. Named volume korunursa uygulama verileri container yaşam döngüsünden bağımsız kalabilir; yine de işlem öncesi yedek veya snapshot alın.
docker inspect n8n > /root/n8n-before-port-fix.jsondocker rm -f n8ndocker run -d --name n8n --restart=always --env-file /root/n8n.env -p 127.0.0.1:5678:5678 -v n8n_data:/home/node/.n8n docker.n8n.io/n8nio/n8n:latestFinal kontrolde önce docker ps ile port mappinglerini, ardından ss ile gerçek socketleri okuyun. Nginx config testini, public HTTPS isteğini ve Certbot renewal dry-run testini çalıştırın.
Beklenen sonuç: uygulama portları 127.0.0.1 üzerinde, public web girişi yalnız Nginx 80/443 üzerinde, HTTPS endpointleri başarılı ve sertifika yenileme testi hatasız olmalıdır.
docker ps --format 'table {{.Names}}\t{{.Ports}}'ss -lntp | grep -E ':80|:443|:9443|:11434|:3000|:5678'nginx -tcurl -I https://n8n.ekasunucu.comcertbot renew --dry-runContainer image güncellemesi sırasında eski docker run parametreleri unutulursa servis yeniden 0.0.0.0 üzerinde publish edilebilir. Bu nedenle update prosedürünüzde port mapping kontrolünü zorunlu adım haline getirin.
Port binding, Nginx upstream, HTTPS health ve Docker private network testlerinin birlikte doğrulanması self-hosted servislerde yanlışlıkla public exposure riskini ciddi biçimde azaltır.
docker ps --format 'table {{.Names}}\t{{.Ports}}'ss -lntpdocker network inspect eka-ainginx -tHost IP belirtilmediğinde Docker varsayılan olarak portu hostun tüm adreslerinde yayınlayabilir.
Published portu yalnız Docker hostun loopback adresi üzerinden erişilebilir yapar.
IPv4 tarafında servisin tüm uygun host interface'lerinde dinlediğini veya publish edildiğini ifade eder.
docker ps Ports sütununu ve ss -lntp çıktısını birlikte kontrol edin.
Bu mimaride hayır; 127.0.0.1:5678 üzerinde tutulup Nginx HTTPS üzerinden yayınlanır.
Bu rehberde yalnız localhost'a bind edildi ve domain erişimi Nginx üzerinden sağlandı.
Bu mimaride hayır; hostta 127.0.0.1 ve containerlar arasında private Docker network kullanıldı.
Host tarafında yalnız 127.0.0.1:9443 üzerinde tutulup domain Nginx üzerinden yayınlandı.
Public domain ve TLS trafiğini localhost üzerinde çalışan backend uygulamaya iletir.
Upgrade ve Connection başlıkları reverse proxy tarafından açıkça iletilmelidir.
Docker kendi firewall/NAT kurallarını yönettiği için yalnız UFW beklentisine güvenmeyin; host bind adresini doğru seçin.
Normalde publish mapping için containerı doğru volume, env ve network ayarlarıyla yeniden oluşturmak gerekir.
certbot renew --dry-run ile yenileme sürecini simüle edebilirsiniz.
docker ps, ss, Nginx config, HTTPS health, private Docker network ve Certbot renewal tekrar kontrol edilmelidir.
Portainer, Ollama, Open WebUI, n8n ve diğer Docker servislerini kendi altyapınızda Nginx + HTTPS mimarisiyle çalıştırmak için EKA Sunucu Linux VPS paketlerini inceleyebilirsiniz.
Güncellendi: 10.08.2026