Dockerfile构建缓存权限问题

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

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.)

huangapple
  • 本文由 发表于 2022年6月21日 17:00:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/72697986.html
匿名

发表评论

匿名网友

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

确定