Docker 上的 Nginx 无法访问绑定挂载

Docker 上的 Nginx 无法访问绑定挂载

概括:

我正在尝试将 Nginx 容器设置为 Docker 堆栈的一部分。我想使用绑定挂载使计算机上的文件夹可供容器使用/data/www,并将其用作 Nginx 提供内容的根文件夹。Nginx 容器构建并启动时没有任何错误,并且端口公开为8080;但是,如果我实际尝试转到localhost:8080,我会收到 HTTP 403 错误。

细节:

以下是我的项目的相关文件夹结构:

/frontend
  /static
    index.html
  frontend.dockerfile
  nginx.conf
docker-compose.yml

该文件夹/frontend/static是我尝试作为绑定挂载卷添加到 Nginx 容器的文件夹。

docker-compose.yml

version: '3.7'

services:
  frontend:
    build:
      context: frontend
      dockerfile: frontend.dockerfile
    ports:
      - 8080:80
    volumes:
      - type: bind
        source: ./frontend/static
        target: /data/www
        read_only: true

前端.docker文件

FROM nginx:1.16-alpine
EXPOSE 80
COPY nginx.conf /etc/nginx/nginx.conf

nginx.conf

events {
}

http {
  server {
    listen 80;

    location / {
      root /data/www;
    }
  }
}

当我运行 时docker-compose up,容器构建并启动没有任何问题,但是当我localhost:8080在浏览器中输入时,我得到 HTTP 403,并且在 docker 控制台中出现以下错误:

frontend_1  | 172.18.0.1 - - [04/Aug/2019:22:15:50 +0000] "GET / HTTP/1.1" 403 555 "-" "Mozilla/5.0 (X11; Fedora; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.87 Safari/537.36"
frontend_1  | 2019/08/04 22:15:50 [error] 7#7: *1 "/data/www/index.html" is forbidden (13: Permission denied), client: 172.18.0.1, server: , request: "GET / HTTP/1.1", host: "localhost:8080"

因此,Nginx 显然接收了 HTTP 请求并尝试提供内容(在本例中为index.html),但它无权访问文件夹/data/www(即绑定挂载卷)中的任何文件。

我正在运行 Fedora 30。项目本身位于我的主文件夹中:~/Dev/sandbox。我在项目文件夹中使用了chmod -R 755 frontend/static来授予需要绑定的文件夹的权限。

我也尝试过使用非 Alpine 版的 Nginx 镜像,没有什么区别。

答案1

这显然是权限问题。请检查文档根目录“/data/www/”是否归 Nginx 用户所有。您也可以通过使用以下命令进入容器来更改所有权。

docker exec -it bash

请尝试一下并回复您发现的错误,我们将尽力解决它。

答案2

由于源的相对路径,compose 的执行上下文可能未指向您想要的位置。如果卷已绑定在 docker-compose.yml 文件中,而主机上的源(尚)不存在,Docker 还会在主机上(而不仅仅是在容器中)创建一个前端/静态目录(仅具有 root 权限)。使用 sudo 在主机上找到并删除此目录。然后将源指向绝对路径,而不是相对路径。

答案3

这确实是权限问题;具体来说,是 SELinux 权限问题。尽管chmod挂载卷的权限设置为 755,docker但根据 SELinux 更严格的规则,用户(Docker 容器在其下执行)仍然无权访问它。

由于这只是在我的计算机上发生的,而且我不想花 24 小时深入研究 SELinux 权限,所以我只是永久切换到permissive模式,我的问题就顺利解决了。

答案4

docker-compose.yml:

version: '3.7'

services:
  frontend:
    build:
      context: frontend
      dockerfile: frontend.dockerfile
    ports:
      - "8080:80"
    volumes:
      - ./frontend/static:/data/www:ro

前端.docker文件

FROM nginx:1.16-alpine
COPY nginx.conf /etc/nginx/nginx.conf

nginx.conf

events {}

http {
  server {
    listen 80;

    location / {
      root /data/www;
    }
  }
}

确保您已调整主机上的文件权限,如前面的回复中所述。使用此简化的设置,它应该以只读模式将主机上的 ./frontend/static 文件夹绑定到容器内的 /data/www 文件夹。

尝试再次运行 docker-compose up 并在浏览器中访问 localhost:8080。如果问题仍然存在,则问题可能与主机上的文件权限或 SELinux 设置有关。

相关内容