SSD Nodes Learn Hosting plans →
راهنماها Matt Connorتوسط Matt Connor · به‌روزرسانی شده 2026-08-27

آموزش اتصال کانتینر Docker به VPN با Gluetun

هنگام استفاده از network_mode: service:gluetun پورت‌ها در Docker ناپدید می‌شوند. در این راهنما علت این مشکل و نحوه تنظیم صحیح فایل docker-compose برای رفع آن را بررسی می‌کنیم.

چرا هنگام هدایت کانتینرهای Docker از طریق VPN، پورت‌ها ناپدید می‌شوند

برای هدایت کانتینرهای Docker از طریق VPN، شما تونل را به یک کانتینر اختصاص می‌دهید و سپس بقیه کانتینرها را با استفاده از network_mode: "service:gluetun" به فضای نام شبکه (network namespace) آن متصل می‌کنید. این اتصال همان بخشی است که باعث تعجب کاربران می‌شود. کانتینر متصل‌شده دیگر شبکه اختصاصی خود را ندارد، بنابراین پورت‌های منتشرشده (published ports) و نام سرویس Docker آن همراه با شبکه اختصاصی‌اش از بین می‌روند. پورت‌ها را روی کانتینر VPN منتشر کنید تا سایر کانتینرها بتوانند از طریق نام کانتینر VPN به برنامه دسترسی پیدا کنند.

اگر یک بلوک ports: روی کانتینر متصل‌شده باقی بگذارید، Docker از ایجاد آن کانتینر به‌طور کامل خودداری می‌کند:

Error response from daemon: conflicting options: port publishing and the container type network mode

ابزار مورد استفاده در اینجا Gluetun است؛ کانتینری که از طریق WireGuard یا OpenVPN به یک ارائه‌دهنده VPN تجاری متصل می‌شود و فایروال اختصاصی خود را دارد. نسخه v3.41.3 تا اوت 2026 نسخه جاری است. مثال‌ها از Mullvad با WireGuard استفاده می‌کنند، بنابراین شما به یک حساب کاربری و یک کلید از ارائه‌دهنده خود نیاز دارید. اگر ترجیح می‌دهید تونل را روی سخت‌افزاری که مالک آن هستید خاتمه دهید، راه‌اندازی سرور WireGuard شخصی روی یک VPS سمت دیگر اتصال را می‌سازد و wg-easy در Docker آن را در یک رابط کاربری وب بسته‌بندی می‌کند.

عملکرد واقعی network_mode: "service:gluetun"

هر container در Docker به‌طور معمول فضای نام شبکه (network namespace) اختصاصی خود را دارد: رابط‌ها، جدول مسیریابی، قوانین فایروال و سوکت‌های در حال گوش دادن (listening sockets) مختص به خود. حالت service: از این مرحله صرف‌نظر کرده و container را درون فضای نام gluetun اجرا می‌کند. یک فضای نام به معنای یک آدرس IP واحد است و این موضوع 6 مورد را تغییر می‌دهد:

  • برنامه هیچ آدرس مستقلی ندارد. آدرس آن همان آدرس gluetun است.
  • برنامه به هیچ شبکه Docker متصل نیست، بنابراین نام سرویس آن هرگز ثبت نمی‌شود و قابل resolve نیست. سایر containerها باید از gluetun استفاده کنند.
  • containerهای درون این فضای نام از طریق localhost به یکدیگر دسترسی پیدا می‌کنند.
  • دو container در یک فضای نام نمی‌توانند روی یک پورت مشابه گوش دهند. مستندات Gluetun در این مورد صریح است: هیچ راه حلی برای آن وجود ندارد.
  • قابلیت‌ها (Capabilities) متعلق به یک container هستند، نه یک فضای نام. Gluetun دارای NET_ADMIN و /dev/net/tun است زیرا رابط تونل را ایجاد می‌کند. container متصل‌شده این قابلیت‌ها را به ارث نمی‌برد.
  • ابزار Compose هر فایلی را که در آن یک سرویس همزمان network_mode و networks را تنظیم کرده باشد، رد می‌کند. gluetun را به شبکه‌های خود متصل کنید تا برنامه همراه آن عمل کند.

