I am trying to create a docker image out of a mostly-go source base. The problem is that the go code also calls a C++ library (libsodium), so the generated container lacks libstdc++.
Here is my approach: first, I bundle the distroless go image with a few things created with pkg_tar():
container_image(
name = "new_base_image",
base = "@go_image_base//image",
tars = [
":bash_static_tar",
":passwd_tar",
":dirs_tar",
],
visibility = ["//:__subpackages__"],
)
Then I create my go image, package it, and push it to my registry:
go_image(
name = "alice-go-image",
embed = [":alice_lib"],
base = "//:new_base_image",
visibility = ["//visibility:public"],
)
container_image(
name = "alice-image",
base = ":alice-go-image",
user = "alice",
entrypoint = "/bin/sh",
directory = "/opt/alice",
workdir = "/opt/alice",
)
container_push(
name = "alice-push",
format = "Docker",
image = ":alice-image",
registry = "us-central1-docker.pkg.dev",
repository = "mycoolproject/pub-docker/alice",
)
Unforunately, the Go code calls some vendored C++ code (libsodium, not that it matters), so attempting to run the resulting binary from within the container yields:
sh-5.1$ ./apollo
./alice: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory
I thought I could simply include the distroless CC image in a bundle, but I cannot figure out how to do it. I would think that putting
container_load(
name = "distroless-cc",
registry = "gcr.io",
repository = "distroless/cc",
tag = "latest",
)
in the WORKSPACE, then including the @distroless-cc//image label as one of the entries in the tars attribute of container_image would do the trick. Unfortunately, what it does instead is include the layer.tar files and associated metadata as part of the image! That is, if I change the first rule to:
container_image(
name = "new_base_image",
base = "@go_image_base//image",
tars = [
":bash_static_tar",
":passwd_tar",
":dirs_tar",
"@distroless-cc//image",
],
visibility = ["//:__subpackages__"],
)
the result is:
drwxr-xr-x 0/0 0 1969-12-31 19:00 ./
drwxr-xr-x 0/0 0 1969-12-31 19:00 ./bin/
-r-xr-xr-x 0/0 1248656 1969-12-31 19:00 ./bin/sh
drwxr-xr-x 0/0 0 1969-12-31 19:00 ./etc/
-rw-r--r-- 0/0 74 1969-12-31 19:00 ./etc/passwd
drwxr-xr-x 0/0 0 1969-12-31 19:00 ./opt/
drwxr-xr-x 0/0 0 1969-12-31 19:00 ./opt/config/
-rw-r--r-- 0/0 776 1969-12-31 19:00 ./46bdf18e6b66057ca3b88eb8e0e2b8443297e36629e5fba3f33c2b2c717aa083.json
-rw-r--r-- 0/0 3061760 1969-12-31 19:00 ./4441c0604495fd6824901b4a57c65ffbb9025023edc1bee6f1a8fe2c312347a3/layer.tar
-rw-r--r-- 0/0 245 1969-12-31 19:00 ./4441c0604495fd6824901b4a57c65ffbb9025023edc1bee6f1a8fe2c312347a3/json
-rw-r--r-- 0/0 3 1969-12-31 19:00 ./4441c0604495fd6824901b4a57c65ffbb9025023edc1bee6f1a8fe2c312347a3/VERSION
-rw-r--r-- 0/0 17786880 1969-12-31 19:00 ./51aee51224937d5c4fe6e805be3dac78ace093d894d99923afb39a6fbcb9711b/layer.tar
-rw-r--r-- 0/0 321 1969-12-31 19:00 ./51aee51224937d5c4fe6e805be3dac78ace093d894d99923afb39a6fbcb9711b/json
-rw-r--r-- 0/0 3 1969-12-31 19:00 ./51aee51224937d5c4fe6e805be3dac78ace093d894d99923afb39a6fbcb9711b/VERSION
-rw-r--r-- 0/0 1996800 1969-12-31 19:00 ./605a66edf924fdfdddccc79e556050288e91ecf53a2d71fa8c17d793c7d26451/layer.tar
-rw-r--r-- 0/0 485 1969-12-31 19:00 ./605a66edf924fdfdddccc79e556050288e91ecf53a2d71fa8c17d793c7d26451/json
-rw-r--r-- 0/0 3 1969-12-31 19:00 ./605a66edf924fdfdddccc79e556050288e91ecf53a2d71fa8c17d793c7d26451/VERSION
-rw-r--r-- 0/0 359 1969-12-31 19:00 ./manifest.json
-rw-r--r-- 0/0 92 1969-12-31 19:00 ./repositories
Which is clearly not what I want!
Of course I could manually create an image by untarring the go and the cc distroless images together and then pushing it to my private registry, but that would require doing stuff manually, and I can't figure out how to do it with the bazel docker rules.
Help?