Docker部署Nginx+PHP环境返回403 Forbidden问题求助
Nginx容器访问PHP文件返回403的解决方法
问题根源
对着你的运行日志、执行命令和现象核对下来,主要是三个容易踩的问题:
- Docker运行命令参数顺序错误:把本地路径参数误放到了镜像名的位置,Docker根本没正确把你本地的phpinfo文件挂载到容器内的web目录
- 索引文件不匹配:Nginx默认关闭了目录浏览功能,默认索引列表也只识别html、htm后缀的文件,访问根路径时找不到可返回的内容就会直接触发403
- PHP解析链路没打通:没有配置Nginx到PHP-FPM的请求转发规则,就算在Nginx容器里装了PHP,遇到.php后缀的请求还是只会当静态文件读取,权限不匹配就会直接返回403,根本不会执行PHP代码
分步操作解决
1. 先把Docker运行命令改对
docker run的固定参数顺序是:docker run [容器运行配置参数] 镜像名 [容器内执行命令],你原来的命令把本地路径/home/taufik/html插在了配置参数和镜像名中间,Docker会把这个路径当成镜像名称识别,跑起来的容器根本读不到你本地写的phpinfo文件。
正确的执行步骤:
# 先进入存放phpinfo文件的本地目录,让$(pwd)匹配实际文件路径 cd /home/taufik/Documents/praktikum/docker/30-mar-2021/sosial-media/html # 修正参数顺序,把nginx镜像名放在命令最后 docker run -it --rm -dp 8080:80 --name=nginx -v $(pwd):/usr/share/nginx/html nginx
2. 解决根路径访问403的问题
从日志里的报错directory index of "/usr/share/nginx/html/" is forbidden就能看出来,Nginx在web根目录下找不到默认索引文件,又因为安全策略不让展示目录列表,所以直接返回403。
两种快速解决方式:
- 直接访问具体的PHP文件路径:比如你的phpinfo文件叫
info.php,就直接访问http://0.0.0.0:8080/info.php,别直接敲根路径 - 把你的phpinfo文件重命名为
index.php,匹配Nginx的默认索引识别逻辑
3. 打通PHP解析流程
把所有组件塞到Nginx同一个容器里不是合理的容器用法,而且就算装了PHP,没有转发规则Nginx也不会自动把PHP请求交给PHP-FPM处理。最小成本的可行部署流程分三步:
- 先启动PHP-FPM容器,挂载同样的web目录:
docker run -it --rm -dp 9000:9000 --name=php-fpm -v $(pwd):/usr/share/nginx/html php:fpm - 在本地新建Nginx配置文件
default.conf,加上PHP请求转发规则:server { listen 80; server_name localhost; root /usr/share/nginx/html; # 把index.php加入默认索引列表 index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php?$query_string; } # 所有.php后缀的请求统一转发给PHP-FPM容器处理 location ~ \.php$ { fastcgi_pass php-fpm:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } } - 给两个容器搭内部通信网络,重启Nginx容器并挂上自定义配置:
# 创建Docker内部网络,让两个容器可以用容器名互相访问 docker network create app-net # 把正在运行的两个容器都加入这个网络 docker network connect app-net nginx docker network connect app-net php-fpm # 停掉之前启动的Nginx容器,挂载自定义配置重新启动 docker stop nginx docker run -it --rm -dp 8080:80 --name=nginx \ --network app-net \ -v $(pwd):/usr/share/nginx/html \ -v $(pwd)/default.conf:/etc/nginx/conf.d/default.conf \ nginx
4. 最后排查权限问题
做完前面的操作如果还是报403,就进Nginx容器检查一下挂载文件的权限:
docker exec -it nginx ls -l /usr/share/nginx/html
Nginx进程在容器内是用www-data用户运行的,如果本地文件权限设置成了只有root能读,容器内的进程就会因为读不到文件返回403。只需要给本地web目录加上全局可读权限即可:
chmod -R 755 /home/taufik/Documents/praktikum/docker/30-mar-2021/sosial-media/html
内容的提问来源于stack exchange,提问作者Taufik Maulana
相关产品推荐
相关产品推荐

