我目前在尝试在 Openshift 中设置 nginx:alpine 时遇到问题。
我的构建运行得很好,但我无法在权限被拒绝的情况下进行部署,并出现以下错误
2019/01/25 06:30:54 [紧急] 1#1:mkdir()“/var/cache/nginx/client_temp”失败(13:权限被拒绝)
nginx:[emerg] mkdir()“/var/cache/nginx/client_temp”失败(13:权限被拒绝)
现在我知道 Openshift 在权限方面有点棘手,因为容器在没有 root 权限的情况下运行,并且 UID 是在 runetime 上生成的,这意味着它在 /etc/passwd 中不可用。但该用户是 root 组的一部分。现在这里描述了应该如何处理这个问题
我什至更进一步,使整个 /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
有趣的是,这种方法似乎只影响 alpine 版本的 nginx。 nginx:latest (我认为基于 debian) 没有问题,设置方法在这里描述
https://torstenwalter.de/openshift/nginx/2017/08/04/nginx-on-openshift.html
有效。 (但我在该版本中遇到了一些其他问题,所以我切换到高山)
有什么想法为什么这仍然不起作用吗?
我使用的是 openshift,权限有限,所以我使用以下 nginx 镜像(而不是
nginx:latest
)解决了这个问题
FROM nginxinc/nginx-unprivileged
解决这个问题。我认为这个 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 也只存在于容器中,所以我需要在该容器内执行复制命令
nginx:alpine
Dockerfile
也有同样的错误
nginx
图像中已经有一个名为
nginx:alpine
的用户。我的猜测是用它来运行 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
...
[emerg] mkdir() ... failed
错误的一般帮助的人特别有帮助)。
此解决方案来自 Builing nginx from source意识到解决方案与编译nginx时设置的前缀路径有直接关系。 这就是我的配置抛出 nginx 的地方(作为一个非常简单的例子),从这个
nginx 源编译而来:
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.conf 文件更改文件夹。您可以在
以非root用户身份运行nginx输出: 注释:
openshift.io/sa.scc.supplemental-groups=1001240000/10000
openshift.io/sa.scc.uid-range=1001240000/10000
Nginx 配置文件(示例):
nginx_default.conf
server {
listen 4200;
server_name supp-homolog.procuradoria.go.gov.br;
sendfile on;
default_type application/octet-stream;
gzip on;
gzip_http_version 1.1;
gzip_disable "MSIE [1-6]\.";
gzip_min_length 1100;
gzip_vary on;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
gzip_comp_level 9;
root /usr/share/nginx/html;
location / {
try_files $uri $uri/ /index.html =404;
}
}
user root;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
FROM nginx:alpine as build
RUN chgrp -R 1001240000 /var/cache/nginx /var/run /var/log/nginx && \
chmod -R 770 /var/cache/nginx /var/run /var/log/nginx && \
chown -R 1001240000 /run
COPY --chown=1001240000:1001240000 docker/dev/nginx.conf /etc/nginx/nginx.conf
COPY --chown=1001240000:1001240000 docker/dev/nginx_default.conf /etc/nginx/conf.d/default.conf
HEALTHCHECK --interval=5s --timeout=3s CMD curl --fail http://localhost:4200/ || exit
EXPOSE 4200
CMD ["nginx", "-g", "daemon off;"]
运行以下命令来修复上述问题。需要 anyuid 安全上下文约束。