作为一个PHPer,没有手动搭过几次LNMP环境,都不算是一个真正的PHPer。此文主要以实际着手搭建一套lnmp环境为主线,介绍其中涉及到的技术点。包括php配置、php-fpm配置、nginx配置、mysql配置。以及这他们之间的关系。
2 准备工作
2.1 软件下载
- Linux: CentOS6.5
- Nginx: 1.13.4,下载地址:http://nginx.org/download/nginx-1.13.4.tar.gz
- Mysql: 5.6.37,下载地址:https://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.37.tar.gz
- PHP: 5.5.38,下载地址:http://cn2.php.net/distributions/php-5.5.38.tar.gz
在/usr/local目录下创建我们的LNMP安装目录,我们这里定义为lnmp。
1 | mkdir -p /usr/local/lnmp/src |
为了方便知道我们安装的软件版本,故目录命名均采用软件名-三位版本号的形式:
1 | mkdir /usr/local/lnmp/php-5.5.38 |
2.2 工具安装
本实验所有的安装都是根据源码进行编译安装,编译此三软件,需要使用到的工具有:
cmake
cmake是一款开源跨平台的编译工具,其包含编译构建、测试打包等一体的工具包。其[官网](https://cmake.org/)。mysql官方文档记载说mysql 5.6版本源码编译安装需要使用cmake。其下载地址:[https://cmake.org/files/v3.9/cmake-3.9.1.tar.gz](https://cmake.org/files/v3.9/cmake-3.9.1.tar.gz) ,当然,我们也可以去github:[https://github.com/Kitware/CMake/archive/v3.9.1.tar.gz](https://github.com/Kitware/CMake/archive/v3.9.1.tar.gz) ,这里也提醒大家,所有开源软件基本都可以在github上找到,开源的世界就是这么好。感恩!
GCC(version >= 4.2.1)
作为RD应该都听说过GCC(the GNU Compiler Collection),即GNU编译套件集合,是由 GNU 开发的编程语言编译器。它是以[GPL](https://baike.baidu.com/item/GPL)许可证所发行的自由软件。其包括C、C++、Objective-C、Fortran、Java、Ada和Go语言的前端,也包括了这些语言的库(如libstdc++、libgcj等等)。GCC的初衷是为GNU操作系统专门编写的一款编译器。GNU系统是彻底的自由软件。此处,“自由”的含义是它尊重用户的自由。这里不展开讲解,感兴趣的同学可以去查阅相关资料,这里给出[官网](http://gcc.gnu.org/)
make(version >= 3.75)
又叫GNU Make,此软件是GNU系列的编译软件,其[官网](http://www.gnu.org/software/make/),其[使用手册](http://www.gnu.org/software/make/manual/make.html),既然在linux下编译软件,此软件几乎是少不了的。
autoconf:
又一款GNU下的软件,Autoconf是一个用于包,以适应多种[Unix](https://baike.baidu.com/item/Unix/219943)类系统的 [shell脚本](https://baike.baidu.com/item/shell%E8%84%9A%E6%9C%AC/572265)的工具,其[官网](http://www.gnu.org/software/autoconf/autoconf.html),[使用手册](http://www.gnu.org/software/autoconf/manual/autoconf.html),此软件和make基本结对出现。
bison(version >= 2.1)
GNU bison 是属于 [GNU](https://baike.baidu.com/item/GNU) 项目的一个[语法分析器](https://baike.baidu.com/item/%E8%AF%AD%E6%B3%95%E5%88%86%E6%9E%90%E5%99%A8)生成器。Bison 把一个关于“向前查看 从左到右 最右”(LALR) 上下文无关文法的描述转化成可以分析该文法的 C 或 [C++](https://baike.baidu.com/item/C%2B%2B) 程序。它也可以为二义文法生成 “通用的 从左到右 最右” (GLR)语法分析器。其[官网](http://www.gnu.org/software/bison/),[使用手册](http://www.gnu.org/software/bison/manual/)
mysql源码编译安装依赖 https://dev.mysql.com/doc/refman/5.6/en/source-installation.html
3 Nginx安装
3.1 编译安装
1 | #解压源码文件 |
3.2 软件配置
为了能够让我们的软件运行起来,我们最开始只做最简单的配置。
3.2.1 nginx.conf
1 | #user nobody; |
3.2.2 vhost
因为软件可能运行不止一个网站,故我们在nginx的conf目录下创建vhost目录,用于存放虚拟主机。同时为了把业务项目与运行环境分开,这里我们将代码目录建在/data0/www/htdocs/lnmp.com目录下,我们的网站就叫lnmp.com吧。
1 | server { |
3.3 测试
检测安装是否成功,进入 /usr/local/lnmp/nginx-1.13.4/sbin目录,执行 ./nginx -t
命令,若输出如下信息,则表示安装成功。
nginx: the configuration file /usr/local/lnmp/nginx-1.13.4/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/lnmp/nginx-1.13.4/conf/nginx.conf test is successful
否则,跟进提示进行修正,如我修改完配置文件执行时,报错如下
nginx: [emerg] unexpected “}” in /usr/local/lnmp/nginx-1.13.4/conf/nginx.conf:72
nginx: configuration file /usr/local/lnmp/nginx-1.13.4/conf/nginx.conf test failed
提示很明显,因为nginx.conf文件72行遇到了不接受的”}”符号,打开文件发现其实在include vhost/*.conf后忘记添加分号,添加上分号,再次执行,提示成功。
3.3 使用解读
nginx安装完毕后,目录如下:
1 | . |
3.3.1 sbin
这里我们先说sbin目录,其中只有一个文件nginx可执行文件,此文件用于管理nginx的启动、停止、重启。
nginx命令支持以下参数:
-v :显示版本号并退出
-V:显示版本号,同时显示编译时选项并退出
-t:测试配置文件,并退出
-T:测试配置文件,并将其输出,然后退出
-s signal:发送信号给nginx master,用于平滑停止,退出,平滑重启,重启。signal包括(stop|quit|reload|reopen)
-c:指定nginx的配置文件,默认为conf/nginx.conf
-g:设置配置文件之外的全局指令,用的比较少
nginx启动
使用默认的配置文件:
1 | /usr/local/lnmp/nginx-1.13.4/sbin/nginx |
使用指定的配置文件:
1 | /usr/local/lnmp/nginx-1.13.4/sbin/nginx -c /path/配置文件 |
nginx停止
1 | /usr/local/lnmp/nginx-1.13.4/sbin/nginx -s stop |
对于nginx的关闭,还可以使用kill命令:
1 | kill -QUIT 主进程pid 或 kill -QUIT `cat /path/pid` 从容关闭 |
但我们推荐使用./nginx -s stop命令
nginx重启
1 | /usr/local/lnmp/nginx-1.13.4/sbin/nginx -s reload |
对于重启,还可以使用kill命令:
1 | kill -USR2 `cat /path/pid` |
3.3.2 conf
nginx配置文件主要为nginx.conf,这里我们就来详细解读下其中的相关配置指令及含义。
nginx的强大都是靠配置文件来实现,nginx就是一个二进制文件,nginx读入一个配置文件nginx.conf(nginx.conf可能include包含若干子配置文件)来实现各种各样的功能。我们分段来介绍nginx.conf文件。
3.3.2.1 全局配置段
1 | worker_processes 1; |
这些是配置文件开始的默认行。通常的环境下,你不需要修改这些选项。这一部分有几个方面需要我们注意:
- 所有以#号开的行是注释,nginx不会解析。默认的配置文件有许多说明解释的注释块
- 指令是以一个变量名开头(例如,worker_processes或pid),然后包含一个参数(例如,1或 logs/nginx.pid)或者多个参数(例如,”logs/error.log notice”)
- 所有指令以分号结尾
- 某些指令,像上面的
events
可以包含多个子指令作为参数。这些子指令以花括号包围。 - 虽然nginx不解析空白符(例如tab,空格,和换行符),但是良好的缩进能提高你维护长期运行配置文件的效率。良好的缩进使配置文件读起来更流畅,能让你很容易明白配置的策略,即使几个月前。
3.3.2.2 http段
官方定义如下:
1 | Syntax: http { ... } |
本实践示例如下:
1 | http { |
“http { }”块的开头像配置文件的开头一样都是标准配置不需要修改。这里我们需要把注意力放在这些元素上:
- 这部分内容的开始”include”语句包含/usr/local/lnmp/nginx-1.13.4/conf/mime.types文件到nginx.conf文件include语句所在位置。include对ningx.conf文件的可读性和组织性很有用。
- 不能过多使用include,如果太多递归地include文件会产生混乱,所以需要合理有限制地使用include来保证配置文件的清晰和可管理。
- 你可以去掉log_format指令前的注释并修改这几行设置的变量为你想记录的信息。
- gzip指令告诉nginx使用gzip压缩的方式来降低带宽使用和加快传输速度。如果想使用gzip压缩,需要添加如下配置到配置文件的gzip位置。
- include vhost/*.conf;表示包含的虚拟主机配置,这将在下一段讲解。
3.3.2.3 server段
虚拟主机配置指令块为server,其包含与http指令块中,为了方面我们配置,我们将其独立出来,通过include指令将其包含进入http指令块中去。
1 | Syntax: server { ... } |
本实践配置示例:
1 | server { |
listen:指令告诉nginx在一个特定的hostname,ip或者tcp端口监听连接。默认,http服务运行在80端口。以下这些listen指令都是有效的
1
2
3
4 > listen 127.0.0.1:80;
> listen localhost:80;
> listen 12.34.56.79:80;
>
server_name:指令可以设置基于域名的虚拟主机,根据请求头部的内容,一个ip的服务器可以配置多个域名。以下这些配置均是可以的
1
2
3 > server_name lnmp.com www.lnmp.com;
> server_name *.lnmp.com;
>
多个域名之间以空格分隔。nginx允许一个虚拟主机有一个或多个名字,也可以使用通配符”*”来设置虚拟主机的名字。
access_log:用于配置虚拟主机日志,以下配置均可以。第一个使用相对路径,日志存储在/usr/local/lnmp/nginx-1.13.4/logs/lnmp.access.log中,第二个使用绝对路径,第三个表示不记录日志到文件。第一行参数有两个,第一个表示日志文件,第二个表示日志类型
1
2
3
4 > access_log logs/lnmp.access.log main;
> access_log /data0/www/logs/lnmp.access.log main;
> access_log off;
>
location指令
1 | 语法: location [ = | ~ | ~* | ^~ ] uri { ... } |
语法解释:
~ :波浪线表示执行一个正则匹配,区分大小写
~* :表示执行一个正则匹配,不区分大小写
^~ :^~表示普通字符匹配,如果该选项匹配,只匹配该选项,不匹配别的选项,一般用来匹配目录
= :进行普通字符精确匹配
@ :”@” 定义一个命名的 location,使用在内部定向时,例如 error_page, try_files
location分类:
普通location(无任何前缀的、”=”、”^~ “、”@”均表示普通location)
1)严格精确匹配
2)最长前缀匹配
- 正则location(“~ ”和“~* ”前缀表示正则location)
注:“^~ ”符号(^ 表示“非”,~ 表示“正则”,字符意思是:不要继续匹配正则)
location匹配顺序:
正则 location 匹配让步普通 location 的严格精确匹配结果;但覆盖普通 location 的最大前缀匹配结果。详细解释下就是:优先普通location匹配中的严格精确匹配,若没有命中严格精确匹配,则进行最长前缀匹配,若命中一个最长前缀匹配,则先暂时将其定为优先选择,接着进行正则匹配,若正则匹配命中,则使用正则匹配到的结果覆盖之前的最长前缀匹配结果。这里并不是所有的普通location都会进行后续的正则搜索匹配,若最长前缀匹配结果是”^~” 和 “=”,则会阻止后续的正则匹配,直接使用此结果。
location物理位置:
对于location之间的配置顺序,普通location 与其无关,正则location 与其有关的。
location示例:
1 | location = / { |
- “/“ 请求将会匹配配置A,因为其为普通location里的严格精确匹配,结束匹配。
- “/index.html” 将会匹配配置B,此为前缀字符串匹配(普通匹配之后的正则搜索没有匹配到)
- “/documents/index.html” 将会匹配配置C,先进行普通匹配,命中C,后续进行正则匹配,没有命中,故使用最长前缀匹配到的结果,所以最终匹配C。
- “/images/1.gif” 将会匹配配置D,普通location最长前缀匹配成功后,不在匹配正则匹配
- “/documents/1.jpg” 将会匹配配置E,最长前缀匹配到C,继续搜索正则,后正则匹配到E,则最终匹配到E
更多nginx配置指令请移步官方文档:http://nginx.org/en/docs/
4 mysql安装
4.1 编译安装
1 | #添加mysql用户组 |
1 | #在测试库创建测试用户表 |
4.2 配置
官方文档,mysql启动时,需要加载my.cnf配置文件,加载查找路径为:/etc/my.cnf > $basedir/my.cnf 本实践中查找路径为/usr/local/lnmp/mysql-5.6.37/my.cnf
1 | [client] |
这些配置在默认生成的文件中都没有,mysql支持启动时设置参数。
4.3 启动
对于mysql的启动,方式比较多
mysqld_safe启动
1 | /usr/local/lnmp/mysql-5.6.37/bin/mysqld_safe --user=mysql |
mysqld启动
1 | /usr/local/lnmp/mysql-5.6.37/bin/mysqld --user=mysql --explicit_defaults_for_timestamp |
init.d启动:需要将support-files/mysql.server拷贝到/etc/init.d/mysql.server
1 | cp support-files/mysql.server /etc/init.d/mysql.server |
5 PHP安装
5.1 编译安装
1 | #解压源文件 |
5.2 配置PHP
PHP配置包括两部分,一部分是fpm的配置,因为我们nginx和php进行交互是采用fpm的形式进行的;另一部分为php.ini,php全局配置。php.ini去源码目录拷贝一份便可。
php.ini
存放目录:/usr/local/lnmp/php-5.5.38/lib,基本上安装完毕,拷贝到此目录基本不需要修改即可运行,这里我们简单罗列一些基本的配置。
1 | [PHP] |
php-fpm.conf
1 | [global] |
6 遇到的问题
6.1 nginx到php
问题描述:2017/08/12 23:27:22 [error] 13752#0: *10 FastCGI sent in stderr: “Primary script unknown” while reading response header from upstream, client: 127.0.0.1, server: localhost, request: “GET /index.php HTTP/1.1”, upstream: “fastcgi://127.0.0.1:9000”, host: “127.0.0.1:9091”
这里的问题是nginx配置里到fpm的代理配置有问题:
fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
将此处修改为
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
说明:
$document_root 代表当前请求在root指令中指定的值,上面配置中的$document_root就是针对/data0/www/htdocs/lnmp.com目录下的php文件进行解析
6.2 其他问题
在安装过程中若遇到其他问题,均可以根据错误提示信息找到答案,google、百度都可以帮助你解决问题。