Skip to content

Fresh install on Debian 12 LXC: docker socket permission denied — recovery path doesn't fire #2006

@dooha333

Description

@dooha333

Summary

On a fresh Debian 12 LXC container (Proxmox VE host), bash nanoclaw.sh installs Docker via
setup/install-docker.sh, adds the user to the docker group via sudo usermod -aG docker "$USER", but
subsequent steps in the same setup process still fail with permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock.

The current shell's supplementary group list is fixed at login, so the new docker membership isn't visible to
the running setup process or any of its children.

Environment

  • Host: Proxmox VE (LXC, privileged container with nesting=1,keyctl=1, AppArmor unconfined,
    lxc.cgroup2.devices.allow: a, lxc.cap.drop: cleared)
  • Guest: Debian 12 (minimal template), x86_64
  • User: non-root with sudo, fresh login (no prior Docker install)
  • NanoClaw: main @ <commit-sha> (run git rev-parse --short HEAD and paste)

Reproduction

  1. Fresh Debian 12 LXC, no Docker pre-installed.
  2. apt install -y curl git sudo ca-certificates
  3. adduser nanoclaw && usermod -aG sudo nanoclaw && loginctl enable-linger nanoclaw
  4. su - nanoclaw
  5. git clone https://github.com/qwibitai/nanoclaw.git nanoclaw-v2 && cd nanoclaw-v2 && bash nanoclaw.sh

Expected

After install-docker.sh runs usermod -aG docker, the rest of the setup process should be able to talk to
/var/run/docker.sock without manual intervention. The codebase already has three recovery mechanisms for this
exact situation (see "Code I checked" below), so this should be transparent.

Actual

Setup fails at the container step (or later, at service) with permission denied on the Docker socket.
Re-running setup after a logout/login works.

Code I checked

There are three recovery paths in the codebase, and at least one of them isn't triggering on minimal Debian 12
LXC:

  1. setup/container.ts:134 — re-execs the container step under sg docker, but is gated on
    commandExists('sg'). The sg binary lives in the passwd package on Debian and may not be present on minimal
    LXC templates
    . If sg is missing, this branch silently falls through.

  2. setup/auto.ts:938-953maybeReexecUnderSg() re-execs the whole driver under sg docker after the
    container step, also gated on which sg. Same problem if sg is missing.

  3. setup/service.ts:312 — fallback applies sudo setfacl -m u:$user:rw /var/run/docker.sock. This is a
    last-resort fix for the systemd user service, but (a) requires setfacl which isn't always installed (acl
    package), and (b) ACLs may not be honored on every LXC storage backend.

Suggested fixes (in order of preference)

  1. install-docker.sh should ensure its own recovery dependencies are present. After installing docker on
    Linux, also apt install -y acl passwd (or the equivalent dnf/pacman) so sg and setfacl are guaranteed to
    exist for the recovery paths in container.ts / auto.ts / service.ts.

  2. When sg is unavailable, fail loudly instead of silently falling through. setup/container.ts:134 and
    setup/auto.ts:945 should log a clear message ("docker group not active and sg not available — install passwd
    package or log out/in") rather than dropping straight to the unfriendly permission denied error.

  3. Detect this preemptively before running other steps. After usermod -aG docker, check id -nG | grep -q docker; if it doesn't show in the current process's groups, prompt the user with a clear choice: re-exec under
    sg docker, apply the setfacl workaround, or log out and back in.

Why this isn't more widely reported

  • macOS Docker Desktop doesn't use the docker group, so the entire macOS install base is unaffected.
  • Most Linux users already have Docker installed; install-docker.sh is a no-op for them.
  • Standard Debian/Ubuntu VM installs ship sg by default, so the recovery path in container.ts:134 works
    silently.
  • Minimal LXC templates strip optional packages, exposing the unguarded dependency on sg (and setfacl).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions