Skip to content

Commit fccf8d3

Browse files
fix: use non-root accessible paths for Rust cache volumes
Fix critical permissions issue where cache volumes were mounted to paths inaccessible by non-root users (/root, /usr/local/cargo). Changes: - Mount cargo caches to /workspace/.cargo (instead of /usr/local/cargo) - Mount sccache to /workspace/.cache/sccache (instead of /root/.cache) - Add CARGO_HOME=/workspace/.cargo environment variable - Update documentation to reflect new paths - Update test assertions for new paths Containers run as non-root (--user flag), so all caches must be under /workspace (HOME) where the user has write access. Addresses GitHub Actions bot review feedback. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 2f32525 commit fccf8d3

1 file changed

Lines changed: 20 additions & 13 deletions

File tree

packages/multiplexer/src/backends/docker.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,11 @@ fn detect_git_worktree(path: &Path) -> anyhow::Result<Option<PathBuf>> {
7575
const DOCKER_IMAGE: &str = "ghcr.io/shepherdjerred/dotfiles";
7676

7777
/// Shared cache volumes used across all mux Docker containers for faster Rust builds:
78-
/// - mux-cargo-registry: Downloaded crates from crates.io (/usr/local/cargo/registry)
79-
/// - mux-cargo-git: Git dependencies (/usr/local/cargo/git)
80-
/// - mux-sccache: Compilation cache (/root/.cache/sccache)
78+
/// - mux-cargo-registry: Downloaded crates from crates.io (/workspace/.cargo/registry)
79+
/// - mux-cargo-git: Git dependencies (/workspace/.cargo/git)
80+
/// - mux-sccache: Compilation cache (/workspace/.cache/sccache)
8181
///
82+
/// Caches are mounted under /workspace (HOME) since containers run as non-root user.
8283
/// sccache (Mozilla's compilation cache) is configured via RUSTC_WRAPPER environment variable.
8384
/// If sccache is not installed in the dotfiles image, cargo will show a warning but continue
8485
/// to work. To enable sccache compilation caching, install it in the dotfiles image:
@@ -210,23 +211,26 @@ impl DockerBackend {
210211
// These are shared across ALL mux sessions and persist between container restarts
211212
// sccache provides compilation caching (path-independent, content-addressed)
212213
// cargo caches provide dependency download caching
214+
// Note: Mounted under /workspace (HOME) since containers run as non-root user
213215
args.extend([
214216
"-v".to_string(),
215-
"mux-cargo-registry:/usr/local/cargo/registry".to_string(),
217+
"mux-cargo-registry:/workspace/.cargo/registry".to_string(),
216218
"-v".to_string(),
217-
"mux-cargo-git:/usr/local/cargo/git".to_string(),
219+
"mux-cargo-git:/workspace/.cargo/git".to_string(),
218220
"-v".to_string(),
219-
"mux-sccache:/root/.cache/sccache".to_string(),
221+
"mux-sccache:/workspace/.cache/sccache".to_string(),
220222
]);
221223

222224
// Configure sccache as Rust compiler wrapper (if installed in dotfiles image)
223225
// If sccache is not installed, cargo will show a clear warning but continue to work
224226
// This is a progressive enhancement - works without sccache, better with it
225227
args.extend([
228+
"-e".to_string(),
229+
"CARGO_HOME=/workspace/.cargo".to_string(),
226230
"-e".to_string(),
227231
"RUSTC_WRAPPER=sccache".to_string(),
228232
"-e".to_string(),
229-
"SCCACHE_DIR=/root/.cache/sccache".to_string(),
233+
"SCCACHE_DIR=/workspace/.cache/sccache".to_string(),
230234
]);
231235

232236
// Detect if workdir is a git worktree and mount parent .git directory
@@ -738,28 +742,31 @@ mod tests {
738742
// Check cargo cache volumes
739743
let has_registry = args
740744
.iter()
741-
.any(|a| a.contains("mux-cargo-registry:/usr/local/cargo/registry"));
745+
.any(|a| a.contains("mux-cargo-registry:/workspace/.cargo/registry"));
742746
assert!(has_registry, "Expected mux-cargo-registry volume mount");
743747

744748
let has_git = args
745749
.iter()
746-
.any(|a| a.contains("mux-cargo-git:/usr/local/cargo/git"));
750+
.any(|a| a.contains("mux-cargo-git:/workspace/.cargo/git"));
747751
assert!(has_git, "Expected mux-cargo-git volume mount");
748752

749753
// Check sccache volume
750754
let has_sccache = args
751755
.iter()
752-
.any(|a| a.contains("mux-sccache:/root/.cache/sccache"));
756+
.any(|a| a.contains("mux-sccache:/workspace/.cache/sccache"));
753757
assert!(has_sccache, "Expected mux-sccache volume mount");
754758

755-
// Check sccache environment variables
759+
// Check cargo and sccache environment variables
760+
let has_cargo_home = args.iter().any(|a| a == "CARGO_HOME=/workspace/.cargo");
761+
assert!(has_cargo_home, "Expected CARGO_HOME=/workspace/.cargo");
762+
756763
let has_rustc_wrapper = args.iter().any(|a| a == "RUSTC_WRAPPER=sccache");
757764
assert!(has_rustc_wrapper, "Expected RUSTC_WRAPPER=sccache");
758765

759766
let has_sccache_dir = args
760767
.iter()
761-
.any(|a| a == "SCCACHE_DIR=/root/.cache/sccache");
762-
assert!(has_sccache_dir, "Expected SCCACHE_DIR=/root/.cache/sccache");
768+
.any(|a| a == "SCCACHE_DIR=/workspace/.cache/sccache");
769+
assert!(has_sccache_dir, "Expected SCCACHE_DIR=/workspace/.cache/sccache");
763770
}
764771

765772
/// Test that attach command uses bash, not zsh (which doesn't exist in container)

0 commit comments

Comments
 (0)