راه‌اندازی مجدد (Restart) gluetun باعث قطع اتصال تمام مواردی می‌شود که به آن متصل هستند. این یک رفتار مستندشده است و به همین دلیل است که gluetun به‌جای خروج در هنگام شکست اتصال، فرآیند VPN را درون container مجدداً راه‌اندازی می‌کند. پس از اینکه خودتان gluetun را restart یا recreate کردید، containerهای متصل به آن را نیز restart کنید.

فایل compose که کار می‌کند

services:
  gluetun:
    image: qmcgaw/gluetun:v3
    container_name: gluetun
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun:/dev/net/tun
    environment:
      - VPN_SERVICE_PROVIDER=mullvad
      - VPN_TYPE=wireguard
      - SERVER_CITIES=Amsterdam
      - TZ=Europe/Amsterdam
    env_file:
      - ./gluetun.env
    volumes:
      - ./gluetun:/gluetun
    ports:
      - 127.0.0.1:8080:8080/tcp
    restart: unless-stopped

  qbittorrent:
    image: lscr.io/linuxserver/qbittorrent:latest
    container_name: qbittorrent
    network_mode: "service:gluetun"
    environment:
      - PUID=1000
      - PGID=1000
      - TZ=Europe/Amsterdam
      - WEBUI_PORT=8080
    volumes:
      - ./qbittorrent:/config
      - ./downloads:/downloads
    depends_on:
      gluetun:
        condition: service_healthy
    restart: unless-stopped

تگ :v3 جدیدترین نسخه پایدار در سری v3 است. تگ :latest به آخرین commit از شاخه master اشاره دارد که لبه توسعه (development edge) محسوب می‌شود؛ بنابراین :v3 را روی ماشینی که نمی‌خواهید در روز سه‌شنبه عیب‌یابی کنید، ثابت (pin) نکنید.

مقدار WEBUI_PORT=8080 باید با پورت منتشرشده مطابقت داشته باشد، زیرا qBittorrent در داخل فضای نام (namespace) gluetun متصل می‌شود و قانون انتشار، ترافیک میزبان را به پورت 8080 در آنجا هدایت می‌کند. اگر یکی از این اعداد را بدون دیگری تغییر دهید، پورت به هیچ درخواستی پاسخ نخواهد داد. مقدار 127.0.0.1:8080:8080 رابط وب را روی آدرس loopback میزبان نگه می‌دارد. یک 8080:8080 ساده، پورت را روی تمام رابط‌ها منتشر می‌کند و قانون فایروال مخصوص خود را می‌نویسد؛ این همان روشی است که پورت‌های منتشرشده Docker مستقیماً از ufw عبور می‌کنند.

سرویس را بالا بیاورید و سپس آن را به این ترتیب بررسی کنید:

docker compose up -d
docker compose ps
docker compose logs gluetun | tail -30

دستور docker compose ps باید gluetun را به صورت healthy و qbittorrent را به صورت running نشان دهد. سپس آدرس خروجی را از داخل فضای نام تأیید کنید؛ این همان بررسی است که وضعیت همه چیز را تعیین می‌کند:

docker run --rm --network=container:gluetun alpine:3.22 sh -c "apk add wget && wget -qO- https://ipinfo.io"

فیلد ip در آن JSON باید آدرس ارائه‌دهنده VPN شما باشد. اگر این آدرس، آدرس خودِ سرور شما باشد، برنامه در تونل قرار ندارد و هیچ‌کدام از موارد زیر طبق توضیحات عمل نخواهند کرد.

کلیدها را خارج از فایل compose نگه دارید

gluetun.env حاوی اعتبارنامه‌ها است و نباید در git قرار بگیرد:

WIREGUARD_PRIVATE_KEY=wOEI9rqqbDwnN8/Bpp22sVz48T71vJ4fYmFWujulwUU=
WIREGUARD_ADDRESSES=10.64.222.21/32

