Skip to content

Commit ab018e5

Browse files
committed
fix(devcontainer): restore the gh config mount, which does work
The previous two commits removed the ~/.config/gh bind mount and justified it, in devcontainer.json, AGENTS.md and both commit messages, with the claim that the mount never worked because gh keeps its token in the system keyring, so the mounted hosts.yml carries no oauth_token. That claim is false on this host. ~/.config/gh/hosts.yml contains a real oauth_token, and in a running container using the mount, with GH_TOKEN and GITHUB_TOKEN unset, `gh auth status` reports: Logged in to github.com account blooop (/home/vscode/.config/gh/hosts.yml) gh writes to a keyring only when one is available and falls back to the file otherwise, so the keyring claim was true of some environment but not this one, and it was generalised into the file as if it always held. Nothing broke under `dl`, which is why it went unnoticed: `dl` forwards GH_TOKEN, devpod applies workspace env after the devcontainer's own, and the env token wins wherever both are present. The containers that lost gh auth they previously had are the ones opened another way -- a plain `devpod up`, or VS Code's Reopen in Container. devlaunch's own README says to keep the mount for exactly those entry paths. So the mount comes back as the third entry in mounts, the Dockerfile creates /home/vscode/.config/gh for it again, and the comment above the mounts block now says why it is kept rather than why it was dropped. AGENTS.md again states that host gh authentication is shared through the mount, and adds that a forwarded GH_TOKEN outranks it under `dl`. The ~/.ssh removal is untouched and was verified separately: devpod forwards an ssh agent at a socket path of its own, and in a live container `ssh-add -l` lists the host key and `git ls-remote` against a git@github.com: origin succeeds with an empty ~/.ssh. The old hardcoded SSH_AUTH_SOCK=/home/vscode/.ssh/agent.sock overrode that working forwarded socket, so it stays gone too.
1 parent 9bb1d62 commit ab018e5

3 files changed

Lines changed: 30 additions & 21 deletions

File tree

‎.devcontainer/Dockerfile‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,6 @@ RUN echo 'eval "$(pixi completion -s bash)"' >> /home/vscode/.bashrc \
1414
&& echo 'export PATH="$HOME/.pixi/bin:$PATH"' >> /home/vscode/.profile \
1515
&& echo '# Workaround: pixi trampoline fails for bash scripts, so add env bin directly' >> /home/vscode/.profile \
1616
&& echo '[ -d "$HOME/.pixi/envs/claude-shim/bin" ] && export PATH="$HOME/.pixi/envs/claude-shim/bin:$PATH"' >> /home/vscode/.profile
17+
18+
# Create .config/gh so the host's GitHub CLI config mounts cleanly onto it
19+
RUN mkdir -p /home/vscode/.config/gh

‎.devcontainer/devcontainer.json‎

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -62,30 +62,36 @@
6262
"XDG_DATA_HOME": "/home/vscode/.local/share"
6363
},
6464

