SSD Nodes Learn Hosting plans →
নির্দেশিকা Matt Connorদ্বারা Matt Connor

Docker container-কে VPN-এর মাধ্যমে রুট করার সঠিক নিয়ম

Gluetun sidecar ব্যবহার করলে কেন Docker container-এর port অদৃশ্য হয়ে যায় তা জানুন। shared network namespace-এর সমস্যার সমাধান এবং কার্যকরী Docker compose ফাইলটি এখানে দেখুন।

VPN-এর মাধ্যমে Docker container route করলে port কেন অদৃশ্য হয়ে যায়

Docker container-কে VPN-এর মাধ্যমে route করতে হলে একটি container-এ tunnel তৈরি করুন। এরপর network_mode: "service:gluetun" ব্যবহার করে অন্য container-গুলোকে সেই container-এর network namespace-এ যুক্ত করুন। এই সংযোগের বিষয়টিই অনেককে অবাক করে। যুক্ত container-এর নিজস্ব network আর থাকে না। ফলে তার published port এবং Docker service name-ও আর থাকে না। তাই port-গুলো VPN container-এ publish করুন। অন্য container-গুলো VPN container-এর name ব্যবহার করে app-এ পৌঁছাবে।

যুক্ত container-এ একটি ports: block রাখলে Docker সেটি তৈরি করতেই অস্বীকার করবে:

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

এখানে Gluetun ব্যবহার করা হয়েছে। এটি এমন একটি container, যা WireGuard বা OpenVPN-এর মাধ্যমে commercial VPN (virtual private network) provider-এর সঙ্গে সংযোগ স্থাপন করে এবং নিজস্ব firewall পরিচালনা করে। October 2026 অনুযায়ী Release v3.41.3 বর্তমান। উদাহরণগুলোতে WireGuard-সহ Mullvad ব্যবহার করা হয়েছে। তাই provider-এর কাছ থেকে একটি account এবং key প্রয়োজন। আপনি যদি নিজের মালিকানাধীন hardware-এ tunnel terminate করতে চান, তাহলে VPS-এ নিজের WireGuard server চালানো tunnel-এর অপর প্রান্ত তৈরি করে। আর Docker-এ wg-easy সেটিকে একটি web interface-এর মাধ্যমে পরিচালনা করে।

network_mode: "service:gluetun" আসলে যা করে

প্রতিটি Docker container সাধারণত নিজস্ব network namespace পায়: নিজস্ব interface, routing table, firewall rule এবং listening socket। service: মোড সেই ধাপটি এড়িয়ে যায় এবং gluetun-এর namespace-এর ভেতরে container-টি চালু করে। একটি namespace মানে একটি IP address, যা ছয়টি বিষয় পরিবর্তন করে।

  • অ্যাপটির নিজস্ব কোনো address থাকে না। এর address হয় gluetun-এর address।
  • অ্যাপটি কোনো Docker network-এর সাথে যুক্ত থাকে না, তাই এর service name কখনো নিবন্ধিত হয় না এবং resolve-ও হয় না। অন্যান্য container-কে অবশ্যই gluetun ব্যবহার করতে হবে।
  • namespace-এর ভেতরের container-গুলো localhost-এর মাধ্যমে একে অপরের সাথে যোগাযোগ করে।
  • একটি namespace-এর ভেতরে দুটি container একই port-এ listen করতে পারে না। Gluetun-এর নথিপত্রে এ বিষয়ে স্পষ্টভাবে বলা হয়েছে: এর কোনো বিকল্প সমাধান নেই।
  • Capabilities একটি container-এর নিজস্ব বিষয়, namespace-এর নয়। Gluetun-এর কাছে NET_ADMIN এবং /dev/net/tun থাকে কারণ এটি tunnel interface তৈরি করে। সংযুক্ত container এগুলো উত্তরাধিকারসূত্রে পায় না।
  • Compose এমন কোনো ফাইল গ্রহণ করে না যেখানে একটি service একই সাথে network_mode এবং networks সেট করে। আপনার network-এর সাথে gluetun-কে যুক্ত করুন, তাহলেই অ্যাপটি তার সাথে যুক্ত হয়ে যাবে।