هر دو مقدار از فایل پیکربندی WireGuard که در پنل کاربری ارائه‌دهنده خود ایجاد می‌کنید، به دست می‌آیند. مجوز فایل را روی 600 تنظیم کنید. در مورد مزیت این کار صادق باشید: کلید در مخزن شما ذخیره نمی‌شود، اما docker inspect gluetun همچنان تمام متغیرهای محیطی را برای هر کسی که به Docker socket دسترسی داشته باشد، نمایش می‌دهد. فایل‌های محیطی و secrets در Docker Compose گزینه‌های امن‌تر را بررسی می‌کند.

نحوه ارتباط یک کانتینر خارج از تونل با کانتینری در داخل آن

هر دو جهت ارتباط کار می‌کنند و هر کدام از نام متفاوتی استفاده می‌کنند. این دو کانتینر به یک شبکه Docker مشترک نیاز دارند؛ یعنی شبکه gluetun، زیرا کانتینر متصل‌شده به آن، شبکه اختصاصی خود را ندارد. بخش نحوه سیم‌کشی شبکه‌های Docker Compose پیش‌فرض‌ها را پوشش می‌دهد.

برای ارتباط از خارج به داخل، از نام gluetun و پورتی که برنامه روی آن گوش می‌دهد استفاده کنید. یک کانتینر reverse proxy به رابط وب qBittorrent در آدرس gluetun:8080 دسترسی پیدا می‌کند. برای این کار نیازی به ورودی ports: نیست، زیرا ترافیک بین کانتینرها در شبکه Docker باقی می‌ماند و هرگز با پورت میزبان تماس پیدا نمی‌کند.

برای ارتباط از داخل به خارج، از نام سرویس کانتینر دیگر، مثلاً postgres:5432 استفاده کنید. gluetun از نسخه 3.41 به بعد، نام سایر کانتینرها را از داخل فضای نام خود حل (resolve) می‌کند؛ بنابراین اگر نامی حل نمی‌شود، آن نسخه یا نسخه‌های جدیدتر را پین کنید.

فایروال gluetun تعیین می‌کند چه کسی اجازه برقراری اتصال با آن را دارد. ترافیک شبکه Docker خودِ gluetun مجاز است. اتصالات از یک زیرشبکه (subnet) متفاوت، مانند لپ‌تاپ در شبکه LAN شما یا کانتینری در یک شبکه bridge جداگانه، تا زمانی که آن زیرشبکه را نام نبرید، مسدود (drop) می‌شوند:

FIREWALL_OUTBOUND_SUBNETS=192.168.1.0/24

معنای مستندات دقیق است: زیرشبکه‌های جداشده با کاما که gluetun و کانتینرهایی که از پشته شبکه آن استفاده می‌کنند، اجازه دسترسی به آن‌ها را دارند.

اتصالات ورودی از اینترنت یک مسئله جداگانه است. همتایان (peers) یک کلاینت تورنت از سمت VPN می‌آیند، بنابراین انتشار پورت 6881 روی میزبان هیچ تأثیری برای آن‌ها ندارد. شما به یک پورت فوروارد شده از طرف ارائه‌دهنده خود نیاز دارید و آن پورت باید در FIREWALL_VPN_INPUT_PORTS فهرست شود، که اجازه می‌دهد پورت‌ها از سمت سرور VPN عبور کنند. این همان بخشی است که اکثر استک‌های رسانه‌ای ساخته‌شده با Docker Compose آن را ناقص باقی می‌گذارند.

کلید قطع اضطراری (kill switch): هنگام قطع تونل چه رخ می‌دهد

این الگو پیچیدگی خود را در زمان بروز خطا نشان می‌دهد. کانتینر متصل، مسیر دومی ندارد. تنها راه خروج آن از ماشین، همان namespace مشترکی است که با کانتینر VPN دارد؛ بنابراین وقتی تونل قطع می‌شود، هیچ مسیر جایگزینی برای ترافیک وجود ندارد. فایروال Gluetun همین قانون را از سمت دیگر اعمال می‌کند: ترافیک خروجی باید از طریق تونل یا به سمت endpoint سرور VPN هدایت شود و سایر ترافیک‌ها مسدود (drop) می‌شوند. هیچ بازه زمانی وجود ندارد که در آن بسته‌ها در حین اتصال مجدد کلاینت، از طریق رابط شبکه اصلی (plain interface) نشت کنند.

