Docker'da proxy kurulumu; imaj çekme, build alma veya uygulama içinden dış kaynaklara erişme gibi işlerde giden ağ trafiğini aracı bir proxy sunucusu üzerinden yönlendirmek için tek tek konteynerleri, docker-compose servislerini ya da doğrudan Docker daemon'ını yapılandırmak anlamına gelir.
Docker ile neden proxy kullanılır?
Docker ortamlarına proxy entegre etmek birkaç yaygın ihtiyacı karşılar:
- İnternet erişimi denetimi: Kurumsal veya kısıtlı ağlarda, build sunucularından ya da konteynerlerden doğrudan internet erişimi yasak olabilir. Proxy, denetimli bir ağ geçidi görevi görür.
- Güvenlik taraması ve filtreleme: Proxy'ler konteynerlerden çıkan trafiği zararlı içerik için tarayabilir veya içerik politikalarını uygulayabilir.
- Önbellekleme: Proxy'ler sık erişilen dış kaynakları (örneğin paket yöneticisi depoları, temel imajlar) önbelleğe alarak bant genişliği kullanımını azaltır ve build/indirme işlemlerini hızlandırır.
- Anonimlik/coğrafi engel aşma: Kurumsal kurulumlarda daha az yaygın olsa da proxy'ler kaynak IP'yi gizleyebilir veya coğrafi kısıtlamaları aşabilir.
Proxy yapılandırma türleri
Docker'da proxy kullanımının iki temel bağlamı vardır:
- Docker daemon proxy'si: Temel imaj çekme, uzak registry'lere erişme veya build süreci (
RUN apt-get updategibi komutlar) sırasında Docker daemon'ının proxy kullanmasını sağlar. - Konteyner/servis proxy'si: Tek tek konteynerlerin veya
docker-composeiçindeki servislerin çalışma zamanında kendi giden uygulama trafiği için proxy kullanmasını sağlar.
Bu yapılandırmalar birbirinden bağımsızdır ve eksiksiz bir kurulum için çoğu zaman ikisi birden gerekir.
Docker daemon proxy yapılandırması
Bu yöntem, imaj çekme ve bazı build adımları dahil olmak üzere Docker daemon işlemlerinin belirtilen proxy üzerinden geçmesini sağlar.
systemd tabanlı Linux sunucuları için
Modern Linux dağıtımlarının çoğu systemd kullanır. Docker servisi için bir drop-in dizini oluşturun:
sudo mkdir -p /etc/systemd/system/docker.service.d
Bu dizinin içinde bir yapılandırma dosyası oluşturun (örneğin http-proxy.conf):
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf
YOUR_PROXY_HOST ve YOUR_PROXY_PORT yerine kendi proxy bilgilerinizi yazarak aşağıdaki içeriği ekleyin:
[Service]
Environment="HTTP_PROXY=http://YOUR_PROXY_HOST:YOUR_PROXY_PORT"
Environment="HTTPS_PROXY=http://YOUR_PROXY_HOST:YOUR_PROXY_PORT"
Environment="NO_PROXY=localhost,127.0.0.1,::1,YOUR_DOCKER_NETWORK_CIDR,YOUR_INTERNAL_DOMAINS"
Not:
* TLS anlaşmasını proxy sunucusu yürüttüğü için, HTTP_PROXY ve HTTPS_PROXY genellikle HTTPS trafiğinde bile http:// şemasını kullanmalıdır.
* NO_PROXY kritik önemdedir. Belirtilen host veya ağlara giden trafiğin proxy üzerinden geçmesini engeller. Konteynerlerin birbirleriyle ve host ile sorunsuz iletişim kurabilmesi için localhost, 127.0.0.1, ::1 ve tüm Docker iç ağlarını (örneğin varsayılan bridge ağı için 172.17.0.0/16 veya özel ağ CIDR'leri) ekleyin. Ayrıca proxy'yi atlaması gereken tüm iç alan adlarını da ekleyin.
Değişikliklerin geçerli olması için systemd'yi yeniden yükleyin ve Docker daemon'ını yeniden başlatın:
sudo systemctl daemon-reload
sudo systemctl restart docker
Bir imaj çekerek doğrulayın:
docker pull alpine
Proxy doğru yapılandırıldıysa bu çekme işlemi proxy üzerinden gerçekleşir.
Docker CLI için (istemci tarafı yapılandırma)
Bu yapılandırma, registry'lerle etkileşim sırasında Docker istemcisini etkiler. Daemon genelinde proxy için daha az kullanılır, ancak belirli CLI işlemleri için yararlıdır.
~/.docker/config.json dosyasını oluşturun veya düzenleyin:
{
"proxies": {
"default": {
"httpProxy": "http://YOUR_PROXY_HOST:YOUR_PROXY_PORT",
"httpsProxy": "http://YOUR_PROXY_HOST:YOUR_PROXY_PORT",
"noProxy": "localhost,127.0.0.1,::1,YOUR_DOCKER_NETWORK_CIDR,YOUR_INTERNAL_DOMAINS"
}
}
}
Bu yapılandırma, Docker CLI'yi çalıştıran kullanıcı için geçerlidir.
Konteyner/servis proxy yapılandırması
Bu yöntem, belirli konteynerlerin veya docker-compose servislerinin çalışma zamanındaki giden trafiği için proxy kullanmasını sağlar. Daemon proxy'sinden farklıdır ve konteyner içinde çalışan uygulamaların dış kaynaklara proxy üzerinden erişmesi için çoğu zaman gereklidir.
Dockerfile kullanımı
Proxy ortam değişkenlerini doğrudan Dockerfile'ınızda tanımlayabilirsiniz. Bu, proxy ayarlarını imajın içine gömer.
FROM ubuntu:latest
# Build zamanı işlemleri için proxy ayarı (örneğin apt-get update)
ENV HTTP_PROXY="http://YOUR_PROXY_HOST:YOUR_PROXY_PORT" \
HTTPS_PROXY="http://YOUR_PROXY_HOST:YOUR_PROXY_PORT" \
NO_PROXY="localhost,127.0.0.1,::1,YOUR_DOCKER_NETWORK_CIDR,YOUR_INTERNAL_DOMAINS"
RUN apt-get update && apt-get install -y curl
# Bu ENV değişkenleri, üzerine yazılmadıkça çalışma zamanında da geçerli olur
CMD ["curl", "http://example.com"]
Dikkat edilecekler:
* Dockerfile içindeki proxy kimlik bilgileri güvenlik riskidir. Bunun yerine build argümanlarını (ARG) veya çalışma zamanı ortam değişkenlerini (-e ya da docker-compose.yml içindeki environment) kullanmayı düşünün.
* Proxy yalnızca build sırasında gerekiyorsa, çok aşamalı bir build'de değişkenleri build aşamasının sonunda temizleyin veya daha güvenli bir yöntem için RUN --mount=type=secret,id=proxy,target=/run/secrets/proxy-creds kullanın.
docker run kullanımı
Tek tek konteynerler için proxy ayarlarını -e bayrağıyla geçirin:
docker run -e HTTP_PROXY="http://YOUR_PROXY_HOST:YOUR_PROXY_PORT" \
-e HTTPS_PROXY="http://YOUR_PROXY_HOST:YOUR_PROXY_PORT" \
-e NO_PROXY="localhost,127.0.0.1,::1,172.17.0.0/16,my-app-service" \
my-image:latest curl http://example.com
docker-compose.yml kullanımı
Çok servisli uygulamalarda standart yöntem docker-compose'dur. Proxy erişimi gereken her servisin environment bölümünde proxy ortam değişkenlerini tanımlayın:
version: '3.8'
services:
webapp:
image: my-webapp:latest
environment:
- HTTP_PROXY=http://YOUR_PROXY_HOST:YOUR_PROXY_PORT
- HTTPS_PROXY=http://YOUR_PROXY_HOST:YOUR_PROXY_PORT
- NO_PROXY=localhost,127.0.0.1,::1,your-db-service,your-cache-service,172.18.0.0/16 # İç servis adlarını ve ağ CIDR'lerini ekleyin
# ... diğer servis yapılandırmaları
database:
image: postgres:13
# Yalnızca iç iletişim kuruyorsa veya dışarı trafik üretmiyorsa bu servisin genelde proxy ayarına ihtiyacı yoktur
# ... diğer servis yapılandırmaları
docker-compose içinde NO_PROXY hakkında not:
* localhost, 127.0.0.1, ::1 ekleyin.
* Aynı docker-compose ağındaki diğer servislerin adlarını ekleyin (örneğin your-db-service).
* docker-compose tarafından oluşturulan Docker ağının CIDR aralığını ekleyin (örneğin docker-compose ağınız o aralıktaysa 172.18.0.0/16). CIDR'yi öğrenmek için ağı docker network inspect <network_name> ile inceleyebilirsiniz.
Harici proxy.env dosyası
Hassas veya sık değişen proxy ayarlarını daha iyi yönetmek için bunları harici bir .env dosyasında tanımlayıp docker-compose.yml içinde referans verebilirsiniz:
proxy.env:
HTTP_PROXY=http://YOUR_PROXY_HOST:YOUR_PROXY_PORT
HTTPS_PROXY=http://YOUR_PROXY_HOST:YOUR_PROXY_PORT
NO_PROXY=localhost,127.0.0.1,::1,your-db-service,your-cache-service,172.18.0.0/16
docker-compose.yml:
version: '3.8'
services:
webapp:
image: my-webapp:latest
env_file:
- ./proxy.env
# ... diğer servis yapılandırmaları
Bu yaklaşım daha derli topludur ve docker-compose.yml dosyasını doğrudan değiştirmeden kolay güncelleme yapmanıza olanak tanır.
SOCKS proxy yapılandırması
HTTP/HTTPS proxy'ler en yaygın olsa da bazı ortamlar SOCKS proxy kullanır. Docker, SOCKS proxy ortam değişkenlerini (SOCKS_PROXY, ALL_PROXY) HTTP/HTTPS kadar yaygın biçimde yerel olarak desteklemez.
- Uygulama düzeyi: Uygulamaların çoğu açık SOCKS desteğine ihtiyaç duyar. Konteyner içindeki uygulamanız SOCKS destekliyorsa
ALL_PROXYveya benzeri değişkenleri geçirebilirsiniz. - Proxychains-NG: SOCKS'u yerel olarak desteklemeyen uygulamalar için trafiği bir SOCKS proxy üzerinden zorlamak amacıyla konteyner içine
proxychains-nggibi araçlar kurulabilir. Bu, karmaşıklık ve ek yük getirir.
Tipik Docker dağıtımlarında daha geniş destek nedeniyle HTTP/HTTPS proxy tercih edilir.
Proxy yapılandırma yöntemlerinin karşılaştırması
| Yöntem | Kapsam | Ne zaman kullanılır | Artıları | Eksileri |
|---|---|---|---|---|
Docker daemon (systemd) |
Host genelinde Docker daemon işlemleri | Host üzerindeki tüm imaj çekme, build adımları ve registry etkileşimleri için. | Daemon için merkezî. Tüm build/çekme işlemlerinin proxy kullanmasını sağlar. | systemd bilgisi gerektirir. Daemon'ın yeniden başlatılmasını gerektirir. Konteynerlerde çalışan uygulamaları etkilemez. |
Docker CLI (config.json) |
Kullanıcıya özel Docker CLI işlemleri | Belirli bir kullanıcının registry ile etkileşen CLI komutları için. | Kullanıcıya özeldir; diğer kullanıcıları veya daemon'ı etkilemez. | Yalnızca CLI'yi etkiler; daemon'ı veya konteyner çalışma zamanını etkilemez. |
Dockerfile (ENV) |
İmaj build zamanı ve konteyner çalışma zamanı | Proxy ayarları bir imajın tüm örnekleri için aynı olduğunda. | İmajın içinde kendi kendine yeter. Geliştirme için basittir. | Ayarları imaja gömer (daha az esnek). Kimlik bilgileri eklenirse güvenlik riski. |
docker run (-e) |
Tek konteyner çalışma zamanı | Anlık testler, belirli konteyner çalıştırmaları veya Dockerfile ayarlarını geçersiz kılmak için. | Çok esnek, çalışma zamanına özel. | Çok sayıda konteyner veya docker-compose kurulumları için zahmetli. |
docker-compose.yml (environment/env_file) |
Servise özel konteyner çalışma zamanı | Her servisin farklı proxy ihtiyacı olan çok servisli uygulamalar için. | Ayarları servis bazında düzgün tanımlar. Sırlar/esneklik için harici .env dosyalarını destekler. |
Her servis için ayrı tanımlama gerektirir. Daemon düzeyindeki işlemleri etkilemez (örneğin docker-compose build). |
Yaygın proxy sorunlarının giderilmesi
- Ortam değişkenlerini doğrulayın: Çalışan bir konteynerin içinde
HTTP_PROXY,HTTPS_PROXYveNO_PROXYdeğerlerinin doğru ayarlandığını kontrol etmek içindocker exec -it <container_id> envkomutunu kullanın. - Konteynerden bağlantıyı test edin:
bash docker exec -it <container_id> curl -v --proxy <YOUR_PROXY_HOST:YOUR_PROXY_PORT> http://example.com
Bu, doğrudan test içincurl'ü konteyner ortam değişkenlerini atlayarak proxy kullanmaya zorlar. - Proxy sunucusu loglarını kontrol edin: Docker host'undan veya konteynerlerden gelen trafiğin sunucuya ulaşıp işlendiğini görmek için proxy sunucunuzun erişim loglarını inceleyin.
- Ağ bağlantısı: Docker host'unun proxy sunucusuna belirtilen port üzerinden erişebildiğinden emin olun. Docker host'undan
curlveyatelnetkullanın. - Güvenlik duvarı kuralları: Hiçbir güvenlik duvarının (host, ağ veya proxy sunucusu) Docker host'u/konteynerleri ile proxy sunucusu arasındaki trafiği engellemediğini doğrulayın.
- DNS çözümlemesi: Özellikle proxy host'u ve hedef alan adları için, konteynerler içinde DNS çözümlemesinin düzgün çalıştığından emin olun.
NO_PROXYyapılandırması: Yanlış veya eksikNO_PROXYayarları sıklıkla iç iletişim hatalarına yol açar. Tüm iç ağların, Docker bridge ağlarının ve servis adlarının listelendiğinden emin olun.
