Openshift Nginx 权限问题 [nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)]

Openshift Nginx permission problem [nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)]

我目前 运行 在尝试在 Openshift 中设置 nginx:alpine 时遇到问题。

我的构建运行得很好,但我无法部署,权限被拒绝,出现以下错误

2019/01/25 06:30:54 [emerg] 1#1: mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)

nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)

现在我知道 Openshift 在权限方面有点棘手,因为容器 运行 没有 root 权限并且 UID 在运行时生成,这意味着它在 /etc/passwd 中不可用。但是用户是组 root 的一部分。现在这里描述了应该如何处理

https://docs.openshift.com/container-platform/3.3/creating_images/guidelines.html#openshift-container-platform-specific-guidelines

为了测试目的,我什至更进一步,使整个 /var 完全可访问 (777),但我仍然遇到错误。这就是我的 Dockerfile 的样子

Dockerfile

FROM nginx:alpine

#Configure proxy settings
ENV HTTP_PROXY=http://my.proxy:port
ENV HTTPS_PROXY=http://my.proxy:port
ENV HTTP_PROXY_AUTH=basic:*:username:password

WORKDIR /app
COPY . .

# Install node.js
RUN apk update && \
    apk add nodejs npm python make curl g++


# Build Application
RUN npm install
RUN ./node_modules/@angular/cli/bin/ng build
COPY ./dist/my-app /usr/share/nginx/html

# Configure NGINX
COPY ./openshift/nginx/nginx.conf /etc/nginx/nginx.conf
COPY ./openshift/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf

RUN chgrp -R root /var/cache/nginx /var/run /var/log/nginx && \
    chmod -R 777 /var
RUN sed -i.bak 's/^user/#user/' /etc/nginx/nginx.conf

EXPOSE 8080

有趣的是,这种方法似乎只对 nginx 的 alpine 版本有效。 nginx:latest(我认为是基于 debian)没有问题,这里描述了设置它的方法

https://torstenwalter.de/openshift/nginx/2017/08/04/nginx-on-openshift.html

有效。 (但我对该构建还有一些其他问题,所以我切换到高山)

知道为什么这仍然不起作用吗?

解决这个问题。我认为这个 Dockerfile 中的问题是我使用 COPY 命令来移动我的构建,但它不存在。所以这是我的工作

Dockerfile

FROM nginx:alpine

LABEL maintainer="ReliefMelone"

WORKDIR /app
COPY . .

# Install node.js
RUN apk update && \
    apk add nodejs npm python make curl g++


# Build Application
RUN npm install
RUN ./node_modules/@angular/cli/bin/ng build --configuration=${BUILD_CONFIG}
RUN cp -r ./dist/. /usr/share/nginx/html

# Configure NGINX
COPY ./openshift/nginx/nginx.conf /etc/nginx/nginx.conf
COPY ./openshift/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf

RUN chgrp -R root /var/cache/nginx /var/run /var/log/nginx && \
    chmod -R 770 /var/cache/nginx /var/run /var/log/nginx

EXPOSE 8080

CMD ["nginx", "-g", "daemon off;"]

请注意,在 构建应用程序 部分下,我现在做的是

RUN cp -r ./dist/. /usr/share/nginx/html

而不是

COPY ./dist/my-app /usr/share/nginx/html

副本将无法正常工作,因为我之前 运行 ng build 在容器内部 dist 也只存在于容器中,所以我需要在该容器内执行复制命令

我使用的是 openshift,权限有限,所以我使用以下 nginx 映像(而不是 nginx:latest)解决了这个问题

FROM nginxinc/nginx-unprivileged 

运行 下面的命令可以解决上面的问题。需要 anyuid 安全上下文约束。

oc adm policy add-scc-to-user anyuid system:serviceaccount:<NAMESPACE>:default

如果您在这里是因为未能部署示例 helm chart(例如:helm create mychart),请按照@quasipolynomial 的建议进行操作,但更改您的部署文件以拉取正确的图像。

containters: 
    - image: nginxinc/nginx-unprivileged 

关于官方非特权图像的更多信息:https://github.com/nginxinc/docker-nginx-unprivileged

您可以使用 nginx.conf 文件更改文件夹。您可以在 Running nginx as a non-root user.

部分阅读更多信息

可能是也可能不是朝着正确方向迈出的一步(对于那些来这里寻求有关 [emerg] mkdir() ... failed 错误的一般帮助的人尤其有帮助)。

此解决方案从 Builing nginx from source 开始计算。

我用了大概七个小时实现解决办法直接关系到编译nginx时设置的前缀路径

这是我的配置抛出 nginx 的地方(作为一个非常简短的例子),编译自 nginx source:

sudo ./auto/configure \
--prefix=/usr/local/nginx \
--http-client-body-temp-path=/tmp/nginx/client-body-temp \
--http-fastcgi-temp-path=/var/tmp/nginx/fastcgi_temp 

我在没有意识到的情况下将前缀设置为 /usr/local/nginx 但设置了 客户端主体临时路径 & fastcgi 临时路径/tmp/nginx.

内的目录

这基本上破坏了 nginx 访问正确文件的能力,因为临时路径与前缀路径不相关。

所以我修复了它(再次以超级简单的配置为例):

sudo ./auto/configure \
--prefix=/usr/local/nginx \
--http-client-body-temp-path=/usr/local/nginx/client_body_temp \
--http-fastcgi-temp-path=/usr/local/nginx/fastcgi_temp \

进一步简化:

sudo ./auto/configure \
--prefix=/usr/local/nginx \
--http-client-body-temp-path=/client_body_temp \
--http-fastcgi-temp-path=/fastcgi_temp \

再次强调,不能保证 工作,但绝对是朝着正确方向迈出的一步。

在我的 nginx:alpine Dockerfile

上有同样的错误

nginx:alpine 图像中已经有一个名为 nginx 的用户。我的猜测是将它用于 运行 nginx。

我是这样解决的:

  • /var/cache/nginx的所有者设置为nginx(用户101,组101)
  • 创建一个 /var/run/nginx.pid 并将所有者也设置为 nginx
  • 使用--chown=nginx:nginx
  • 将所有文件复制到图像
FROM nginx:alpine
RUN  touch /var/run/nginx.pid && \
     chown -R nginx:nginx /var/cache/nginx /var/run/nginx.pid
USER nginx
COPY --chown=nginx:nginx my/html/files /usr/share/nginx/html
COPY --chown=nginx:nginx config/myapp/default.conf /etc/nginx/conf.d/default.conf
...