将 web 服务器命令复制到镜像中,但在运行容器时找不到。

huangapple go评论125阅读模式
英文:

COPY web server command to image but not found when run container

问题

我按照使用BusyBox Docker镜像构建应用程序的完整指南来自定义一个镜像。

使用的代码是docker-busybox-example

Dockerfile

  1. # 使用busybox作为基础镜像
  2. FROM busybox
  3. # 复制可执行文件
  4. COPY ./server /home/server
  5. # 运行可执行文件
  6. CMD /home/server

web server

  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. )
  6. func handler(w http.ResponseWriter, r *http.Request) {
  7. fmt.Fprintf(w, "Hello World!")
  8. }
  9. func main() {
  10. http.HandleFunc("/", handler)
  11. fmt.Println("Server running...")
  12. http.ListenAndServe(":8080", nil)
  13. }

使用GOOS=linux GOARCH=amd64 go build server.go将其编译为可执行文件server

基于busybox构建的镜像

  1. [mymachine@localhost tmp]$ docker image build -t go-server .
  2. Sending build context to Docker daemon 6.562MB
  3. Step 1/3 : FROM busybox
  4. ---> beae173ccac6
  5. Step 2/3 : COPY ./server /home/server
  6. ---> Using cache
  7. ---> 9d58653768ea
  8. Step 3/3 : CMD /home/server
  9. ---> Running in 994cce171c11
  10. Removing intermediate container 994cce171c11
  11. ---> 38996797b6d8
  12. Successfully built 38996797b6d8
  13. Successfully tagged go-server:latest

当运行容器时,找不到server。我对此一无所知。

  1. [mymachine@localhost tmp]$ docker run -p 8080:8080 --rm -it go-server ls -l /home
  2. total 6408
  3. -rwxrwxr-x 1 root root 6559402 Oct 13 19:53 server
  4. [mymachine@localhost tmp]$ docker run -p 8080:8080 --rm -it go-server
  5. /bin/sh: /home/server: not found

但对于这个应用程序,它可以正常工作。

  1. package main
  2. import "fmt"
  3. func main() {
  4. fmt.Println("hello world")
  5. }

它不支持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

  1. # Use busybox as the base image
  2. FROM busybox
  3. # Copy over the executable file
  4. COPY ./server /home/server
  5. # Run the executable file
  6. CMD /home/server

web server

  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. )
  6. func handler(w http.ResponseWriter, r *http.Request) {
  7. fmt.Fprintf(w, "Hello World!")
  8. }
  9. func main() {
  10. http.HandleFunc("/", handler)
  11. fmt.Println("Server running...")
  12. http.ListenAndServe(":8080", nil)
  13. }

compile as executable file server with GOOS=linux GOARCH=amd64 go build server.go

built image based busybox

  1. [mymachine@localhost tmp]$ docker image build -t go-server .
  2. Sending build context to Docker daemon 6.562MB
  3. Step 1/3 : FROM busybox
  4. ---> beae173ccac6
  5. Step 2/3 : COPY ./server /home/server
  6. ---> Using cache
  7. ---> 9d58653768ea
  8. Step 3/3 : CMD /home/server
  9. ---> Running in 994cce171c11
  10. Removing intermediate container 994cce171c11
  11. ---> 38996797b6d8
  12. Successfully built 38996797b6d8
  13. Successfully tagged go-server:latest

*when run the container, server is not found.I I have no clues about this.

  1. [mymachine@localhost tmp]$ docker run -p 8080:8080 --rm -it go-server ls -l /home
  2. total 6408
  3. -rwxrwxr-x 1 root root 6559402 Oct 13 19:53 server
  4. [mymachine@localhost tmp]$ docker run -p 8080:8080 --rm -it go-server
  5. /bin/sh: /home/server: not found

but it works for this application

  1. package main
  2. import "fmt"
  3. func main() {
  4. fmt.Println("hello world")
  5. }

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是一个动态可执行文件...

  1. $ ldd server
  2. linux-vdso.so.1 (0x00007ffcbdbd2000)
  3. libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f3a78527000)
  4. libc.so.6 => /lib64/libc.so.6 (0x00007f3a78325000)
  5. /lib64/ld-linux-x86-64.so.2 (0x00007f3a78554000)

...而busybox镜像没有所需的运行时库。一个解决方案是使用其他替代品,例如:

  1. FROM ubuntu:22.04
  2. COPY ./server /home/server
  3. CMD ["/home/server"]

(我在这里修改了您的CMD语句,以便可以使用CTRL-C来终止容器。)

另一个选择是构建一个静态可执行文件:

  1. $ CGO_ENABLED=0 go build
  2. $ ldd server
  3. not a dynamic executable

这在您的原始Dockerfile中可以正常工作。

英文:

Your server is a dynamic executable...

  1. $ ldd server
  2. linux-vdso.so.1 (0x00007ffcbdbd2000)
  3. libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f3a78527000)
  4. libc.so.6 => /lib64/libc.so.6 (0x00007f3a78325000)
  5. /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:

  1. FROM ubuntu:22.04
  2. COPY ./server /home/server
  3. 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:

  1. $ CGO_ENABLED=0 go build
  2. $ ldd server
  3. not a dynamic executable

This works fine with your original Dockerfile.

huangapple
  • 本文由 发表于 2022年10月14日 05:23:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/74061957.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定