概括:
我正在尝试将 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 设置有关。