skip to Main Content

I’m having difficulties setting up a golang dockerfile for a personal project.

project structure is:

Project
|
+-- log.go (contains main)
|
+-- go.mod
|      
+-- hash
   |  
   +-- hash.go

The app prints a random hash every 5 seconds and appends a timestamp to it.

File contents:

log.go

  package main

  import (
      "fmt"
      "github.com/postelniql/logger-output/hash"
      "time"
  )

  func log() string {
      dt := time.Now()
      hash := hash.NewSHA1Hash()
      return dt.Format("01-02-2006T15:04:05.000Z") + ": " + hash
  }

  func main() {
      fmt.Println(log())

      tick := time.Tick(5000 * time.Millisecond)
      for range tick {
          fmt.Println(log())
      }
  }

go.mod:

  module github.com/postelniql/logger-output

  go 1.19

hash.go:

  package hash

  import (
      "crypto/sha1"
      "fmt"
      "math/rand"
      "time"
  )

  func init() {
      rand.Seed(time.Now().UnixNano())
  }

  func NewSHA1Hash(n ...int) string {
      noRandomCharacters := 32

      if len(n) > 0 {
          noRandomCharacters = n[0]
      }

      randString := randomString(noRandomCharacters)

      hash := sha1.New()
      hash.Write([]byte(randString))
      bs := hash.Sum(nil)

      return fmt.Sprintf("%x", bs)
  }

  var characterRunes = 
  []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")

  // RandomString generates a random string of n length
  func randomString(n int) string {
      b := make([]rune, n)
      for i := range b {
          b[i] = characterRunes[rand.Intn(len(characterRunes))]
      }
      return string(b)
  }

I scraped together the following Dockerfile:

  FROM golang:1.19-alpine
  WORKDIR /app
  COPY go.mod ./
  RUN apk add git
  RUN go get github.com/postelniql/logger-output/hash
  COPY *.go ./
  RUN go build -o /logger-output-app
  EXPOSE 8080
  CMD [ "/logger-output-app" ]

However I keep getting this error (and similar sort of errors):

   ------
    > [6/8] RUN go get github.com/postelniql/logger-output/hash:
    #10 2.105 go: github.com/postelniql/logger-output/hash: no matching versions for 
    query "upgrade"
   ------
   executor failed running [/bin/sh -c go get github.com/postelniql/logger- 
   output/hash]: exit code: 1

I’ve searched the web for hours trying to fix this, I genuinely don’t understand what’s wrong with it. I suspect I’m doing something wrong when it comes to dependency management in the Dockerfile.

I mention I’m a noob in go and am coding this as part of my learning process.

Please help me write a dockerfile that builds and runs.

Thanks!

2

Answers


  1. This should work, explanation below.

    #build stage
    FROM golang:alpine AS builder
    
    RUN apk add --no-cache git
    WORKDIR /go/src/app
    COPY . .
    
    RUN go get -d -v ./...
    RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o /go/bin/app -v .
    
    #final stage
    FROM alpine:latest
    
    RUN addgroup -S app && adduser -S app -G app
    COPY --from=builder --chown=app /go/bin/app /app
    USER app
    
    ENTRYPOINT ["/app"] 
    

    Place the Dockerfile in your project so that you don’t have to clone the project inside (makes no sense).

    Use 2-stage build to have a clean final image.

    Use a different user than root to run the final binary.

    Don’t expose any port since your app is not listening on any port.

    Use ENTRYPOINT instead of CMD. This way you can later pass arguments on the docker run command line.

    Login or Signup to reply.
  2. You don’t need to go get github.com/postelniql/logger-output/hash: this is part of your local source tree and you have it locally. You do need to make sure you COPY it into your image.

    The changes in your Dockerfile aren’t complicated, but your Dockerfile isn’t that large to start with:

    FROM golang:1.19-alpine
    WORKDIR /app
    COPY go.mod go.sum ./    # add `go.sum`
    RUN go mod download      # add: downloads external dependencies
    # RUN apk add git        # delete
    # RUN go get github.com/postelniql/logger-output/hash  # delete
    COPY *.go ./
    COPY hash/ hash/         # add
    RUN go build -o /logger-output-app
    EXPOSE 8080
    CMD [ "/logger-output-app" ]
    

    The Dockerfile in @Mihai’s answer should work too, since it also deletes the go get your-own-application line. The multi-stage build setup deletes the Go toolchain from the final build so you get a much smaller image out, but it’s also more complex and a little harder to debug.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search