gluetun রিস্টার্ট করলে এর সাথে সংযুক্ত সবকিছু বিচ্ছিন্ন হয়ে যায়। এটি একটি নথিভুক্ত আচরণ, এবং সংযোগ বিচ্ছিন্ন হলে container থেকে বেরিয়ে না গিয়ে gluetun কেন VPN প্রক্রিয়াটি রিস্টার্ট করে, তার কারণও এটি। আপনি নিজে gluetun রিস্টার্ট বা পুনরায় তৈরি করার পর, এর সাথে সংযুক্ত container-গুলোকেও রিস্টার্ট করুন।

যে 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 ট্যাগটি master ব্রাঞ্চের সর্বশেষ কমিট নির্দেশ করে, যা মূলত ডেভেলপমেন্ট ভার্সন। তাই এমন কোনো মেশিনে :v3 ব্যবহার করবেন না যেখানে আপনি ঝামেলা এড়াতে চান।

WEBUI_PORT=8080 অবশ্যই প্রকাশিত পোর্টের সাথে মিলতে হবে, কারণ qBittorrent সরাসরি gluetun-এর নেমস্পেসের ভেতরে বাইন্ড হয় এবং পাবলিশ রুল হোস্ট ট্রাফিককে সেখানে 8080 পোর্টে পাঠায়। একটি সংখ্যা পরিবর্তন করে অন্যটি না করলে পোর্টটি কোনো সাড়া দেবে না। 127.0.0.1:8080:8080 ওয়েব ইন্টারফেসটিকে হোস্টের লুপব্যাক অ্যাড্রেসে সীমাবদ্ধ রাখে। সাধারণ 8080:8080 ব্যবহার করলে তা প্রতিটি ইন্টারফেসে পোর্ট পাবলিশ করে এবং নিজস্ব ফায়ারওয়াল রুল তৈরি করে, যার ফলে Docker published ports slip straight past 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"

সেই JSON-এর ip ফিল্ডে আপনার VPN প্রোভাইডারের অ্যাড্রেস থাকা উচিত। যদি সেখানে আপনার সার্ভারের নিজস্ব অ্যাড্রেস দেখা যায়, তবে অ্যাপটি টানেলের ভেতরে নেই এবং পরবর্তী কোনো কিছুই বর্ণিত নিয়ম অনুযায়ী কাজ করবে না।

Compose file-এর বাইরে কী (keys) রাখুন

gluetun.env-এ ক্রেডেনশিয়াল থাকে এবং এটি git-এর বাইরে রাখা হয়:

WIREGUARD_PRIVATE_KEY=wOEI9rqqbDwnN8/Bpp22sVz48T71vJ4fYmFWujulwUU=
WIREGUARD_ADDRESSES=10.64.222.21/32

উভয় মানই আপনার প্রোভাইডারের অ্যাকাউন্ট এরিয়া থেকে জেনারেট করা একটি WireGuard কনফিগারেশন ফাইল থেকে আসে। ফাইলটির মোড 600 সেট করুন। এটি আপনাকে কী সুবিধা দেয় সে সম্পর্কে স্বচ্ছ ধারণা থাকা প্রয়োজন: কী (key) আপনার রিপোজিটরির বাইরে থাকে, কিন্তু docker inspect gluetun এখনও Docker socket-এ অ্যাক্সেস আছে এমন যে কাউকে প্রতিটি এনভায়রনমেন্ট ভেরিয়েবল দেখিয়ে দিতে পারে। Docker Compose-এ এনভায়রনমেন্ট ফাইল এবং সিক্রেটস অংশে আরও শক্তিশালী বিকল্পগুলো নিয়ে আলোচনা করা হয়েছে।

টানেলের বাইরের একটি container কীভাবে ভেতরের একটি container-এর সঙ্গে যোগাযোগ করে

দুই দিকেই যোগাযোগ কাজ করে, তবে প্রতিটি দিকে আলাদা নাম ব্যবহার করতে হয়। দুইটি container-এর একটি shared Docker network প্রয়োজন। এটি gluetun-এর network, কারণ সংযুক্ত container-এর নিজস্ব কোনো network নেই। ডিফল্ট network কীভাবে কাজ করে, তা Docker Compose network কীভাবে সংযুক্ত থাকে-এ ব্যাখ্যা করা হয়েছে।

