The docs-fact census wave re-read the live hosts and re-keyed every page it could: runtime/payload identities, ports, sizes, ledger figures, unit state, and the retirement banners that drifted as the fleet moved. The wave was interrupted mid-run, so this commit carries only what passed the integrity gates: every touched page parses (front matter or H1+status convention intact, balanced fences, no truncated tables, trailing newline), the docs_completeness and link-integrity seams are green, and bats is 384/384. Numbers that this session proved on live hosts are keyed to the measured value, not the page's earlier claim.
5.9 KiB
type, description, tags, timestamp
| type | description | tags | timestamp | ||
|---|---|---|---|---|---|
| reference | Gluetun is a lightweight VPN client container. |
|
2026-08-28 |
Gluetun
Gluetun is a lightweight VPN client container. It connects to a VPN provider (WireGuard or OpenVPN) and shares that tunnel with other containers that attach to its network namespace.
Host: Dankclaw — Tunnel: WireGuard (VPN type: wireguard, journal 2026-10-18) to ProtonVPN US-WA per dankclaw/searxng/quadlet/gluetun.container:6 — Exit: 149.22.88.19, United States, Washington, Seattle (journalctl --user -u gluetun, [ip getter], 2026-10-18; the journal never names the provider, so the provider attribution is the repo's) — Docs: https://github.com/qdm12/gluetun
Facts (from research, primary source)
| Item | Value |
|---|---|
| Image | docker.io/qmcgaw/gluetun:latest (dankclaw/searxng/quadlet/gluetun.container:19; live 2026-10-18). Tagged :latest, so a redeploy can move the version — pin it deliberately if that ever matters. |
| Capabilities | NET_ADMIN required (dankclaw/searxng/quadlet/gluetun.container:20) |
| Device | /dev/net/tun:/dev/net/tun (dankclaw/searxng/quadlet/gluetun.container:21) |
| Ports published | Two, both on this container because it owns the netns: 8081 → 8080 (SearXNG) and 8082 → 8085 (Marreta) (dankclaw/searxng/quadlet/gluetun.container:31-32; podman inspect gluetun --format '{{json .NetworkSettings.Ports}}' and ss -ltnp 2026-10-18). Neither consumer container publishes anything. |
| Tunnel check | the tun0 interface exists — the boot config dump logs Network interface: tun0 (journalctl --user -u gluetun 2026-10-18). The control server listens on :8000 inside the netns only (.NetworkSettings.Ports shows "8000/tcp": null, 2026-10-18), so nothing on the host can reach it. |
Required Environment
environment:
VPN_SERVICE_PROVIDER: "${VPN_SERVICE_PROVIDER}" # e.g. mullvad, protonvpn
VPN_TYPE: wireguard
WIREGUARD_PRIVATE_KEY: "${WIREGUARD_PRIVATE_KEY}" # from .env, never committed
VPN_TYPEdefault isopenvpn; WireGuard preferred when the provider supports it (https://github.com/qdm12/gluetun-wiki/blob/main/setup/options/vpn.md). This deployment runs WireGuard (WIREGUARD_*variables,dankclaw/searxng/quadlet/gluetun.container:24-30).- Provider-specific variables come from the Gluetun wiki (https://github.com/qdm12/gluetun-wiki); set them in
.env.
Optional DNS (from research)
| Variable | Default | Purpose |
|---|---|---|
DNS_UPSTREAM_RESOLVER_TYPE |
dot |
DNS over TLS |
DNS_UPSTREAM_RESOLVERS |
cloudflare |
upstream DoT providers |
DNS_CACHING |
on |
cache queries |
BLOCK_MALICIOUS |
on |
block malicious hostnames |
Names and defaults match the upstream wiki (https://github.com/qdm12/gluetun-wiki/blob/main/setup/options/dns.md); live confirmation 2026-10-18: [dns] ready and using DNS server with dot upstream resolvers and [dns] downloading hostnames and IP block lists.
Warning from the wiki: do NOT set DNS_UPSTREAM_PLAIN_ADDRESSES to a LAN/bridge address — DNS queries leak out of the tunnel.
Attaching a Container
Three units reuse gluetun's network namespace — SearXNG and both Marreta containers:
[Container]
ContainerName=searxng
Network=gluetun.container
Network=gluetun.container also adds a systemd dependency on gluetun, so the consumer starts after the tunnel (dankclaw/searxng/quadlet/searxng.container:13-18, dankclaw/marreta/quadlet/marreta.container:29-34, dankclaw/marreta/quadlet/marreta-browser.container:20-25). Live 2026-10-18 all three report HostConfig.NetworkMode=container:03a75714…, which is gluetun's own container id (podman inspect gluetun --format '{{.Id}}') — one netns, four containers, ports published only by gluetun.
Boot Persistence
gluetun runs as the gluetun quadlet unit (see SearXNG for the full trio). It sets WantedBy=default.target and Restart=always (dankclaw/searxng/quadlet/gluetun.container:37,39-40) and user linger is on, so the tunnel starts at boot — live 2026-10-18 systemctl --user is-enabled gluetun → generated, is-active → active, NRestarts=0 since the 01:25 boot. The WireGuard credentials live in /opt/searxng/.env (mode 0600 — -rw------- dank:dank, ls -l 2026-10-18). Deploy with scripts/deploy.sh dankclaw --service gluetun (scripts/deploy-remote.sh:596-597); scripts/deploy-searxng-quadlet.sh dankclaw is a compatibility wrapper that now forwards to deploy.sh --service searxng, so it does not deploy the tunnel.
Verify the Tunnel
podman exec gluetun curl -s ifconfig.me
The returned IP must differ from the host IP. A read-only alternative is the journal: gluetun logs its own egress at start, and on 2026-10-18 it logged [ip getter] Public IP address is 149.22.88.19 (United States, Washington, Seattle …) — not the host's address.
Gotchas
- The container that holds the published port must be the one with the ports mapping (gluetun) — searxng, marreta and marreta_browser publish nothing of their own (
dankclaw/searxng/quadlet/searxng.containeranddankclaw/marreta/quadlet/*.containerhave noPublishPort=;ss -ltnp2026-10-18 shows only gluetun's rootlessport on 8081/8082). Restart=alwayson gluetun (dankclaw/searxng/quadlet/gluetun.container:37) so the tunnel reconnects after VPN drops.- When gluetun restarts, attached containers inherit the new network state; searxng may need a restart to re-resolve DNS.
- The gluetun health-check probe cannot open ICMP sockets: it logs
listening for ICMP packets: not permitted: you can try adding NET_RAW capability to resolve this; permanently falling back to plain DNS(journal 2026-10-18). The unit grantsNET_ADMINonly; the fallback works, so this is expected noise, not a fault.
See Also
- SearXNG — the consumer of the tunnel
- Dankclaw Stack
- Knowledge base: SearXNG