Docker'da bir container'ın ağ davranışını, bağlandığı ağın sürücüsü (driver) belirler. Linux üzerinde Docker Engine ile gelen yerleşik sürücüler şunlardır: bridge (varsayılan, aynı sunucudaki container'lar için), host (container sunucunun ağını doğrudan kullanır), none (yalnızca loopback, tam yalıtım), overlay (Swarm ile birden fazla sunucuyu bağlar), macvlan ve ipvlan (container'ı fiziksel ağa doğrudan bağlar). Tek bir VPS üzerinde çalışan uygulamaların büyük çoğunluğu için doğru seçim, kendi oluşturduğunuz (user-defined) bir bridge ağıdır.
Bu yazıda her sürücünün ne yaptığını, hangi durumda tercih edildiğini, container'ın ağı nasıl gördüğünü, IP adresi ve DNS ayarlarının nasıl dağıtıldığını ve Compose dosyasında ağ modlarının nasıl seçildiğini resmî Docker belgelerine dayanarak anlatıyoruz. Sürücülerin ayrıntılı kullanımı serinin diğer yazılarında: bridge ağı, port yayınlama, macvlan ve ipvlan ve IPv6. Docker'a yeni başlıyorsanız önce Docker öğrenme rehberine bakabilirsiniz.
Container ağı nasıl görür?
Docker belgelerinin vurguladığı ilk nokta şudur: container, hangi tür ağa bağlı olduğunu ya da karşısındaki makinenin bir container olup olmadığını bilmez. Container'ın içinden bakıldığında yalnızca bir ağ arayüzü, bu arayüzün IP adresi, bir varsayılan ağ geçidi (gateway), bir yönlendirme tablosu ve DNS ayarları görünür. Bu yüzden uygulama kodunuzu değiştirmeden aynı imajı bridge ağında, host ağında ya da macvlan ağında çalıştırabilirsiniz; değişen şey, paketlerin sunucunun içinde hangi yoldan geçtiğidir.
Container'ların ağ erişimi varsayılan olarak açıktır ve dışarıya bağlantı kurabilirler. Linux üzerinde Docker Engine ilk kez başladığında "default bridge" adlı tek bir yerleşik ağ oluşturur. --network seçeneği vermeden başlattığınız her container bu ağa bağlanır. Bu ağdaki container'lar dış dünyaya "masquerading" ile çıkar: giden paketlerin kaynak adresi sunucunun adresiyle değiştirilir. Sunucunun internet erişimi varsa container için ek bir ayar gerekmez.
Yeni kurulmuş bir sunucuda docker network ls komutu üç ağı listeler. Belgelerdeki örnek çıktı şöyledir (kimlikler her kurulumda farklıdır):
docker network ls
NETWORK ID NAME DRIVER SCOPE
17e324f45964 bridge bridge local
6ed54d316334 host host local
7092879f2cc8 none null localDikkat ederseniz none ağının sürücü sütununda null yazar. bridge, host ve none ağları Docker tarafından hazır gelir; bunları silmezsiniz, yalnızca kullanırsınız ya da kullanmazsınız.
Yerleşik sürücüler tek tek

