fix(docker): prevent root-owned bind mount directories - #160
Conversation
Pre-create and validate bind mount sources before invoking Docker so Docker cannot silently create missing host directories as root. Replace legacy -v bind syntax with explicit --mount specifications, remove unnecessary runtime Cargo mounts, and support writable and read-only bind mounts through a shared helper. This prevents builder cache ownership failures that block Lotus builds and leave required binaries such as lotus-seed unavailable. Signed-off-by: Jakub Sztandera <[email protected]>
There was a problem hiding this comment.
🟡 Not ready to approve
The new mounts helper currently treats read-only mounts like writable ones (creating and write-testing sources), and build container setup can silently create a missing source directory instead of failing fast.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
This PR hardens Docker invocations across foc-devnet by switching from -v bind syntax to explicit --mount specifications and adding a shared helper that prepares/validates bind sources to prevent Docker from auto-creating host directories as root (which can break subsequent builds via ownership mismatches).
Changes:
- Introduces
src/docker/mounts.rshelpers to pre-create and validate bind mount sources and to build/push--mountarguments (including read-only). - Replaces many
-vusages with--mount(and shared helpers) across startup/deploy/build codepaths. - Removes some legacy runtime cache mounts (e.g., Cargo) while keeping mount handling consistent.
File summaries
| File | Description |
|---|---|
| src/docker/shell.rs | Renames the helper to run containers using prepared --mount specs. |
| src/docker/portainer.rs | Uses --mount for docker socket bind and Portainer data volume. |
| src/docker/mounts.rs | Adds bind mount preparation/validation and --mount argument builders (plus tests). |
| src/docker/mod.rs | Exposes the new mounts helpers via pub use. |
| src/commands/start/usdfc_funding/funding_operations.rs | Switches USDFC funding operations to use --mount with validated bind sources. |
| src/commands/start/usdfc_deploy/verification.rs | Uses validated bind mounts for contract verification runs. |
| src/commands/start/usdfc_deploy/foundry_setup.rs | Uses validated bind mounts for Foundry project setup. |
| src/commands/start/usdfc_deploy/deployment.rs | Uses validated bind mounts for Foundry deployment. |
| src/commands/start/multicall3_deploy/deployment.rs | Builds docker args as Vec<String> and appends validated bind mounts. |
| src/commands/start/mod.rs | Updates regenesis fallback Docker deletion to --mount. |
| src/commands/start/lotus/setup.rs | Replaces volume list -v usage with validated bind mounts. |
| src/commands/start/lotus_miner/docker_command.rs | Replaces -v usage with validated bind mounts and removes builder Cargo mount. |
| src/commands/start/genesis/sectors.rs | Uses validated bind mounts for preseal workflow and removes builder Cargo mount. |
| src/commands/start/genesis/proof_parameters.rs | Uses validated bind mounts for proof-params download and removes builder Cargo mount. |
| src/commands/start/genesis/construction/signers.rs | Uses validated bind mounts and removes builder Cargo mount. |
| src/commands/start/genesis/construction/miner.rs | Uses validated bind mounts and removes builder Cargo mount. |
| src/commands/start/genesis/construction/creation.rs | Uses validated bind mounts and removes builder Cargo mount. |
| src/commands/start/foc_deployer/mod.rs | Uses validated bind mounts and removes builder Cargo mount; updates optional pdp repo mount. |
| src/commands/start/curio/verification.rs | Uses validated bind mounts for test-data and bin mounts. |
| src/commands/start/curio/db_setup.rs | Uses validated bind mounts for lotus bins and lotus data access. |
| src/commands/start/curio/daemon.rs | Replaces volume mount list with validated bind mounts including a read-only mount. |
| src/commands/build/docker.rs | Uses validated bind mounts for build source/output and mapped volumes. |
Review details
- Files reviewed: 22/22 changed files
- Comments generated: 2
- Review effort level: Low
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
| fn bind_mount_with_mode( | ||
| source: &Path, | ||
| target: &str, | ||
| read_only: bool, | ||
| ) -> Result<String, Box<dyn Error>> { | ||
| prepare_bind_source(source)?; | ||
| let read_only_option = if read_only { ",readonly" } else { "" }; | ||
| Ok(format!( | ||
| "type=bind,source={},target={}{}", | ||
| source.display(), | ||
| target, | ||
| read_only_option | ||
| )) | ||
| } |
There was a problem hiding this comment.
Read-only is mostly focused on in-container scope. IDK if it is worth addressing.
| push_bind_mount( | ||
| &mut docker_run_args, | ||
| Path::new(source_dir), | ||
| container_source_dir, | ||
| )?; | ||
| push_bind_mount( | ||
| &mut docker_run_args, | ||
| Path::new(output_dir), | ||
| container_output_dir, | ||
| )?; |
There was a problem hiding this comment.
The point of this is to create these directories in general. Yes, we could special case source directories but that is nitpicking.
Pre-create and validate bind mount sources before invoking Docker so Docker cannot silently create missing host directories as root.
Replace legacy -v bind syntax with explicit --mount specifications, remove unnecessary runtime Cargo mounts, and support writable and read-only bind mounts through a shared helper.
This prevents builder cache ownership failures that block Lotus builds and leave required binaries such as lotus-seed unavailable.
Signed-off-by: Jakub Sztandera [email protected]