বাইর থেকে ভেতরে যোগাযোগের জন্য gluetun-এর নাম এবং অ্যাপটি যে port-এ listen করে, সেটি ব্যবহার করুন। একটি reverse proxy container gluetun:8080-এ qBittorrent web interface-এ পৌঁছাতে পারে। এর জন্য কোনো ports: entry প্রয়োজন নেই, কারণ container থেকে container-এর traffic Docker network-এর মধ্যেই থাকে এবং কখনো host port-এ যায় না।

ভেতর থেকে বাইরে যোগাযোগের জন্য অন্য container-এর service name ব্যবহার করুন, যেমন postgres:5432। v3.41 থেকে gluetun নিজের namespace-এর ভেতর অন্য container-এর নাম resolve করতে পারে। কোনো নাম resolve না হলে এই version বা তার পরের version নির্দিষ্ট করুন।

কে gluetun-এর কাছে connection খুলতে পারবে, তা gluetun-এর firewall নির্ধারণ করে। gluetun-এর নিজস্ব Docker network থেকে আসা traffic অনুমোদিত থাকে। অন্য subnet-এর কোনো client, LAN-এর কোনো laptop বা আলাদা bridge network-এর কোনো container-এর জন্য gluetun-এর firewall ও routing-এ return path অনুমোদিত থাকতে হবে:

FIREWALL_OUTBOUND_SUBNETS=192.168.1.0/24

এর নথিভুক্ত অর্থ নির্দিষ্ট: comma-separated subnet, যেগুলোতে Gluetun এবং তার network stack শেয়ার করা container-গুলো access করতে পারবে।

Internet থেকে আসা inbound connection আলাদা সমস্যা। কোনো torrent client-এর peer-রা VPN দিক থেকে আসে, তাই host-এ port 6881 publish করলেই তাদের জন্য কাজ হবে না। আপনার provider-এর কাছ থেকে একটি forwarded port প্রয়োজন। সেই port FIREWALL_VPN_INPUT_PORTS-এ তালিকাভুক্ত করতে হবে, যা VPN server-এর দিক থেকে আসা port অনুমোদন করে। এই উদাহরণে ব্যবহৃত Mullvad port forwarding সমর্থন করে না। তাই এমন provider প্রয়োজন, যে এই সুবিধা দেয়। Docker Compose দিয়ে তৈরি অধিকাংশ media stack এই অংশটি অসম্পূর্ণ রেখে দেয়।

কিল সুইচ: টানেল বিচ্ছিন্ন হলে কী ঘটে

ব্যর্থতার সময় এই প্যাটার্নের জটিলতা সার্থক হয়। সংযুক্ত container Gluetun-এর interface এবং routing table শেয়ার করে। Gluetun-এর firewall টানেলের বাইরে সাধারণ Internet traffic block করে। একই সঙ্গে VPN server endpoint, স্থানীয় Docker traffic এবং configured exception অনুমোদন করে। টানেল বিচ্ছিন্ন হলে ওই firewall-ই plain interface-এ fallback হওয়া ঠেকায়। কোনো client পুনরায় সংযোগ করার সময় plain interface দিয়ে packet leak হওয়ার কোনো সময়সীমা থাকে না।

Gluetun নিজের connection পর্যবেক্ষণ করে। প্রতি মিনিটে এটি HEALTH_ICMP_TARGET_IPS-এ থাকা address-গুলোতে ICMP echo (একটি ping) পাঠায়। 1.1.1.1,8.8.8.8 হলো এর default মান। ICMP অনুমোদিত না থাকলে এই ছোট check-এর পরিবর্তে plaintext UDP DNS query পাঠানো হয়। প্রতি পাঁচ মিনিটে এটি HEALTH_TARGET_ADDRESSES-এ সম্পূর্ণ TCP এবং TLS (transport layer security) connection স্থাপনের চেষ্টা করে। cloudflare.com:443,github.com:443 হলো এর default মান। এগুলো ব্যর্থ হলে এটি container-এর ভেতরে VPN পুনরায় চালু করে এবং log-এ তা লিখে:

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

এই বিষয়টি মনে রেখে সংযুক্ত container-এর log পড়ুন। App-এর ভেতরের connection refused, operation not permitted এবং i/o timeout-এর মতো line-গুলো dead tunnel-এর ফল, কারণ নয়। Gluetun documentation-এ বিষয়টি স্পষ্টভাবে বলা আছে, কারণ অনেকে ফলাফলটি দেখে এবং ঘণ্টার পর ঘণ্টা সেটির কারণ খোঁজেন।

