dsf5632 2019-03-11 13:43
浏览 230
已采纳

如何在Docker中正确运行Golang应用程序?

I developed Golang application in Windows 10. In my local machine it works fine. I remove source code to remote CentOS server which has Docker. Right now I am trying to run this application in Docker.

I created Dockerfile in the same folder where located main.go file.

- questionnaire
    - database
    - routes
    - utils
    - models
    - controllers
      main.go
      Dockerfile

Dockerfile looks like this:

FROM golang:1.12

RUN go get github.com/gorilla/mux && \
  go get github.com/gorilla/handlers && \
  go get github.com/lib/pq && \
  go get github.com/joho/godotenv && \
  go get github.com/jinzhu/gorm && \
  go get github.com/go-goracle/goracle

COPY / ./

EXPOSE 8000

CMD ["go", "run", "main.go"]

My main.go file looks pretty simple:

package main

import (
  "github.com/gorilla/handlers"
  "github.com/gorilla/mux"
  "github.com/joho/godotenv"
  "log"
  "net/http"
  "questionnaire/database"
  "questionnaire/routes"
  "questionnaire/utils"
)

func main()  {
  err := godotenv.Load(".env")
  if err != nil {
    panic(err)
  }

  database.ConnectOracle()
  defer database.DisconnectOracle()

  router := mux.NewRouter()

  headers := handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization"})
  methods := handlers.AllowedMethods([]string{"GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS"})
  origins := handlers.AllowedOrigins([]string{"*"})

  router.StrictSlash(true)

  routes.Handle(router)

  port := utils.CheckEnvironmentVariable("APPLICATION_PORT")

  log.Printf("RESTful web service is running on %s port.", port)

  log.Fatal(http.ListenAndServe(":" + port, handlers.CORS(headers, methods, origins)(router)))
}

I successfully created Docker Image but I have error when created Docker Container:

main.go:9:2: cannot find package "questionnaire/database" in any of:
        /usr/local/go/src/questionnaire/database (from $GOROOT)
        /go/src/questionnaire/database (from $GOPATH)
main.go:10:2: cannot find package "questionnaire/routes" in any of:
        /usr/local/go/src/questionnaire/routes (from $GOROOT)
        /go/src/questionnaire/routes (from $GOPATH)
main.go:11:2: cannot find package "questionnaire/utils" in any of:
        /usr/local/go/src/questionnaire/utils (from $GOROOT)
        /go/src/questionnaire/utils (from $GOPATH)

Can anyone say how to fix this problem?

I also tried to build binary of golang application inside Docker by next Dockerfile but error message was the same RUN go build command:

FROM golang:1.12

RUN go get github.com/gorilla/mux && \
  go get github.com/gorilla/handlers && \
  go get github.com/lib/pq && \
  go get github.com/joho/godotenv && \
  go get github.com/jinzhu/gorm && \
  go get gopkg.in/goracle.v2

ADD . /go/src/questionnaire

WORKDIR /go/src/questionnaire

RUN go build -o /bin questionnaire

ENV PORT=8000

CMD ["/bin"]
  • 写回答

1条回答 默认 最新

  • douxing7101 2019-03-11 15:13
    关注

    The imports in your main.go file specify:

    "questionnaire/database" "questionnaire/routes" "questionnaire/utils"

    This means the go compiler is looking for those packages in $GOPATH/questionnaire and $GOROOT/questionnaire. You have to make sure those are copied into the correct place inside the docker image you are building.

    The default $GOPATH inside that golang:1.12 image is /go. Make sure your questionnaire package is correctly placed in the /go/src directory inside the docker image.

    As for the Dockerfile: A common strategy when building / deploying Docker images for go apps is to use a builder pattern (see example Dockerfile below). The gist of it is to create a multi-stage Dockerfile, where the first stage builds the go executable, and the second stage runs it. This means you can isolate all of your dependencies in the first stage, and end up with a very small overall image at the end.

    It might look something like this:

    FROM golang:1.11-alpine AS builder
    
    ########
    # Prep
    ########
    
    # add the source
    COPY . /go/src/questionnaire
    WORKDIR /go/src/questionnaire/
    
    ########
    # Build Go Wrapper
    ########
    
    # Install go dependencies
    RUN go get github.com/gorilla/mux && \
      go get github.com/gorilla/handlers && \
      go get github.com/lib/pq && \
      go get github.com/joho/godotenv && \
      go get github.com/jinzhu/gorm && \
      go get github.com/go-goracle/goracle
    
    #build the go app
    RUN GOOS=linux GOARCH=amd64 go build -o ./questionnaire ./main.go
    
    ########
    # Package into runtime image
    ########
    FROM alpine
    
    # copy the executable from the builder image
    COPY --from=builder /go/src/questionnaire .
    
    ENTRYPOINT ["/questionnaire"]
    
    EXPOSE 8080
    

    Hope this helps!

    (edited to reflect the comments below)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 用三极管设计—个共射极放大电路
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?
  • ¥15 求daily translation(DT)偏差订正方法的代码
  • ¥15 js调用html页面需要隐藏某个按钮
  • ¥15 ads仿真结果在圆图上是怎么读数的
  • ¥20 Cotex M3的调试和程序执行方式是什么样的?
  • ¥20 java项目连接sqlserver时报ssl相关错误
  • ¥15 一道python难题3
  • ¥15 牛顿斯科特系数表表示