bridge
Bir sürücü belirtmeden ağ oluşturursanız oluşan ağ bridge türündedir. Belgelere göre bridge ağları, aynı sunucuda çalışan ve birbiriyle konuşması gereken container'lar için kullanılır. Bir bridge ağının bir IPv4 alt ağı ve isteğe bağlı bir IPv6 alt ağı vardır. Aynı bridge ağındaki container'lar birbirine ve sunucuya sınırsız erişebilir, başka ağlardaki container'lar ve sunucunun dışından gelen bağlantılar ise engellenir. Dışarıdan erişim yalnızca -p ile yayınladığınız portlar üzerinden olur.
Varsayılan bridge ile sizin oluşturduğunuz bridge arasında önemli farklar vardır: kullanıcı tanımlı bridge ağlarında container'lar birbirini adıyla bulur, varsayılan ağda yalnızca IP adresiyle bulabilir. Docker belgeleri kullanıcı tanımlı bridge'i açıkça daha üstün sayar ve varsayılan bridge'i üretim için önermez. Ayrıntılar Docker bridge network yazısında.
host
host modunda container'ın ağ yığını sunucudan yalıtılmaz; container sunucunun ağ ad alanını (network namespace) paylaşır ve kendine ait bir IP adresi almaz. Container içinde 80 numaralı porta bağlanan bir uygulama, doğrudan sunucunun IP adresinin 80 numaralı portunda erişilebilir olur. Container'ın kendi IP adresi olmadığı için port eşleme bu modda işe yaramaz: -p, --publish, -P ve --publish-all seçenekleri yok sayılır ve Docker şu uyarıyı verir:
WARNING: Published ports are discarded when using host network modeBelgeler host modunun iki kullanım alanını sayar: performansı iyileştirmek ve çok geniş bir port aralığını yönetmesi gereken container'lar. Sebep, bu modda ağ adresi dönüştürmesi (NAT) yapılmaması ve her port için ayrı bir "userland-proxy" süreci oluşturulmamasıdır. Bedeli ise yalıtımın kaybıdır. Compose belgeleri bu modu kullanan bir container'ın sunucudaki bütün portlara erişebileceğini ve sunucudaki bütün ağ trafiğini gözlemleyebileceğini, bu nedenle yalnızca gerçekten gerektiğinde kullanılmasını söyler. Ağ dışındaki alanlarda (dosya sistemi, süreç ad alanı, kullanıcı ad alanı) container yalıtılmış olarak kalır.
Host sürücüsü Linux üzerindeki Docker Engine'de desteklenir; Docker Desktop'ta 4.34 ve sonraki sürümlerde ayarlardan açılan bir özellik olarak bulunur. Bir Swarm servisi de --network host ile çalıştırılabilir; bu durumda yönetim trafiği yine overlay ağından gider, ama servis container'ları veri için sunucunun portlarını kullanır. Bunun sonucu olarak 80 numaralı porta bağlanan bir servisten bir Swarm düğümünde yalnızca bir container çalışabilir.
none
--network none ile başlatılan container'ın ağ yığını tamamen yalıtılır; içeride yalnızca loopback aygıtı oluşturulur. Belgelerdeki örnekte ip link show çıktısında sadece lo arayüzü görünür:
docker run --rm --network none alpine:latest ip link show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00Belgelere göre none sürücüsünü kullanan container'larda IPv6 loopback adresi de yapılandırılmaz; yalnızca 127.0.0.1/8 bulunur. Ayrıca none Swarm servisleri için kullanılamaz. Ağa hiç ihtiyaç duymayan bir işi çalıştırırken bu mod, yanlışlıkla dışarıya bağlantı kurulmasının önüne geçer.
overlay
Overlay ağları birden fazla Docker daemon'ını birbirine bağlar ve Swarm servislerinin ve container'larının farklı düğümler arasında konuşmasını sağlar. Belgelere göre bu yaklaşım işletim sistemi düzeyinde yönlendirme kurma ihtiyacını ortadan kaldırır. Farklı sunuculardaki container'ların haberleşmesi gerekiyorsa ya da birlikte çalışan servisleri Swarm ile yönetiyorsanız overlay en uygun sürücüdür. Swarm kurulumu ve servis ağları Docker Swarm kurulumu yazısında anlatılıyor.
macvlan ve ipvlan
Macvlan, her container'a kendi MAC adresini verir ve container ağdaki diğer cihazlara fiziksel bir makine gibi görünür. Belgeler bu sürücüyü özellikle sanal makine düzeninden geçiş yapanlar ve doğrudan fiziksel ağa bağlı olmayı bekleyen eski uygulamalar için önerir. IPvlan benzer şekilde çalışır ama container'lara ayrı MAC adresi atamaz; bir ağ arayüzüne ya da porta atanabilecek MAC adresi sayısında sınır varsa tercih edilir. İkisi de bulut sağlayıcılarında çoğu zaman kullanılamaz; ayrıntılar Docker macvlan ve ipvlan yazısında.
Ağ eklentileri
Docker'ın ağ alt sistemi eklenebilir (pluggable) yapıdadır. Yerleşik sürücülerin yanında üçüncü taraf ağ eklentileri kurup kullanabilirsiniz. Belgeler bunları özel ağ yığınlarıyla bütünleşmek için bir seçenek olarak anar.
Sürücü karşılaştırması
| Sürücü | Container IP adresi | Port yayınlama | Tipik kullanım |
|---|---|---|---|
| bridge (kullanıcı tanımlı) | Ağın alt ağından | Gerekir (-p) | Tek sunucudaki çok servisli uygulamalar |
| bridge (varsayılan) | docker0 alt ağından | Gerekir (-p) | Özel ihtiyacı olmayan tekil container'lar |
| host | Yok, sunucunun ağı kullanılır | Yok sayılır | Performans, çok geniş port aralığı |
| none | Yok, yalnızca loopback | Yok | Ağ gerektirmeyen işler |
| overlay | Overlay alt ağından | Swarm yönlendirmesi | Birden fazla sunucu, Swarm servisleri |
| macvlan | Fiziksel ağın alt ağından | Gerekmez | Fiziksel cihaz gibi görünmesi gereken uygulamalar |
| ipvlan | Fiziksel ağın alt ağından | Gerekmez | MAC adresi sınırı olan ağlar, L3 yönlendirme |
Tablodaki "Gerekmez" ifadesi, container zaten fiziksel ağdan erişilebilir bir adres aldığı için port eşlemeye gerek kalmaması anlamındadır. Güvenlik açısından önemli bir ayrıntı daha var: Docker belgelerine göre Docker güvenlik duvarı kurallarını bridge ağları için oluşturur; ipvlan, macvlan ve host ağları için hiçbir kural oluşturmaz. Bu ağlarda erişim denetimi tamamen sizin sunucu ve ağ yapılandırmanıza kalır. Bridge tarafındaki kurallar Docker iptables ve UFW yazısında ele alınıyor.
Container ağı paylaşma: container:<ad> modu

