Kurumsal bir ağda Docker ile çalışıyorsanız, sınırlı erişime sahip bir sunucuda bulunuyorsanız veya konteynerlerinizin belirli bir IP üzerinden internete çıkmasını istiyorsanız, doğru proxy ayarları olmadan Docker, Docker Hub veya başka bir kayıt deposundan görüntüleri çekemez. Bu yazıda, proxy ayarlarının tüm seviyelerini — daemon'dan ayrı bir konteynere kadar inceleyeceğiz.
Docker için proxy neden gereklidir
Docker, sürekli olarak dış kaynaklara erişim sağlayan bir araçtır. Her docker pull veya docker build komutunda, daemon Docker Hub, GitHub Container Registry, Google Container Registry veya özel kayıt deponuza erişim sağlar. İşte burada sorunlar başlar.
Proxy olmadan geçilemeyecek durumlar:
- Kurumsal ağda güvenlik duvarı — tüm trafik kurumsal proxy sunucusu üzerinden gitmek zorundadır, aksi takdirde bağlantı engellenir.
- Coğrafi kısıtlamalar — Docker Hub veya belirli kayıtlar ülkenizden veya veri merkezinizden erişilemez.
- Doğrudan internete çıkışı olmayan sınırlı sunucu — kapalı bir ağda, internet yalnızca bir geçit üzerinden erişilebilir.
- Konteynerlerin çıkış trafiğini kontrol etme — konteynerler içindeki uygulamaların belirli bir IP üzerinden internete çıkmasını istiyorsanız, örneğin, veri çekme, API istekleri veya coğrafi bağımlı içerik testleri için.
- İsteklerin anonimleştirilmesi — konteynerden dış hizmetlere erişim sağlarken gerçek sunucu IP'sini gizlemek.
- Rate limiting — Docker Hub, anonim kullanıcılar için çekme isteklerini sınırlar (6 saat içinde 100 çekme). IP döngüsü ile proxy üzerinden bu sınırlamayı aşabilirsiniz.
Docker'ın tek bir uygulama değil, birkaç bileşenden oluşan bir sistem olduğunu anlamak önemlidir. Daemon (dockerd) hostta bulunur ve görüntüleri çeker. Konteynerler, kendi ağ ayarları ile izole edilmiş süreçlerdir. Bu nedenle, daemon için proxy ayarlamak ile konteynerler için proxy ayarlamak iki farklı görevdir ve farklı şekillerde çözülür.
Docker'da üç proxy seviyesi
Konfigürasyon dosyalarına girmeden önce, mimariyi anlamak gerekir. Docker'da, her biri ayrı proxy ayarları gerektiren üç bağımsız seviye vardır:
| Seviye | Ne yapar | Nerede ayarlanır |
|---|---|---|
| Docker daemon | Görüntüleri indirir (docker pull), kayıtlarla iletişim kurar | systemd override veya daemon.json |
| Docker build | Görüntü oluşturma sırasında komutları çalıştırır (RUN apt-get, pip install vb.) | Dockerfile'da ARG ve ENV veya --build-arg |
| Runtime konteyner | HTTP istekleri yapan çalıştırılan uygulama | docker run sırasında ENV veya docker-compose.yml içinde |
Tipik bir hata, sadece bir seviyede proxy ayarlamak ve görüntülerin hala çekilmemesi veya uygulamanın proxy'yi görememesi karşısında şaşırmaktır. Her bir seviyeyi detaylı olarak inceleyelim.
Docker daemon için proxy ayarı (görüntüleri çekme)
Proxy ayarlarının en önemli kısmıdır, eğer görüntüleri proxy üzerinden çekmek istiyorsanız. Docker daemon, systemd üzerinden başlatılan bir sistem hizmetidir. Kullanıcı veya root ortam değişkenlerini göremez. Proxy'yi hizmetin ortamına iletmek gerekir.
Yöntem 1: systemd override ile (önerilir)
Hizmet ayarlarını geçersiz kılmak için bir dizin oluşturun:
sudo mkdir -p /etc/systemd/system/docker.service.d
Aşağıdaki içeriğe sahip bir /etc/systemd/system/docker.service.d/http-proxy.conf dosyası oluşturun:
[Service] Environment="HTTP_PROXY=http://username:password@proxy-host:port" Environment="HTTPS_PROXY=http://username:password@proxy-host:port" Environment="NO_PROXY=localhost,127.0.0.1,::1,your-private-registry.example.com"
Eğer proxy kimlik doğrulaması yoksa, username:password@ kısmını kaldırın. Dosyayı oluşturduktan sonra systemd yapılandırmasını yeniden yükleyin ve Docker'ı yeniden başlatın:
sudo systemctl daemon-reload sudo systemctl restart docker
Ayarların uygulandığını kontrol edin:
sudo systemctl show --property=Environment docker
Çıktıda HTTP_PROXY ve HTTPS_PROXY değişkenleriniz görünmelidir.
Yöntem 2: ~/.docker/config.json üzerinden (Docker Desktop ve yeni sürümler)
Docker Engine 23.0'dan itibaren daha kullanışlı bir yöntem — proxy ayarlarını istemci yapılandırma dosyası üzerinden yapmaktır. Aşağıdaki içeriğe sahip bir ~/.docker/config.json dosyası oluşturun veya düzenleyin:
{
"proxies": {
"default": {
"httpProxy": "http://username:password@proxy-host:port",
"httpsProxy": "http://username:password@proxy-host:port",
"noProxy": "localhost,127.0.0.1,::1"
}
}
}
Bu yöntem, root yetkisi gerektirmediği ve daemon'u yeniden başlatmayı gerektirmediği için kullanışlıdır. Ayarlar otomatik olarak konteynerlere build-argümanları olarak iletilir. Ancak, daemon'ın pull isteklerini yönetmesi için yine de systemd üzerinden bir yöntem gereklidir.
💡 NO_PROXY hakkında önemli
Her zaman NO_PROXY içine iç kayıtlarınızın ve hizmetlerinizin adreslerini ekleyin. Aksi takdirde, Docker bunlara proxy üzerinden erişmeye çalışacak ve bağlantı hataları alacaksınız. Tipik bir liste: localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
Konteyner içinde proxy ayarı (build-time)
Docker bir görüntü oluşturduğunda ve RUN apt-get install, RUN pip install veya RUN npm install gibi komutları çalıştırdığında — bu komutlar geçici bir konteyner içinde çalıştırılır. Varsayılan olarak, hostun proxy'sine erişimi yoktur. Proxy'yi açıkça build-argümanları ile iletmek gerekir.
Proxy'yi --build-arg ile iletme
docker build \ --build-arg HTTP_PROXY=http://proxy-host:port \ --build-arg HTTPS_PROXY=http://proxy-host:port \ --build-arg NO_PROXY=localhost,127.0.0.1 \ -t my-image .
Dockerfile'da ayarlama
Eğer proxy yalnızca build aşamasında gerekiyorsa ve son görüntüye girmesini istemiyorsanız — ARG kullanın, ENV değil:
FROM ubuntu:22.04 # Build argümanlarını tanımlıyoruz ARG HTTP_PROXY ARG HTTPS_PROXY ARG NO_PROXY # Komutlarda kullanıyoruz RUN apt-get update && apt-get install -y curl wget # Bu bloktan sonra proxy, konteynerin ENV'sinde olmayacak
Eğer proxy, çalışan konteynerde de gerekiyorsa — ENV kullanın:
FROM python:3.11 ENV HTTP_PROXY=http://proxy-host:port ENV HTTPS_PROXY=http://proxy-host:port ENV NO_PROXY=localhost,127.0.0.1 RUN pip install requests beautifulsoup4 CMD ["python", "app.py"]
⚠️ Dikkat: Güvenlik
Eğer görüntü kamuya açık olacaksa veya bir depoya girecekse, proxy'nin kullanıcı adı ve şifresini doğrudan Dockerfile'a sabitlemeyin. --build-arg kullanın ve değerleri CI/CD sisteminin ortam değişkenlerinden iletin. docker history komutu ARG değerlerini gösterebilir, bu nedenle gizli bilgiler için Docker BuildKit gizli anahtarlarını kullanın.
Çalışan konteyner için proxy (runtime)
Bu, HTTP istekleri yapan uygulamalar için en yaygın senaryodur — veri çekiciler, botlar, belirli bir IP üzerinden çıkışa ihtiyaç duyan mikro hizmetler. Burada ayar en basit şekildedir: konteyneri başlatırken ortam değişkenlerini iletmek gerekir.
docker run ile
docker run \ -e HTTP_PROXY=http://username:password@proxy-host:port \ -e HTTPS_PROXY=http://username:password@proxy-host:port \ -e NO_PROXY=localhost,127.0.0.1 \ my-image
Çoğu popüler HTTP kütüphanesi otomatik olarak HTTP_PROXY ve HTTPS_PROXY değişkenlerini alır: Python requests, curl, wget, Go'nun net/http'si, Node.js https-proxy-agent ve diğerleri. Kodu eklemeye gerek yoktur.
.env dosyası ile
Ayarları .env dosyasında saklamak ve tamamını iletmek daha kullanışlıdır:
# .env dosyası HTTP_PROXY=http://username:password@proxy-host:port HTTPS_PROXY=http://username:password@proxy-host:port NO_PROXY=localhost,127.0.0.1
docker run --env-file .env my-image
Konteynerde SOCKS5 proxy
Eğer SOCKS5 proxy kullanıyorsanız (örneğin, rezidans proxy'leri genellikle bu protokolü destekler), sözdizimi biraz farklıdır:
docker run \ -e ALL_PROXY=socks5://username:password@proxy-host:port \ my-image
Dikkat: Tüm kütüphaneler, ek bağımlılıklar olmadan ortam değişkeni üzerinden SOCKS5'i desteklemiyor. Python requests, requests[socks] yüklenmesini gerektirir, curl ise libcurl-socks desteği ile derlenmelidir.
Docker Compose'da proxy
Gerçek projelerde genellikle sadece docker run kullanılmaz. Çoğunlukla, birden fazla hizmetin tek bir dosyada tanımlandığı Docker Compose ile çalışılır. Burada proxy ayarı, her hizmet seviyesinde veya değişken dosyası aracılığıyla yapılır.
Seçenek 1: docker-compose.yml içinde environment
version: '3.8'
services:
scraper:
image: my-scraper:latest
environment:
- HTTP_PROXY=http://username:password@proxy-host:port
- HTTPS_PROXY=http://username:password@proxy-host:port
- NO_PROXY=localhost,127.0.0.1
restart: unless-stopped
api:
image: my-api:latest
# Bu hizmet proxy olmadan — yalnızca iç kaynaklara erişir
ports:
- "8080:8080"
Seçenek 2: .env dosyası aracılığıyla (önerilir)
.env dosyasını docker-compose.yml dosyasının bulunduğu dizinde oluşturun. Docker Compose bu dosyayı otomatik olarak alır:
# .env PROXY_HOST=proxy-host PROXY_PORT=8080 PROXY_USER=username PROXY_PASS=password
version: '3.8'
services:
scraper:
image: my-scraper:latest
environment:
- HTTP_PROXY=http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}
- HTTPS_PROXY=http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}
- NO_PROXY=localhost,127.0.0.1
Compose'da build aşamasında proxy
Eğer Compose'da bir build bölümü varsa ve proxy'yi build aşamasında iletmek gerekiyorsa:
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
args:
HTTP_PROXY: http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}
HTTPS_PROXY: http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}
environment:
- HTTP_PROXY=http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}
- HTTPS_PROXY=http://${PROXY_USER}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}
Docker için hangi proxy türünü seçmeliyim
Proxy türü seçimi, göreve bağlıdır. Docker ortamları için üç ana tür geçerlidir, her birinin kendine özgü bir yeri vardır:
| Proxy Türü | Hız | Anonimlik | Docker için en iyi senaryo |
|---|---|---|---|
| Veri merkezi | ⚡ Yüksek | Orta | Görüntüleri çekme, CI/CD hatları, Docker Hub'daki rate limiting'i aşma |
| Rezidans | 🔄 Orta | Yüksek | Koruma olan siteleri tarama, coğrafi kısıtlamalı API'ler, test etme |
| Mobil | 🔄 Orta | Maksimum | Mobil API'lerle (Instagram, TikTok) çalışan uygulamalar |
Görüntüleri çekme ve CI/CD için en uygun olanı veri merkezi proxy'leridir — büyük görüntüleri (birkaç gigabayt) indirirken maksimum hız ve uzun derlemeler için kararlı bir bağlantı sağlarlar.
Proxy'lere ihtiyaç duyan konteynerler için, koruma olan siteleri aşmak ve normal bir kullanıcı gibi görünmek için rezidans proxy'leri daha uygundur. Gerçek ev kullanıcılarının IP'lerine sahip oldukları için yoğun isteklerde bile engellenme olasılığını azaltır.
Mobil platformlarla çalışan uygulamalar için — Instagram Graph API, TikTok API, hizmetlerin mobil versiyonları — mobil proxy'leri değerlendirilmelidir. Bunlar, cep telefonu operatörlerinin IP'lerini kullanır ve anti-bot sistemleri tarafından en az şüphe uyandırır.
Protokoller: HTTP vs SOCKS5
Docker daemon yalnızca HTTP/HTTPS proxy'lerini destekler — SOCKS5, görüntüleri çekmek için çalışmaz. Eğer SOCKS5 proxy'niz varsa ve görüntüleri çekmeniz gerekiyorsa, privoxy veya microsocks gibi yerel bir dönüştürücü kullanmanız gerekecek; bu, HTTP'yi alır ve SOCKS5 üzerinden proxy'ler.
Runtime konteynerleri için durum daha iyidir: Çoğu HTTP kütüphanesi, ALL_PROXY=socks5://... ortam değişkeni üzerinden SOCKS5'i doğrudan destekler.
Yaygın hatalar ve nasıl düzeltileceği
Docker'da proxy ayarlarken karşılaşılan en yaygın sorunları inceleyelim:
Hata 1: Proxy hostta ayarlandı, ancak Docker bunu göremiyor
Belirti:
Error response from daemon: Get "https://registry-1.docker.io/v2/": dial tcp: connection refused
Neden: Docker daemon, sistem hizmeti olarak başlatılır ve mevcut kullanıcının ortam değişkenlerini miras almaz, hatta terminalde export HTTPS_PROXY=... ayarlamış olsanız bile.
Çözüm: Proxy'yi systemd override ile ayarlayın (yukarıdaki bölümdeki yöntem 1). Mutlaka systemctl daemon-reload && systemctl restart docker komutunu çalıştırın.
Hata 2: apt-get / pip / npm build sırasında çalışmıyor
Belirti:
Err:1 http://archive.ubuntu.com/ubuntu focal InRelease
Could not connect to archive.ubuntu.com:80
Neden: Daemon için proxy ayarı, Dockerfile'daki RUN komutları için otomatik olarak yayılmaz. Bu iki farklı bağlamdır.
Çözüm: Proxy'yi --build-arg ile iletin veya ~/.docker/config.json dosyasını proxies bölümü ile kullanın (Docker 23.0+, otomatik olarak build sırasında argümanları iletir).
Hata 3: İç hizmetler proxy üzerinden erişilemiyor
Belirti:
curl: (7) Failed to connect to internal-service.local port 8080: Connection refused
Neden: Proxy, dışarıdan erişilemeyen iç adreslere istekleri proxy'lemeye çalışıyor.
Çözüm: Tüm iç alan adlarını ve alt ağları NO_PROXY içine ekleyin. Kurumsal ağlar için tipik bir liste: localhost,127.0.0.1,::1,.internal,.local,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
Hata 4: Proxy kimlik doğrulaması çalışmıyor — şifrede özel karakterler
Eğer şifre özel karakterler içeriyorsa (@, #, %), URL yanlış bir şekilde ayrıştırılır.
Çözüm: Şifreyi URL kodlaması ile kodlayın. Örneğin, p@ss#word → p%40ss%23word. Python'da hızlı bir şekilde kodlanmış versiyonu elde edebilirsiniz:
python3 -c "from urllib.parse import quote; print(quote('p@ss#word', safe=''))"
# Çıktı: p%40ss%23word
Hata 5: Proxy çalışıyor, ancak SSL sertifikası doğrulanmıyor
Kurumsal proxy'ler genellikle SSL denetimi (MITM) yapar ve sertifikaları değiştirir. Bu durumda Docker hata verir:
x509: certificate signed by unknown authority
Çözüm: Kurumsal kök sertifikasını hostta güvenilir sertifikalar arasına ekleyin ve Docker'ı yeniden başlatın. Ubuntu/Debian üzerinde:
sudo cp corporate-ca.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates sudo systemctl restart docker
Hata 6: Kubernetes / Docker Swarm — proxy tüm düğümlerde çalışmıyor
Küme ortamlarında, her düğümde ayrı ayrı proxy ayarları yapılması gerekir. Kubernetes için, pod manifestolarında veya ConfigMap aracılığıyla ortam değişkenlerinin ayarlanması gereklidir. Bunu Ansible veya diğer yapılandırma yönetim araçları ile otomatikleştirebilirsiniz.
Sonuç
Docker'da proxy ayarlamak, tek bir ayar değil, üç bağımsız seviyeden oluşur: görüntüleri çekmek için daemon, build-time için ve çalışan konteynerler için runtime. Bu mimariyi anladıktan sonra, hangi trafiğin proxy üzerinden gideceğini ve hangisinin doğrudan gideceğini esnek bir şekilde yönetebilirsiniz.
Doğru ayarların kısa bir kontrol listesi:
- ✅ Görüntüleri çekmek için — HTTP_PROXY ve HTTPS_PROXY değişkenleri ile systemd override ayarlayın
- ✅ Build için — proxy'yi
--build-argveya~/.docker/config.jsonüzerinden iletin - ✅ Runtime için —
-eveya--env-fileile ortam değişkenlerini kullanın - ✅ Her zaman iç adresler için NO_PROXY ayarını yapın
- ✅ Proxy şifrelerini Dockerfile'da saklamayın — build-arg'leri ve .env dosyalarını kullanın
- ✅ CI/CD hatları için hızlı veri merkezi proxy'lerini seçin
- ✅ Veri çekme konteynerleri için — rezidans veya mobil proxy'leri
Eğer konteyner uygulamalarınız dış hizmetlere istek yapıyorsa, veri çekiyorsa veya coğrafi kısıtlamalara sahip API'lerle çalışıyorsa, rezidans proxy'lerini kullanmanızı öneririz — bu, hizmetler tarafından yüksek bir güven düzeyi sağlar ve yoğun çalışma sırasında bile engellenme riskini en aza indirir.