如何运行使用go二进制文件创建的Docker容器?

时间:2019-05-16 12:25:26

标签: docker go dockerfile

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

我的文件夹中有两个文件:Dockerfilemain,其中FROM golang:1.11-alpine WORKDIR /app COPY main /app/ RUN ["chmod", "+x", "/app/main"] ENTRYPOINT ["./main"] 是我简单的go文件的二进制文件。

Dockerfile的内容:

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

    http.ListenAndServe(port(), nil)
}

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

我尝试了以下步骤:

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

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

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

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

WebDriverWait wait = new WebDriverWait (driver, 15);
      wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("/html/body/div/div/div/div/div/div/div/div[2]/a/img")));

      WebElement element1 = driver.findElement(By.xpath("/html/body/div/div/div/div/div/div/div/div[2]/a/img"));
      Actions builder = new Actions(driver);
      Action seriesOfActions = builder.moveToElement(element1).click().sendKeys(Keys.PAGE_DOWN).build();
      seriesOfActions.perform();

二进制“主”在独立运行时会按预期运行。因此go文件的内容没有问题。

2 个答案:

答案 0 :(得分:3)

您需要使用CGO_ENABLED=0进行编译,以防止在Go中使用网络时链接到Linux上的libc。 Alpine附带musl而不是libc,并且尝试查找libc导致没有此类文件或目录错误。您可以通过运行ldd main来查看动态链接来进行验证。

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

答案 1 :(得分:1)

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