SSD Nodes Learn 🎉 VPS $4.99/aydan başlayan
Rehberler Matt ConnorYazan Matt Connor · Güncellendi 2026-08-07

Gluetun arkasindaki containerlara nasil erisilir?

Gluetun kullanan containerlarin kendi ag arayuzleri yoktur. Portlari gluetun uzerinden yayinlayin ve sadece tunel disina cikmasi gereken alt aglara izin verin.

Bir container gluetun ağina katildiğinda ne olur

network_mode: service:gluetun ayarini kullanan bir container'in kendine ait ağ arayüzleri yoktur. Bu container, gluetun'in ağ ad alanina (network namespace) katilir; bu nedenle port yayinlama ve güvenlik duvari kurallari artik o container'in değil, gluetun servisinin bir özelliği haline gelir. Aşağıdaki tüm yanitlar bu temel gerçeğe dayanmaktadir.

Ağ ad alani, çekirdeğin ağ yığınının özel bir kopyasidir: kendine ait arayüzleri, yönlendirme tablosu, güvenlik duvari kurallari ve dinleme soketleri bulunur. Docker, varsayilan olarak her container'a bir tane atar. network_mode: service:gluetun komutunu kullandığınızda Docker bu adimi atlar ve yeni container'i gluetun'in halihazirda sahip olduğu ad alaninin içine yerleştirir. Container kendi dosya sistemini ve kendi /etc/hosts dosyasini korur; bu ikinci dosya daha sonra önem kazanacaktir.

Bunu doğrudan görebilirsiniz.

docker inspect -f '{{.HostConfig.NetworkMode}}' qbittorrent

Bu komut, normal bir container'in bridge çiktisi vereceği yerde, container: ifadesini ve ardindan gluetun container kimliğini yazdirir. Bu rehber, Docker trafiğini gluetun ile VPN üzerinden yönlendirme konusunun kaldığı yerden devam eder: tünel çalişmaktadir ve artik container ile iletişim kurulamamaktadir.

Portu uygulama üzerinde değil, gluetun üzerinde yayımlayın

Servis üzerinde ports: bloğunu bırakırsanız ve network_mode ayarlanırsa, Docker container'ı oluşturmayı reddeder:

Error response from daemon: conflicting options: port publishing and the container type network mode

Bunun nedeni açıktır. Bir portu yayımlamak, ana makine portunu container'ın kendi ağ ad alanına (network namespace) yönlendiren bir NAT (ağ adresi çevirisi) kuralı eklemek anlamına gelir; ancak bu container'ın kendine ait bir ağ ad alanı yoktur. Port eşleştirmesini gluetun servisine taşıyın. Uygulama paylaşılan ad alanında aynı portu dinlemeye devam ettiği için port numarası değişmez.

services:
  gluetun:
    ports:
      - "8080:8080/tcp"   # qBittorrent web UI

  qbittorrent:
    network_mode: "service:gluetun"
    # no ports: block here

Bağımlı servis üzerindeki bir expose: bloğu da aynı derecede anlamsızdır ve oradaki bir networks: bloğu kesin bir engeldir: Compose, servisin birbirini dışlayan network_mode ve networks tanımladığını bildirir ve dosyanın yüklenmesini tamamen reddeder.

Bunun bir sonucu daha sonra ortaya çıkar. Ad alanındaki her container tek bir port alanını paylaşır; bu nedenle varsayılan olarak 8080 portunu kullanan iki uygulama çakışır ve ikinci başlayan uygulama, adresin kullanımda olduğu hatasıyla başarısız olur. Bunlardan birini kendi yapılandırması üzerinden değiştirin; örneğin LinuxServer qBittorrent imajındaki WEBUI_PORT değişkenini değiştirin ve ardından yeni numarayı gluetun üzerinde yayımlayın.

Gluetun arkasındaki container'lar birbirine nasıl ulaşır?

