解决Nginx报错Permission denied和Primary script unknown技术
作为程序员,当我去开发的时候,会尽量的做到简单。也就是随时随地都可以开发,尽量的零配置。所以首选当然是语言自带的轻量级服务器。
但是 PHP7.1 实在是太不争气了。PHP7 自带的服务器有个毛病,不能正确加载静态资源,也就是只要你访问的 URL 是以 .js .css .jpg 等后缀结尾的,它都认为这是静态资源,如果这个静态文件或文件夹不存在,就直接返回 404。按理来讲,PHP7 不应该出现这样低级的 Bug。也许一个人技术再牛逼,没有实战经验做出来的东西还是不行的。技术人员的阶层已经出现了,做底层的人只知道底层,完全不理解应用层的业务逻辑,这样自作聪明是很傻的。
所以,当 PHP7 有了这么低级的 Bug 之后,我就屁颠屁颠的去配置一下 Nginx 来开发吧。
且看我如下 Nginx 的配置:
server { listen 7777; server_name 192.168.1.250; error_log /var/log/nginx/port_7777.error.log; charset utf-8; root /home/may/work/code/repo/lmlphp.com; index index.html index.php; location / { fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #return 200 "$document_root $fastcgi_script_name"; try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/run/php-fpm/php-fpm.sock; fastcgi_split_path_info ^(.+\.php)(.*)$; include fastcgi_params; } }
Nginx 的配置依然是很简单,随便在已加载的配置文件中加入上述代码片段即可。
细心的人一定看到,我天生喜欢在 home 目录下保存自己的东西,养成这个习惯也许是用户登录之后默认进入到用户自己的目录下。于是我在用户目录下建立了 work 文件夹,下面又建立了 code 文件夹,真正到项目文件夹已经很深了。所以这样的地址 Nginx 肯定是没有权限访问到的。Nginx 没有权限访问并不是因为这个目录很深,最重要的关卡就在用户目录 /home/may 这里。一般的 Linux 发行版用户的 home 目录默认情况下同组用户和其他用户都是没有权限访问的,也就是 700 权限。
想了一下,最简单的方法那就是 sudo chmod o+x /home/may,更傻逼的办法当然是 sudo chmod -R 777 /home/may。但这样做总是不安全的,比较好的办法就是将 Nginx 和 php-fpm 的运行用户 http 添加到用户 may 的组别中。于是:
$ sudo usermod -a -G may http $ chmod g+x /home/may
在没有执行上述命令之前,Nginx 的错误日志文件中会出现如下错误:
2016/12/28 20:16:43 [crit] 10666#10666: *42 stat() "/home/may/work/code/repo/lmlphp.com/" failed (13: Permission denied), client: 192.168.1.125, server: 192.168.1.250, request: "GET / HTTP/1.1", host: "192.168.1.250:7777"
执行了之后,还是会报错,只不过错误信息变成如下所示:
2016/12/28 20:39:49 [error] 12704#12704: *101 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream, client: 192.168. 1.125, server: 192.168.1.250, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php-fpm/php-fpm.sock:", host: "192.168.1.250:7777"
在浏览器中访问,返回 File not found。
在网上找了半天错误,关于 Primary script unknown 的,硬是没有一个能解决问题的。
最后发现问题是因为我忘记了重启 php-fpm 了,这个报错太诡异了啊。重启 php-fpm 之后就 OK 了。
$ sudo systemctl restart nginx.service $ sudo systemctl restart php-fpm.service
最开始,报 Primary script unknown 的错误我没有想到是权限问题导致,是因为我直接将权限改成 o+x 时是可以正常访问的,这种方式无需重启 php-fpm。但是,如果是通过添加组和改变组的访问权限来解决问题时,必须要重启 php-fpm 才能访问。
不得不说,Linux 的权限是最难理解的一部分,组别权限的更新必须退出登录才能生效,这里面估计只有真正看懂了内核源码的人才完全明白吧,市面上的那些讲技术的书籍的作者大部分也都是半桶水,说不清楚的。