Kullanıcı tanımlı ağlara ek olarak bir container'ı başka bir container'ın ağ yığınına doğrudan bağlayabilirsiniz. Bunun için --network container:<ad|id> biçimi kullanılır. İki container aynı ağ arayüzünü, aynı IP adresini ve aynı loopback'i paylaşır. Belgelerdeki örnekte Redis yalnızca 127.0.0.1 adresini dinler; ikinci container aynı ağ yığınına katıldığı için redis-cli ile 127.0.0.1 üzerinden bağlanabilir:
docker run -d --name redis redis --bind 127.0.0.1
docker run --rm -it --network container:redis redis redis-cli -h 127.0.0.1Bu modda ağ ayarlarının sahibi ilk container olduğu için şu seçenekler desteklenmez: --add-host, --hostname, --dns, --dns-search, --dns-option, --mac-address, --publish, --publish-all ve --expose. Port yayınlamak istiyorsanız bunu ağ yığınının sahibi olan container üzerinde yapmanız gerekir. Compose dosyalarında aynı davranış network_mode: "service:[servis adı]" ile elde edilir.
Birden fazla ağa bağlanma ve varsayılan ağ geçidi
Belgeler ağa bağlanmayı bir makineye Ethernet kablosu takmaya benzetir. Bir makine birden fazla ağa bağlanabildiği gibi bir container da birden fazla Docker ağına bağlanabilir. Örneğin bir ön yüz container'ı dış erişimi olan bir bridge ağına ve arka uç servisleriyle konuşmak için --internal ile oluşturulmuş, dış erişimi olmayan bir ağa aynı anda bağlı olabilir. Farklı türdeki ağlar da birleştirilebilir: internet erişimi için bir ipvlan ağı, yerel servisler için bir bridge ağı gibi.
Paket gönderilirken hedef doğrudan bağlı ağlardan birindeyse paket o ağa gider; değilse varsayılan ağ geçidine gönderilir. Varsayılan ağ geçidini Docker seçer ve container'ın ağ bağlantıları değiştikçe bu seçim değişebilir. Belirli bir ağın her zaman varsayılan ağ geçidi olmasını istiyorsanız gw-priority değerini kullanırsınız. Varsayılan değer 0'dır ve en yüksek önceliğe sahip ağın ağ geçidi seçilir; dolayısıyla bir ağa 1 vermek yeterlidir:
docker run --network name=gwnet,gw-priority=1 --network anet1 --name myctr myimage
docker network connect anet2 myctrÇalışan bir container'ı ek bir ağa docker network connect ile bağlarsınız. Bağlanırken --ip ve --ip6 ile o ağdaki adresi, --alias ile o ağda geçerli ek bir ad verebilirsiniz.
IP adresi dağıtımı ve alt ağ havuzları
Bir ağ oluşturduğunuzda IPv4 adres dağıtımı varsayılan olarak açıktır ve --ipv4=false ile kapatılabilir; IPv6 ise --ipv6 ile açılır. Container bağlandığı her Docker ağı için o ağın alt ağından bir IP adresi alır. Alt ağı açıkça verebilirsiniz (--subnet 192.0.2.0/24); vermezseniz Docker, daemon'ın "default address pools" adlı havuzlarından otomatik bir alt ağ seçer. Belgelere göre yerleşik varsayılan havuz şu yapılandırmaya eşdeğerdir:
{
"default-address-pools": [
{ "base": "172.17.0.0/16", "size": 16 },
{ "base": "172.18.0.0/16", "size": 16 },
{ "base": "172.19.0.0/16", "size": 16 },
{ "base": "172.20.0.0/14", "size": 16 },
{ "base": "172.24.0.0/14", "size": 16 },
{ "base": "172.28.0.0/14", "size": 16 },
{ "base": "192.168.0.0/16", "size": 20 }
]
}Burada base dağıtımın yapılacağı alt ağı, size her ağa verilecek önek uzunluğunu belirtir. Docker sunucuda kullanılan adres öneklerinden kaçınmaya çalışır, ama bazı ortamlarda (örneğin sunucunun bağlı olduğu özel ağ 172.16.0.0/12 aralığındaysa) yönlendirme çakışmalarını önlemek için bu havuzu özelleştirmeniz gerekebilir. Varsayılan havuzlar büyük alt ağlar kullandığı için oluşturabileceğiniz ağ sayısı sınırlıdır. Belgelerdeki örnekte tek bir 172.17.0.0/16 tabanı /24 parçalara bölünerek 256 ağ elde edilir:
{
"default-address-pools": [{ "base": "172.17.0.0/16", "size": 24 }]
}Docker Engine 29.0.0 ile gelen bir yenilik de var: --subnet seçeneğinde belirtilmemiş adres kullanarak varsayılan havuzdan belirli uzunlukta bir alt ağ isteyebilirsiniz, örneğin --subnet 0.0.0.0/24 ya da --subnet ::/56. Belgeler bir uyarı ekler: Docker bu desteğin olmadığı eski bir sürüme düşürülürse bu şekilde oluşturulmuş ağlar kullanılamaz hale gelir; silinip yeniden oluşturulmaları ya da daemon'ın 29.0.0 veya sonrasına döndürülmesi gerekir. daemon.json dosyasının genel kullanımı için daemon.json yapılandırma yazısına bakın.
DNS ve ad çözümleme

