go 不会从容器中写入文件,除非应用程序是从容器中手动启动的

我写了一个小 golang 应用程序。它做两件事:

  • 处理 http://localhost:5000

  • 每秒写一个日志

此应用程序位于 docker 容器内。你可以看到的记录器是我的,只是一个练习。申请开始。如果我 curl http://localhost:5000 我可以看到“Ciao,mondo!”。但是记录器没有启动。奇怪的是,如果我进入容器,我手动运行应用程序。记录器开始记录。我认为这可能是权限问题。

这里是 docker-compose。

version: "3.9"

services:

    app:

        container_name: 'go_docker_app'

        build:

            dockerfile: Dockerfile

            context: .

        volumes:

            - ./logs:/app/logs

            - .:/opt/app/api

        ports:

            - "5000:5000"

这里是 main.go 文件

package main


import (

        "fmt"

        "net/http"

        "time"

        "github.com/sensorario/gol"

)


func main() {

    http.HandleFunc("/", HelloServer);

    http.ListenAndServe(":5000", nil);


    go forever()

    select{}

}


func HelloServer(w http.ResponseWriter, r *http.Request) {

    fmt.Fprintf(w, "Ciao, mondo!");

}


func forever() {

    l := gol.NewCustomLogger("/app");

    for {

        l.Info(fmt.Sprintf("%v+\n", time.Now()));

        time.Sleep(time.Second)

    }

}

这里是 Dockerfile

我尝试了更多解决方案。例如从 Dockerfile 创建 logger.log。我不认为是权限问题,因为我没有错误。


FROM golang:1.17-alpine

RUN mkdir -p /app/logs

ADD . /app

WORKDIR /app

RUN go get -d -v ./...

RUN go install -v ./...

RUN go build -o /application

EXPOSE 5000

RUN touch /app/logs/logger.log

CMD ["/application"]


子衿沉夜
浏览 63回答 1
1回答

大话西游666

这是由于ListenAndServe在你的 goroutine 之前运行引起的。go forever()从不执行,所以它不会输出任何日志文件。奇怪的是,如果我进入容器,我手动运行应用程序。记录器开始记录。我假设您在运行容器上执行,您的应用程序的一个实例已经在运行,因此端口 5000已经被占用。您没有任何错误处理,因此它会跳过它并转到forever()函数。select{}不需要空,因为ListenAndServe会“阻止”程序:一个很好的解释https://stackoverflow.com/a/44598343/14484111func main() {    go forever()    http.HandleFunc("/", HelloServer);    // added error validating    err := http.ListenAndServe(":5000", nil);    log.Fatal(err)    // or shorter version    // log.Fatal(http.ListenAndServe(":5000", nil))}
打开App,查看更多内容
随时随地看视频慕课网APP