هل تعمل مع Docker في شبكة مؤسسية، على خادم ذو وصول محدود، أو ترغب في أن تتصل حاوياتك بالإنترنت من خلال عنوان IP محدد؟ بدون إعداد بروكسي صحيح، لن يتمكن Docker من تنزيل الصور من Docker Hub أو أي سجل آخر. في هذه المقالة، سنستعرض جميع مستويات البروكسي - من الخادم إلى الحاوية المنفصلة.
لماذا يحتاج Docker إلى بروكسي
Docker هو أداة تتواصل باستمرار مع الموارد الخارجية. في كل docker pull أو docker build، يقوم الخادم بالاتصال بـ Docker Hub، أو GitHub Container Registry، أو Google Container Registry، أو سجل خاص بك. وهنا تبدأ المشاكل.
الحالات التي لا يمكن الاستغناء فيها عن البروكسي:
- شبكة مؤسسية مع جدار ناري - يجب أن يمر كل حركة المرور عبر خادم البروكسي المؤسسي، وإلا سيتم حظر الاتصال.
- قيود جغرافية - Docker Hub أو سجلات معينة غير متاحة من بلدك أو مركز البيانات الخاص بك.
- خادم محدود بدون اتصال مباشر بالإنترنت - VPS في دائرة مغلقة، حيث يتوفر الإنترنت فقط عبر بوابة.
- التحكم في حركة المرور الصادرة من الحاويات - ترغب في أن تتصل التطبيقات داخل الحاويات بالشبكة عبر عنوان IP محدد، على سبيل المثال، لجمع البيانات، أو طلبات API، أو اختبار المحتوى المعتمد على الجغرافيا.
- إخفاء الهوية - إخفاء عنوان IP الحقيقي للخادم عند الاتصال بالخدمات الخارجية من الحاوية.
- تحديد معدل الطلبات - يحدد Docker Hub عدد طلبات السحب للمستخدمين المجهولين (100 سحب خلال 6 ساعات). يمكن تجاوز هذا القيد عبر بروكسي مع تدوير IP.
من المهم أن نفهم أن Docker ليس تطبيقًا واحدًا، بل هو نظام يتكون من عدة مكونات. يعيش الخادم (dockerd) على المضيف ويقوم بسحب الصور. الحاويات هي عمليات معزولة بإعدادات شبكية خاصة بها. لذلك، فإن إعداد البروكسي للخادم وللحاويات هو مهمتان مختلفتان يتم حلهما بطرق مختلفة.
ثلاثة مستويات من البروكسي في Docker
قبل الغوص في التكوينات، يجب فهم الهيكلية. في Docker، هناك ثلاثة مستويات مستقلة، كل منها يتطلب إعداد بروكسي منفصل:
| المستوى | ماذا يفعل | أين يتم الإعداد |
|---|---|---|
| خادم Docker | يسحب الصور (docker pull)، يتصل بالسجلات | تجاوز systemd أو daemon.json |
| بناء Docker | ينفذ الأوامر أثناء بناء الصورة (RUN apt-get، pip install، إلخ) | ARG وENV في Dockerfile أو --build-arg |
| حاوية وقت التشغيل | تطبيق قيد التشغيل يقوم بإجراء طلبات HTTP | ENV عند docker run أو في docker-compose.yml |
خطأ شائع هو إعداد البروكسي على مستوى واحد فقط والتعجب من سبب عدم سحب الصور أو عدم رؤية التطبيق للبروكسي. دعونا نستعرض كل مستوى بالتفصيل.
إعداد بروكسي لخادم Docker (سحب الصور)
هذه هي الإعدادات الأكثر أهمية إذا كنت ترغب في سحب الصور عبر البروكسي. خادم Docker هو خدمة نظامية يتم تشغيلها عبر systemd. لا يرى متغيرات البيئة الخاصة بك أو حتى root. يجب تمرير البروكسي إلى بيئة الخدمة.
الطريقة 1: عبر تجاوز systemd (موصى بها)
أنشئ دليلًا لتجاوز إعدادات الخدمة:
sudo mkdir -p /etc/systemd/system/docker.service.d
أنشئ ملفًا /etc/systemd/system/docker.service.d/http-proxy.conf بالمحتوى التالي:
[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"
إذا كان البروكسي بدون مصادقة - فقط قم بإزالة username:password@. بعد إنشاء الملف، أعد تحميل تكوين systemd وأعد تشغيل Docker:
sudo systemctl daemon-reload sudo systemctl restart docker
تحقق من أن الإعدادات قد تم تطبيقها:
sudo systemctl show --property=Environment docker
يجب أن تظهر متغيراتك HTTP_PROXY و HTTPS_PROXY في الإخراج.
الطريقة 2: عبر ~/.docker/config.json (Docker Desktop والإصدارات الجديدة)
بدءًا من Docker Engine 23.0، تم تقديم طريقة أكثر ملاءمة - إعداد البروكسي عبر ملف تكوين العميل. أنشئ أو عدل ملف ~/.docker/config.json:
{
"proxies": {
"default": {
"httpProxy": "http://username:password@proxy-host:port",
"httpsProxy": "http://username:password@proxy-host:port",
"noProxy": "localhost,127.0.0.1,::1"
}
}
}
هذه الطريقة مريحة لأنها لا تتطلب حقوق الجذر وإعادة تشغيل الخادم. يتم تمرير الإعدادات تلقائيًا إلى الحاويات أثناء البناء كوسائط بناء. ومع ذلك، لا يزال يتطلب التحكم في طلبات السحب الخاصة بالخادم طريقة عبر systemd.
💡 مهم حول NO_PROXY
دائمًا أضف إلى NO_PROXY عناوين سجلاتك الداخلية والخدمات. خلاف ذلك، سيحاول Docker الوصول إليها عبر البروكسي ويواجه أخطاء في الاتصال. قائمة نموذجية: localhost,127.0.0.1,::1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
بروكسي داخل الحاوية أثناء البناء (وقت البناء)
عندما يقوم Docker ببناء صورة وينفذ أوامر مثل RUN apt-get install، RUN pip install أو RUN npm install - يتم تنفيذ هذه الأوامر داخل حاوية مؤقتة. ليس لديها وصول افتراضي إلى بروكسي المضيف. يجب تمرير البروكسي بوضوح عبر وسائط البناء.
تمرير البروكسي عبر --build-arg
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
إذا كان البروكسي مطلوبًا فقط في مرحلة البناء ولا ترغب في أن يتم تضمينه في الصورة النهائية - استخدم ARG، وليس ENV:
FROM ubuntu:22.04 # إعلان عن وسائط البناء ARG HTTP_PROXY ARG HTTPS_PROXY ARG NO_PROXY # استخدامها في الأوامر RUN apt-get update && apt-get install -y curl wget # بعد هذه الكتلة، لن يكون البروكسي في ENV للحاوية
إذا كان البروكسي مطلوبًا أيضًا في الحاوية قيد التشغيل - استخدم ENV:
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"]
⚠️ انتبه: الأمان
لا تقم بتشفير اسم المستخدم وكلمة المرور للبروكسي مباشرة في Dockerfile إذا كانت الصورة ستكون عامة أو ستدخل في مستودع. استخدم --build-arg ومرر القيم من متغيرات البيئة في نظام CI/CD. يمكن أن تظهر الأمر docker history قيم ARG، لذلك استخدم أسرار Docker BuildKit للسرية.
بروكسي للحاوية قيد التشغيل (وقت التشغيل)
هذا هو السيناريو الأكثر شيوعًا للتطبيقات التي تقوم بإجراء طلبات HTTP أثناء التشغيل - مثل برامج جمع البيانات، والروبوتات، والميكروسيرفيسات التي تحتاج إلى الخروج عبر عنوان IP محدد. هنا، يكون الإعداد بسيطًا للغاية: يجب تمرير متغيرات البيئة عند تشغيل الحاوية.
عبر docker run
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
معظم مكتبات HTTP الشائعة تلتقط تلقائيًا متغيرات HTTP_PROXY و HTTPS_PROXY: Python requests، curl، wget، Go's net/http، Node.js https-proxy-agent وغيرها. لا تحتاج إلى كتابة أي شيء إضافي في الكود.
عبر ملف .env
من الأسهل تخزين الإعدادات في ملف .env وتمريره بالكامل:
# ملف .env 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
بروكسي SOCKS5 في الحاوية
إذا كنت تستخدم بروكسي SOCKS5 (على سبيل المثال، البروكسي السكنية تدعم عادةً هذا البروتوكول)، فإن الصيغة تختلف قليلاً:
docker run \ -e ALL_PROXY=socks5://username:password@proxy-host:port \ my-image
لاحظ: ليست جميع المكتبات تدعم SOCKS5 عبر متغير البيئة بدون تبعيات إضافية. تتطلب مكتبة Python requests تثبيت requests[socks]، ويجب أن يتم بناء curl مع دعم libcurl-socks.
بروكسي في Docker Compose
في المشاريع الحقيقية، نادرًا ما يتم استخدام docker run بمفرده. غالبًا ما يتم العمل مع Docker Compose، حيث يتم وصف عدة خدمات في ملف واحد. يتم إعداد البروكسي هنا على مستوى كل خدمة أو عبر ملف المتغيرات.
الخيار 1: البيئة في docker-compose.yml
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
# هذه الخدمة بدون بروكسي - تتصل فقط بالموارد الداخلية
ports:
- "8080:8080"
الخيار 2: عبر ملف .env (موصى به)
أنشئ .env في الدليل الذي يحتوي على docker-compose.yml. يقوم Docker Compose بالتقاط هذا الملف تلقائيًا:
# .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
إذا كان في Compose قسم build وتحتاج إلى تمرير البروكسي أثناء مرحلة البناء:
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
يعتمد اختيار نوع البروكسي على المهمة. بالنسبة لبيئات Docker، هناك ثلاثة أنواع رئيسية، لكل منها مكانتها الخاصة:
| نوع البروكسي | السرعة | الخصوصية | أفضل سيناريو لـ Docker |
|---|---|---|---|
| مركز البيانات | ⚡ عالية | متوسطة | سحب الصور، خطوط CI/CD، تجاوز تحديد معدل Docker Hub |
| السكنية | 🔄 متوسطة | عالية | جمع البيانات من المواقع المحمية، API مع قيود جغرافية، اختبار |
| المحمول | 🔄 متوسطة | قصوى | تطبيقات تعمل مع API المحمول (Instagram، TikTok) |
لسحب الصور وCI/CD، فإن بروكسيات مراكز البيانات هي الأمثل - فهي توفر أقصى سرعة عند تنزيل صور كبيرة (عدة جيجابايت) واتصال مستقر لبناءات طويلة.
للحاويات التي تجمع البيانات، التي تحتاج إلى تجاوز حماية المواقع والظهور كمستخدم عادي، فإن البروكسيات السكنية هي الأنسب. لديهم IP لمستخدمين حقيقيين في المنازل، مما يقلل من احتمال الحظر حتى مع الطلبات المكثفة.
للتطبيقات التي تعمل مع المنصات المحمولة - Instagram Graph API، TikTok API، والإصدارات المحمولة من الخدمات - يجب النظر في البروكسيات المحمولة. تستخدم IP لمشغلي الشبكات الخلوية وتثير الحد الأدنى من الشكوك من أنظمة مكافحة الروبوتات.
البروتوكولات: HTTP مقابل SOCKS5
يدعم خادم Docker فقط بروكسي HTTP/HTTPS - لا يعمل SOCKS5 لسحب الصور. إذا كان لديك بروكسي SOCKS5 وتحتاج إلى تنزيل الصور، سيتعين عليك استخدام محول محلي مثل privoxy أو microsocks، الذي سيقبل HTTP ويقوم بتمريره عبر SOCKS5.
بالنسبة للحاويات في وقت التشغيل، فإن الوضع أفضل: تدعم معظم مكتبات HTTP SOCKS5 مباشرة عبر متغير ALL_PROXY=socks5://....
الأخطاء الشائعة وكيفية إصلاحها
دعونا نستعرض أكثر المشاكل شيوعًا التي تواجه عند إعداد البروكسي في Docker:
الخطأ 1: تم إعداد البروكسي على المضيف، لكن Docker لا يراه
الأعراض:
خطأ في الاستجابة من الخادم: الحصول على "https://registry-1.docker.io/v2/": الاتصال مرفوض
السبب: يتم تشغيل خادم Docker كخدمة نظامية ولا يرث متغيرات البيئة الخاصة بالمستخدم الحالي، حتى لو قمت بتعيين export HTTPS_PROXY=... في الطرفية.
الحل: قم بإعداد البروكسي عبر تجاوز systemd (الطريقة 1 من القسم أعلاه). تأكد من تنفيذ systemctl daemon-reload && systemctl restart docker.
الخطأ 2: apt-get / pip / npm لا تعمل أثناء البناء
الأعراض:
خطأ:1 http://archive.ubuntu.com/ubuntu focal InRelease
تعذر الاتصال بـ archive.ubuntu.com:80
السبب: إعداد البروكسي للخادم لا ينتشر تلقائيًا إلى الأوامر داخل RUN في Dockerfile. هذه سياقات مختلفة.
الحل: قم بتمرير البروكسي عبر --build-arg أو استخدم ~/.docker/config.json مع قسم proxies (Docker 23.0+، يمرر الوسائط تلقائيًا أثناء البناء).
الخطأ 3: الخدمات الداخلية غير متاحة عبر البروكسي
الأعراض:
curl: (7) فشل الاتصال بالخدمة الداخلية.local المنفذ 8080: الاتصال مرفوض
السبب: يحاول البروكسي تمرير الطلبات إلى العناوين الداخلية التي لا يمكن الوصول إليها من الخارج.
الحل: أضف جميع النطاقات الداخلية والشبكات الفرعية إلى NO_PROXY. لقوائم الشبكات المؤسسية، القائمة النموذجية هي: localhost,127.0.0.1,::1,.internal,.local,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
الخطأ 4: مصادقة البروكسي لا تعمل - رموز خاصة في كلمة المرور
إذا كانت كلمة المرور تحتوي على رموز خاصة (@، #، %)، يتم تحليل URL بشكل غير صحيح.
الحل: قم بتشفير كلمة المرور في ترميز URL. على سبيل المثال، p@ss#word → p%40ss%23word. في Python، يمكنك بسرعة الحصول على النسخة المشفرة:
python3 -c "from urllib.parse import quote; print(quote('p@ss#word', safe=''))"
# الإخراج: p%40ss%23word
الخطأ 5: يعمل البروكسي، لكن شهادة SSL لا يتم التحقق منها
غالبًا ما تقوم البروكسيات المؤسسية بتنفيذ فحص SSL (MITM) واستبدال الشهادات. في هذه الحالة، يظهر Docker خطأ:
x509: شهادة موقعة من قبل سلطة غير معروفة
الحل: أضف شهادة الجذر المؤسسية إلى الموثوق بها على المضيف وأعد تشغيل Docker. على Ubuntu/Debian:
sudo cp corporate-ca.crt /usr/local/share/ca-certificates/ sudo update-ca-certificates sudo systemctl restart docker
الخطأ 6: Kubernetes / Docker Swarm - البروكسي لا يعمل على جميع العقد
في البيئات العنقودية، يجب إعداد البروكسي على كل عقدة بشكل منفصل. بالنسبة لـ Kubernetes، يجب أيضًا إعداد متغيرات البيئة في بيانات تعريف الحاويات أو عبر ConfigMap. يمكن أتمتة ذلك عبر Ansible أو أدوات إدارة التكوين الأخرى.
الخاتمة
إعداد البروكسي في Docker ليس إعدادًا واحدًا، بل ثلاثة مستويات مستقلة: الخادم لسحب الصور، وقت البناء للبناء، ووقت التشغيل للحاويات النشطة. من خلال فهم هذه الهيكلية، يمكنك إدارة حركة المرور بشكل مرن، سواء كانت تمر عبر البروكسي أو مباشرة.
قائمة مراجعة مختصرة للإعداد الصحيح:
- ✅ لسحب الصور - قم بإعداد تجاوز systemd مع متغيرات HTTP_PROXY و HTTPS_PROXY
- ✅ للبناء - قم بتمرير البروكسي عبر
--build-argأو~/.docker/config.json - ✅ لوقت التشغيل - استخدم متغيرات البيئة عبر
-eأو--env-file - ✅ دائمًا قم بإعداد NO_PROXY للعناوين الداخلية
- ✅ لا تخزن كلمات مرور البروكسي في Dockerfile - استخدم build-args وملفات .env
- ✅ لخطوط CI/CD، اختر بروكسيات مراكز البيانات السريعة
- ✅ للحاويات التي تجمع البيانات - استخدم البروكسيات السكنية أو المحمولة
إذا كانت تطبيقات الحاويات الخاصة بك تقوم بإجراء طلبات إلى خدمات خارجية، أو تجمع بيانات، أو تعمل مع APIs التي لديها قيود جغرافية، نوصي باستخدام البروكسيات السكنية - فهي توفر مستوى عالٍ من الثقة من قبل الخدمات وأقل خطر للحظر حتى مع العمل المكثف.