Namespace içinde zaten bir loopback arayüzünü paylaşırlar. Gluetun arkasındaki bir container, kardeşine 127.0.0.1:<port> üzerinden, herhangi bir Docker ağına dahil olmadan ulaşır.

Namespace dışından bakıldığında, container'ın bir ismi yoktur. Docker'ın gömülü DNS'i, bir servis ismini o servisin kullanıcı tanımlı ağ üzerindeki adresine çözümler; ancak bu container'ın herhangi bir ağ üzerinde adresi bulunmaz. Bu nedenle, Sonarr gibi normal bir container, torrent istemcisine http://qbittorrent:8080 üzerinden ulaşamaz. Ona http://gluetun:8080 üzerinden ulaşır; çünkü socket, gluetun'un namespace'inde ve gluetun'un adresi üzerinde dinleme yapmaktadır. Bu durum, Docker Compose ağlarının ve servis isimlerinin nasıl çalıştığını bilen ve standart isimlendirme kurallarının geçerli olmasını bekleyen kullanıcıları şaşırtır. Her iki container da aynı Compose ağı üzerinde olduğu için, host tarafında herhangi bir port yayınlamaya gerek kalmadan da çalışır.

Başka bir hata ayıklama işlemine geçmeden önce DNS ayarlarını kontrol edin. Gluetun kendi çözümleyicisini çalıştırır ve kendi container'ı içindeki /etc/resolv.conf dosyasını yeniden yazar; ancak /etc/resolv.conf container bazlı bir dosya olduğundan, gluetun'un yazdığı dosya ile uygulamanızın okuduğu dosya aynı değildir.

docker exec qbittorrent cat /etc/resolv.conf

Docker ana makinesinde çalışan bir servise nasıl erişirim?

host.docker.internal kullanın. İki farklı şey hatalı olduğu için, iki farklı yerde iki ayar yapılması gerekir.

İsimlendirme ilk sırada gelir. /etc/hosts konteyner bazlıdır, bu nedenle extra_hosts girdisi gluetun üzerinde değil, uygulama konteyneri üzerinde yer almalıdır.

  prowlarr:
    network_mode: "service:gluetun"
    extra_hosts:
      - "host.docker.internal:host-gateway"

host-gateway, Docker'ın ana makinenin kendi dahili adresiyle değiştirdiği özel bir değerdir. Standart bir Linux Docker kurulumunda bu, genellikle 172.17.0.1 olan docker0 köprüsünün adresidir. Kendi adresinizi VPS üzerinde ip -4 addr show docker0 ile doğrulayın. Docker Desktop bu ismi kendi başına çözümler; dizüstü bilgisayarlar için yazılan rehberlerin extra_hosts satırını atlamasının ve aynı dosyanın sunucuda başarısız olmasının nedeni budur.

Yönlendirme ikinci sırada gelir. İsmi eklemek, konteynere yalnızca hangi adresi kullanacağını söyler. Paket yine de gluetun'un varsayılan rotası olan tünel üzerinden çıkar ve gluetun'un güvenlik duvarı tarafından düşürülür. Belirti, reddedilen bir bağlantıdan ziyade, bekleyip zaman aşımına uğrayan bir bağlantıdır. Reddedilme, paketin ulaştığı ve bir yanıtın "hayır" olduğu anlamına gelir. Zaman aşımı ise paketin hiç ulaşmadığı anlamına gelir.

  gluetun:
    environment:
      - FIREWALL_OUTBOUND_SUBNETS=172.17.0.1/32

Ardından, ana makine servisinin gerçekten bu adresi dinlediğinden emin olun. Yalnızca 127.0.0.1 adresine bağlı bir PostgreSQL sunucusuna, tünel olsun veya olmasın hiçbir konteynerden erişilemez; çünkü isim alanı (namespace) içindeki 127.0.0.1, o isim alanının kendi loopback adresidir. Bunun yerine servisi 172.17.0.1 adresine bağlayın: bu adres, genel arayüzü dışarıda tutarken konteynerlerden gelen bağlantıları kabul eder. Ana makinede ss -lntp | grep 5432 ile doğrulama yapın.

