为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
子衿沉夜 2022-10-10 16:49:16
我写了一个小 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 mainimport (        "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-alpineRUN mkdir -p /app/logsADD . /appWORKDIR /appRUN go get -d -v ./...RUN go install -v ./...RUN go build -o /applicationEXPOSE 5000RUN touch /app/logs/logger.logCMD ["/application"]
查看完整描述

1 回答

?
大话西游666

TA贡献1817条经验 获得超14个赞

这是由于ListenAndServe在你的 goroutine 之前运行引起的。go forever()从不执行,所以它不会输出任何日志文件。

奇怪的是,如果我进入容器,我手动运行应用程序。记录器开始记录。

我假设您在运行容器上执行,您的应用程序的一个实例已经在运行,因此端口 5000已经被占用。您没有任何错误处理,因此它会跳过它并转到forever()函数。select{}不需要空,因为ListenAndServe会“阻止”程序:一个很好的解释https://stackoverflow.com/a/44598343/14484111

func 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))


}


查看完整回答
反对 回复 2022-10-10
  • 1 回答
  • 0 关注
  • 62 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信