macOS上GoLang容器内启动rust-optimizer容器的Volume挂载报错
系统环境:搭载arm64/aarch64/M1芯片、32GB内存的MacOS Ventura 13.2.1,Docker新手。
背景:由于Rust(Wasm)代码无法在macOS编译,需要在Ubuntu容器中部署Cosmos区块链节点,涉及三层容器结构:
-- MacOS ====| -- Container1 (golang): 运行正常 ==========| -- Container2 (wasmd): 运行正常 ==========| -- Container3 (rust-optimizer): 出现问题
在Container1中启动Container3时报错,相关步骤及信息如下:
Dockerfile
FROM --platform=linux/amd64 golang:latest # Update package manager and install basic utilities: RUN apt-get -y update && upgrade RUN apt-get install -y openssh-client && bash && build-essential && curl && git && vim RUN apt-get clean # Install rust: ENV PATH="/root/.cargo/bin:${PATH}" RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | bash -s -- -y --default-toolchain nightly RUN git clone https://github.com/twilight-rs/http-proxy.git RUN cd http-proxy && . $HOME/.cargo/env && cargo +nightly build --release -Z sparse-registry RUN rustup target add wasm32-unknown-unknown # Install Docker: RUN curl -fsSL https://get.docker.com | sh # Install wasmd: RUN git clone https://github.com/CosmWasm/wasmd.git && cd wasmd && make install # Dowload code over SSH: RUN mkdir -p -m 0700 ${HOME}/.ssh && ssh-keyscan github.com >> ${HOME}/.ssh/known_hosts ENV GIT_SSH_COMMAND="ssh -i /run/secrets/id_ed25519" # Clone the conf files into the docker container RUN --mount=type=secret,id=id_ed25519 git clone git@github.com:<myRepo>.git
构建命令
docker build -t myImage --secret id=id_ed25519,src=${HOME}/.ssh/id_ed25519 .
启动Container1命令
docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock myImage
启动Container2后,在Container1的新bash会话中启动Container3,myRepo位于/go目录,尝试在该目录及/root目录执行以下命令均报错:
docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ cosmwasm/rust-optimizer:0.12.8
错误信息
Error response from daemon: Mounts denied: The path /root/myRepo is not shared from the host and is not known to Docker. You can configure shared paths from Docker -> Preferences... -> Resources -> File Sharing. ERRO[0001] error waiting for container:
已排查过macOS宿主的Docker Desktop共享设置,但问题出在Container1与Container3的挂载逻辑,寻求解决方案。
问题根源
你在Container1中挂载了宿主的/var/run/docker.sock,这意味着Container1内的docker命令实际调用的是宿主MacOS上的Docker守护进程,而非Container1内部的Docker。当你执行-v "$(pwd)":/code时,$(pwd)是Container1内的路径(比如/root/myRepo),但宿主的Docker守护进程无法识别这个路径——因为宿主的文件系统里根本不存在这个目录,所以触发了挂载拒绝的错误。
可行解决方法
方法1:通过宿主共享目录传递代码
- 在宿主MacOS上创建一个本地目录,比如
~/cosmos-repo,并确保该目录已添加到Docker Desktop的「文件共享」列表中。 - 启动Container1时,将宿主的这个目录挂载到Container1内部:
docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock -v ~/cosmos-repo:/container-repo myImage
- 在Container1内部,将克隆的
myRepo内容复制到挂载的/container-repo目录:
cp -r /go/myRepo/* /container-repo/
- 进入
/container-repo目录,执行启动Container3的命令:
cd /container-repo docker run --rm -v "$(pwd)":/code \ --mount type=volume,source="$(basename "$(pwd)")_cache",target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ cosmwasm/rust-optimizer:0.12.8
此时$(pwd)对应宿主的~/cosmos-repo路径,宿主Docker可以正常识别并挂载。
方法2:使用Docker卷传递代码
- 在宿主MacOS上创建一个Docker卷:
docker volume create cosmos-repo-volume
- 启动Container1时,将这个卷挂载到Container1内部的某个路径:
docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock -v cosmos-repo-volume:/repo-volume myImage
- 在Container1内部,将
myRepo的内容复制到卷目录:
cp -r /go/myRepo/* /repo-volume/
- 启动Container3时,直接使用这个卷作为
/code挂载点:
docker run --rm -v cosmos-repo-volume:/code \ --mount type=volume,source=repo_cache,target=/code/target \ --mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \ cosmwasm/rust-optimizer:0.12.8
Docker卷由宿主Docker管理,无需依赖宿主本地目录,更适合容器间的代码传递。
方法3:调整Container1的代码克隆路径
修改Container1的Dockerfile,将代码克隆到与宿主共享的挂载路径下(比如前面方法1中的/container-repo),这样在Container1内执行启动命令时,$(pwd)直接对应宿主可识别的路径。修改Dockerfile的最后一行:
RUN --mount=type=secret,id=id_ed25519 git clone git@github.com:<myRepo>.git /container-repo
然后启动Container1时挂载宿主目录到/container-repo,后续直接在该目录启动Container3即可。
内容的提问来源于stack exchange,提问作者pdini