HEALTH_RESTART_VPN=on হলো default এবং এটি চালু রাখা উচিত। একটি নির্দিষ্ট failure debug করার সময়ই কেবল এটি বন্ধ করুন। কারণ এটি বন্ধ থাকলে dead tunnel dead-ই থাকে।

Ordering: টানেল চালু হওয়ার আগে stack শুরু বন্ধ রাখা

Image-এ একটি Docker healthcheck রয়েছে:

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

এই command-টি gluetun-এর একটি দ্বিতীয়, স্বল্পস্থায়ী copy চালায়। এটি http://127.0.0.1:9999/-এ চলমান gluetun-এর health server-এ query পাঠায়। সচল tunnel 200 OK উত্তর দেয়। Tunnel-এ সমস্যা থাকলে এটি error string-সহ 500 Internal server error উত্তর দেয়। পরপর তিনটি check ব্যর্থ হলে Docker container-টিকে unhealthy হিসেবে চিহ্নিত করে।

condition: service_healthy এই অবস্থার জন্য অপেক্ষা করে। সাধারণ depends_on: [gluetun] শুধু container start হওয়া পর্যন্ত অপেক্ষা করে। Handshake সম্পূর্ণ হওয়ার কয়েক সেকেন্ড আগেই container start হয়। তাই app একটি অকার্যকর network নিয়ে চালু হয় এবং প্রথম connection attempt-এই প্রায়ই ব্যর্থ হয়। Docker Compose-এ healthcheck-এ syntax এবং timing field-গুলো ব্যাখ্যা করা হয়েছে।

একটি সীমাবদ্ধতা অনেকের নজর এড়িয়ে যায়। Stack শুরু করার সময় Compose এই condition মূল্যায়ন করে। পরে gluetun unhealthy হলে এটি app থামায় বা restart করে না। ওই পরিস্থিতি gluetun-এর internal auto-healing সামলে নেয়। তাই এটি container নয়, VPN process restart করে।

বিশ্বাস করার আগে DNS leak পরীক্ষা করুন

DNS (domain name system) হলো এমন একটি leak, যা সঠিক tunnel থাকলেও থেকে যেতে পারে। Gluetun namespace-এর ভেতরে নিজস্ব resolver চালায় এবং ডিফল্টভাবে DoT (DNS over TLS) ব্যবহার করে Cloudflare-এ query পাঠায়: DNS_UPSTREAM_RESOLVER_TYPE=dot এবং DNS_UPSTREAM_RESOLVERS=cloudflare। দুটিই অপরিবর্তিত রাখলে আপনার lookup encrypted থাকে এবং tunnel-এর মধ্য দিয়ে যায়।

Local resolver-এ নির্দেশ করলে যে setting এটি নষ্ট করে, সেটি হলো DNS_UPSTREAM_PLAIN_ADDRESSES। কোনো name resolve না হলে এবং router বা provider-এর resolver দিয়ে উত্তর পাওয়ার প্রয়োজন হলে অনেকে এটি ব্যবহার করেন। Gluetun-এর documentation সতর্ক করে যে Docker bridge বা LAN-এর resolver-এ পাঠানো query VPN tunnel-এর বাইরে leak করে। Public plaintext resolver-এ পাঠানো query tunnel-এর মধ্য দিয়ে গেলেও VPN provider সেগুলো পড়তে এবং পরিবর্তন করতে পারে। WireGuard tunnel-এ একই সমস্যাটি WireGuard tunnel-এর মাধ্যমে DNS resolve হওয়া বন্ধ হলে অংশে আলোচনা করা হয়েছে।

পরীক্ষা করতে gluetun-এ SHADOWSOCKS=on এবং SHADOWSOCKS_PASSWORD সেট করুন, 8388:8388/tcp এবং 8388:8388/udp publish করুন, তারপর UDP DNS tunnel করার জন্য configured একটি Shadowsocks client দিয়ে সংযোগ করুন এবং DNS leak test চালু করুন। ফলাফলে আপনার provider বা Cloudflare-এর নাম থাকা উচিত; home router-এর নাম থাকা উচিত নয়। Gluetun-এর নিজস্ব documentation সতর্ক করে যে কিছু leak test অস্বাভাবিক ফলাফল দেখাতে পারে, কারণ namespace-এর ভেতরের resolver হলো একটি local caching intermediary, শেষ পর্যন্ত উত্তর দেওয়া server নয়। ভুল country বা আপনার নিজের ISP-এর resolver দেখা গেলে সেটিকেই প্রকৃত signal হিসেবে বিবেচনা করুন।

