Home > Software engineering >  go does not write file from container unless application is manually started from container
go does not write file from container unless application is manually started from container

Time:10-27

I've written a little golang application. It do two things:

  • handle http://localhost:5000
  • write a log each seconds

This application is inside a docker container. The logger you can see is mine, is just an exercise. Application start. If I curl http://localhost:5000 I can see "Ciao, mondo!". But the logger does not starts. The strange thing is that if I go into the container, and I run the application by hand. The logger start to log. I thought this can be a problem of permissions.

Here the 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"

Here the main.go file

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

Here the Dockerfile

I've tried more solutions. For example creating logger.log from Dockerfile. I dont think is a problem of permissions because I have no errors.

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"]

CodePudding user response:

It's caused by running ListenAndServe before your goroutine. go forever() never execute, so it will not output any log file.

The strange thing is that if I go into the container, and I run the application by hand. The logger start to log.

I assume that You exec on running container, where one instance of your app is alredy running so the Port 5000 is alredy taken. You don't have any error handling, so it skips it and go to the forever() function. Empty select{} won't be needed, coz ListenAndServe will "block" the program: a nice explenation 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))

}
  • Related