image(debian): move the shell history to a mountable directory - #466
Merged
Merged
Conversation
nozaq
force-pushed
the
claude/bash-history-persistence-w8pkhc
branch
from
September 12, 2026 05:27
9b5e719 to
e21e48b
Compare
nozaq
force-pushed
the
claude/bash-history-persistence-w8pkhc
branch
from
September 12, 2026 05:29
e21e48b to
377df5e
Compare
nozaq
marked this pull request as ready for review
September 12, 2026 05:31
Dev container templates can keep bash history across rebuilds by mounting a named volume, but the history file has to sit in a directory of its own for that: a named volume cannot be mounted over ~/.bash_history, and mounting one over the home directory would shadow everything the image puts there. Set HISTFILE to /home/dev/.local/state/bash/history and create that directory, the way the terraform and opentofu images set TF_PLUGIN_CACHE_DIR and create the directory their templates mount. The path follows the XDG Base Directory specification, which names history as state data under $XDG_STATE_HOME. Creating the directory in the image also makes the mount belong to "dev": Docker creates a mount point missing from the image owned by root, and nothing in the container could fix that afterwards. Bash also wrote the history file only when the shell exited, which a container stop does not always allow. Appending on every prompt keeps the session's history even when the shell is killed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01L6orjBAZq9L5t7rV5RDmXd
nozaq
force-pushed
the
claude/bash-history-persistence-w8pkhc
branch
from
September 12, 2026 05:50
377df5e to
677f710
Compare
This was referenced Sep 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lets a dev container keep bash history across rebuilds by mounting a named volume, as in the VS Code persist-bash-history recipe. The templates side is bare-devcontainer/templates#202 and depends on this landing first.
Why the image owns this
A named volume mounts as a directory, so bash's default
~/.bash_historycannot be persisted where it is. Mounting a volume over the home directory instead would shadow everything the image puts there and freeze it at first-start contents, which is the opposite of what these images are for.So the history file needs a directory of its own, and
HISTFILEhas to point into it. Both belong to the image, the same wayterraformandopentofualready do it for the plugin cache their templates mount:Creating the directory in the image is also what makes the mount usable: Docker creates a mount point missing from the image as
root:root, and the containers run asdevwith nosudoandno-new-privileges, so nothing inside could fix it afterwards. The VS Code recipe does the same withmkdir+chownfor non-root users./home/dev/.local/state/bashfollows the XDG Base Directory Specification, which names history as state data under$XDG_STATE_HOME(default$HOME/.local/state). Themiseimage already uses/home/dev/.local/state/mise.Changes
debian/Dockerfile: setHISTFILEand create its directory, after theUSERswitch so it belongs todev.debian/assets/.bashrc: append each command to$HISTFILEas it is entered, composing with anyPROMPT_COMMANDa user sets later.histappendalone defers the write to shell exit, which a container stop does not always allow.debian/smoke-test.sh: assert the directory is writable bydev.debian/README.md: document the variable, the directory, and what a dev container does with them.Everything here is inherited by every image built on this base.
Note for review
HISTFILEnow applies to every container from these images, including plaindocker runand CI, not only dev containers that mount the volume. Without a mount the history lands in the container layer, exactly as~/.bash_historywould, so nothing breaks; the path is simply no longer bash's default. This is the same trade theTF_PLUGIN_CACHE_DIRimages already make.Verification
Docker is not available in this environment, so the image was not built here. The
.bashrcchange was verified against bash 5.2 by running an interactive shell with the new rcfile, issuing a command, and killing the shell withSIGKILL: the command is in$HISTFILEafterwards, and with the current.bashrcit is not.build-checks.ymlbuilds the image and runs the new smoke-test assertion.🤖 Generated with Claude Code
https://claude.ai/code/session_01L6orjBAZq9L5t7rV5RDmXd