英文:
dockerfile build cache permission issue
问题
我正在使用以下类似的二进制文件构建一个容器:
基本上,容器将运行一个可执行的Go程序。
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
然而,在Jenkins中运行容器时,我遇到了以下错误:
failed to initialize build cache at /.cache/go-build: mkdir /.cache: permission denied
在Kubernetes部署中手动运行容器时,我没有遇到任何问题,但是Jenkins会抛出此错误,并且我可以看到Pod处于CrashLoopBackOff状态,容器显示先前的权限问题。
此外,我不确定我是否正确构建了容器。也许我需要将可执行的Go程序包含在二进制文件中,然后再创建运行时?
如果有清晰的示例,将不胜感激。
英文:
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.
答案1
得分: 1
Go是一种编译语言,这意味着你实际上不需要go
工具来运行Go程序。在Docker环境中,一个典型的设置是使用多阶段构建来编译应用程序,然后将构建好的应用程序复制到最终的镜像中运行。最终的镜像不需要Go工具链或源代码,只需要编译好的二进制文件。
我可能会将最终阶段重写为:
FROM myrepo/ubi8/go-toolset:latest AS build
# ...按照你现在的方式...
FROM myrepo/ubi8/ubi-minimal:latest AS runtime
# 在这个阶段不要安装`go`
RUN microdnf update -y --nodocs &&
microdnf install cronie -y && \
microdnf clean all
# 创建一个非root用户,但不创建主目录;
# 具体的uid/gid并不重要
RUN adduser --system usercontainer
# 从第一个容器中获取构建好的二进制文件
# 并将其放在$PATH中的某个位置
COPY --from=build /build/build /usr/local/bin/myapp
# 切换到非root用户并解释如何运行容器
USER usercontainer
CMD ["myapp"]
这个步骤在最终镜像中不使用go run
或任何go
命令,希望能解决需要$HOME/.cache
目录的问题。(它还将给你一个更小的容器和更快的启动时间。)
英文:
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.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论