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 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错
  • ¥15 coze 的插件输入飞书多维表格 app_token 后一直显示错误,如何解决?
  • ¥15 vite+vue3+plyr播放本地public文件夹下视频无法加载
  • ¥15 c#逐行读取txt文本,但是每一行里面数据之间空格数量不同
  • ¥50 如何openEuler 22.03上安装配置drbd
  • ¥20 ING91680C BLE5.3 芯片怎么实现串口收发数据
  • ¥15 无线连接树莓派,无法执行update,如何解决?(相关搜索:软件下载)