I’m building a container using a binary like this:
Basically the container will run an executable go program.
FROM myrepo/ubi8/go-toolset:latest AS build COPY --chown=1001:0 . /build RUN cd /build && \ go env -w GO111MODULE=auto && \ go build #--------------------------------------------------------------- FROM myrepo/ubi8/ubi-minimal:latest AS runtime RUN microdnf update -y --nodocs && microdnf clean all && \ microdnf install go -y && \ microdnf install cronie -y && \ groupadd -g 1000 usercontainer && adduser -u 1000 -g usercontainer usercontainer && chmod 755 /home/usercontainer && \ microdnf clean all ENV XDG_CACHE_HOME=/home/usercontainer/.cache COPY executable.go /tmp/executable.go RUN chmod 0555 /tmp/executable.go USER usercontainer WORKDIR /home/usercontainer
However, when running the container in Jenkins I’m getting this error:
failed to initialize build cache at /.cache/go-build: mkdir /.cache: permission denied
When running the container manually in a kubernetes deployment I’m not getting any issue but Jenkins is throwing this error and I can see the pod in CrashLoopBackOff and the container is showing the previous permissions issue.
Also, I’m not sure if I’m building the container correctly. Maybe I need to include the executable go program in the binary and later create the runtime?
Any clear example would be appreciated.
Go is a compiled language, which means that you don’t actually need the
go tool to run a Go program. In a Docker context, a typical setup is to use a multi-stage build to compile an application, and then copy the built application into a final image that runs it. The final image doesn’t need the Go toolchain or the source code, just the compiled binary.
I might rewrite the final stage as:
FROM myrepo/ubi8/go-toolset:latest AS build # ... as you have it now ... FROM myrepo/ubi8/ubi-minimal:latest AS runtime # Do not install `go` in this sequence RUN microdnf update -y --nodocs && microdnf install cronie -y && \ microdnf clean all # Create a non-root user, but not a home directory; # specific uid/gid doesn't matter RUN adduser --system usercontainer # Get the built binary out of the first container # and put it somewhere in $PATH COPY --from=build /build/build /usr/local/bin/myapp # Switch to a non-root user and explain how to run the container USER usercontainer CMD ["myapp"]
This sequence doesn’t use
go run or use any
go command in the final image, which hopefully gets around the issue of needing a
$HOME/.cache directory. (It will also give you a smaller container and faster startup time.)
Answered By – David Maze
Answer Checked By – David Marino (GoLangFix Volunteer)