Separating Atuin shell history per Distrobox container

By default Atuin keeps a single shell history database in ~/.local/share/atuin, since home directories are shared into every Distrobox container, that means every container is dumping its history into the same database. That’s not great — history from one distrobox ends up mixed in with others.

The fix is to give each container its own Atuin data directory, keyed off the container name, while leaving the host with the original untouched database.

Distrobox already exports a CONTAINER_ID environment variable inside every container (it’s what the distrobox prompt itself uses), so just key off that.

bash

In ~/.bashrc, before the eval "$(atuin init bash)" line:

if [ -n "$CONTAINER_ID" ]; then
    export ATUIN_DATA_DIR="$HOME/.local/share/atuin-$CONTAINER_ID"
fi

eval "$(atuin init bash)"

zsh

Same idea in ~/.zshrc, again before atuin init:

if [ -n "$CONTAINER_ID" ]; then
    export ATUIN_DATA_DIR="$HOME/.local/share/atuin-$CONTAINER_ID"
fi

eval "$(atuin init zsh)"

That’s it. ATUIN_DATA_DIR controls where Atuin stores history.db, key, meta.db, and records.db, so setting it before atuin init runs is enough — no config.toml changes needed. When CONTAINER_ID is unset (i.e. you’re on the bare host, not inside a distrobox), Atuin just falls back to the default ~/.local/share/atuin.

Each container ends up with its own independent database and its own encryption key, so histories are properly isolated:

$ du -sh ~/.local/share/atuin*
12M     /home/user/.local/share/atuin       # host
448K    /home/user/.local/share/atuin-fpkg
1.0M    /home/user/.local/share/atuin-hugo
644K    /home/user/.local/share/atuin-pkg
916K    /home/user/.local/share/atuin-std

A couple of things worth noting:

  • This is purely local separation — no Atuin server login/sync is involved, so nothing needs a network round trip and there’s no server-side config to touch.
  • If you already have containers running with history in the shared database, this doesn’t retroactively split anything out — it just stops future commands from mixing together going forward.