使用Bazel构建包含本地Golang模块的Docker容器。

huangapple go评论114阅读模式
英文:

Bazel build docker container with local golang module

问题

让我先说一下,我对Bazel还不熟悉。我正在尝试从一个包含本地模块引用的golang项目构建一个Docker容器。

首先,我正在创建一个本地的golang模块:

  1. go mod init go-example

这是项目的一般结构:

  1. .
  2. ├── BUILD.bazel
  3. ├── WORKSPACE
  4. ├── cmd
  5. └── hello
  6. ├── BUILD.bazel
  7. └── main.go
  8. ├── go.mod
  9. ├── go.sum
  10. └── pkg
  11. └── echo
  12. ├── BUILD.bazel
  13. └── echo.go

main.go中,我正在从本地模块导入pkg/echo

  1. import (
  2. "go-example/pkg/echo"
  3. )
  1. (top level BUILD.bazel)
  2. ...
  3. # gazelle:prefix go-example

✅ 默认的bazel构建可以工作

  1. $ bazel run //:gazelle
  2. $ bazel build //cmd/hello

❌ Docker构建失败。我得到以下错误:

  1. (cmd/hello/BUILD.bazel)
  2. ...
  3. go_image(
  4. name = "docker",
  5. srcs = ["main.go"],
  6. importpath = "go-example/cmd/hello",
  7. )
  1. $ bazel build //cmd/hello:docker
  2. ...
  3. compilepkg: missing strict dependencies:
  4. /private/var/tmp/_bazel[...]/__main__/cmd/hello/main.go: import of "go-example/pkg/echo"
  5. No dependencies were provided.
英文:

Let me start by saying I'm new to Bazel. I am trying to build a Docker container from a golang project that contains local module references.

First I'm creating a local golang module:

  1. go mod init go-example

Here is the general project structure:

  1. .
  2. ├── BUILD.bazel
  3. ├── WORKSPACE
  4. ├── cmd
  5. │   └── hello
  6. │   ├── BUILD.bazel
  7. │   └── main.go
  8. ├── go.mod
  9. ├── go.sum
  10. └── pkg
  11.    └── echo
  12.    ├── BUILD.bazel
  13.    └── echo.go

In main.go I am importing pkg/echo from the local module.

  1. import (
  2. "go-example/pkg/echo"
  3. )
  1. (top level BUILD.bazel)
  2. ...
  3. # gazelle:prefix go-example

✅ Default bazel build works

  1. $ bazel run //:gazelle
  2. $ bazel build //cmd/hello

❌ Docker build fails. I get the following error:

  1. (cmd/hello/BUILD.bazel)
  2. ...
  3. go_image(
  4. name = "docker",
  5. srcs = ["main.go"],
  6. importpath = "go-example/cmd/hello",
  7. )
  1. $ bazel build //cmd/hello:docker
  2. ...
  3. compilepkg: missing strict dependencies:
  4. /private/var/tmp/_bazel[...]/__main__/cmd/hello/main.go: import of "go-example/pkg/echo"
  5. No dependencies were provided.

答案1

得分: 1

找到了,如果有其他人遇到这个问题,我在这里发布。

答案很简单-你需要在go_image规则内嵌入go_library规则。这是我的cmd/hello/BUILD.bazel文件,我还在其中将go镜像嵌入到一个Docker容器中:

  1. load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
  2. load("@io_bazel_rules_docker//go:image.bzl", "go_image")
  3. load("@io_bazel_rules_docker//container:container.bzl", "container_image")
  4. go_library(
  5. name = "hello_lib",
  6. srcs = ["main.go"],
  7. importpath = "go-example/cmd/hello",
  8. visibility = ["//visibility:private"],
  9. deps = ["//pkg/echo"],
  10. )
  11. go_binary(
  12. name = "hello",
  13. embed = [":hello_lib"],
  14. visibility = ["//visibility:public"],
  15. )
  16. go_image(
  17. name = "hello_go_image",
  18. embed = [":hello_lib"],
  19. goarch = "amd64",
  20. goos = "linux",
  21. pure = "on",
  22. )
  23. container_image(
  24. name = "docker",
  25. base = ":hello_go_image",
  26. )

现在可以使用bazel build //cmd/hello:docker来运行了。

英文:

Figured it out, posting here if anyone else stumbles on this.

The answer is simple - you need to embed the go_library rule within the go_image rule. Here is my cmd/hello/BUILD.bazel where I also embed the go image in a docker container

  1. load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
  2. load("@io_bazel_rules_docker//go:image.bzl", "go_image")
  3. load("@io_bazel_rules_docker//container:container.bzl", "container_image")
  4. go_library(
  5. name = "hello_lib",
  6. srcs = ["main.go"],
  7. importpath = "go-example/cmd/hello",
  8. visibility = ["//visibility:private"],
  9. deps = ["//pkg/echo"],
  10. )
  11. go_binary(
  12. name = "hello",
  13. embed = [":hello_lib"],
  14. visibility = ["//visibility:public"],
  15. )
  16. go_image(
  17. name = "hello_go_image",
  18. embed = [":hello_lib"],
  19. goarch = "amd64",
  20. goos = "linux",
  21. pure = "on",
  22. )
  23. container_image(
  24. name = "docker",
  25. base = ":hello_go_image",
  26. )

Now it works to run bazel build //cmd/hello:docker

huangapple
  • 本文由 发表于 2021年11月16日 08:54:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/69982637.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定