FIREWALL_OUTBOUND_SUBNETS ayarı gerçekte neleri değiştirir

gluetun belgeleri bu ayarı, gluetun ve onun ağ yığınını paylaşan container'ların erişimine izin verilen, virgülle ayrılmış alt ağlar olarak tanımlar ve bunun güvenlik duvarı ile yönlendirme değişikliklerini içerdiğini belirtir. Her iki kısım da önemlidir. gluetun, listelenen her alt ağ için Docker köprü ağ geçidi üzerinden bir rota ekler; böylece bu adreslere yönelik paketler tünel yerine eth0 üzerinden çıkar. Ayrıca bu adresler için güvenlik duvarını açar, çünkü gluetun aksi takdirde VPN sunucusuna yönelmeyen giden trafiği düşürür.

Değeri, virgüllerden sonra boşluk bırakmadan yazın.

      - FIREWALL_OUTBOUND_SUBNETS=172.17.0.1/32,192.168.1.0/24,100.64.7.9/32

İki özellik gözden kaçırılmaya müsaittir. Bu, namespace düzeyinde bir ayardır; dolayısıyla yalnızca aklınızdaki container için değil, gluetun arkasındaki her container için geçerlidir. Ayrıca bu ayar yalnızca giden trafik içindir; bir container'ın başlattığı bağlantıları yönetir. Yayınlanmış bir porta gelen bağlantılar farklı bir yol izler ve buraya girilmeleri gerekmez.

Bir Tailscale eşinden web arayüzüne erişim

Tailscale, her makineye taşıyıcı sınıfı NAT için ayrılmış 100.64.0.0/10 aralığında bir adres atar. İki yönlü iletişim için farklı işlemler yapılması gerekir.

Gelen trafik en basit olanıdır. 8080:8080 değerini gluetun üzerinde yayınlamak, ilgili portu ana makinenin tüm adreslerinde bağlar; ana makinenin tailscale0 arayüzü de bunlardan biri olduğu için bir eş http://<machine-name>:8080 adresini açarak konteynere ulaşır. Docker'ın NAT kuralı isim alanının dışında, ana makine üzerinde yer aldığından gluetun bu yolda herhangi bir rol oynamaz.

Arayüzün yalnızca tailnet üzerinden erişilebilir olmasını sağlamak için, yayınlanan portu tüm adreslere değil, yalnızca ana makinenin Tailscale adresine bağlayın.

    ports:
      - "100.101.102.103:8080:8080/tcp"

Bu adresi ana makinede tailscale ip -4 komutuyla bulun. Bağlama işlemi, bir güvenlik duvarı kuralından daha güçlü bir denetim sağlar; çünkü port, genel arayüzde hiçbir şekilde açılmaz. Bu yöntem ayrıca Docker'ın ufw'yi atlayarak port yayınlaması sorununu da ortadan kaldırır.

Giden trafik ise FIREWALL_OUTBOUND_SUBNETS değerinin devreye girdiği yerdir. Bir konteynerin bir eşe çağrı yapması gerekiyorsa, o eşin adresini ekleyin ve tüm /10 aralığı yerine eş başına bir /32 tercih edin. MagicDNS isimleri konteyner içinde çözümlenmeyecektir; çünkü konteyner ana makinenin çözümleyicisini kullanmaz. Bu nedenle sayısal 100.x adresini kullanın veya bir extra_hosts satırı ile sabitleyin. Aynı durum kendi Tailscale kontrol sunucunuzu Headscale ile çalıştırdığınızda da geçerlidir.

Yaygın bir yapı için eksiksiz bir compose dosyası

VPN arkasında bir indirme istemcisi, yalnızca tailnet üzerinde yanıt veren iki web arayüzü ve ana makinede çalışan bir PostgreSQL veritabanını okuyan bir container.

