【问题标题】:How to run a docker container created with go binary?如何运行使用 go binary 创建的 docker 容器?
【发布时间】:2019-05-16 12:25:25
【问题描述】:

我正在尝试使用 Dockerfile 和 go 文件二进制文件创建一个 docker 容器。

我的文件夹中有两个文件:Dockerfilemain,后者是我的简单 go 文件的二进制文件。

Dockerfile 的内容:

FROM golang:1.11-alpine
WORKDIR /app
COPY main /app/
RUN ["chmod", "+x", "/app/main"]
ENTRYPOINT ["./main"]

我尝试了以下步骤:

  1. sudo docker build -t naive5cr .
  2. sudo docker run -d -p 8080:8080 naive5cr

我在“docker logs”中看到的错误:

standard_init_linux.go:207: exec 用户进程导致“没有这样的文件或目录”

我的go文件内容[我认为与问题无关]:

func main() {
    http.HandleFunc("/", index)

    http.ListenAndServe(port(), nil)
}

func port() string {
    port := os.Getenv("PORT")
    if len(port) == 0 {
        port = "8080"
    }
    return ":" + port
 } 

二进制“main”在独立运行时按预期运行。所以go文件的内容没有问题。

【问题讨论】:

标签: docker go dockerfile


【解决方案1】:

在 Go 中使用网络时,您需要使用 CGO_ENABLED=0 进行编译以防止链接到 Linux 上的 libc。 Alpine 附带 musl 而不是 libc,尝试查找 libc 会导致 no such file or directory 错误。您可以通过运行ldd main 查看动态链接来验证这一点。

您还可以在基于 Alpine 的主机上构建以链接到 musl 而不是 libc。完全静态编译的二进制文件的优点是能够从头开始运行,根本不需要任何库。

【讨论】:

  • 我用 CGO_ENABLED=0 go build 构建了 go 文件,然后它工作了。是否有任何命令可以详细输出我得到的错误? standard_init_linux.go:207: exec 用户进程导致“没有这样的文件或目录”
  • @inlineMacro 错误来自内核/系统调用,docker 只是通过它。如果您的主机上缺少库,您将在 docker 之外遇到相同的错误。
【解决方案2】:

go 会编译为本机代码,因此请确保在 Docker 映像上构建您的 go 代码,而不是将二进制文件复制到 docker 映像。

例如

FROM golang:1.11-alpine
WORKDIR /app
ADD . /app
RUN cd /app && go build -o goapp
ENTRYPOINT ./goapp

另外,以下是如何使用多阶段 Docker 构建创建非常小的 Docker 映像:

FROM golang:1.11-alpine AS build-env
ADD . /src
RUN cd /src && go build -o goapp

FROM alpine
WORKDIR /app
COPY --from=build-env /src/goapp /app/
ENTRYPOINT ./goapp

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 2018-01-05
    • 1970-01-01
    • 2021-02-21
    • 1970-01-01
    • 2018-01-07
    • 1970-01-01
    相关资源
    最近更新 更多