一、LNMP介绍
LNMP是一组众所周知的Web网站服务器架构环境,即由Linux+Nginx+MySQL+PHP(MySQL有时也指 Mariadb)组合成一个高性能、轻量、稳定、扩展性强的Web网站服务器架构环境。
Nginx (“engine x”)是一个轻量级、高性能的HTTP和反向代理服务器,负载均衡服务器。Nginx的官方网站为nginx.org。MySQL分为社区版和商业版,本课程也将以社区版为基础进行讲解。PHP是一个使用者最多、运行最快、入门最简单的脚本语言。
本课程以RHEL9为例,进行安装配置之前,建议先关闭防火墙和selinux。
1、关闭firewalld
[root@localhost ~]# systemctl stop firewalld.service
[root@localhost ~]# systemctl disable firewalld.service
2、关闭selinux
[root@localhost ~]# grubby --update-kernel ALL --args selinux=0
然后修改:
/etc/selinux/config,将“SELINUX=enforcing”改为“SELINUX=disabled”
最后,重启系统。
二、源码编译、安装Nginx
Nginx可以通过源码方式、yum方式进行安装,根据线上环境运维部署经验,推荐采用源码方式进行安装。
依赖安装:
[root@localhost ~]# yum -y install zlib pcre pcre-devel openssl openssl-devel
创建nginx用户www:
[root@localhost ~]# useradd -s /sbin/nologin www
[root@localhost ~]# id www
uid=501(nginx) gid=501(www) groups=501(www)
Nginx有很多编译参数,这里仅列出常用的一些参数,configure过程如下:
[root@localhost ~]# tar zxvf nginx-1.26.3.tar.gz
[root@localhost ~]# cd nginx-1.26.3
[root@localhost nginx-1.26.3]# ./configure \
--prefix=/usr/local/nginx \
--sbin-path=/usr/local/nginx/sbin/nginx \
--conf-path=/usr/local/nginx/conf/nginx.conf \
--error-log-path=/usr/local/nginx/logs/error.log \
--http-log-path=/usr/local/nginx/logs/access.log \
--pid-path=/usr/local/nginx/logs/nginx.pid \
--with-http_stub_status_module \
--with-http_ssl_module \
--with-http_gzip_static_module \
--with-pcre
[root@localhost nginx-1.26.3]# make
[root@localhost nginx-1.26.3]# make install
其中,每个编译参数的含义如下所示:
--prefix 指定Nginx程序的安装路径
--sbin-path 设置Nginx二进制文件的路径名
--conf-path 指定Nginx配置文件路径
--error-log-path 指定Nginx错误日志文件路径
--http-log-path 指定Nginx访问日志文件路径
--pid-path 设置Nginx的pid文件nginx.pid的路径
--lock-path 设置Nginx的lock文件nginx.lock文件路径
--with-openssl 指定OpenSSL源码包的路径,如果编译的时候没有指定“--with-openssl”选项,那么默认会使用系统自带的openssl库
--with-pcre 设置Nginx启用正则表达式
--with-http_stub_status_module 安装用来监控Nginx状态的模块
--with-http_ssl_module 表示启用Nginx的SSL模块,此模块依赖“--with-openssl”这个选项,通常一起使用。
--with-http_gzip_static_module 表示启用Nginx的gzip压缩.
编写nginx管理脚本nginx.service,内容如下:
[root@localhost ~]# vi /etc/systemd/system/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/bin/rm -f /usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillSignal=SIGQUIT
TimeoutStopSec=5
KillMode=process
PrivateTmp=true
[Install]
WantedBy=multi-user.target
接着,就可以通过systemctl管理nginx服务了。
[root@localhost ~]# systemctl daemon-reload #重载nginx服务
[root@localhost ~]# systemctl start nginx #启动nginx服务
[root@localhost ~]# systemctl stop nginx #关闭nginx服务
[root@localhost ~]# systemctl enable nginx #设置nginx服务开机自启动
[root@localhost ~]# systemctl status nginx #查看nginx服务运行状态
三、二进制部署mysql
Mysql有多种部署方式,这里以二进制方式来进行安装,mysql安装包可从官方网站获取,这里用mysql-8.4.3-linux-glibc2.28-x86_64.tar.xz,安装过程如下:
[root@mysqlserver ~]# cd /usr/local/
[root@mysqlserver local]# tar xvf mysql-8.4.3-linux-glibc2.28-x86_64.tar.xz
[root@mysqlserver local]# mv mysql-8.4.3-linux-glibc2.28-x86_64 mysql
[root@mysqlserver local]# mkdir /usr/local/mysql/data
[root@mysqlserver local]# mkdir /usr/local/mysql/etc
[root@mysqlserver local]# mkdir /usr/local/mysql/logs
[root@mysqlserver local]# useradd mysql
然后,创建一个mysql配置文件,继续执行如下操作:
[root@mysqlserver ~]# vim /usr/local/mysql/etc/my.cnf
[mysqld]
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
log-error=/usr/local/mysql/logs/mysqld.log
pid-file=/usr/local/mysql/logs/mysqld.pid
接着,给mysql授权,并执行初始化操作:
[root@mysqlserver ~]# chown -R mysql:mysql /usr/local/mysql
[root@mysqlserver ~]# cd /usr/local/mysql
[root@mysqlserver mysql]# bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
[root@mysqlserver mysql]# rm -rf /etc/my.cnf
接着,再写一个mysql服务管理脚本/etc/systemd/system/mysqld.service,内容如下:
[Unit]
Description=MySQL Server
After=network.target
[Service]
User=mysql
Group=mysql
ExecStart=/usr/local/mysql/bin/mysqld_safe --defaults-file=/usr/local/mysql/etc/my.cnf
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/bin/kill -TERM $MAINPID
Restart=on-failure
[Install]
WantedBy=multi-user.target
然后启动服务:
[root@mysqlserver ~]# systemctl daemon-reload
[root@mysqlserver ~]# systemctl start mysqld
Mysql启动成功后,需要重置root密码,临时密码在上面定义的mysql日志文件/usr/local/mysql/logs/mysqld.log中可以查到。找到临时密码后,执行如下sql
[root@mysqlserver ~]# /usr/local/mysql/bin/mysql -uroot -p
输入临时密码:
进入sql命令行后,执行如下命令,修改root密码:
SQL> alter user 'root'@'localhost' identified by 'abc123456';
到这里为止,mysql服务部署完成。
四、源码编译、安装PHP
1、依赖库安装
安装依赖库推荐通过yum来在线安装,操作如下:
[root@localhost ~]# yum install libxml2 libxml2-devel bzip2 bzip2-devel libjpeg-turbo libjpeg-turbo-devel libpng libpng-devel freetype freetype-devel zlib zlib-devel libcurl libcurl-devel libjpeg libjpeg-devel libpng libpng-devel libxml2 libxml2-devel zlib zlib-devel curl curl-devel openssl openssl-devel sqlite-devel libzip
2、编译安装PHP
[root@localhost ~]# tar zxvf php-8.4.5.tar.gz
[root@localhost ~]# cd php-8.4.5
[root@localhost php-8.4.5]# ./configure --prefix=/usr/local/php --enable-fpm --with-fpm-user=nobody --with-fpm-group=nobody --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd --with-zlib --with-curl --enable-gd --with-jpeg=/usr --with-freetype=/usr --with-openssl --enable-mbstring --enable-xml --enable-session --enable-ftp --enable-pdo -enable-tokenizer --with-zip
[root@localhost php-8.4.5]# make
[root@localhost php-8.4.5]# make install
[root@localhost php-8.4.5]# cp php.ini-production /usr/local/php/lib/php.ini
[root@localhost php-8.4.5]# cp sapi/fpm/php-fpm.service /usr/lib/systemd/system/
其中:
–with-pdo-mysql=mysqlnd
表示使用mysqlnd驱动,这里选项涉及两个概念,一个是pdo,另一个是mysqlnd.
- PDO是PHP Data Objects的缩写,它是PHP应用中的一个数据库抽象层规范。PDO提供了一个统一的API接口可以使得PHP应用不用去关心具体要连接的数据库类型,也就是说,如果使用PDO的API,可以在任何需要的时候无缝切换数据库服务器,比如从Oracle到MySQL,仅仅需要修改很少的PHP代码。它的功能类似于JDBC、ODBC、DBI之类接口。因此,这里的”–with-pdo-mysql”就是PHP与MySQL进行连接的方式。
- mysqlnd是mysql native driver的简写,它是由PHP官方提供的mysql驱动连接代码,它出现的目的是代替旧的libmysql驱动,而libmysql是mysql官方自带的mysql与php连接的驱动,从PHP5.3开始已经不推荐使用libmysql驱动,而建议使用mysqlnd,而在PHP7版本中,libmysql驱动已经被移除。
因此,在PHP7中,“–with-mysql=mysqlnd”的写法已经被废除。另外,由于mysqlnd内置于PHP源代码,因此在编译安装php时就不需要预先安装好mysql, 这将减化不少安装工作量。
- –with-mysqli=mysqlnd
mysqli叫做 “MySQL增强扩展”。也是PHP连接mysql数据库的一种方式,这里也使用mysqlnd驱动进行连接。
3、编译过程问题总结
(1)、php: 安装时提示Package ‘oniguruma’, required by ‘virtual:world’, not found
此问题是缺少oniguruma-devel-6.9.6-1.el9.6.x86_64.rpm包,此包课程提供了,直接安装即可:
[root@localhost ~]# rpm -ivh oniguruma-devel-6.9.6-1.el9.6.x86_64.rpm
(2)、Package ‘libzip’, required by ‘virtual:world’, not found
此问题需要手动编译安装libzip,过程如下:
[root@localhost ~]# wget https://libzip.org/download/libzip-1.11.3.tar.xz
[root@localhost ~]# tar -zxvf libzip-1.11.3.tar.gz
[root@localhost ~]# cd libzip-1.11.3
[root@localhost ~]# mkdir build
[root@localhost ~]# cd build
[root@localhost ~]# cmake ..
[root@localhost ~]# make &&make install
最后,使用如下命令检测是否安装成功:
[root@localhost ~]# pkg-config --libs libzip
或者
[root@localhost ~]# pkg-config --list-all|grep libzip
五、Nginx与PHP-FPM整合原理
PHP-FPM是一个第三方的FastCGI进程管理器,最先它是作为PHP的一个补丁来开发的,现在PHP-FPM已经集成到了PHP源码中,在安装PHP的时候,通过指定“–enable-fpm”选项即可启用PHP-FPM功能。
PHP-FPM管理的进程包含master进程和worker进程两种。master进程只有一个,主要负责监听端口,接收来自Web Server的请求,而worker进程则一般有多个(具体数量根据实际需要配置),每个进程内部都嵌了一个PHP解释器,是PHP代码真正执行的地方。
那么Nginx又是如何发送请求给PHP-FPM的呢,这就要从Nginx层面讲起了,我们知道,Nginx不仅仅是一个Web服务器,也是一个功能强大的代理服务器,除了进行http请求的代理,也可以进行许多其他协议请求的代理,包括本节介绍的与PHP-FPM相关的FastCGI协议。为了能够使Nginx理解FastCGI协议,Nginx提供了一个FastCGI模块来将http请求映射为对应的FastCGI请求,这样,Nginx就可以将请求发送给PHP-FPM了,也就实现了Nginx与PHP-FPM的集成。
1、PHP-FPM配置文件
[www]
user = www
group = www
listen = 127.0.0.1:9000
pm = dynamic
pm.max_children = 100
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 50
其中:
- user和group用于设置运行php-fpm进程的用户和用户组。
- listen是配置php-fpm进程监听的IP地址以及端口,默认是127.0.0.1:9000
- pm.max_children用于设置php-fpm的进程数。
- pm:pm用来指定php-fpm进程池开启进程的方式,有两个值可以选择,分别是static(静态)和dynamic(动态)。
- pm.max_children:在static方式下表示固定开启的php-fpm进程数量,在dynamic方式下表示开启php-fpm的最大进程数。
- pm.start_servers:表示在dynamic方式下初始开启php-fpm进程数量。
- pm.min_spare_servers:表示在dynamic方式空闲状态下开启的最小php-fpm进程数量。
- pm.max_spare_servers:表示在dynamic方式空闲状态下开启的最大php-fpm进程数量,这里要注意pm.max_spare_servers的值只能小于等于pm.max_children的值。
2、配置Nginx来支持PHP
server {
listen 80;
server_name localhost;
location / {
index index.html index.htm index.php;
root html;
}
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
3、测试Nginx对PHP的解析功能
Nginx与PHP-FPM整合完成后,重启服务:
[root@localhost ~]# systemctl restart nginx
[root@localhost ~]# systemctl start php-fpm
此过程中,可能出现php-fpm无法启动的情况,检查php-fpm日志,会发现如下错误:
ERROR: failed to open error_log (/usr/local/php/var/log/php-fpm.log): Read-only file system (30)
此问题是/usr/lib/systemd/system/php-fpm.service脚本问题,需要修改/usr/lib/systemd/system/php-fpm.service文件,找到:
ProtectSystem=full
改成
ProtectSystem=false
当ProtectSystem这个值为true或full的时候,php-fpm进程将以只读的方式挂载 /usr 目录,这就是问题所在。
最后,重启php-fpm即可:
[root@localhost ~]# systemctl daemon-reload
[root@localhost ~]# systemctl start php-fpm
最后,创建一个phpinfo.php文件,内容如下:
<?php phpinfo(); ?>
然后通过浏览器访问http://ip/index.html,默认会在浏览器显示“Welcome to Nginx!”表示Nginx正常运行。接着在浏览器中访问http://ip/phpinfo.php,如果PHP能够正常解析,会出现PHP安装配置以及功能列表统计信息。
也可以通过如下命令查看PHP安装的模块信息:
[root@localhost ~]# /usr/local/php/bin/php -m
通过输出可以判断,目前已经成功安装了哪些模块,同时确认需要的模块是否已经正常安装,这里重点需要注意的是mysqli、mysqlnd、pdo_mysql、gd、curl、openssl、pcre等常用功能模块是否已经安装好。
4、测试PHP连接MySQL是否正常
(1)、mysqli方式连接MySQL的代码
<?php
$conn = mysqli_connect('127.0.0.1', 'root', 'mysqlabc123', 'mysql');
if(!$conn){
die("数据库连接错误" . mysqli_connect_error());
}else{
echo"数据库连接成功";
}
将上面代码写入文件mysqli.php,然后放到/usr/local/nginx/html/下面即可进行测试。
(2)、pdo-mysql方式连接MySQL的代码
<?php
try{
$pdo=new pdo('mysql:host=127.0.0.1;dbname=mysql','root','mysqlabc123');
}catch(PDDException $e){
echo "数据库连接错误";
}
echo "数据库连接成功";
?>
将上面代码写入文件pdo-mysql.php,然后放到/usr/local/nginx/html/下面即可进行测试。
六、在LNMP环境下部署应用项目
这里以wordpress为例,介绍下在LNMP环境下,如何部署和使用这套博客系统,WordPress 是一个基于 PHP 和 MySQL 的开源内容管理系统(CMS),用户可以免费使用、修改和分发,安装完成后,通过后台管理界面进行网站的配置和内容管理。
课程提供了对应的WordPress 代码包,将wordpress-6.7.2-zh_CN.zip包放到nginx的程序根目录(/usr/local/nginx/html)下,解压即可完成程序部署。详细安装和使用过程请看视频讲解。
七、LNMP环境下开启https
1、HTTP与https
HTTP是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准(TCP),HTTP协议传输的数据都是未加密的,也就是明文的,因此使用HTTP协议传输隐私信息非常不安全。
HTTPS是以安全为目标的HTTP通道,简单讲是HTTP的安全版本,HTTPS协议是利用SSL+HTTP协议建立安全信道,加密数据包,提供身份认证的网络协议,要比http协议安全。
HTTPS和HTTP的区别:
- http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
- http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- 使用https协议需要申请SSL证书,证书有收费和免费的。
现在网站几乎所有都开启了https协议,所以使用https已经是个趋势。
2、SSL证书的获取
很多网站都提供免费的SSL证书,例如阿里云,可以一次申请3个月免费的SSL证书,过期后,可继续再次申请3个月的免费证书,申请方式如下:

注意:商业CA机构颁发证书时,需要绑定公网域名,也就是说申请SSL证书之前,你的域名已经申请好了,并且也做了域名备案和解析,否则无法申请SSL证书。
在练习本课程的时候,可以自己购买一个域名,最便宜的每年10元以内,难点在于备案,域名在进行公网解析的时候,需要首先进行备案,然后才能解析,可通过购买阿里云主机,获取一个公网ip,然后将域名解析到这个外网ip上来,大致分为6个步骤,流程如下:
购买域名—》购买云主机—》备案域名(备案需要域名和解析的IP地址,两周内即可完成备案)—》备案成功后,就可以做域名解析了—》从阿里云购买免费的ssl证书—》在云主机部署网站程序,加载免费证书。
3、绑定ssl证书到nginx
完成上面6个步骤之后,将证书绑定到我们服务器的nginx配置上即可,在nginx上配置ssl证书,需要在nginx.conf中添加一个server段,内容如下:
server
{
listen 443 ssl;
server_name www.iivey.com;
ssl_certificate iivey/www.iivey.com.pem;
ssl_certificate_key iivey/www.iivey.com.key;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "HIGH:!aNULL:!MD5";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-Xss-Protection 1;
location / {
root html;
index index.html index.htm index.php;
}
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
4、https方式访问web站点
配置完成,重启nginx服务:
[root@mysqlserver ~]# systemctl restart nginx
最后,再次通过域名https://www.iivey.com访问博客,如下图所示:

至此,一个完整的博客系统搭建完毕。
发表回复