services:
  gluetun:
    image: qmcgaw/gluetun:latest
    container_name: gluetun
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    ports:
      - "127.0.0.1:8000:8000/tcp"        # gluetun control server, host only
      - "100.101.102.103:8080:8080/tcp"  # qBittorrent UI, tailnet only
      - "100.101.102.103:9696:9696/tcp"  # Prowlarr UI, tailnet only
    volumes:
      - ./gluetun:/gluetun
    environment:
      - VPN_SERVICE_PROVIDER=mullvad
      - VPN_TYPE=wireguard
      - WIREGUARD_PRIVATE_KEY=${WIREGUARD_PRIVATE_KEY}
      - WIREGUARD_ADDRESSES=${WIREGUARD_ADDRESSES}
      - SERVER_CITIES=Amsterdam
      - FIREWALL_OUTBOUND_SUBNETS=172.17.0.1/32,100.64.7.9/32
      - TZ=Europe/Amsterdam
    restart: unless-stopped

  qbittorrent:
    image: lscr.io/linuxserver/qbittorrent:latest
    network_mode: "service:gluetun"
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Amsterdam
      - WEBUI_PORT=8080
    volumes:
      - ./qbittorrent:/config
      - /srv/downloads:/downloads
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

  prowlarr:
    image: lscr.io/linuxserver/prowlarr:latest
    network_mode: "service:gluetun"
    extra_hosts:
      - "host.docker.internal:host-gateway"
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Amsterdam
      - PROWLARR__POSTGRES__HOST=host.docker.internal
      - PROWLARR__POSTGRES__PORT=5432
      - PROWLARR__POSTGRES__USER=prowlarr
      - PROWLARR__POSTGRES__PASSWORD=${PROWLARR_DB_PASSWORD}
      - PROWLARR__POSTGRES__MAINDB=prowlarr-main
      - PROWLARR__POSTGRES__LOGDB=prowlarr-log
    volumes:
      - ./prowlarr:/config
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

Dosyayı ürün isimlerinden ziyade yapısal model için inceleyin. Her iki web arayüzü de gluetun üzerinde yayınlanmakta ve ana makinenin tailnet adresine bağlanmaktadır; bu sayede yalnızca Tailscale üzerinden yanıt verirler ve başka hiçbir yerden erişilemezler. Yalnızca Prowlarr extra_hosts satırını içerir, çünkü host.docker.internal çözümlemesini yapan container Prowlarr'dır. FIREWALL_OUTBOUND_SUBNETS iki tekil adresi tanımlar: Prowlarr'ın veritabanı bağlantısı açabilmesi için ana makinenin Docker bridge adresi ve bir tailnet eşi.

PostgreSQL sunucusu kasten dosyanın dışında tutulmuştur. VPS üzerinde 172.17.0.1:5432 adresini dinleyen standart bir sistem servisi olarak çalışır. Bu, veritabanının Docker dışına taşındığı Docker Compose üzerinde bir arr yığını ile aynı katmanlama mantığıdır.

WireGuard özel anahtarını compose dosyasının dışında tutun. ${WIREGUARD_PRIVATE_KEY}, yanında bulunan bir .env dosyasından okuma yapar; bu yöntem Docker Compose için env dosyaları ve gizli veriler bölümünde açıklanmıştır. condition: service_healthy yan tümcesi, gluetun imajının halihazırda sunduğu sağlık kontrolünü kullanır, böylece tünel aktif olduğunu bildirene kadar hiçbir şey başlamaz. Compose sağlık kontrolleri genel yapıyı açıklamaktadır.

Yalnızca tailnet yerine tüm adreslerde yayınlama

VPS'in genel IP adresini de içeren 0.0.0.0 üzerindeki adres önekini ve port bağlamalarını kaldırın. Bunu yalnızca kontrolünüz altındaki bir güvenlik duvarının arkasında yapın ve öncesinde yukarıdaki ufw notunu okuyun.

    ports:
      - "8080:8080/tcp"

Tünelin trafik taşıdığını doğrulama

