对复制到 Dockerfile 中的文件设置不同的用户权限

Setup different user permissions on files copied in Dockerfile

我有这个 Dockerfile 设置:

FROM node:14.5-buster-slim AS base
WORKDIR /app


FROM base AS production
ENV NODE_ENV=production

RUN chown -R node:node /app
RUN chmod 755 /app
USER node
... other copies
COPY ./scripts/startup-production.sh ./
COPY ./scripts/healthz.sh ./

CMD ["./startup-production.sh"]

我面临的问题是我无法执行 ./healthz.sh,因为它只能由 node 用户执行。当我注释掉 RUNUSER 这两个命令时,我可以很好地执行文件。但出于安全原因,我只想对 node 执行可执行权限。

我需要 ./healthz.sh 可以通过 Kubernetes 的活跃度和冗余度探测器在外部执行。

我怎样才能做到这一点?文件夹重组之类的对我来说没问题。

在大多数情况下,您可能希望您的代码由 root 所有,但要全世界都可读,并且脚本要全世界都可执行。 Dockerfile COPY 指令将从主机系统复制一个具有现有权限的文件(隐藏在最后的要点列表中的是一个注释,文件“与其元数据一起单独复制”)。因此,最简单的方法是确保脚本在主机系统上具有正确的权限:

# mode 0755 is readable and executable by everyone but only writable by owner
chmod 0755 healthz.sh
git commit -am 'make healthz script executable'

然后你就可以 COPY 它了,不需要任何特殊设置。

# Do not RUN chown or chmod; just
WORKDIR /app
COPY ./scripts/healthz.sh .

# Then when launching the container, specify
USER node
CMD ["./startup-production.sh"]

您应该能够通过 运行 您的容器并手动调用运行状况检查脚本在本地验证这一点

docker run -d --name app the-image
# possibly with a `docker exec -u` option to specify a different user
docker exec app /app/healthz.sh && echo OK

要检查的重要事项是该文件是全球可执行的。您还可以通过查看构建的容器来仔细检查这一点

docker run --rm the-image ls -l /app/healthz.sh

那应该打印出一行,以权限字符串开头 -rwxr-xr-x;最后三个 r-x 是重要的部分。如果您无法通过其他方式获得正确的权限,您也可以在镜像构建中修复它们

COPY ./scripts/healthz.sh .
# If you can't make the permissions on the original file right:
RUN chmod 0755 *.sh

您需要像这样修改用户 Dockerfile CMD 命令:["sh", "./startup-production.sh"]

这会将脚本解释为 sh,但如果您的脚本使用 bash 特定功能(例如 [[]] 且第一行为 #!/bin/bash,则可能很危险.

此外,我会说在这里使用 ENTRYPOINT 而不是 CMD 如果你想在容器启动时 运行