Ship the tools the VPN toggle grants capability for
Build Container / build-container (pull_request) Successful in 11m28s
Build Container / build-container (pull_request) Successful in 11m28s
`vpn_support_enabled` hands a project CAP_NET_ADMIN and /dev/net/tun, and the image then contains no `ip` and no `wg` — a capability with nothing able to exercise it. Bake `iproute2` and `wireguard-tools` (~4.3 MB with deps). They belong in the image rather than a runtime install for the reason the Dockerfile already gives for the Playwright libraries: the writable layer is lost on base-image migration. A hand-installed `wg` works until an upgrade and then vanishes, which presents as a tunnel that will not come up rather than as a missing package. One project only had `ip` at all because MariaDB pulled in iproute2 as a transitive dependency. `iptables` stays out. Only a desktop client's killswitch wants it, and those clients need a GUI the container cannot provide. Also correct three things the docs left users to discover: - the toggle grants capability and routes nothing, which is being reported as the default network "not routing through the VPN automatically" - no tunnel survives a restart, and `/run` state riding the snapshot makes it look as though one did while traffic goes out the real address - a full tunnel captures the Docker resolver, which sits outside the container's subnet, and takes DNS down with it — Claude Code then reports a connection failure because it cannot resolve api.anthropic.com, and a health check aimed at an IP literal passes throughout Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -34,6 +34,8 @@ RUN for i in 1 2 3 4 5; do \
|
||||
cron \
|
||||
bubblewrap \
|
||||
socat \
|
||||
iproute2 \
|
||||
wireguard-tools \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# `libnss3-tools` above provides `certutil`. Chrome/Chromium read neither
|
||||
@@ -42,6 +44,23 @@ RUN for i in 1 2 3 4 5; do \
|
||||
# corporate CA, no matter what the system trust store says. entrypoint.sh
|
||||
# degrades to a warning if it is ever missing.
|
||||
|
||||
# `iproute2` and `wireguard-tools` above are what the VPN support toggle
|
||||
# (`vpn_support_enabled`) grants capability *for*. That toggle hands a project
|
||||
# CAP_NET_ADMIN and /dev/net/tun; without `ip` there is then no way to add a
|
||||
# route, and without `wg` no way to build the tunnel those two exist to serve —
|
||||
# a capability with nothing able to use it.
|
||||
#
|
||||
# They are baked rather than left to a runtime `apt-get install` for the same
|
||||
# reason as the Playwright libraries below: the writable layer is re-paid after
|
||||
# every Reset and lost on base-image migration. A hand-installed `wg` therefore
|
||||
# works right up until an upgrade, then disappears and takes the tunnel with it
|
||||
# — silently, since a VPN that fails to come up looks exactly like one that was
|
||||
# never started. Together they are ~4.3 MB including dependencies.
|
||||
#
|
||||
# `iptables` is deliberately NOT here. The only thing that wants it is a desktop
|
||||
# VPN client's killswitch, and those clients need a GUI that a container has no
|
||||
# way to give them; leaving it out keeps the reach of CAP_NET_ADMIN smaller.
|
||||
|
||||
# Remove default ubuntu user to free UID 1000 for host-user remapping
|
||||
RUN if id ubuntu >/dev/null 2>&1; then userdel -r ubuntu 2>/dev/null || userdel ubuntu; fi \
|
||||
&& if getent group ubuntu >/dev/null 2>&1; then groupdel ubuntu 2>/dev/null || true; fi
|
||||
|
||||
Reference in New Issue
Block a user