Skip to content
مقاله / 1 دقیقه مطالعه

پیکربندی پروکسی Docker و SOCKS5: دیمن، ساخت، کانتینرها و پل‌ها

داکر یک کلید پروکسی واحد ندارد. دیمن، فرایند ساخت، و هر کانتینر تنظیمات پروکسی را در جاهای مختلف می‌خوانند — و SOCKS5 اصلاً توسط دیمن پشتیبانی نمی‌شود. در ادامه نحوه پیکربندی هر لایه و تأیید کارکرد آن آمده است.

پیکربندی پروکسی Docker و SOCKS5: دیمن، ساخت، کانتینرها و پل‌ها

اگر برای «socks5 configurator» جست‌وجو می‌کنید چون pullهای Docker مدام تایم‌اوت می‌شوند، تنها نیستید. Docker حداقل سه لایه پروکسی دارد و این لایه‌ها تنظیمات مشترکی ندارند. پروکسی‌ای که برای docker pull کار می‌کند ممکن است به apt-get داخل یک build کمک نکند، و SOCKS5 — که در بسیاری از سرویس‌های پروکسی رایج است — اصلاً توسط متغیرهای پروکسی دیمن Docker پذیرفته نمی‌شود. این راهنما هر لایه را با پیکربندی کپی-پیست و مراحل تأیید بررسی می‌کند تا فقط چیزی را که نیاز به مسیریابی دارد مسیردهی کنید و از نشت DNS یا اعتبارنامه‌ها جلوگیری کنید.

سه لایه پروکسی Docker (و اینکه هر کدام کجا اعمال می‌شود)

لایه چه چیزی را تحت تأثیر قرار می‌دهد کجا تنظیمش می‌کنید پشتیبانی پروتکل
دیمن docker pull، docker push، احراز هویت رجیستری systemd drop-in (لینوکس) یا تنظیمات Docker Desktop URLهای پروکسی HTTP/HTTPS
ساخت دستورات RUN در حین docker build (apt، pip، npm) --build-arg + ARG در Dockerfile URLهای پروکسی HTTP/HTTPS
زمان اجرای کانتینر ترافیک برنامه شما داخل کانتینر فلگ‌های -e یا environment در Compose بسته به برنامه (HTTP، HTTPS، SOCKS5 اگر برنامه پشتیبانی کند)

جای چهارمی که مردم فراموش می‌کنند: مدیر بسته و ابزارهای خود میزبان. اگر نمی‌توانید به رجیستری Docker دسترسی پیدا کنید، معمولاً نمی‌توانید به apt یا pip روی میزبان هم دسترسی داشته باشید. ابتدا یک پروکسی در سطح میزبان تنظیم کنید، سپس Docker را پیکربندی کنید. برای مسیریابی به‌ازای هر برنامه روی میزبان، راهنمای پیکربندی‌کننده SOCKS5 ما را برای مرورگرها، SSH، curl، git و Python ببینید.

پروکسی در سطح دیمن: برای pull کردن ایمیج‌ها و ارتباط با رجیستری‌ها

دیمن Docker متغیرهای محیطی استاندارد پروکسی را از سرویس systemd خود می‌خواند. یک فایل drop-in بسازید:

sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf > /dev/null <<'EOF'
[Service]
Environment=HTTP_PROXY=http://user:[email protected]:3128
Environment=HTTPS_PROXY=http://user:[email protected]:3128
Environment=NO_PROXY=localhost,127.0.0.1,::1,.internal.example,registry.internal.example
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

یادداشت‌ها:

  • مقدار، URL پروکسی است. برای یک پروکسی HTTP استاندارد که از CONNECT پشتیبانی می‌کند، از http:// استفاده کنید. اگر خود endpoint پروکسی شما با TLS پوشانده شده است، از https:// استفاده کنید.
  • NO_PROXY باید هر رجیستری یا میزبان داخلی را که نمی‌خواهید از پروکسی رد شود شامل شود. نقطه ابتدایی در .internal.example در بسیاری از پیاده‌سازی‌ها با زیردامنه‌ها مطابقت دارد، اما رفتار متفاوت است.
  • اعتبارنامه‌های موجود در فایل systemd برای root قابل مشاهده هستند. برای ماشین‌های اشتراکی، یک فورواردر محلی را در نظر بگیرید که به اعتبارنامه در محیط نیاز ندارد.

تأیید:

docker info | grep -i -A2 'Proxy'

باید خطوط HTTP Proxy، HTTPS Proxy و No Proxy را ببینید. اگر خالی هستند، دیمن فایل drop-in را برنداشته است.

سپس یک pull را آزمایش کنید:

docker pull alpine:latest

اگر هنوز شکست خورد، لاگ‌های دیمن را بررسی کنید:

journalctl -u docker.service --no-pager -n 50

Docker Desktop (macOS/Windows) یک تنظیم پروکسی گرافیکی زیر Settings، Resources، Proxies دارد. همان متغیرها را برای دیمن می‌نویسد.

