英文:
COPY web server command to image but not found when run container
问题
我按照使用BusyBox Docker镜像构建应用程序的完整指南来自定义一个镜像。
使用的代码是docker-busybox-example。
Dockerfile
# 使用busybox作为基础镜像
FROM busybox
# 复制可执行文件
COPY ./server /home/server
# 运行可执行文件
CMD /home/server
web server
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World!")
}
func main() {
http.HandleFunc("/", handler)
fmt.Println("Server running...")
http.ListenAndServe(":8080", nil)
}
使用GOOS=linux GOARCH=amd64 go build server.go
将其编译为可执行文件server
。
基于busybox构建的镜像
[mymachine@localhost tmp]$ docker image build -t go-server .
Sending build context to Docker daemon 6.562MB
Step 1/3 : FROM busybox
---> beae173ccac6
Step 2/3 : COPY ./server /home/server
---> Using cache
---> 9d58653768ea
Step 3/3 : CMD /home/server
---> Running in 994cce171c11
Removing intermediate container 994cce171c11
---> 38996797b6d8
Successfully built 38996797b6d8
Successfully tagged go-server:latest
当运行容器时,找不到server
。我对此一无所知。
[mymachine@localhost tmp]$ docker run -p 8080:8080 --rm -it go-server ls -l /home
total 6408
-rwxrwxr-x 1 root root 6559402 Oct 13 19:53 server
[mymachine@localhost tmp]$ docker run -p 8080:8080 --rm -it go-server
/bin/sh: /home/server: not found
但对于这个应用程序,它可以正常工作。
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
它不支持Web服务器可执行文件吗?
docker: executable file not found in $PATH对此没有帮助。
有解决方案吗?
英文:
I follow Using the BusyBox Docker Image for Building Applications : A Complete Guide to customize an image.
Using code docker-busybox-example.
Dockerfile
# Use busybox as the base image
FROM busybox
# Copy over the executable file
COPY ./server /home/server
# Run the executable file
CMD /home/server
web server
package main
import (
"fmt"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello World!")
}
func main() {
http.HandleFunc("/", handler)
fmt.Println("Server running...")
http.ListenAndServe(":8080", nil)
}
compile as executable file server
with GOOS=linux GOARCH=amd64 go build server.go
built image based busybox
[mymachine@localhost tmp]$ docker image build -t go-server .
Sending build context to Docker daemon 6.562MB
Step 1/3 : FROM busybox
---> beae173ccac6
Step 2/3 : COPY ./server /home/server
---> Using cache
---> 9d58653768ea
Step 3/3 : CMD /home/server
---> Running in 994cce171c11
Removing intermediate container 994cce171c11
---> 38996797b6d8
Successfully built 38996797b6d8
Successfully tagged go-server:latest
*when run the container, server
is not found.I I have no clues about this.
[mymachine@localhost tmp]$ docker run -p 8080:8080 --rm -it go-server ls -l /home
total 6408
-rwxrwxr-x 1 root root 6559402 Oct 13 19:53 server
[mymachine@localhost tmp]$ docker run -p 8080:8080 --rm -it go-server
/bin/sh: /home/server: not found
but it works for this application
package main
import "fmt"
func main() {
fmt.Println("hello world")
}
Does it not support web server executable file?
docker: executable file not found in $PATH is not helpful
Any solutions for this?
答案1
得分: 2
您的server
是一个动态可执行文件...
$ ldd server
linux-vdso.so.1 (0x00007ffcbdbd2000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f3a78527000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3a78325000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3a78554000)
...而busybox
镜像没有所需的运行时库。一个解决方案是使用其他替代品,例如:
FROM ubuntu:22.04
COPY ./server /home/server
CMD ["/home/server"]
(我在这里修改了您的CMD
语句,以便可以使用CTRL-C
来终止容器。)
另一个选择是构建一个静态可执行文件:
$ CGO_ENABLED=0 go build
$ ldd server
not a dynamic executable
这在您的原始Dockerfile中可以正常工作。
英文:
Your server
is a dynamic executable...
$ ldd server
linux-vdso.so.1 (0x00007ffcbdbd2000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f3a78527000)
libc.so.6 => /lib64/libc.so.6 (0x00007f3a78325000)
/lib64/ld-linux-x86-64.so.2 (0x00007f3a78554000)
...and the busybox
image doesn't have any of the required runtime libraries. One solution is to use something other than busybox, e.g:
FROM ubuntu:22.04
COPY ./server /home/server
CMD ["/home/server"]
(I've modified your CMD
statement here so that it's possible to kill the container using CTRL-C
.)
The other option is to build a static executable:
$ CGO_ENABLED=0 go build
$ ldd server
not a dynamic executable
This works fine with your original Dockerfile.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论