Summary
The claude-code template persists Claude config (~/.claude), fish history
(~/.local/share/fish), and node_modules via named volumes, but it does not
persist the GitHub CLI's auth/state. gh is installed in the
ghcr.io/gatezh/devcontainers/claude-code image, and it stores credentials in
~/.config/gh/hosts.yml by default. That path lives on the container's ephemeral
writable layer, so every container rebuild wipes the GitHub login and the user
must re-run gh auth login. This is inconsistent with how .claude auth already
survives rebuilds and is a surprising paper-cut for anyone using gh for PRs/issues
from inside the container.
Reproduction
- Open the
claude-code devcontainer.
gh auth login and authenticate.
- Rebuild the container ("Dev Containers: Rebuild Container").
gh auth status.
You are not logged into any GitHub hosts. To log in, run: gh auth login
Verification
# gh ships in the image, defaults its config to ~/.config/gh:
$ which gh && gh --version | head -1
/usr/bin/gh
gh version 2.46.0 (2025-01-13 Debian 2.46.0-3)
# But ~/.config is NOT on a named volume — only .claude / fish / node_modules are:
$ mount | grep -E '/home/node|/workspace'
/dev/sdf on /workspace type ext4 ...
/dev/sdd on /workspace/node_modules type ext4 ...
/dev/sdd on /home/node/.claude type ext4 ...
/dev/sdd on /home/node/.local/share/fish type ext4 ...
# (no entry for /home/node/.config) -> ephemeral, wiped on rebuild
Suggested fix
Add a dedicated named volume for gh's default config dir, alongside the existing
claude-config / fish-data mounts in
claude-code/.devcontainer/devcontainer.json:
And extend the updateContentCommand ownership safety-net (which already chowns
/home/node/.claude) so node can write to the root-owned mount point on first
create:
A dedicated per-tool volume (rather than mounting all of ~/.config) keeps gh's
auth state on an independently resettable volume, matching the template's existing
per-concern convention. Same change applies to the claude-code-sandbox variant if
it should support authenticated gh too.
Affected files
claude-code/.devcontainer/devcontainer.json (mounts, updateContentCommand)
claude-code/.devcontainer/claude-sandbox/devcontainer.json (same change, if the
sandbox variant should support gh auth persistence)
Related
Summary
The
claude-codetemplate persists Claude config (~/.claude), fish history(
~/.local/share/fish), andnode_modulesvia named volumes, but it does notpersist the GitHub CLI's auth/state.
ghis installed in theghcr.io/gatezh/devcontainers/claude-codeimage, and it stores credentials in~/.config/gh/hosts.ymlby default. That path lives on the container's ephemeralwritable layer, so every container rebuild wipes the GitHub login and the user
must re-run
gh auth login. This is inconsistent with how.claudeauth alreadysurvives rebuilds and is a surprising paper-cut for anyone using
ghfor PRs/issuesfrom inside the container.
Reproduction
claude-codedevcontainer.gh auth loginand authenticate.gh auth status.Verification
Suggested fix
Add a dedicated named volume for gh's default config dir, alongside the existing
claude-config/fish-datamounts inclaude-code/.devcontainer/devcontainer.json:And extend the
updateContentCommandownership safety-net (which already chowns/home/node/.claude) sonodecan write to the root-owned mount point on firstcreate:
A dedicated per-tool volume (rather than mounting all of
~/.config) keeps gh'sauth state on an independently resettable volume, matching the template's existing
per-concern convention. Same change applies to the
claude-code-sandboxvariant ifit should support authenticated
ghtoo.Affected files
claude-code/.devcontainer/devcontainer.json(mounts,updateContentCommand)claude-code/.devcontainer/claude-sandbox/devcontainer.json(same change, if thesandbox variant should support
ghauth persistence)Related
claude-configvolume added in fix(devcontainer): theme, login, node_modules isolation, self-contained claude-code config #58 (self-containedclaude-code config) — same persistence rationale, applied to
gh.openssh-clientfor SSH commit signing) — that'sa different gh/git concern.