M2 Mac构建Rust API Docker镜像后执行提示文件不存在但实际存在
Rust Docker镜像运行报错"exec ./backend: no such file or directory"排查与解决
问题场景
在M2 Mac上使用docker buildx构建linux/amd64架构的Rust API Docker镜像,推送至仓库后在Scaleway的amd64实例上运行时,出现错误:
exec ./backend: no such file or directory
但进入镜像执行ls -al能看到backend文件确实存在。
相关配置
Dockerfile
# Build stage FROM --platform=linux/amd64 rust:1.72-buster as builder RUN rustup update # Install dependencies RUN apt-get update && apt-get install -y \ libpq-dev \ libssl-dev # Create a new user for the application RUN useradd --create-home appuser # Set the working directory for the rest of the commands WORKDIR /home/appuser # Copy the application source code COPY . . # Build the application RUN cargo build --release # Runtime stage FROM --platform=linux/amd64 debian:bookworm-20230814-slim as runner # Install dependencies RUN apt-get update && apt-get install -y \ libpq5 \ libssl3 # Create a new user for the application RUN useradd --create-home appuser # Set the working directory for the rest of the commands WORKDIR /home/appuser # Copy the compiled binary from the build stage COPY --from=builder /home/appuser/target/release/backend . USER appuser RUN ls -al EXPOSE 8880 # CMD ["./backend"]
构建命令
docker buildx build --platform linux/amd64 --output type=docker -t backend-api .
Cargo.toml(关键部分)
[profile.release] opt-level = 'z' # Optimize for size. lto = true # Enable Link Time Optimization codegen-units = 1 # Reduce number of codegen units to increase optimizations. panic = 'abort' # Abort on panic strip = true # Strip symbols from binary*
原因分析
这个错误并非真的文件不存在,而是二进制文件依赖的动态链接库缺失或基础镜像的库版本不兼容:
- Builder阶段基于
debian:buster,但Runner阶段用了debian:bookworm-slim,两个debian版本的系统库(如glibc、ssl)版本差异可能导致链接失败。 - Slim镜像默认缺少部分基础系统库,即使安装了libpq5和libssl3,仍可能遗漏必要依赖。
strip = true虽一般安全,但极端情况下可能破坏二进制的链接信息(概率较低)。
解决步骤
1. 对齐Builder和Runner的基础镜像版本
将Runner阶段的基础镜像改为与Builder一致的debian:buster-slim,避免跨版本库冲突:
修改Dockerfile的Runner部分:
# Runtime stage FROM --platform=linux/amd64 debian:buster-slim as runner # Install dependencies RUN apt-get update && apt-get install -y \ libpq5 \ libssl1.1 # buster对应的ssl版本是libssl1.1,而非bookworm的libssl3
2. 检查并补充缺失的系统依赖
进入运行中的镜像(或临时启动镜像),执行ldd ./backend查看二进制的依赖项:
docker run -it --rm backend-api bash # 进入后执行 ldd ./backend
如果输出中有not found的项,在Runner阶段的apt-get install中添加对应的库,例如常见缺失项可能包括libc6、libgcc1等。
3. 临时禁用strip配置测试
注释掉Cargo.toml中的strip = true,重新构建镜像,排除strip操作导致的二进制损坏:
[profile.release] opt-level = 'z' lto = true codegen-units = 1 panic = 'abort' # strip = true # 先注释掉
4. 调整构建命令(可选)
使用--load参数确保构建的镜像直接加载到本地Docker,方便测试:
docker buildx build --platform linux/amd64 --load -t backend-api .
验证
修改后重新构建、推送镜像,在Scaleway实例上运行,确认错误消失。
内容的提问来源于stack exchange,提问作者user1445685
相关产品推荐
相关产品推荐

