From 14aee333f20bcbb9544c1d1cac5b56437c028ce1 Mon Sep 17 00:00:00 2001 From: Alpha Chen Date: Fri, 24 Apr 2026 19:41:05 -0700 Subject: [PATCH] Run container as host uid/gid Bind-mounted repos under /var/quire are owned by the host's git user; baking a quire user with a different uid into the image triggered git's safe.directory "dubious ownership" check. Setting the user at docker run time keeps ownership aligned end-to-end. Assisted-by: Claude Opus 4.7 via Claude Code --- Dockerfile | 11 ++++------- docs/host/README.md | 20 ++++++++++++++++++-- docs/host/sshd_config | 2 +- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index cd2a393..fc74769 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,14 +18,11 @@ RUN apt-get update \ COPY --from=builder /usr/local/cargo/bin/quire /usr/local/bin/quire -RUN groupadd --system quire \ - && useradd --system --gid quire --create-home quire +# Volume layout per PLAN.md. Ownership is set on the host; the container +# runs as the host uid/gid passed via `docker exec --user`, so no user +# is created in the image. +RUN mkdir -p /var/quire/repos /var/quire/runs -# Volume layout per PLAN.md. -RUN mkdir -p /var/quire/repos /var/quire/runs \ - && chown -R quire:quire /var/quire - -USER quire WORKDIR /var/quire ENTRYPOINT ["quire"] diff --git a/docs/host/README.md b/docs/host/README.md index 0e21244..c75d653 100644 --- a/docs/host/README.md +++ b/docs/host/README.md @@ -25,9 +25,18 @@ Reference configs for dispatching SSH connections into the quire container. sudo cp sshd_config /etc/ssh/sshd_config.d/quire.conf sudo systemctl reload sshd -4. Start the quire container: +4. Start the quire container, running as the host's `git` user so file + ownership on the bind-mounted `/var/quire` matches inside and out: - docker run -d --name quire-container quire + docker run -d --name quire-container \ + --user "$(id -u git):$(id -g git)" \ + -e HOME=/tmp \ + -v /var/quire:/var/quire \ + quire + + In a compose file, the equivalent is `user: "${QUIRE_UID}:${QUIRE_GID}"` + with the values templated from `id -u git` / `id -g git` during host + setup. 5. Test: @@ -40,3 +49,10 @@ ForceCommand passes `$SSH_ORIGINAL_COMMAND` directly to the binary, which validates the git command against an allowlist (git-receive-pack, git-upload-pack, git-upload-archive) and sanitizes the repository path before exec'ing the git subprocess. + +The container image doesn't bake in a `quire` user — it runs as whatever +uid/gid the host passes via `--user`. This avoids "dubious ownership" +errors from git when the bind-mounted repo dir's host uid wouldn't +otherwise match a container user. `HOME=/tmp` is set because the host +uid has no `/etc/passwd` entry inside the container, and git needs a +writable `HOME` for its config probing. diff --git a/docs/host/sshd_config b/docs/host/sshd_config index 096eb66..d32d3af 100644 --- a/docs/host/sshd_config +++ b/docs/host/sshd_config @@ -7,7 +7,7 @@ Match User git AuthorizedKeysFile /home/git/.ssh/authorized_keys - ForceCommand docker exec -i quire-container quire exec "$SSH_ORIGINAL_COMMAND" + ForceCommand docker exec --interactive quire-container quire exec "$SSH_ORIGINAL_COMMAND" AllowTcpForwarding no AllowAgentForwarding no X11Forwarding no -- 2.54.0