VPN sidecar-এর পাশে Tailscale যোগ করা এবং কোনটি কার্যকর হবে

Tailscale হলো WireGuard-এর ওপর তৈরি একটি overlay network, যা নিজের মেশিনে সংযোগের জন্য ব্যবহৃত হয়। অনেকে stack-এর প্রশাসনিক পথ সচল রাখতে provider VPN-এর পাশে এটি চালান। একই namespace শেয়ার করলে firewall rule-ও শেয়ার হয়। তাই দুটির firewall ও routing setting পরস্পরের সঙ্গে সামঞ্জস্যপূর্ণ হতে হবে। Tailscale-এর documentation অনুযায়ী default আচরণ হলো: এটি একটি overlay network হিসেবে কাজ করে, শুধু Tailscale চালানো device-গুলোর মধ্যে traffic route করে, এবং আপনার public internet traffic-এ হস্তক্ষেপ করে না।

তাই উত্তরটি একটি setting-এর ওপর নির্ভর করে।

  • Tailscale নিজের container-এ, default configuration-এ: এটি app-এর outbound traffic কখনো দেখে না। Gluetun পুরো traffic বহন করে। Tailscale container-এর কোনো process shared Docker network-এর মাধ্যমে gluetun:8080-এ app-এ পৌঁছাতে পারে; tailnet client-দের কাছে সেই connection প্রকাশ করতে forwarding বা proxy প্রয়োজন।
  • network_mode: "service:gluetun" ব্যবহার করে Tailscale-কে gluetun-এর namespace-এ যুক্ত করলে: default userspace networking mode-এ TS_USERSPACE চালু থাকে। tailscaled কোনো interface তৈরি করে না এবং SOCKS5 বা HTTP proxy হিসেবে কাজ করে। তাই এটি routing পরিবর্তন করতে পারে না। কোনো app স্পষ্টভাবে ওই proxy ব্যবহার না করলে Gluetun সাধারণ outbound traffic বহন করতে থাকে।
  • একই configuration-এ TS_USERSPACE=false ব্যবহার করলে: Tailscale-এর নিজস্ব /dev/net/tun device ও capabilities প্রয়োজন, কারণ namespace থেকে সেগুলো পাওয়া যায় না। tailscaled একটি tunnel device তৈরি করে এবং Linux-এ সাধারণত 100.64.0.0/10-এর জন্য একটি aggregate route-এর পরিবর্তে প্রতিটি IPv4 peer-এর জন্য /32 route ইনস্টল করে। শুধু TS_USERSPACE=false সেট করলে aggregate route চালু হয় না। TS_EXTRA_ARGS-এর মাধ্যমে --accept-routes পাঠালেই এটি অন্য node-এর subnet route ইনস্টল করে। TS_ROUTES বিপরীত দিকে কাজ করে: এই container যে subnet-গুলোতে পৌঁছাতে পারে, সেগুলো আপনার tailnet-এর অন্য সদস্যদের কাছে advertise করে। এটি tailscale set --advertise-routes=-এর সমতুল্য এবং এখানে কোনো route যোগ করে না। Public traffic এখনও gluetun-এর মাধ্যমেই বের হয়।
  • exit node নির্বাচিত অবস্থায় gluetun-এর namespace-এ kernel networking, sudo tailscale set --exit-node=<exit-node-ip>: Tailscale ওই namespace-এ default route ইনস্টল করে। তবে Gluetun-এর firewall সেই পথ আটকে দিতে পারে। আলাদা container-এ exit node নির্বাচন করলে app-এর route পরিবর্তিত হয় না। Userspace mode-এও শুধু proxy-তে স্পষ্টভাবে পাঠানো traffic বহন করা হয়। gluetun-এর namespace-এ পরস্পরের সঙ্গে প্রতিদ্বন্দ্বী default route একসঙ্গে ব্যবহার করবেন না। একটি default route-এর একজন owner থাকবে।