65-
// Two mounts, and the two that are gone were removed for reasons rather
66-
// than tidiness -- both follow the precedent already reasoned out in
67-
// blooop/wayfinder's devcontainer.json.
65+
// Three mounts. The pixi volume keeps the environment out of the bind-
66+
// mounted workspace; the other two share host credentials.
6867
//
69-
// ~/.config/gh is gone because it never worked: `gh` keeps its token in the
70-
// system keyring, so the mounted hosts.yml carries no oauth_token and
71-
// `gh auth status` inside the container reports the token as invalid.
72-
// GitHub auth arrives as GH_TOKEN instead, which `dl` forwards into every
73-
// workspace it starts (from GH_TOKEN, GITHUB_TOKEN or `gh auth token`,
74-
// whichever answers first). Opened by something other than `dl` -- a plain
75-
// `devpod up`, or VS Code's Reopen in Container -- this container has no
76-
// `gh` login; export GH_TOKEN yourself for those.
68+
// ~/.config/gh is here because it works. `gh` uses a system keyring when
69+
// one is available and falls back to hosts.yml when it is not, and on this
70+
// host it falls back: hosts.yml carries a real oauth_token, and inside a
71+
// container built from this config -- with GH_TOKEN and GITHUB_TOKEN unset
72+
// -- `gh auth status` reports "Logged in to github.com account blooop
73+
// (/home/vscode/.config/gh/hosts.yml)". This mount is the only thing that
74+
// gives `gh` a login in a container opened WITHOUT `dl`: a plain
75+
// `devpod up`, or VS Code's Reopen in Container. Under `dl` it is
76+
// redundant but harmless -- `dl` forwards GH_TOKEN from the host (from
77+
// GH_TOKEN, GITHUB_TOKEN or `gh auth token`, whichever answers first), and
78+
// devpod applies workspace env after the devcontainer's own, so where both
79+
// are present the forwarded token is the one `gh` uses.
7780
//
78-
// ~/.ssh is gone because mounting the directory put entries on the
79-
// developer's real config that nothing outside the container could honour:
80-
// devpod running in here writes `Host <id>.devpod` blocks whose
81-
// ProxyCommand names a binary that exists only inside this container, and
82-
// those outlived the container they pointed at. It also handed over the
83-
// private key, which was never load-bearing -- devpod forwards git
84-
// credentials and can forward an ssh agent, which lends the use of a key
85-
// without copying it. SSH_AUTH_SOCK is gone from containerEnv with it,
86-
// rather than being left as a path nothing fills.
81+
// ~/.ssh is deliberately not mounted, for reasons that have nothing to do
82+
// with the above. devpod forwards an ssh agent of its own, at a socket path
83+
// it chooses -- verified in a live container: `ssh-add -l` lists the host's
84+
// key and `git ls-remote` against a git@github.com: origin succeeds with an
85+
// empty ~/.ssh -- so the private key does not need to be in here at all.
86+
// Mounting the directory also wrote `Host <id>.devpod` blocks onto the
87+
// developer's real ssh config, naming a ProxyCommand binary that exists
88+
// only inside the container, and those outlived the container. SSH_AUTH_SOCK
89+
// is gone from containerEnv for the same reason: hardcoding
90+
// /home/vscode/.ssh/agent.sock overrode the socket devpod actually
91+
// forwards with a path nothing fills.
8792
"mounts": [
8893
"source=${localWorkspaceFolderBasename}-pixi,target=${containerWorkspaceFolder}/.pixi,type=volume",
94+
"source=${localEnv:HOME}/.config/gh,target=/home/vscode/.config/gh,type=bind",
8995
"source=${localEnv:HOME}/.claude,target=/home/vscode/.claude,type=bind"
9096
],
9197

‎AGENTS.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This project uses a devcontainer with pixi for environment management.
66

77
### Available Tools
88

9-
- **GitHub CLI (`gh`)**: Available via `pixi run gh` or directly if using a login shell. Authentication arrives as `GH_TOKEN`, which `dl` forwards into every workspace it starts, taking it from `GH_TOKEN`, `GITHUB_TOKEN` or `gh auth token` -- whichever answers first. The container used to mount the host's `~/.config/gh` instead, which never worked: `gh` keeps its token in the system keyring, so the mounted `hosts.yml` carried no `oauth_token`. If the container was opened by something other than `dl` -- a plain `devpod up`, or VS Code's Reopen in Container -- it has no `gh` login and you have to export `GH_TOKEN` yourself.
9+
- **GitHub CLI (`gh`)**: Available via `pixi run gh` or directly if using a login shell. The container mounts the host's `~/.config/gh`, so if you are authenticated on the host, that authentication is shared -- including in a container opened without `dl`, such as a plain `devpod up` or VS Code's Reopen in Container. Under `dl` there is also a forwarded `GH_TOKEN` (taken from `GH_TOKEN`, `GITHUB_TOKEN` or `gh auth token`, whichever answers first), and that takes precedence over the mounted `hosts.yml`.
1010

1111
### Running Commands
1212

0 commit comments

Comments
 (0)