Aynı isteği biri namespace içinden, diğeri ise ana makineden olmak üzere iki kez çalıştırın ve sonuçları karşılaştırın.

docker run --rm --network=container:gluetun curlimages/curl:latest -s https://api.ipify.org
curl -s https://api.ipify.org

İlk komut, VPN sağlayıcınızın çıkış adresini yazdırmalıdır. İkincisi ise VPS adresini yazdırmalıdır. Eğer bu adresler aynıysa, container trafiği tünel üzerinden geçmiyor demektir; bu durum düzeltilene kadar bu rehberdeki diğer tüm adımlar etkisiz kalacaktır.

Yönlendirme tablosu, hangi trafiğin tünel üzerinden geçtiğini, hangisinin geçmediğini gösterir.

docker run --rm --network=container:gluetun alpine:3.22 ip route show

Varsayılan yönlendirme (default route), tun0 tünel arayüzünü işaret etmelidir. Bunun altında, FIREWALL_OUTBOUND_SUBNETS içindeki her bir girdi için Docker köprü ağ geçidini işaret eden birer rota görmelisiniz. eth0 üzerinden çıkan diğer tüm rotalar, VPN'i atlayan trafiği temsil eder.

Gluetun kontrol sunucusu, /v1/publicip/ip adresindeki 8000 numaralı port üzerinden aynı genel IP adresini raporlar. Güncel sürümler, kontrol sunucusu rotaları için kimlik doğrulama yapılandırmanızı gerektirir; bu nedenle bu veriye güvenmeden önce ilgili ayarları tamamlayın.

Yanlış bir alt ağın oluşturduğu sızıntı

FIREWALL_OUTBOUND_SUBNETS, güvenlik duvarında bilerek açtığınız bir deliktir; dolayısıyla deliğin boyutu, riskin boyutunu belirler. Bu deliği gereğinden fazla büyütmenin dört yolu şunlardır:

  • 0.0.0.0/0, her şeyi tünelin dışına gönderir. Yukarıdaki iki IP kontrolü, ilk çalıştırmada aynı adresi döndürecekleri için bu durumu yakalar.
  • Hedeften daha geniş bir aralık. 10.0.1.7 adresindeki tek bir makineye ulaşmak için 10.0.0.0/8 aralığını açmak, bir torrent eşinin bu aralıkta duyurabileceği her adresi de açar. Bunun yerine 10.0.1.7/32 yazın.
  • Tünelin kendi adresleriyle çakışan bir aralık. gluetun belgeleri, bunun VPN trafiğinin köprü üzerinden dışarı gönderilmesine neden olduğu ve port yönlendirmeyi bozduğu konusunda uyarır. Herhangi bir özel aralığı açmadan önce WIREGUARD_ADDRESSES değerinizi kontrol edin.
  • Tailscale için 100.64.0.0/10. Bu, tek bir eşe ulaşılabilmesi için yaklaşık dört milyon adresin açılması demektir. İhtiyacınız olan eşleri /32 girdileri olarak listeleyin.

Bu ayarın tüm ad alanını kapsadığını unutmayın. Bir indeksleyicinin bir ana bilgisayar servisine ulaşabilmesi için bir alt ağ açmak, aynı alt ağı o ad alanını paylaşan torrent istemcisi için de açar. Bu değişkende yapılan her değişiklikten sonra genel IP kontrolünü tekrar çalıştırın; çünkü değişikliğin amaçladığınız şeyi yapıp yapmadığını gösteren tek test budur.

gluetun yeniden başlatıldığında ne bozulur

gluetun ağ ad alanını (namespace) yönetir, bu nedenle gluetun'un yaşam döngüsü ad alanının yaşam döngüsüdür. gluetun kapalıyken bağımlı bir container başlatılırsa işlem hemen başarısız olur:

Error response from daemon: cannot join network of a non running container