যদি advertised route-গুলোই উদ্দেশ্য হয় এবং শুধু box নয়, box-এর পেছনের পুরো private network-এ পৌঁছাতে চান, তাহলে VPS-এ Tailscale subnet router চালানো route approval, IP forwarding এবং client-side flag-এর বিষয়টি দেখায়। শুধু TS_ROUTES দিয়ে যে কাজটি সম্পন্ন হয় না, সেখানে সেটিই প্রয়োজনীয়।

Tailscale-এর উদ্দেশ্য যদি route দেওয়ার বদলে একটি admin URL দেওয়া হয়, তাহলে tailscale serve এবং tailscale funnel একটি local HTTP service-এর সামনে HTTPS বসায়। শুধু funnel service-টিকে public internet-এ প্রকাশ করে। Tailscale v1.104.5-এ Tailscale container shared Docker network-এর মাধ্যমে target-এ পৌঁছাতে পারলে তাদের HTTP reverse proxy সরাসরি http://gluetun:8080 গ্রহণ করে। localhost নয় এমন target-এর জন্য http:// scheme অন্তর্ভুক্ত করুন। gluetun-এর network namespace শেয়ার করে http://127.0.0.1:8080 target করলেও কাজ করে।

Tailscale tunnel-এর ভেতরে চললে একটি পার্শ্বপ্রতিক্রিয়া দেখা যায়। এর peer-রা VPN provider-এর address দেখতে পায়। তাই এটি বেশি সময় relay-এ fallback করতে পারে। এমন হলে tailscale status, direct-এর পরিবর্তে peer-এর পাশে relay "..." দেখায়। connection কাজ করে, তবে ধীর হয়। আপনার আসলে শুধু overlay প্রয়োজন হলে plain WireGuard এবং Tailscale-এর পার্থক্য দিয়ে শুরু করাই ভালো।

কী নষ্ট হতে পারে এবং আপনি যে বার্তা দেখতে পারেন

Docker অ্যাপের container তৈরি করতে অস্বীকার করে। Error response from daemon: conflicting options: port publishing and the container type network mode-এর অর্থ হলো একটি ports: block এখনও সংযুক্ত service-এ রয়েছে। সেটি gluetun-এ সরিয়ে নিন।

Compose পুরো file গ্রহণ করে না। কোনো service একই সঙ্গে network_mode এবং networks সেট করতে পারে না। network-গুলো gluetun-এ যুক্ত করুন।

অন্য container অ্যাপটি resolve করতে পারে না। curl: (6) Could not resolve host: qbittorrent-এর আচরণ সঠিক, কারণ সংযুক্ত container কোনো network-এ যুক্ত হয়নি এবং কোনো নাম নিবন্ধন করেনি। gluetun ও port ব্যবহার করুন।

দ্বিতীয় সংযুক্ত container চালু হয় না। একই namespace-এর দুটি process একই port-এ bind করতে পারে না। যে process ব্যর্থ হয়, সেটি address ইতিমধ্যে ব্যবহৃত হওয়ার বার্তা দেয়। অ্যাপের internal port পরিবর্তন করুন, অথবা দ্বিতীয় gluetun চালান।

gluetun-এ পরিবর্তন করার পরে অ্যাপের network নেই। gluetun restart বা recreate করলে এর সঙ্গে সংযুক্ত সবকিছুর connectivity বিচ্ছিন্ন হয়। ওই container-গুলো restart করুন।

ছোট page load হয়, কিন্তু বড় page আটকে থাকে। এটি MTU (maximum transmission unit) সমস্যা। tunnel অতিরিক্ত overhead যোগ করে, এবং network path-এর কোনো অংশ error না পাঠিয়ে অতিরিক্ত বড় packet বাদ দেয়। WIREGUARD_MTU পরীক্ষা করুন। v3.41.3-এ এর default মান 1320। path-এ ছোট packet প্রয়োজন হলে মানটি কমান। এই setting unset থাকলে development image path MTU discovery ব্যবহার করে।

Gluetun কখনও healthy হয় না। Startup check-এ প্রথমে যে বিষয়গুলো পরীক্ষা করতে হবে সেগুলোর নাম দেয়: WARN [vpn] restarting VPN because it failed to pass the healthcheck: startup check: dialing: dial tcp4: lookup cloudflare.com: i/o timeout। প্রথমে key-এর মেয়াদ শেষ হয়েছে কি না পরীক্ষা করুন। এরপর server list পুরোনো কি না পরীক্ষা করুন। সবশেষে host firewall outbound UDP block করছে কি না পরীক্ষা করুন।