Gluetun اتصال خود را پایش می‌کند. هر دقیقه یک ICMP echo (پینگ) به آدرس‌های موجود در HEALTH_ICMP_TARGET_IPS ارسال می‌کند که به‌صورت پیش‌فرض 1.1.1.1,8.8.8.8 هستند. هر پنج دقیقه یک اتصال کامل TCP و TLS (امنیت لایه انتقال) به HEALTH_TARGET_ADDRESSES برقرار می‌کند که به‌صورت پیش‌فرض cloudflare.com:443,github.com:443 است. هنگامی که این موارد با شکست مواجه شوند، VPN را داخل کانتینر ری‌استارت کرده و آن را لاگ می‌کند:

WARN [vpn] restarting VPN because it failed to pass the healthcheck: periodic check: dialing: dial tcp4: lookup cloudflare.com: i/o timeout

لاگ‌های کانتینر متصل را با در نظر گرفتن این ترتیب بخوانید. خطوطی مانند connection refused، operation not permitted و i/o timeout در داخل برنامه، پیامد قطع بودن تونل هستند، نه علت آن. مستندات Gluetun مستقیماً به این موضوع اشاره دارد، زیرا کاربران اغلب پیامد را گزارش کرده و ساعت‌ها به دنبال علت آن می‌گردند.

HEALTH_RESTART_VPN=on مقدار پیش‌فرض است و باید فعال بماند. آن را فقط زمانی غیرفعال کنید که در حال عیب‌یابی یک خطای خاص هستید، زیرا با غیرفعال بودن آن، تونل قطع‌شده در همان وضعیت باقی می‌ماند.

ترتیب‌بندی: جلوگیری از شروع پشته پیش از برقراری تونل

این ایمیج دارای یک healthcheck در Docker است:

HEALTHCHECK --interval=5s --timeout=5s --start-period=10s --retries=1 CMD /gluetun-entrypoint healthcheck

این دستور یک کپی دوم و کوتاه‌مدت از gluetun را اجرا می‌کند که سرور سلامت نمونه در حال اجرا را در http://127.0.0.1:9999/ پرس‌وجو می‌کند. یک تونل فعال، پاسخ 200 OK را برمی‌گرداند. تونل قطع‌شده پاسخ 500 Internal server error را به همراه یک رشته خطا برمی‌گرداند و کانتینر پس از یک بار شکست، در وضعیت ناسالم (unhealthy) قرار می‌گیرد.

condition: service_healthy همان چیزی است که منتظر این وضعیت می‌ماند. عبارت ساده depends_on: [gluetun] فقط منتظر شروع کانتینر می‌ماند، که چندین ثانیه پیش از تکمیل handshake رخ می‌دهد؛ بنابراین برنامه در یک شبکه غیرفعال شروع به کار می‌کند و اغلب در اولین تلاش برای اتصال، متوقف می‌شود. بررسی‌های سلامت در Docker Compose نحو و فیلدهای زمان‌بندی را بررسی می‌کند.

یک محدودیت وجود دارد که کاربران را دچار مشکل می‌کند. Compose این شرط را فقط یک بار، هنگام ایجاد کانتینر ارزیابی می‌کند. اگر gluetun بعداً ناسالم شود، برنامه را متوقف یا ری‌استارت نمی‌کند. قابلیت خودترمیمی داخلی gluetun این مورد را پوشش می‌دهد، به همین دلیل است که به‌جای ری‌استارت کردن کانتینر، فرآیند VPN را مجدداً راه‌اندازی می‌کند.

بررسی نشت DNS پیش از اعتماد به تنظیمات

DNS (سیستم نام دامنه) نشتی است که حتی پس از برقراری صحیح تونل نیز باقی می‌ماند. Gluetun به‌صورت پیش‌فرض resolver اختصاصی خود را درون namespace اجرا کرده و پرس‌وجوها را از طریق DoT (DNS over TLS) به Cloudflare ارسال می‌کند: DNS_UPSTREAM_RESOLVER_TYPE=dot و DNS_UPSTREAM_RESOLVERS=cloudflare. این دو را تغییر ندهید تا جستجوهای شما رمزنگاری شده و از طریق تونل عبور کنند.

تنظیمی که این وضعیت را مختل می‌کند DNS_UPSTREAM_PLAIN_ADDRESSES است. کاربران زمانی به سراغ این گزینه می‌روند که نامی resolve نمی‌شود و می‌خواهند روتر یا resolver ارائه‌دهندهٔ خدماتشان پاسخگو باشد. مستندات Gluetun هزینهٔ این کار را به‌وضوح بیان می‌کند: تمام ترافیک DNS از تونل VPN عبور نکرده و از آن نشت می‌کند. ترافیک شما خصوصی باقی می‌ماند، اما لیست نام‌های میزبان (hostname) خیر. نسخهٔ مشابه این اشتباه در WireGuard در DNS که در تونل WireGuard از کار می‌افتد بررسی شده است.

برای تست این موضوع، HTTPPROXY=on را در gluetun تنظیم کرده و 8888:8888/tcp را منتشر کنید، سپس مرورگر خود را به آن پروکسی هدایت کرده و یک تست نشت DNS را بارگذاری کنید. نتیجه باید نام ارائه‌دهندهٔ شما یا Cloudflare را نشان دهد و هرگز نباید روتر خانگی شما را نمایش دهد. مستندات خودِ Gluetun هشدار می‌دهد که برخی تست‌های نشت، نتایج عجیبی گزارش می‌کنند، زیرا resolver درون namespace یک واسط کش محلی است، نه سروری که در نهایت پاسخ می‌دهد. نمایش کشور اشتباه یا resolver متعلق به ISP خودتان را به عنوان نشانهٔ واقعی نشت در نظر بگیرید.

افزودن Tailscale در کنار sidecar مربوط به VPN و تعیین اولویت آن‌ها

Tailscale یک شبکه overlay مبتنی بر WireGuard برای دسترسی به ماشین‌های شخصی شماست و کاربران اغلب آن را در کنار یک VPN عمومی اجرا می‌کنند تا یک مسیر مدیریتی به stack خود داشته باشند. این دو به دلیلی که ارزش درک دارد، به‌ندرت با هم تداخل پیدا می‌کنند. مستندات Tailscale رفتار پیش‌فرض را این‌گونه بیان می‌کند: این ابزار به‌عنوان یک شبکه overlay عمل کرده، ترافیک را فقط بین دستگاه‌هایی که Tailscale روی آن‌ها اجرا شده مسیریابی می‌کند و به ترافیک اینترنت عمومی شما دست نمی‌زند.

بنابراین پاسخ به یک تنظیم خاص بستگی دارد.

  • Tailscale در container اختصاصی خود با پیکربندی پیش‌فرض: این حالت هرگز ترافیک خروجی برنامه را نمی‌بیند. Gluetun تمام ترافیک را هدایت می‌کند. Tailscale دقیقاً مانند هر container خارجی دیگر، از طریق gluetun:8080 به برنامه دسترسی پیدا می‌کند.
  • Tailscale متصل به namespace مربوط به gluetun با network_mode: "service:gluetun": این حالت به cap_add اختصاصی از net_admin و net_raw نیاز دارد، زیرا قابلیت‌ها (capabilities) همراه با namespace منتقل نمی‌شوند. در حالت پیش‌فرض شبکه userspace، وقتی TS_USERSPACE فعال است، tailscaled هیچ رابط (interface) ایجاد نمی‌کند و به‌عنوان یک SOCKS5 یا HTTP proxy عمل می‌کند، بنابراین نمی‌تواند مسیریابی را تغییر دهد. Gluetun همچنان تمام ترافیک را حمل می‌کند.
  • همان حالت با TS_USERSPACE=false: ابزار tailscaled یک دستگاه تونل ایجاد کرده و مسیرها را نصب می‌کند، اما فقط برای محدوده tailnet یعنی 100.64.0.0/10 به علاوه هر subnet route که با TS_ROUTES معرفی کرده باشید. ترافیک عمومی همچنان از طریق gluetun خارج می‌شود.
  • هر یک از موارد بالا با انتخاب یک exit node یعنی sudo tailscale set --exit-node=<exit-node-ip>: Tailscale مسیر پیش‌فرض (default route) را تصاحب کرده و اولویت می‌یابد. این حالت را با gluetun ترکیب نکنید. تنها یک مسیر پیش‌فرض و یک مالک برای آن وجود دارد.