Container'lar varsayılan olarak sunucunun DNS sunucularını kullanır ve ayarlarını sunucudaki /etc/resolv.conf dosyasından devralır. Burada sürücüye göre önemli bir fark vardır. Varsayılan bridge ağına bağlanan container'lar bu dosyanın bir kopyasını alır. Kullanıcı tanımlı bir ağa bağlanan container'lar ise Docker'ın gömülü DNS sunucusunu kullanır. Gömülü DNS sunucusunun adresi 127.0.0.11'dir; dış adlar için gelen sorguları sunucuda yapılandırılmış DNS sunucularına iletir. Belgelere göre bunun IPv6 karşılığı yoktur, ama IPv4 adresi yalnızca IPv6 kullanan container'larda bile çalışır. Uygulamanız açık bir DNS sunucusu adresi istiyorsa 127.0.0.11 verebilirsiniz.
Birden fazla DNS sunucusu tanımladığınızda davranış da farklıdır. Varsayılan bridge ağında sorguların nasıl yapılacağına container içindeki çözümleyici kütüphane karar verir: bazıları sunucuları sırayla dener, bazıları paralel sorgulayıp ilk gelen yanıtı (NXDOMAIN olsa bile) kullanır. Kullanıcı tanımlı ağda gömülü DNS sunucusu üst sunucuları sırayla sorgular ve başarılı bir yanıt ya da NXDOMAIN aldığında durur.
| Bayrak | Ne yapar |
|---|---|
| --dns | DNS sunucusunun IP adresi; birden fazla sunucu için bayrağı tekrarlayın. Adres container'ın ağ ad alanından kullanılır. |
| --dns-search | Tam nitelikli olmayan adlar için arama alan adı; birden fazlası için bayrağı tekrarlayın. |
| --dns-option | resolv.conf seçeneği olarak anahtar-değer çifti. |
| --hostname | Container'ın kendisi için kullandığı ad; verilmezse container kimliğidir. |
--dns=127.0.0.1 yazarsanız bu adres sunucunun değil container'ın kendi loopback adresi anlamına gelir; çünkü DNS istekleri container'ın ağ ad alanından gönderilir. Sunucunun /etc/hosts dosyasındaki özel kayıtlar da container'lara geçmez; ek kayıt gerekiyorsa --add-host ya da Compose'daki extra_hosts kullanılır.
Compose'ta ağ modu seçimi
Compose varsayılan olarak her proje için <proje-adı>_default adlı bir bridge ağı oluşturur ve bütün servisleri bu ağa bağlar. Belgeler bu varsayılanı en güvenli mod olarak tanımlar. Servis düzeyinde network_mode ile host, none, service:{ad} ya da container:{ad} seçebilir, üst düzey networks anahtarıyla kendi ağlarınızı tanımlayabilirsiniz. Aşağıdaki dosya beş servisi farklı ağ düzenlerine yerleştirir ve Docker CLI 29.8.1, Docker Compose v5.5.1 ile docker compose config --quiet komutundan hatasız geçmiştir:
services:
web:
image: nginx:latest
networks:
- frontend
ports:
- "127.0.0.1:8080:80"
api:
image: example/api:latest
networks:
- frontend
- backend
db:
image: postgres:18
networks:
- backend
monitor:
image: netdata/netdata
network_mode: host
batch:
image: alpine:latest
command: ["sh", "-c", "echo ağ yok"]
network_mode: none
networks:
frontend:
backend:
internal: trueBu düzende web yalnızca frontend ağındadır ve portu sadece sunucunun loopback adresine yayınlanır. api iki ağa birden bağlı olduğu için hem web hem db ile konuşabilir. db ise internal: true olan backend ağındadır; Compose belgelerine göre bu ağın dış bağlantı için varsayılan ağ geçidi yoktur. monitor sunucunun ağını kullanır ve servis adıyla DNS çözümlemesi bu container için çalışmaz. batch ise hiçbir ağa çıkamaz.
network_mode ile networks aynı serviste birlikte kullanılamaz. Bunu denediğinizde Compose dosyayı reddeder. Aşağıdaki çıktı, network_mode: host ve networks içeren bir dosyada docker compose config --quiet komutunun gerçek çıktısıdır:
docker compose -f compose.yaml config --quiet
service monitor declares mutually exclusive `network_mode` and `networks`: invalid compose projectCompose'taki temel ağ kullanımı (servis adıyla bağlanma, override dosyaları) Docker Compose rehberinde anlatılıyor; bu yazı yalnızca ağ türü seçimine odaklanıyor.
Hangi sürücüyü ne zaman seçmeli?
- Tek bir VPS üzerinde web, API ve veritabanından oluşan bir uygulama çalıştırıyorsanız kullanıcı tanımlı bir bridge ağı (Compose'un varsayılan ağı da budur) kullanın.
- Veritabanı gibi dışarıya hiç çıkmaması gereken servisleri ayrı bir internal ağa koyun ve yalnızca onlarla konuşması gereken servisleri o ağa da bağlayın.
- Container çok geniş bir port aralığı kullanıyorsa ya da NAT'ın getirdiği ek işlemden kaçınmak istiyorsanız host modunu düşünün, ama yalıtımın kalktığını unutmayın.
- Birden fazla sunucuya yayılan servisler için Swarm ve overlay ağı kullanın.
- Container'ın yerel ağda kendi MAC ve IP adresiyle görünmesi gerekiyorsa ve ağ donanımınız buna izin veriyorsa macvlan; MAC adresi sınırı varsa ipvlan seçin.
- Ağ gerektirmeyen tek seferlik işlerde none kullanın.
Sık yapılan hatalar
- Varsayılan bridge'de container adıyla bağlanmaya çalışmak: varsayılan ağda ad çözümleme yoktur;
ping: bad addresstüründe hata alırsınız. Kullanıcı tanımlı bir ağ oluşturun. - Host modunda -p kullanmak: port eşleme bu modda yok sayılır. Compose belgeleri
network_mode: hostileportsbirlikte kullanıldığında çalışma zamanında hata oluşacağını belirtir;docker compose configbu birleşimi reddetmez, hata container başlatılırken ortaya çıkar. - IP adresine güvenmek: Compose belgelerine göre container IP adresleri her başlatmada dinamik olarak verilir ve yeniden oluşturmada değişir. Servislere adıyla erişin.
- Alt ağ çakışmasını gözden kaçırmak: sunucunun özel ağı Docker'ın varsayılan havuzlarıyla çakışıyorsa
default-address-poolsayarını değiştirin. - macvlan, ipvlan ve host ağlarında Docker'ın güvenlik duvarı kuralı koyacağını sanmak: belgelere göre bu ağlar için kural oluşturulmaz.
Sık Sorulan Sorular
Docker'da varsayılan network hangisidir?
Linux üzerinde Docker Engine ilk başladığında "bridge" adlı varsayılan bridge ağını oluşturur ve --network verilmeyen container'lar bu ağa bağlanır. Compose ise her proje için ayrı bir <proje-adı>_default bridge ağı oluşturur.
host network daha mı hızlı?
Belgeler host modunu performans iyileştirmesi için kullanılabilecek bir seçenek olarak anar, çünkü NAT yapılmaz ve port başına userland-proxy oluşturulmaz. Bir hız rakamı vermez. Karşılığında container'ın ağ yalıtımı ortadan kalkar.
Bir container aynı anda birden fazla ağa bağlanabilir mi?
Evet. --network bayrağını birden fazla kez verebilir ya da çalışan container'ı docker network connect ile yeni bir ağa bağlayabilirsiniz. Hangi ağın varsayılan ağ geçidi olacağını gw-priority ile belirlersiniz.
Container'ın içinden 127.0.0.11 adresi ne işe yarar?
Kullanıcı tanımlı ağlardaki container'ların kullandığı gömülü DNS sunucusunun adresidir. Container adlarını çözer ve dış adlar için sorguları sunucunun DNS sunucularına iletir.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Docker öğrenme rehberi · Docker bridge network · Docker port yayınlama · Docker iptables ve UFW · Docker macvlan ve ipvlan · Docker IPv6 · Docker Compose rehberi