gluetun'u yerinde yeniden başlatmak daha sessiz bir hata türüdür. Bağımlı container'lar çalışmaya devam ederken, bağlı oldukları ad alanı altlarında yeniden oluşturulur; bu yüzden docker ps her şeyin sağlıklı olduğunu rapor eder ancak hiçbir servis yanıt vermez. gluetun servisinde herhangi bir değişiklik yaptıktan sonra, parçalardan birini yeniden başlatmak yerine tüm grubu yeniden oluşturun.

docker compose up -d --force-recreate

Aynı durum imaj güncellemeleri için de geçerlidir. Yeni bir gluetun imajı çekip sadece o servisi yeniden oluşturmak, diğerlerinin artık var olmayan bir ad alanına işaret etmesine neden olur.

FAQ

Docker neden "port publishing and the container type network mode" hatası veriyor?

Çünkü ports: bloğu, aynı zamanda network_mode: service:gluetun ayarını yapan bir serviste tanımlanmıştır. Bir portu dışarı açmak, ana makine portunu container'ın kendi ağ ad alanına (network namespace) yönlendiren bir NAT kuralı ekler; bu moddaki bir container'ın ise kendine ait bir ağ ad alanı yoktur. İlgili servisten ports: bloğunu silin ve aynı eşleştirmeyi gluetun servisine ekleyin. Uygulama paylaşılan ad alanı içinde aynı portu dinlemeye devam ettiği için port numarası değişmez.

Diğer container'lar gluetun arkasındaki bir servise nasıl erişir?

Aynı ad alanı içindeki container'lar birbirine 127.0.0.1 üzerinden ulaşır. Dışarıdaki container'lar ise gluetun servis adını kullanır; bu nedenle http://qbittorrent:8080 çalışmazken http://gluetun:8080 çalışır. Uygulama container'ı herhangi bir Docker ağında adres tutmadığı için, gömülü DNS sunucusu onun ismi için çözümleme yapamaz. Her iki container aynı Compose ağını paylaştığı sürece, bunun için herhangi bir port açma işlemine gerek yoktur.

FIREWALL_OUTBOUND_SUBNETS içine ne yazmalıyım?

Yalnızca gluetun arkasındaki bir container'ın bağlantı başlatması gereken adresleri, mümkün olduğunca dar kapsamlı şekilde yazın. Tek bir makine için /32 kullanılır. En yaygın iki giriş, 172.17.0.1/32 adresindeki Docker ana makinesi ve eriştiğiniz her bir Tailscale eşi için bir adet /32 adresidir. Asla 0.0.0.0/0 eklemeyin ve VPN tünel adreslerinizle çakışan bir aralık tanımlamayın. Dışarıdan açılan bir porta gelen bağlantılar için burada bir giriş yapılmasına gerek yoktur.

Container neden Tailscale MagicDNS isimlerini çözümleyemiyor?

MagicDNS, ana makinenin çözümleyicisini Tailscale'in DNS sunucusuna yönlendirerek çalışır; ancak container ana makinenin çözümleyicisini kullanmaz. Container, kendi /etc/resolv.conf ayarında ne tanımlıysa onu kullanır; gluetun arkasında ise bu, gluetun'un DNS yapılandırmasıdır. Bunu docker exec <container> cat /etc/resolv.conf ile doğrulayın. Eşin sayısal 100.x adresini kullanın veya o container üzerinde bir extra_hosts girişi ile ismi sabitleyin.

Trafiğin hala VPN üzerinden geçtiğini nasıl doğrularım?

Ad alanı içinden bir istek gönderin, aynı isteği bir de ana makineden gönderin ve yanıtları karşılaştırın. docker run --rm --network=container:gluetun curlimages/curl:latest -s https://api.ipify.org, VPN sağlayıcınızın çıkış adresini döndürmelidir; VPS üzerindeki curl -s https://api.ipify.org ise VPS adresini döndürmelidir. İki yanıtın aynı olması, tünelin container trafiğini taşımadığı anlamına gelir. Bu kontrolü FIREWALL_OUTBOUND_SUBNETS üzerinde yaptığınız her değişiklikten sonra tekrarlayın.