اگر هدف شما استفاده از آن مسیرهای معرفی‌شده (advertised routes) است و می‌خواهید کل شبکه خصوصی پشت آن جعبه قابل دسترسی باشد، نه فقط خود جعبه، اجرای یک Tailscale subnet router روی یک VPS مراحل تأیید مسیر، IP forwarding و پرچم سمت کلاینت را که TS_ROUTES به‌تنهایی انجام نمی‌دهد، پوشش می‌دهد.

اگر Tailscale برای ارائه یک URL مدیریتی در آنجا قرار دارد و نه برای مسیریابی، tailscale serve و tailscale funnel پروتکل HTTPS را برای tailnet شما در مقابل gluetun:8080 قرار می‌دهند و تنها با استفاده از funnel آن را برای اینترنت عمومی باز می‌کنند.

یک اثر جانبی زمانی قابل مشاهده است که Tailscale داخل تونل اجرا شود. همتایان (peers) آن، آدرس ارائه‌دهنده VPN را می‌بینند، بنابراین انتظار داشته باشید که بیشتر به relayها متوسل شود. وقتی این اتفاق می‌افتد، tailscale status به جای direct، عبارت relay "..." را در کنار یک peer نشان می‌دهد. اتصال برقرار است اما سرعت آن کمتر است. اگر شبکه overlay تنها چیزی است که واقعاً به آن نیاز دارید، تفاوت بین WireGuard ساده و Tailscale نقطه شروع بهتری است.

چه چیزی از کار می‌افتد و چه پیامی مشاهده خواهید کرد

Docker از ایجاد container برنامه خودداری می‌کند. Error response from daemon: conflicting options: port publishing and the container type network mode به این معنی است که یک ports: همچنان روی سرویس متصل باقی مانده است. آن را به gluetun منتقل کنید.

Compose کل فایل را رد می‌کند. یک سرویس نمی‌تواند همزمان network_mode و networks را تنظیم کند. شبکه‌ها را روی gluetun قرار دهید.

یک container دیگر نمی‌تواند برنامه را resolve کند. curl: (6) Could not resolve host: qbittorrent رفتار درستی است، زیرا container متصل به هیچ شبکه‌ای ملحق نشده و نامی ثبت نکرده است. از gluetun و پورت مربوطه استفاده کنید.

دومین container متصل شروع به کار نمی‌کند. دو پردازش در یک namespace نمی‌توانند به یک پورت متصل شوند (bind شوند) و پردازشی که شکست می‌خورد گزارش می‌دهد که آدرس در حال استفاده است. پورت داخلی برنامه را تغییر دهید یا یک gluetun دوم اجرا کنید.

پس از دستکاری gluetun، برنامه هیچ دسترسی شبکه‌ای ندارد. راه‌اندازی مجدد یا ایجاد دوباره gluetun، اتصال تمام موارد متصل به آن را قطع می‌کند. آن containerها را restart کنید.

صفحات کوچک بارگذاری می‌شوند اما صفحات بزرگ متوقف می‌مانند. این مشکل مربوط به MTU (حداکثر واحد انتقال) است. تونل سربار ایجاد می‌کند و بخشی از مسیر، بسته‌های بیش از حد بزرگ را بدون ارسال پیام خطا حذف می‌کند. مقدار WIREGUARD_MTU را کاهش دهید، 1400 را امتحان کنید و سپس 1320 را تست کنید.

وضعیت gluetun هرگز healthy نمی‌شود. بررسی اولیه هنگام شروع کار، اولین مظنون‌ها را نام می‌برد: WARN [vpn] restarting VPN because it failed to pass the healthcheck: startup check: dialing: dial tcp4: lookup cloudflare.com: i/o timeout. بررسی کنید که آیا کلید منقضی شده است یا خیر، سپس بررسی کنید که آیا لیست سرورها قدیمی است و در نهایت چک کنید که آیا فایروال میزبان شما ترافیک خروجی UDP را مسدود می‌کند یا خیر.

