树莓派64位Raspbian运行Docker容器报错:standard_init_linux.go:219
问题
我尝试在搭载64位Raspbian系统的树莓派上创建并运行边缘服务的Docker容器。受其他限制影响,我选择将已编译的Golang可执行文件打包进容器,而非在Dockerfile中构建.go源码。
我的Dockerfile内容如下:
FROM golang:alpine WORKDIR /build ADD server . EXPOSE 50051 CMD ["./server"]
单独运行该可执行文件正常,使用命令sudo docker build -t server:v7 .构建镜像时Docker Daemon无报错,镜像也正常显示在镜像列表中。但运行镜像时出现错误:
standard_init_linux.go:219: exec user process caused: no such file or directory
补充说明:所有程序在Ubuntu编写,在树莓派上编译为可执行文件,Dockerfile也在树莓派编写。使用命令sudo docker run -it -d <镜像ID> sh可启动镜像,通过sudo docker exec -it <容器ID> sh能进入shell,但在shell中运行程序同样失败,报错sh: error <程序名> not found。
执行ldd <程序名>得到以下结果:
/lib/ld-linux-aarch64.so.1 (0x7f8731f000) libpthread.so.0 => /lib/ld-linux-aarch64.so.1 (0x7f8731f000) libc.so.6 => /lib/ld-linux-aarch64.so.1 (0x7f8731f000)
Alpine系统和$PATH均无异常。
解决方案
- 改用基于glibc的基础镜像:把Dockerfile的基础镜像从
golang:alpine换成Debian或Ubuntu的ARM64镜像,比如debian:bookworm-slim或者ubuntu:22.04,这类镜像自带glibc,能匹配你编译的程序依赖:FROM debian:bookworm-slim WORKDIR /build ADD server . EXPOSE 50051 CMD ["./server"] - 静态编译Go程序:如果坚持用Alpine镜像,重新编译Go程序时加上静态编译参数,让程序不依赖系统libc,编译命令:
编译完成后再打包进Alpine镜像,这样程序就能在musl libc环境下运行。CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o server main.go - 验证依赖匹配:编译前确认目标环境的libc类型,Raspbian用glibc,Alpine用musl,两者不兼容,要么让程序不依赖libc(静态编译),要么用对应libc的基础镜像。
内容的提问来源于stack exchange,提问作者Johnney
相关产品推荐
相关产品推荐

