Docker构建极简HelloWorld镜像运行报错:exec /helloworld: no such file or directory
问题:使用scratch镜像构建HelloWorld容器时出现"exec /helloworld: no such file or directory"错误
操作步骤
- 目录结构:
$ ls Dockerfile helloworld.c
- helloworld.c代码:
#include <stdio.h> int main() { printf("Hello world!\n"); return 0; }
- Dockerfile内容:
FROM scratch COPY helloworld / CMD ["/helloworld"]
- 本地编译执行:
$ gcc -o helloworld helloworld.c $ ./helloworld Hello world!
- 构建镜像:
$ docker build --tag helloworld . [+] Building 0.2s (5/5) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 93B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build context 0.0s => => transferring context: 33B 0.0s => CACHED [1/1] COPY helloworld / 0.0s => exporting to image 0.0s => => exporting layers 0.0s => => writing image sha256:c5664c4c93727aae40daca2c1fc0aa13ea2e2c58ba2962fa8d981aa0ec09012e 0.0s => => naming to docker.io/library/helloworld
- 运行容器报错:
$ docker run helloworld exec /helloworld: no such file or directory
问题原因与解决方法
核心原因
本地gcc默认编译出的是动态链接二进制文件,这类文件依赖系统中的glibc等基础库才能运行。但scratch镜像完全是空的,没有任何系统依赖库,因此容器启动时无法找到所需的链接库,从而抛出看似找不到可执行文件的错误(实际是依赖缺失)。
直接解决:编译静态链接二进制
修改gcc编译命令,添加-static参数强制生成静态链接的可执行文件,所有依赖库会被打包到文件内部,无需系统提供:
gcc -static -o helloworld helloworld.c
重新编译后,再执行镜像构建和容器运行命令,即可正常输出"Hello world!"。
进阶优化:Docker多阶段构建
如果希望避免本地编译环境的差异,或者不想在本地安装gcc,可以使用多阶段构建,在容器内完成编译,再将静态二进制复制到scratch镜像中。修改Dockerfile如下:
# 第一阶段:编译环境,生成静态二进制 FROM gcc:alpine AS builder COPY helloworld.c / RUN gcc -static -o helloworld helloworld.c # 第二阶段:构建轻量镜像 FROM scratch COPY --from=builder /helloworld / CMD ["/helloworld"]
直接执行docker build --tag helloworld .即可完成编译与镜像构建,最终镜像体积依然极小,且环境一致性更高。
内容的提问来源于stack exchange,提问作者zer0uno
相关产品推荐
相关产品推荐