FAQ

چرا پورت‌های منتشرشده کانتینر من پس از قرارگیری پشت Gluetun از کار افتادند؟

زیرا network_mode: "service:gluetun" کانتینر را درون فضای نام شبکه (network namespace) متعلق به Gluetun قرار می‌دهد و هر فضای نام تنها یک آدرس IP و یک مجموعه پورت شنود (listening ports) دارد. برنامه همچنان به شنود ادامه می‌دهد، اما قانون انتشار پورت (publish rule) باید روی کانتینری تعریف شود که مالک فضای نام است. لیست ports: را به سرویس gluetun منتقل کنید. اگر آن را روی سرویس متصل‌شده باقی بگذارید، Docker حتی آن را ایجاد نخواهد کرد: Error response from daemon: conflicting options: port publishing and the container type network mode.

چگونه از یک کانتینر خارج از تونل VPN به کانتینری درون آن دسترسی پیدا کنم؟

از نام سرویس gluetun و پورتی که برنامه روی آن شنود می‌کند استفاده کنید، برای مثال gluetun:8080. کانتینر متصل‌شده هیچ شبکه Docker مستقلی ندارد، بنابراین نام خودش هرگز resolve نمی‌شود. برای ترافیک بین کانتینرها نیازی به انتشار پورت نیست. در جهت معکوس، کانتینری که درون فضای نام قرار دارد، در نسخه‌های Gluetun v3.41 و جدیدتر، با استفاده از نام سرویس به کانتینر بیرونی دسترسی پیدا می‌کند، مانند postgres:5432. ترافیک کلاینتی که در زیرشبکه (subnet) متفاوتی قرار دارد، مانند لپ‌تاپی در شبکه LAN شما، توسط فایروال gluetun مسدود می‌شود مگر اینکه آن زیرشبکه را به FIREWALL_OUTBOUND_SUBNETS اضافه کنید.

آیا Gluetun هنگام قطع شدن VPN به عنوان یک kill switch عمل می‌کند؟

بله، و به دو دلیل همزمان. کانتینر متصل‌شده هیچ مسیری (route) به جز مسیر موجود در فضای نام مشترک ندارد، بنابراین با قطع شدن تونل، هیچ راهی برای خروج از ماشین برای آن باقی نمی‌ماند. همچنین فایروال Gluetun ترافیک خروجی را تنها از طریق تونل و به سمت endpoint سرور VPN مجاز می‌داند. Gluetun سپس به جای خروج از برنامه، VPN را به‌صورت داخلی راه‌اندازی مجدد می‌کند و WARN [vpn] restarting VPN because it failed to pass the healthcheck را لاگ می‌کند، زیرا با هر بار راه‌اندازی مجدد خودِ gluetun، تمام کانتینرهای متصل‌شده شبکه خود را از دست می‌دهند.

Tailscale و Gluetun در یک stack: کدام‌یک ترافیک خروجی را حمل می‌کند؟

در تمام پیکربندی‌ها به جز یک مورد، Gluetun. Tailscale به‌صورت پیش‌فرض فقط ترافیک بین دستگاه‌ها در tailnet شما را مسیریابی می‌کند و ترافیک عمومی را تغییر نمی‌دهد. در حالت پیش‌فرض userspace این ایمیج کانتینری، هیچ اینترفیسی ایجاد نمی‌شود، بنابراین نمی‌تواند بر مسیریابی تأثیر بگذارد. با TS_USERSPACE=false، این ابزار فقط مسیرهایی را برای 100.64.0.0/10 و زیرشبکه‌های معرفی‌شده (advertised subnets) شما نصب می‌کند. استثنا، استفاده از exit node است: sudo tailscale set --exit-node=<exit-node-ip> باعث می‌شود Tailscale به مسیر پیش‌فرض تبدیل شود و در نتیجه اولویت پیدا کند. به جای ترکیب هر دو، یکی از این محصولات را برای مدیریت مسیر پیش‌فرض انتخاب کنید.