FAQ

আমার container-এর published port Gluetun-এর পেছনে কাজ করা বন্ধ করল কেন?

কারণ network_mode: "service:gluetun" container-টিকে Gluetun-এর network namespace-এর মধ্যে রাখে, এবং একটি namespace-এ একটি IP address ও listening port-এর একটি সেট থাকে। অ্যাপটি listening চালিয়ে যায়, কিন্তু publish rule-টি সেই container-এ থাকতে হবে যেটি namespace-এর মালিক। ports: list-টি Gluetun service-এ সরান। এটি attached service-এ রেখে দিলে Docker সেটি তৈরি করবেই না: Error response from daemon: conflicting options: port publishing and the container type network mode।

VPN tunnel-এর ভেতরের container-এ tunnel-এর বাইরের container থেকে কীভাবে পৌঁছাব?

Gluetun-এর service name এবং অ্যাপটি যে port-এ listen করে সেটি ব্যবহার করুন, যেমন gluetun:8080। Attached container-টির নিজস্ব কোনো Docker network নেই, তাই তার নিজের name কখনো resolve হয় না। Container-to-container traffic-এর জন্য কিছু publish করার প্রয়োজন নেই। বিপরীত দিকে, namespace-এর ভেতরের container Gluetun v3.41 এবং পরবর্তী সংস্করণে service name ব্যবহার করে বাইরের container-এ পৌঁছাতে পারে, যেমন postgres:5432। আলাদা subnet-এর কোনো client, যেমন আপনার LAN-এর laptop, gluetun-এর firewall ও routing-এ অনুমোদিত return path প্রয়োজন; সেই subnet-টি FIREWALL_OUTBOUND_SUBNETS-এ যোগ করুন।

VPN বিচ্ছিন্ন হলে Gluetun কি kill switch হিসেবে কাজ করে?

হ্যাঁ, firewall সক্রিয় থাকলে। Attached container Gluetun-এর interface ও route ভাগ করে ব্যবহার করে, এবং firewall tunnel-এর বাইরে সাধারণ Internet traffic বন্ধ রাখে; একই সঙ্গে VPN server endpoint, স্থানীয় Docker traffic এবং configuration-এ নির্ধারিত exception অনুমোদন করে। Gluetun তখন VPN-কে অভ্যন্তরীণভাবে পুনরায় চালু করে এবং WARN [vpn] restarting VPN because it failed to pass the healthcheck log করে, exit করে না। কারণ gluetun নিজে restart হলে প্রতিটি attached container তার network হারায়।

একই stack-এ Tailscale এবং Gluetun: outbound traffic কোনটি বহন করে?

আপনি স্পষ্টভাবে Tailscale-এর মাধ্যমে পাঠানো না হলে সাধারণ outbound traffic Gluetun বহন করে। Tailscale ডিফল্টভাবে শুধু আপনার tailnet-এর device-গুলোর মধ্যে traffic route করে এবং public traffic অপরিবর্তিত রাখে। Container image-এর default userspace mode-এ এটি কোনো interface-ই তৈরি করে না, তাই routing-এ প্রভাব ফেলতে পারে না। TS_USERSPACE=false ব্যবহার করলে Linux সাধারণত aggregate 100.64.0.0/10 route-এর পরিবর্তে প্রতিটি IPv4 peer-এর জন্য আলাদা /32 route পায়। এছাড়া --accept-routes-কে TS_EXTRA_ARGS-এর মাধ্যমে যোগ করলেই কেবল অন্য node-এর subnet route যোগ হয়। TS_ROUTES এই container-এর subnet-গুলো আপনার tailnet-এ advertise করে, কিন্তু কোনো local route যোগ করে না। sudo tailscale set --exit-node=<exit-node-ip> দিয়ে exit node নির্বাচন করলে Tailscale-এর kernel networking ব্যবহারকারী namespace-এ কেবল default route install হয়। আলাদা কোনো container app-এর route পরিবর্তন করে না, এবং userspace mode-এ শুধু তার proxy-এর মাধ্যমে পাঠানো traffic বহন হয়। Default route-এর মালিক হিসেবে একটি product বেছে নিন; দুটিকে একসঙ্গে স্তরীভুক্ত করবেন না।

এই লেখাটি কি কাজে লেগেছে?