پروکسی زمان ساخت: وقتی pull کار می‌کند اما RUN apt-get نه

پروکسی دیمن به‌طور خودکار روی کانتینرهای build اعمال نمی‌شود. باید آرگومان‌های پروکسی را پاس دهید و آن‌ها را در Dockerfile تعریف کنید.

FROM debian:bookworm-slim

ARG HTTP_PROXY
ARG HTTPS_PROXY
ARG NO_PROXY

RUN apt-get update && apt-get install -y --no-install-recommends curl ca-certificates && rm -rf /var/lib/apt/lists/*

ساخت:

docker build --build-arg HTTP_PROXY=http://user:[email protected]:3128 --build-arg HTTPS_PROXY=http://user:[email protected]:3128 --build-arg NO_PROXY=localhost,127.0.0.1 -t myapp .

مهم: مقادیر --build-arg می‌توانند در تاریخچه ایمیج و لاگ‌های build قابل مشاهده باشند. هرگز اعتبارنامه‌ها را در ایمیج نهایی جای ندهید. از buildهای چندمرحله‌ای استفاده کنید و آرگومان‌ها را قبل از مرحله نهایی unset کنید، یا از mountهای secret در BuildKit برای اعتبارنامه‌ها استفاده کنید.

پروکسی هر کانتینر: تنظیم متغیرهای محیطی در زمان اجرا

برای برنامه‌هایی که متغیرهای محیطی پروکسی را می‌خوانند، هنگام شروع کانتینر آن‌ها را تنظیم کنید:

docker run --rm -e HTTP_PROXY=http://proxy.example:3128 -e HTTPS_PROXY=http://proxy.example:3128 -e NO_PROXY=localhost,127.0.0.1 myapp

در Docker Compose:

services:
  app:
    image: myapp
    environment:
      HTTP_PROXY: http://proxy.example:3128
      HTTPS_PROXY: http://proxy.example:3128
      NO_PROXY: localhost,127.0.0.1,.internal.example

همه برنامه‌ها به این متغیرها احترام نمی‌گذارند. برخی فقط http_proxy با حروف کوچک را می‌خوانند، برخی NO_PROXY را کاملاً نادیده می‌گیرند، و برخی فایل پیکربندی خودشان را دارند. همیشه مستندات برنامه را بررسی کنید.

SOCKS5: چرا متغیرهای پروکسی Docker آن را نمی‌پذیرند

دیمن Docker و متغیرهای پروکسی --build-arg انتظار URLهای پروکسی HTTP یا HTTPS را دارند. socks5:// یک scheme پشتیبانی‌شده برای دیمن نیست. اگر سرویس پروکسی شما فقط یک endpoint SOCKS5 می‌دهد، سه گزینه عملی دارید:

  1. یک بریج محلی HTTP-to-SOCKS5 اجرا کنید. یک فورواردر کوچک روی 127.0.0.1:3128 گوش می‌دهد و به پروکسی SOCKS5 شما forward می‌کند. سپس HTTP_PROXY داکر را به بریج اشاره دهید. این کار اعتبارنامه‌های SOCKS5 را از محیط Docker بیرون نگه می‌دارد.
  2. از SSH dynamic forwarding به‌همراه یک بریج استفاده کنید. ssh -D 1080 یک پروکسی SOCKS5 محلی به شما می‌دهد؛ بریج آن را برای Docker به HTTP تبدیل می‌کند. این زمانی خوب کار می‌کند که از قبل دسترسی SSH به یک میزبان راه‌دور دارید.
  3. برنامه داخل کانتینر را طوری پیکربندی کنید که مستقیماً از SOCKS5 استفاده کند. بسیاری از ابزارها (curl، requests، git) به‌صورت بومی از socks5h:// پشتیبانی می‌کنند. این کار تنظیمات پروکسی Docker را کاملاً دور می‌زند و فقط روی همان برنامه اثر می‌گذارد.

مثال: آزمایش SOCKS5 از داخل یک کانتینر بدون بریج، با استفاده از curl. روی لینوکس، --add-host=host.docker.internal:host-gateway را اضافه کنید تا کانتینر بتواند به پروکسی‌ای که روی میزبان اجرا می‌شود دسترسی پیدا کند.

docker run --rm --add-host=host.docker.internal:host-gateway curlimages/curl:latest --socks5-hostname host.docker.internal:1080 https://ifconfig.me

--socks5-hostname نام میزبان را برای resolve شدن DNS به پروکسی می‌فرستد، که از نشت DNS جلوگیری می‌کند. اگر از --socks5 استفاده کنید، curl DNS را به‌صورت محلی resolve می‌کند و فقط اتصال TCP را تونل می‌زند — منبعی رایج برای موقعیت مکانی نادرست و نشت‌ها.

برای کد برنامه، scheme socks5h اغلب واضح‌تر است:

curl --proxy socks5h://user:[email protected]:1080 https://ifconfig.me

تأیید اینکه پروکسی واقعاً استفاده می‌شود (و گرفتن نشت‌ها)

پس از پیکربندی، هر لایه را تأیید کنید:

  • دیمن: docker info | grep -i proxy متغیرها را نشان می‌دهد. سپس docker pull باید از پروکسی عبور کند. همچنین می‌توانید لاگ‌های خود پروکسی را برای یک درخواست CONNECT به registry-1.docker.io:443 بررسی کنید.
  • ساخت: یک مرحله RUN اضافه کنید که IP مشاهده‌شده را چاپ کند: RUN curl -s https://ifconfig.me || true. اگر IP، IP واقعی شماست، build از پروکسی رد نمی‌شود. این خط را قبل از انتشار حذف کنید.
  • کانتینر: docker exec -it <container> sh -c 'curl -s https://ifconfig.me' و آن را با IP واقعی خود مقایسه کنید.
  • DNS: پروکسی‌های HTTP معمولاً برای HTTPS (از طریق CONNECT) DNS را در سمت پروکسی resolve می‌کنند، اما درخواست‌های HTTP ساده ممکن است در صورت resolve محلی توسط کلاینت، DNS را نشت دهند. SOCKS5 با socks5h همیشه از راه دور resolve می‌کند. اگر DNS مهم است، با یک DNS leak checker تست کنید یا لاگ‌های پروکسی را بررسی کنید.

مشکلات رایج Docker و پروکسی‌ها

  • NO_PROXY خودکار نیست. اگر رجیستری داخلی شما یا سرویسی روی میزبان بی‌دلیل از پروکسی رد می‌شود، آن را به NO_PROXY اضافه کنید. localhost، 127.0.0.1 و هر دامنه داخلی را شامل کنید.
  • حروف بزرگ در برابر کوچک. برخی ابزارها HTTP_PROXY را می‌خوانند، برخی http_proxy. اگر مطمئن نیستید هر دو را تنظیم کنید. در Dockerfileها، ARG HTTP_PROXY کافی است تا فرایند build نوع با حروف بزرگ را بخواند؛ اگر ابزار خاصی به حروف کوچک نیاز دارد ARG http_proxy را اضافه کنید.
  • اعتبارنامه‌ها در تاریخچه build. مقادیر --build-arg می‌توانند در docker history ظاهر شوند. برای توکن‌ها و گذرواژه‌ها از mountهای secret در BuildKit (--mount=type=secret) استفاده کنید.
  • Docker Desktop در برابر دیمن لینوکس. روی لینوکس systemd را ویرایش می‌کنید؛ روی Docker Desktop از GUI یا settings.json استفاده می‌کنید. فرض نکنید که یک آموزش لینوکسی برای Docker Desktop هم کار می‌کند.
  • IPv6 و dual-stack. اگر پروکسی شما فقط IPv4 را پشتیبانی می‌کند، کانتینر یا دیمن را مجبور کنید IPv4 را ترجیح دهد. برخی ابزارها به یک فلگ صریح نیاز دارند.

یک گردش کار عملی برای شبکه‌های محدود یا فیلترشده

اگر از شبکه‌ای کار می‌کنید که دسترسی به رجیستری در آن کند، محدودشده یا فیلتر شده است — که در برخی شبکه‌های شرکتی و ملی رایج است — با پروکسی دیمن شروع کنید تا pullهای ایمیج موفق شوند. سپس آرگومان‌های زمان ساخت را برای مدیرهای بسته اضافه کنید. در نهایت، متغیرهای محیطی زمان اجرا را فقط برای کانتینرهایی تنظیم کنید که به خروج از طریق پروکسی نیاز دارند. اگر تنها endpoint پروکسی شما SOCKS5 است، یک بریج محلی اجرا کنید و متغیرهای پروکسی HTTP داکر را به آن اشاره دهید، یا SOCKS5 را داخل کانتینر برای برنامه‌هایی که مستقیماً از آن پشتیبانی می‌کنند نگه دارید.

این رویکرد لایه‌ای از فرستادن همه ترافیک کانتینر از پروکسی زمانی که فقط pullهای ایمیج و مراحل build به آن نیاز دارند جلوگیری می‌کند. همچنین اعتبارنامه‌ها را در مکان‌های کمتری نگه می‌دارد.

جمع‌بندی

پیکربندی پروکسی Docker یک تنظیم واحد نیست؛ بلکه یک تنظیم دیمن، یک آرگومان زمان build، و یک متغیر محیطی هر کانتینر است. SOCKS5 فقط جایی پشتیبانی می‌شود که خود برنامه پشتیبانی کند — دیمن Docker از آن پشتیبانی نمی‌کند. با پیکربندی آگاهانه هر لایه و تأیید با docker info، یک pull آزمایشی، و بررسی IP داخل کانتینر، می‌توانید buildها را بدون نشت DNS یا جای‌دادن اعتبارنامه‌ها در ایمیج‌ها سالم نگه دارید.