Jinsi ya Kupitisha Docker Containers Kupitia VPN
Ukiweka container nyuma ya Gluetun, ports hupotea kwa sababu ya shared network namespace. Jifunze kwa nini na upate compose file inayofanya kazi.
Kwa nini port hupotea unapopitisha Docker containers kupitia VPN
Ili kupitisha Docker containers kupitia VPN, unaipa container moja tunnel, kisha unaunganisha nyingine kwenye network namespace yake kwa kutumia network_mode: "service:gluetun". Muunganisho huo ndio huwashangaza watu. Container iliyounganishwa haina tena mtandao wake, kwa hiyo ports zake zilizochapishwa na jina lake la Docker service hupotea pamoja nao. Chapisha ports kwenye VPN container badala yake, na containers nyingine zifikie app kwa kutumia jina la VPN container.
Ukiacha block ya ports: kwenye container iliyounganishwa, Docker hukataa kuiunda kabisa:
Error response from daemon: conflicting options: port publishing and the container type network modeZana inayotumika hapa ni Gluetun, container inayounganisha kwenye mtoa huduma wa VPN (virtual private network) wa kibiashara kupitia WireGuard au OpenVPN na yenye firewall yake. Release v3.41.3 ndiyo ya sasa kufikia August 2026. Mifano inatumia Mullvad pamoja na WireGuard, kwa hiyo unahitaji account na key kutoka kwa mtoa huduma wako. Ikiwa ungependa kusitisha tunnel kwenye hardware unayomiliki, kuendesha WireGuard server yako mwenyewe kwenye VPS hujenga upande mwingine, na wg-easy kwenye Docker hufunga usanidi huo katika web interface.
Kile ambacho network_mode: "service:gluetun" hufanya
Kwa kawaida, kila Docker container hupata network namespace yake: interfaces zake, routing table yake, firewall rules zake na listening sockets zake. Mode ya service: huruka hatua hiyo na kuanzisha container ndani ya namespace ya gluetun. Namespace moja inamaanisha IP address moja, na hilo hubadilisha mambo sita.
- App haina address yake. Address yake ni ya gluetun.
- App haijaunganishwa kwenye Docker network yoyote, kwa hiyo service name yake haisajiliwi na haiwezi kutatuliwa. Containers nyingine lazima zitumie
gluetun. - Containers zilizo ndani ya namespace hiyo hufikiana kupitia
localhost. - Containers mbili zilizo kwenye namespace moja haziwezi kusikiliza port moja. Nyaraka za Gluetun zinasema wazi: hakuna workaround.
- Capabilities ni za container, si za namespace. Gluetun ina
NET_ADMINna/dev/net/tunkwa sababu ndiyo huunda tunnel interface. Container iliyoambatishwa hairithi capabilities hizo. - Compose hukataa file ambayo service moja inaweka
network_modenanetworkskwa pamoja. Unganisha gluetun kwenye networks zako, kisha app itatumia muunganisho huo.
Kuanzisha upya gluetun hutenganisha kila kitu kilichoambatishwa kwake. Hii ni tabia iliyoandikwa kwenye nyaraka, na ndiyo sababu gluetun huanzisha upya VPN process ndani ya container badala ya kutoka wakati connection inashindwa. Baada ya wewe kuanzisha upya au kuunda upya gluetun, anzisha upya containers zilizoambatishwa kwake.
Faili ya compose inayofanya kazi
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-stoppedLebo ya :v3 ni toleo thabiti jipya zaidi katika mfululizo wa v3. Lebo ya :latest inaelekeza kwenye commit ya mwisho ya tawi la master, ambalo ni tawi la maendeleo; kwa hiyo tumia :v3 kwenye mashine ambayo hutaki kuanza kuitatua matatizo siku ya Jumanne.
WEBUI_PORT=8080 lazima ilingane na port iliyochapishwa, kwa sababu qBittorrent huunganisha ndani ya namespace ya gluetun, na kanuni ya publish hupeleka traffic ya host kwenye port 8080 humo. Ukibadilisha namba moja bila kubadilisha nyingine, port haitajibu. 127.0.0.1:8080:8080 huweka web interface kwenye anwani ya loopback ya host. 8080:8080 isiyo na anwani maalum huchapisha kwenye kila interface na huandika kanuni yake ya firewall; hivi ndivyo ports zilizochapishwa na Docker hupita moja kwa moja kwenye ufw.
Iwashe, kisha iangalie kwa mpangilio huu:
docker compose up -d
docker compose ps
docker compose logs gluetun | tail -30docker compose ps inapaswa kuonyesha gluetun ikiwa na hali ya healthy na qbittorrent ikiwa na hali ya running. Kisha thibitisha anwani ya kutoka ukiwa ndani ya namespace; hii ndiyo ukaguzi unaoamua kila kitu kingine:
docker run --rm --network=container:gluetun alpine:3.22 sh -c "apk add wget && wget -qO- https://ipinfo.io"Sehemu ya ip katika JSON hiyo inapaswa kuwa anwani ya mtoa huduma wako wa VPN. Ikiwa ni anwani ya seva yako yenyewe, programu haipo kwenye tunnel, na hakuna chochote hapa chini kitakachofanya kazi kama ilivyoelezwa.
Hifadhi funguo nje ya faili ya compose
gluetun.env huhifadhi credentials, na haijawekwa kwenye git:
WIREGUARD_PRIVATE_KEY=wOEI9rqqbDwnN8/Bpp22sVz48T71vJ4fYmFWujulwUU=
WIREGUARD_ADDRESSES=10.64.222.21/32Thamani zote mbili zinatoka kwenye faili ya usanidi ya WireGuard unayozalisha katika eneo la akaunti yako kwa mtoa huduma. Weka mode ya faili kuwa 600. Eleza kwa uaminifu faida yake: ufunguo unabaki nje ya repository yako, lakini docker inspect gluetun bado huchapisha kila environment variable kwa mtu yeyote anayeweza kufikia Docker socket. Faili za mazingira na secrets katika Docker Compose inaeleza chaguo zenye ulinzi mkubwa zaidi.
Jinsi container iliyo nje ya tunnel inavyowasiliana na iliyo ndani yake
Mawasiliano hufanya kazi katika pande zote mbili, na kila upande hutumia jina tofauti. Containers hizo mbili zinahitaji Docker network ya pamoja. Hii inamaanisha network ya gluetun, kwa sababu container iliyounganishwa haina network yake. Jinsi Docker Compose networks zinavyounganishwa inaeleza mipangilio chaguomsingi.
Kwa mawasiliano kutoka nje kwenda ndani, tumia jina la gluetun na port ambayo app inasikiliza. Container ya reverse proxy hufikia web interface ya qBittorrent kupitia gluetun:8080. Hakuna haja ya kuingiza ports: kwa hilo, kwa sababu traffic kati ya containers hubaki kwenye Docker network na haigusi host port.
Kwa mawasiliano kutoka ndani kwenda nje, tumia service name ya container nyingine, kwa mfano postgres:5432. Gluetun imekuwa ikitatua majina ya containers kutoka ndani ya namespace yake tangu v3.41. Kwa hiyo, weka toleo hilo au jipya zaidi ikiwa jina halitatuliwi.
Firewall ya gluetun huamua ni nani anayeruhusiwa kufungua connection kuelekea kwake. Traffic kutoka Docker network ya gluetun yenyewe inaruhusiwa. Client iliyo kwenye subnet nyingine, laptop iliyo kwenye LAN yako au container iliyo kwenye bridge network tofauti, hudondoshwa hadi uainishe subnet hiyo:
FIREWALL_OUTBOUND_SUBNETS=192.168.1.0/24Maana iliyoandikwa kwenye documentation ni sahihi: subnets zilizotenganishwa kwa koma ambazo Gluetun na containers zinazoshiriki network stack yake zinaruhusiwa kufikia.
Connections zinazoingia kutoka Internet ni tatizo tofauti. Peers wa torrent client hufika kutoka upande wa VPN, kwa hiyo kuchapisha port 6881 kwenye host hakuwasaidii. Unahitaji port iliyoforwardiwa kutoka kwa provider wako, na port hiyo iorodheshwe kwenye FIREWALL_VPN_INPUT_PORTS. Hii inaruhusu ports kutoka upande wa VPN server. Hiki ndicho kipengele ambacho media stacks nyingi zilizoundwa kwa Docker Compose huacha kikiwa hakifanyi kazi.
Kill switch: kinachotokea tunnel inapokatika
Muundo huu unathibitisha ugumu wake wakati wa hitilafu. Container iliyounganishwa haina route ya pili. Njia yake pekee ya kutoka kwenye mashine ni namespace inayoshirikishwa, kwa hiyo tunnel inapokuwa chini hakuna njia mbadala ya kutumia. Firewall ya Gluetun inatekeleza kanuni hiyo kutoka upande mwingine: traffic ya kutoka hupitia kwenye tunnel au kwenda kwenye endpoint ya server ya VPN, na kila kitu kingine hudondoshwa. Hakuna muda ambao packets zinaweza kuvuja kupitia interface ya kawaida wakati client inaunganisha tena.
Gluetun hufuatilia muunganisho wake yenyewe. Kila dakika hutuma ICMP echo (ping) kwenye anwani zilizo katika HEALTH_ICMP_TARGET_IPS, ambazo kwa kawaida ni 1.1.1.1,8.8.8.8. Kila baada ya dakika tano hufanya muunganisho kamili wa TCP na TLS (transport layer security) kwenda HEALTH_TARGET_ADDRESSES, ambayo kwa kawaida ni cloudflare.com:443,github.com:443. Muunganisho huo unaposhindikana, huanzisha upya VPN ndani ya container na kuandika tukio kwenye log:
WARN [vpn] restarting VPN because it failed to pass the healthcheck: periodic check: dialing: dial tcp4: lookup cloudflare.com: i/o timeoutSoma log za container iliyounganishwa ukizingatia mpangilio huo. Mistari kama connection refused, operation not permitted na i/o timeout ndani ya app ni matokeo ya tunnel iliyokufa, si sababu. Nyaraka za Gluetun zinasema hili wazi, kwa sababu watu huripoti matokeo hayo na kuyafuatilia kwa saa nyingi.
HEALTH_RESTART_VPN=on ndiyo hali ya kawaida na inapaswa kubaki imewashwa. Izime tu unapochunguza hitilafu moja mahususi, kwa sababu ikiwa imezimwa tunnel iliyokufa itaendelea kuwa chini.
Mpangilio: zuia stack kuanza kabla tunnel haijawa tayari
Image ina Docker healthcheck:
HEALTHCHECK --interval=5s --timeout=5s --start-period=10s --retries=1 CMD /gluetun-entrypoint healthcheckAmri hiyo huendesha nakala ya pili ya gluetun kwa muda mfupi. Nakala hiyo huuliza health server ya gluetun inayoendelea kwenye http://127.0.0.1:9999/. Tunnel inayofanya kazi hujibu 200 OK. Tunnel yenye hitilafu hujibu 500 Internal server error pamoja na string ya kosa, na container huwekwa kuwa unhealthy baada ya failure moja tu.
condition: service_healthy ndiyo husubiri hali hiyo. depends_on: [gluetun] ya kawaida husubiri tu container ianze. Hilo hutokea sekunde kadhaa kabla handshake kukamilika. Kwa hiyo app huanza ikiwa kwenye network isiyofanya kazi na mara nyingi hukata tamaa kwenye jaribio lake la kwanza la kuunganisha. Healthchecks katika Docker Compose inaeleza syntax na sehemu za muda.
Kuna kikomo kimoja ambacho huwasumbua watu. Compose hutathmini condition hiyo mara moja, wakati wa kuunda container. Haizuii wala kuanzisha upya app baadaye ikiwa gluetun itakuwa unhealthy. Auto-healing ya ndani ya gluetun hushughulikia hali hiyo badala yake. Ndiyo maana huanzisha upya mchakato wa VPN, si container.
Kagua uvujaji wa DNS kabla ya kuamini usanidi
DNS (domain name system) ndiyo uvujaji unaobaki hata tunnel ikiwa imesanidiwa kwa usahihi. Gluetun huendesha resolver yake ndani ya namespace na hutuma maswali kupitia DoT (DNS over TLS) kwa Cloudflare kwa chaguo-msingi: DNS_UPSTREAM_RESOLVER_TYPE=dot na DNS_UPSTREAM_RESOLVERS=cloudflare. Acha mipangilio hii yote bila kuibadilisha ili lookups zako zisimbwe na zipitie kwenye tunnel.
Mpangilio unaosababisha tatizo hili ni DNS_UPSTREAM_PLAIN_ADDRESSES. Watu huuwasha jina linaposhindwa kutatuliwa na wanapotaka router yao au resolver ya provider wao ijibu badala yake. Nyaraka za Gluetun zinaeleza gharama hiyo wazi: traffic yote ya DNS haitapita kwenye VPN tunnel na itavuja nje ya tunnel hiyo. Traffic yako inabaki private. Orodha ya hostnames unazotafuta haibaki private. Toleo la WireGuard la kosa hili limeelezwa katika DNS inayoacha kutatua majina kupitia tunnel ya WireGuard.
Ili kuijaribu, weka HTTPPROXY=on kwenye gluetun na uchapishe 8888:8888/tcp, kisha elekeza browser kwenye proxy hiyo na upakie kipimo cha uvujaji wa DNS. Matokeo yanapaswa kutaja provider wako au Cloudflare, kamwe si router yako ya nyumbani. Nyaraka za Gluetun zenyewe zinaonya kuwa baadhi ya vipimo vya uvujaji huonyesha matokeo yasiyo ya kawaida, kwa sababu resolver iliyo ndani ya namespace ni intermediary ya ndani ya caching, si server inayojibu hatimaye. Chukulia nchi isiyo sahihi au resolver ya ISP wako mwenyewe kuwa ishara halisi.
Kuongeza Tailscale karibu na VPN sidecar, na ni ipi inayotangulia
Tailscale ni overlay network iliyojengwa juu ya WireGuard kwa ajili ya kufikia mashine zako mwenyewe. Watu huiendesha pamoja na provider VPN ili kuhifadhi njia ya usimamizi ya kuingia kwenye stack. Kwa kawaida, huduma hizi mbili hazigombani. Sababu yake ni muhimu kuielewa. Nyaraka za Tailscale zinaeleza hali ya kawaida: hufanya kazi kama overlay network, huelekeza traffic kati ya vifaa vinavyoendesha Tailscale pekee, na haigusi traffic yako ya umma ya Internet.
Kwa hiyo, jibu linategemea setting moja.
- Tailscale ikiwa kwenye container yake yenyewe, kwa configuration ya kawaida: haioni kamwe traffic ya kutoka ya app. Gluetun hubeba traffic yote hiyo. Tailscale hufikia app kupitia
gluetun:8080, sawa kabisa na container nyingine yoyote ya nje. - Tailscale ikiwa imeunganishwa kwenye namespace ya gluetun kupitia
network_mode: "service:gluetun": inahitajicap_addyake yenyewe yanet_adminnanet_raw, kwa sababu capabilities haziji pamoja na namespace. Katika userspace networking mode ya kawaida,TS_USERSPACEimewashwa, tailscaled haiundi interface yoyote na hufanya kazi kama SOCKS5 au HTTP proxy, kwa hiyo haiwezi kubadili routing. Gluetun bado hubeba traffic yote. - Hali hiyo hiyo, ikiwa na
TS_USERSPACE=false: tailscaled huunda tunnel device na kusakinisha routes, lakini kwa tailnet range ya100.64.0.0/10pekee, pamoja na subnet routes zozote unazotangaza kwaTS_ROUTES. Traffic ya umma bado hutoka kupitia gluetun. - Hali yoyote kati ya hizo ikiwa exit node imechaguliwa,
sudo tailscale set --exit-node=<exit-node-ip>: Tailscale hudai default route na kutangulia. Usiichanganye na gluetun. Default route moja, mmiliki mmoja.
Ikiwa routes hizo zilizotangazwa ndizo unazohitaji, na unataka private network yote iliyo nyuma ya box ifikiwe badala ya box pekee, kuendesha Tailscale subnet router kwenye VPS kunaeleza route approval, IP forwarding na flag ya upande wa client ambayo TS_ROUTES haiwezeshi yenyewe.
Ikiwa Tailscale ipo ili kukupa URL ya usimamizi badala ya route, tailscale serve na tailscale funnel huweka HTTPS mbele ya gluetun:8080 kwa ajili ya tailnet yako. Ni funnel pekee inayofungua huduma hiyo kwa public internet.
Athari moja huonekana Tailscale inapofanya kazi ndani ya tunnel. Peers zake huona address ya provider VPN, kwa hiyo tarajia itumie relays mara nyingi zaidi. tailscale status huonyesha relay "..." kando ya peer badala ya direct hali hiyo inapotokea. Connection hufanya kazi, lakini huwa polepole zaidi. Ikiwa overlay ndiyo kitu pekee ulichohitaji, tofauti kati ya WireGuard ya kawaida na Tailscale ndiyo sehemu bora ya kuanzia.
Kinachoharibika na ujumbe utakaouona
Docker inakataa kuunda container ya app. Error response from daemon: conflicting options: port publishing and the container type network mode inamaanisha kuwa block ya ports: bado ipo kwenye service iliyounganishwa. Isogeze kwenye gluetun.
Compose inakataa faili zima. Service haiwezi kuweka network_mode na networks kwa pamoja. Weka networks kwenye gluetun.
Container nyingine haiwezi kutatua app. curl: (6) Could not resolve host: qbittorrent ni tabia sahihi, kwa sababu container iliyounganishwa haikujiunga na network yoyote wala kusajili jina. Tumia gluetun na port.
Container ya pili iliyounganishwa haitaanza. Processes mbili katika namespace moja haziwezi kufunga port moja. Process inayoshindwa huripoti kuwa address tayari inatumika. Badilisha port ya ndani ya app, au endesha gluetun ya pili.
App haina network baada ya kufanya mabadiliko kwenye gluetun. Kuanzisha upya au kuunda gluetun upya hukata muunganisho kwa kila kitu kilichounganishwa nayo. Anzisha upya containers hizo.
Kurasa ndogo hupakia lakini kubwa zinakwama. Hiyo ni MTU (maximum transmission unit). Tunnel huongeza overhead, na kitu kwenye njia hudondosha packets zilizo kubwa kupita kiasi bila kutuma error. Punguza WIREGUARD_MTU, jaribu 1400, kisha 1320.
Gluetun haiwi healthy kamwe. Ukaguzi wa kuanza hutaja washukiwa wa kwanza: WARN [vpn] restarting VPN because it failed to pass the healthcheck: startup check: dialing: dial tcp4: lookup cloudflare.com: i/o timeout. Kagua ikiwa key imekwisha muda, kisha ikiwa orodha ya server ni ya zamani, halafu ikiwa firewall ya host yako inazuia UDP ya kutoka.
FAQ
Kwa nini ports zilizochapishwa za container yangu ziliacha kufanya kazi nyuma ya Gluetun?
Kwa sababu network_mode: "service:gluetun" huiweka container ndani ya network namespace ya gluetun, na namespace ina IP address moja pamoja na seti moja ya ports zinazosikilizwa. App inaendelea kusikiliza, lakini publish rule lazima iwe kwenye container inayomiliki namespace hiyo. Hamisha orodha ya ports: kwenye service ya gluetun. Ikiwa uliiacha kwenye service iliyounganishwa, Docker hataiunda: Error response from daemon: conflicting options: port publishing and the container type network mode.
Ninawezaje kufikia container iliyo ndani ya VPN tunnel kutoka kwenye container iliyo nje yake?
Tumia service name ya gluetun pamoja na port ambayo app inasikiliza, kwa mfano gluetun:8080. Container iliyounganishwa haina Docker network yake, kwa hiyo jina lake lenyewe halitatatuliwa kamwe. Hakuna kitu kinachohitaji kuchapishwa kwa traffic kati ya container na container. Kwa upande mwingine, container iliyo ndani ya namespace inaweza kufikia container ya nje kwa kutumia service name yake, kama postgres:5432, kwenye Gluetun v3.41 na matoleo mapya zaidi. Client iliyo kwenye subnet tofauti, kama laptop kwenye LAN yako, hudondoshwa na firewall ya gluetun hadi uongeze subnet hiyo kwenye FIREWALL_OUTBOUND_SUBNETS.
Je, Gluetun hufanya kazi kama kill switch VPN inapokatika?
Ndiyo, na kwa sababu mbili kwa wakati mmoja. Container iliyounganishwa haina route nyingine isipokuwa ile iliyo kwenye namespace inayoshirikiwa, kwa hiyo tunnel iliyokufa huiacha bila njia ya kutoka kwenye mashine. Firewall ya Gluetun pia huruhusu outbound traffic kupitia tunnel pekee na kwenda kwenye VPN server endpoint. Kisha Gluetun huanzisha VPN upya ndani kwa ndani na kuandika WARN [vpn] restarting VPN because it failed to pass the healthcheck kwenye log, badala ya kutoka, kwa sababu kila container iliyounganishwa hupoteza network yake Gluetun yenyewe inaporestart.
Tailscale na Gluetun kwenye stack moja: ni ipi hubeba outbound traffic?
Gluetun, isipokuwa katika configuration moja. Kwa default, Tailscale huelekeza traffic kati ya vifaa vilivyo kwenye tailnet yako pekee na huacha public traffic ipite kama kawaida. Kwenye userspace mode ya default ya container image, haiundi interface yoyote, kwa hiyo haiwezi kuathiri routing. Kwa TS_USERSPACE=false, huweka routes za 100.64.0.0/10 pamoja na subnets ulizotangaza pekee. Isipokuwa hiyo ni exit node: sudo tailscale set --exit-node=<exit-node-ip> huifanya Tailscale iwe default route, na hapo hushinda. Chagua product moja iimamie default route badala ya kuweka zote mbili juu ya nyingine.