From 3c93d420b9cffd7f9ecc5d05c99ddcefcd937c25 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 5 Aug 2026 17:16:34 +0000 Subject: [PATCH] Automated documentation update [skip ci] --- src/persistence/README.md | 43 ++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/src/persistence/README.md b/src/persistence/README.md index 652a756..15b5b1f 100644 --- a/src/persistence/README.md +++ b/src/persistence/README.md @@ -1,7 +1,7 @@ -# Persistance (persistence) +# Persistence (persistence) -Store data you with to persist between cntainer rebuilds. +Store data you wish to persist between container rebuilds. ## Example Usage @@ -15,9 +15,42 @@ Store data you with to persist between cntainer rebuilds. | Options Id | Description | Type | Default Value | |-----|-----|-----|-----| -| directories | Colon separated list of directory paths to persist. | string | - | -| files | Colon separated list of file paths to persist. | string | - | - +| directories | Colon separated list of directory paths to persist via symlink. | string | - | +| files | Colon separated list of file paths to persist via symlink. | string | - | +| bindDirectories | Colon separated list of directory paths to persist via bind mount, for tools that replace symlinks (e.g. ~/.claude). Requires CAP_SYS_ADMIN. | string | - | +| bindFiles | Colon separated list of file paths to persist via bind mount, for tools that replace symlinks (e.g. ~/.claude.json). Requires CAP_SYS_ADMIN. | string | - | + +## Requirements + +- The persistence volume is mounted at runtime owned by root. When the remote + user is not root, the setup script needs **passwordless sudo** (as provided by + `common-utils`); otherwise container creation fails with a clear error. +- Paths may use `~`, `$HOME`, or `${HOME}` prefixes; they resolve to the remote + user's home. +- The build image needs GNU coreutils `realpath` (any debian/ubuntu-family + image qualifies; busybox-based images such as Alpine do not). The install + fails with a clear error otherwise. + +## Behavior + +- Each configured path is replaced with a symlink into a per-devcontainer volume + (`persistence-${devcontainerId}`), so contents survive rebuilds. +- Paths listed in `bindDirectories`/`bindFiles` are bind-mounted from the volume + instead of symlinked, on every container start (`postStartCommand`). Use this + for tools that delete and recreate their config path, which would destroy a + symlink (the Claude Code extension does this with `~/.claude`). A mountpoint + cannot be unlinked, so it survives. Bind mounts need `CAP_SYS_ADMIN` (e.g. a + privileged container, such as one running docker-in-docker); the post-start + script fails loudly if the mount cannot be made. +- If a configured path already exists in the image, it is moved aside to + `.backup` and its contents are seeded into the volume on first creation. + This includes paths that are symlinks (e.g. from a dotfile manager); their + content is captured and the original link preserved as the backup. +- Seeding happens exactly once per path, tracked via markers in + `.persistence-init/` inside the volume. Later rebuilds keep the volume's + contents as-is, including files or directories you intentionally emptied. +- Configured paths must not collide after flattening (`/home/a_b` and + `/home/a/b` both map to `home_a_b`); the feature install fails if they do. ---