Skip to content

Standalone recreate loses HostConfig fields (CapAdd, Devices, Sysctls, ...) — breaks Gluetun update #27

Description

@amayer1983

Reported by @famewolf in #2.

Symptom

Auto-update of gluetun fails health-check + rolls back. New container log:

NET_ADMIN capability is missing: iptables-legacy: iptables v1.8.11 (legacy):
can't initialize iptables table `filter': Permission denied (you must be root)

Plus collateral damage: all containers using network_mode: container:gluetun
(sonarr, radarr, qbittorrent, sabnzbd, etc.) are left without a network
namespace after the rollback completes, even with the restart_dependents
group flag set, because the cascade only fires on update success.

Root cause

_update_standalone() and _do_selfupdate() reconstruct a docker run
argv from inspect data, but only emit a small subset of HostConfig fields:

Reconstructed Silently dropped
RestartPolicy, NetworkMode, PortBindings, SecurityOpt, Mounts, Env, Hostname, Labels CapAdd, CapDrop, Devices, Privileged, Sysctls, Tmpfs, ExtraHosts, Dns, DnsSearch, DnsOptions, Init, ShmSize, ReadonlyRootfs, LogConfig, Runtime, IpcMode, PidMode, UTSMode, User

Worked for ~90% of containers (image + env + volumes + ports is enough),
broke hard for anything that needed capabilities, devices, sysctls, or
custom user — Gluetun, Pi-hole, any VPN/firewall stack, Crowdsec, etc.

Compounded issue

The restart_dependents cascade in handle_autoupdates only fired on
update success. When the head container's update failed and rolled
back, the dependents were not restarted — leaving them pointing at a
stale network namespace. User had to manually rebuild_all the stack.

Fix (v1.18.10)

  1. Single source of truth UpdateChecker._build_run_args(config, image, name)
    covering 17 HostConfig fields, used by both the standalone update path
    and the selfupdate helper. Defaults that match Docker's own (json-file log,
    runc runtime, 64MiB shm, private ipc, ...) are skipped to keep the rendered
    command readable.

  2. restart_dependents cascade fires on head-container update failure
    too — with a clear "head rollback — dependents kicked" marker so the user
    knows why. The dependents re-attach to the rolled-back head's namespace.

Empirical verification

Reconstructed a Gluetun-flavoured test container (cap-add NET_ADMIN +
SYS_PTRACE, cap-drop ALL, device /dev/null, sysctl net.ipv4.ip_forward,
tmpfs, add-host, dns, user, init, shm-size 256m, read-only, log-opt) and:

  • All 17 fields land in the rebuilt docker run argv
  • Multiple --cap-add flags emit correctly (not just the first)
  • End-to-end: built args → executed docker run → container starts (exit 0)
  • Recreated container's inspect shows identical HostConfig to the original

Target

v1.18.10.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions