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

golang 项目在 docker 容器中运行时找不到依赖项

golang 项目在 docker 容器中运行时找不到依赖项

Go
湖上湖 2021-12-20 19:19:36
我有这个 golang 沙箱项目:https : //github.com/cflynn07/golang-db-gateway-example当我尝试gateway/gateway.go在一个golang:1.6.0-alpine~/g/s/g/c/golang-db-gateway-example git:master ❯❯❯ docker-compose up gatewaymysql_server is up-to-dateStarting gatewayAttaching to gatewaygateway | gateway.go:7:2: cannot find package "github.com/go-sql-driver/mysql" in any of:gateway |   /usr/local/go/src/github.com/go-sql-driver/mysql (from $GOROOT)gateway |   /go/src/github.com/go-sql-driver/mysql (from $GOPATH)gateway | gateway.go:8:2: cannot find package "github.com/gorilla/mux" in any of:gateway |   /usr/local/go/src/github.com/gorilla/mux (from $GOROOT)gateway |   /go/src/github.com/gorilla/mux (from $GOPATH)gateway exited with code 1为什么构建步骤没有检测/example/vendor文件夹内我的项目的依赖项?当我go run gateway/gateway.go从我的主机操作系统运行时,该命令有效。目录结构(安装在容器内 /example)~/g/s/g/c/golang-db-gateway-example git:master ❯❯❯ tree -L 3.├── README.md├── client│   └── client.go├── docker-compose.yml├── gateway│   └── gateway.go├── glide.lock├── glide.yaml├── tmp└── vendor    └── github.com        ├── go-sql-driver        └── gorilla相关文件:docker-compose.ymlmysql:  container_name: mysql_server  image: mysql:5.7.11  environment:    - MYSQL_ROOT_PASSWORD=root  ports:    - 3306gateway:  container_name: gateway  image: golang:1.6.0-alpine  volumes:    - ./:/example  working_dir: /example/gateway  command: go run gateway.go  environment:    - MYSQL_ROOT_PASSWORD=root    - MYSQL_DATABASE=sandbox  links:    - mysql网关/gateway.gopackage mainimport (    "database/sql"    "encoding/json"    "fmt"    _ "github.com/go-sql-driver/mysql"    "github.com/gorilla/mux"    "net/http"    "os")var db *sql.DBfunc main() {    r := mux.NewRouter()    var e error    db, e = sql.Open(        "mysql", os.ExpandEnv("root:${MYSQL_SERVER_PASSWORD}@mysql_server:3306/${MYSQL_DATABASE}"))    fmt.Print("error is", e)    r.HandleFunc("/todos", getTodos).Methods("GET")    http.ListenAndServe(":8080", r)    fmt.Printf("gateway")}
查看完整描述

3 回答

?
慕田峪4524236

TA贡献1875条经验 获得超5个赞

实际上,您成功地运行了 Go 服务器。它没有挂起,只是在等待连接。由于一些怪癖,没有输出:它没有尝试连接到数据库,并且日志语句被缓冲。


尝试修改 gateway.go main:


func main() {

    log.Println("Starting main...")


    conn := os.ExpandEnv("root:${MYSQL_SERVER_PASSWORD}@mysql_server:3306/${MYSQL_DATABASE}")


    var err error

    db, err = sql.Open("mysql", conn)

    if err != nil {

        log.Fatal(err)

    }


    log.Println("pinging", conn)

    if err := db.Ping(); err != nil {

        log.Fatal(err)

    }


    r := mux.NewRouter()

    r.HandleFunc("/todos", getTodos).Methods("GET")


    listen := ":8080"

    log.Printf("Listening on %s\n", listen)

    log.Fatal(http.ListenAndServe(listen, r))

}

运行这个版本给出:


$ docker-compose up gateway

mysql_server is up-to-date

Starting gateway

Attaching to gateway

gateway | 2016/03/15 10:58:05 Starting main...

gateway | 2016/03/15 10:58:05 pinging root:@mysql_server:3306/sandbox

gateway | 2016/03/15 10:58:05 default addr for network 'mysql_server:3306' unknown

gateway | exit status 1

gateway exited with code 1

你应该很高兴从那里出发。笔记:

  • docker-compose 似乎缓冲标准输出直到换行

  • 日志功能,例如 log.Print 添加换行符,fmt.Print 不会

  • sql.Open 不连接到数据库,使用 sql.Ping (see wiki )

  • 缺少 MYSQL_SERVER_PASSWORD

  • 缺少 mysql 连接字符串的网络类型(参见示例

  • 也启动mysql服务器

  • 需要创建新的或安装现有的数据库“沙箱”


查看完整回答
反对 回复 2021-12-20
?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

在我看来,这里的主要问题似乎是您没有提前构建 Go 程序。看起来您已经将 Go 源文件放在 Docker 容器中,并且您依赖于go run构建然后运行程序。


我想你能做到吗?这是非常脚本语言风格的方式。


但是,我认为最好的方法是提前构建 Go 应用程序。


(请注意,对于以下内容,我改编了现有的 makefile 代码,但实际上并没有运行它。)

例如,您可以像这样构建它:


CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -tags netgo -installsuffix netgo -o ./gateway/gateway ./gateway

然后,假设您不需要该容器中的其他内容,您可以使用 Dockerfile 构建 Docker 映像,例如:


FROM scratch

ENTRYPOINT ["/gateway"]

ADD ./gateway/gateway /gateway

结果是一个简单的、小的(大约 8 MB)容器,其中包含一个静态链接的可执行文件。


查看完整回答
反对 回复 2021-12-20
?
慕雪6442864

TA贡献1812条经验 获得超5个赞

首先 - 需要更改${MYSQL_SERVER_PASSWORD}on ${MYSQL_ROOT_PASSWORD},因为环境只有MYSQL_ROOT_PASSWORD变量。

其次 - 这是错误的@mysql_server:3306,正确的是@tcp(mysql_server:3306)能够通过 TCP 连接到 MySQL。

conn := os.ExpandEnv("root:${MYSQL_ROOT_PASSWORD}@tcp(mysql_server:3306)/${MYSQL_DATABASE}")

一切都会好起来的,唯一的问题可能是数据库初始化时需要在运行主程序之前暂停。有几种方法可以解决这个问题,这里有几种方法https://docs.docker.com/compose/startup-order/


查看完整回答
反对 回复 2021-12-20
  • 3 回答
  • 0 关注
  • 223 浏览
慕课专栏
更多

添加回答

举报

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