LNMP 是一个用 Linux Shell 编写的用于在 CentOS/RHEL/Fedora/Debian/Ubuntu 系统上搭建生产环境的 Shell 程序。LNMP = Linux/Nginx/MySQL/PHP。另一个 LNMP 程序:OneinStack
以下针对 LNMP v1.7 版本
我使用的 Vultr $5.00/mo 实例的配置如下:
- CPU: 1 vCore/RAM: 1024 MB/Storage: 25 GB SSD/OS: CentOS 7 x64 with Docker
- 主要使用 Wordpress,附带使用 frp、Fail2mail
经我测试,以上配置支持到的 LNMP 各组件的最高版本如下,再高的话,内存大小不支持或者无法正常安装了:
- Nginx:1.18.0
- PHP:7.3.22
- MySQL:5.7.30
- phpMyAdmin:4.9.7
LNMP 系统要求及安装
系统要求
- CentOS/RHEL/Fedora/Debian/Ubuntu/Raspbian/Deepin/Aliyun/Amazon/Mint Linux 发行版
- 需要 5GB 以上硬盘剩余空间,MySQL 5.7、MariaDB 10 至少 9GB 剩余空间
- 需要 128MB 以上内存(128MB 小内存 VPS、Xen 需有 SWAP,OpenVZ 至少要有 128MB 以上的 vSWAP 或突发内存),注意小内存请勿使用 64 位系统!
- 安装 MySQL 5.6 或 5.7 及 MariaDB 10 必须 1G 或以上内存,更高版本至少要 2G 内存!。
- 安装 PHP 7 及以上版本必须 1G 或以上内存!。
- VPS 或服务器必须设置好可用的 yum 或 apt-get 源并确保能正常工作,离线安装需要增加 CheckMirror=n 参数!
- Linux 下区分大小写,输入命令时请注意!
- 如有通过 yum 或 apt-get 安装的 MySQL/MariaDB 请自行备份数据等相关文件!
- CentOS 5、Debian 6 及之前版本其官网已经结束支持无法使用!
- Ubuntu 18+、Debian 9+、Mint 19+、Deepin 15.7+ 及所有新的 Linux 发行版只能使用 LNMP 1.7!
- PHP 7.1.* 以下版本不支持 Ubuntu 19+、Debian 10 等等非常新的 Linux 发行版!
- 阿里云 Ubuntu 14.04 系统模版有问题不要用!!!
- PHP 7.4 升级或安装必须 CentOS 7+、Debian 8+、Ubuntu 16.04+ 且必须使用 LNMP 1.7!!!
- MySQL 8.0 升级或安装必须 CentOS 8+、Debian 9+、Ubuntu 16.04+ 且必须使用 LNMP 1.7!!!
安装步骤
SSH 到 VPS,运行如下命令:
wget http://soft.vpser.net/lnmp/lnmp1.7.tar.gz -cO lnmp1.7.tar.gz && tar zxf lnmp1.7.tar.gz && cd lnmp1.7 && ./install.sh lnmp
然后根据提示安装即可。
LNMP 各组件的安装目录及配置文件位置
LNMP 各组件升级
注意:以下操作均必须在 lnmp 安装包压缩包解压后的目录里运行,如 lnmp1.7 解压后的目录就是 lnmp1.7 或 lnmp1.7-full。
Nginx
执行:./upgrade.sh nginx
,按提示输入 Nginx 的版本号(访问 https://nginx.org/en/download.html 获取 Nginx 的版本号。如:1.18.0)后回车,再次回车确认即可开始升级 Nginx。Nginx 升级为平滑升级,升级过程不影响 Nginx 的运行。
MySQL
虽然脚本会备份数据,但依然建议先自行备份数据库!
执行:./upgrade.sh mysql
,按提示先输入 MySQL 的 root 密码进行验证,验证通过后输入 MySQL 的版本号(访问 https://dev.mysql.com/downloads/mysql/ 获取 MySQL 的版本号。如:5.7.30)后回车,提示是否启用 InnDB,如要启用 InnoDB 或不确定直接按回车,再次回车确认即可开始升级 MySQL。
将会在 /root 目录下生成 mysql_upgrade+日期.log
的日志文件,供出错时排查。
PHP
执行:./upgrade.sh php
,按提示输入 PHP 的版本号(访问 https://www.php.net/downloads.php 获取 PHP 的版本号。如:7.3.22)后回车,再次回车确认即可开始升级 PHP。
升级完 PHP 后如果 phpMyAdmin 无法使用,需要升级 phpMyAdmin 版本至对应于 PHP 和 MySQL 的版本。
phpMyAdmin
执行:./upgrade.sh phpmyadmin
按提示输入 phpMyAdmin 的版本号(访问 https://www.phpmyadmin.net/downloads 获取 phpMyAdmin 的版本号。如:4.9.7)后回车,再次回车确认即可开始升级 phpMyAdmin。
升级失败的恢复
Nginx
将 /usr/local/nginx/sbin/nginx.+日期
的文件重命名为 nginx
,然后再启动 nginx lnmp nginx start
即可恢复 Nginx。
MySQL
将 /usr/local/oldmysql+日期
目录下的 init.d.mysql.bak.+日期
文件拷贝到 /etc/init.d/ 目录下并重命名为 mysql
,及将 my.cnf.bak.+日期
文件拷贝到 /etc/ 目录下并重命名为 my.cnf
,并将 /usr/local/oldmysql+日期
目录重命名为 mysql
即可恢复 MySQL。
PHP
将 /usr/local/oldphp+日期
目录下的 init.d.php-fpm.bak.+日期
文件拷贝到 /etc/init.d/ 目录下重命名为 php-fpm
,并将 /usr/local/oldphp+日期
目录重命名为 php
即可恢复 PHP。
phpMyAdmin
无
Nginx 配置文件的使用
http 强制跳转 https
这个利用 Nginx 的 rewrite 方法。打开 Nginx 的配置文件(LNMP 的 Nginx 配置文件一般为 /usr/local/nginx/conf/vhost/youdomain.com.conf
),添加 return 301 https://$server_name$request_uri;
语句,然后重启 Nginx 服务:
server { listen 80; server_name youdomain.com; index index.html index.php index.htm; access_log /usr/local/nginx/logs/8080-access.log main; error_log /usr/local/nginx/logs/8080-error.log; return 301 https://$server_name$request_uri; //添加 http 强制转 https 的语句 location ~ / { root /var/www/html/8080; index index.html index.php index.htm; }
Nginx 下的配置方法有很多种,详见 Nginx 的 https 配置记录以及 http 强制跳转到 https 的方法梳理。
配置 http 强制跳转 https 后,你可能会发现你的 WordPress 网站页面部分插件不起作用了,打开 WordPress 后台,修改 WordPress 地址(URL)
和 站点地址(URL)
为 https 即可。
更改域名
与上面的 http 强制跳转 https 类似。例如域名由 aaa.com/blog
更改为 blog.aaa.com
,需要使原所有页面能访问且地址栏显示跳转后的地址。
在 aaa.com
的配置文件 aaa.com.conf
中添加如下语句,然后重启 Nginx 服务。
# https://aaa.com/blog/* 永久重定向到 https://blog.aaa.com/* location / { rewrite ^/blog/(.*)$ https://blog.aaa.com//$1 permanent; }
参考更换域名及 WordPress 和 Nginx 相应的配置更改记录。
Wordpress 放置于子目录
比如之前 Wordpress 核心文件放在 /home/wwwroot/ppgg.in/
目录,通过 https://ppgg.in
访问,现在将其移动到 /home/wwwroot/ppgg.in/blog
目录,通过 https://ppgg.in/blog
来访问。
把 Wordpress 核心文件移动到 /home/wwwroot/ppgg.in/blog
目录,在后台修改 「Wodpress 地址」 和 「站点地址」 为 https://ppgg.in/blog
。
修改 /usr/local/nginx/conf/rewrite/wordpress.conf
文件:
将
try_files $uri $uri/ /index.php?$args;
修改为
try_files $uri $uri/ /blog/index.php?$args;
使用 Nginx 加强 WordPress 防护
具体参考分享个自用的 Nginx 加强 WordPress 防护的规则。
#隐藏 nginx 版本. server_tokens off; #隐藏 PHP 版本 fastcgi_hide_header X-Powered-By; proxy_hide_header X-Powered-By; #禁止目录列表 autoindex off; #验证浏览器行为防 CC #if ($cookie_say != "hbnl$remote_addr"){ # rewrite .* "$scheme://$host$uri" redirect; #return 444; #} #屏蔽 IP 访问 deny 158.69.243.0/24; # MJ12bot deny 46.229.168.0/24; # SemRush deny 54.36.148.0/24; # AhrefsBot deny 54.36.149.0/24; # AhrefsBot #禁止 17ce.com 的测速 if ($http_referer ~* 17ce.com) { return 444; } #禁止恶意 UA 以及为空的请求 (^$) if ($http_user_agent ~ "Go-http-client|Apache-HttpClient|lua-resty-http|loli_spider|ngx_lua"){ return 444; } # 禁止 Scrapy 等工具的抓取 if ($http_user_agent ~* (cdnunion_monitor|python-httpx|Wget|Scrapy|HttpClient|PostmanRuntime|ApacheBench|python-requests|Python-urllib|node-fetch)) { return 499; } #禁止一些特殊的 UA if ($http_user_agent ~ "Mozilla/4.0\ \(compatible;\ MSIE\ 6.0;\ Windows\ NT\ 5.1;\ SV1;\ .NET\ CLR\ 1.1.4322;\ .NET\ CLR\ 2.0.50727\)") { return 444; } # 屏蔽恶意后缀文件访问请求 if ($document_uri ~* \.(asp|aspx|jsp|swp|git|env|yaml|yml|sql|db|bak|ini|docx|doc|rar|tar|gz|zip|log|bak|conf)$) { return 444; } #禁止直接访问任何 php 文件 location ~* /(?:uploads|files|akismet)/.*.php$ { deny all; access_log off; log_not_found off;} # 保护 WordPress 系统文件 location = /wp-admin/install.php { deny all; } location = /nginx.conf { deny all; } location ~ ^/user_extention/ { deny all; } location ~ /\.htaccess$ { deny all; } location ~ /readme\.html$ { deny all; } location ~ /readme\.txt$ { deny all; } location ~ ^/wp-config.php$ { deny all; } location ~ ^/wp-admin/includes/ { deny all; } location ~ ^/wp-includes/[^/]+\.php$ { deny all; } location ~ ^.*/\.git/.*$ { deny all; } location ~ ^.*/\.svn/.*$ { deny all; } # 禁用 Uploads 目录的 PHP location ~ ^/wp\-content/uploads/.*\.(?:php[1-7]?|pht|phtml?|phps)$ { deny all; } # 禁用 Plugins 目录的 PHP location ~ ^/wp\-content/plugins/.*\.(?:php[1-7]?|pht|phtml?|phps)$ { deny all; } # 禁用 Themes 目录的 PHP,慎重使用会影响到部分主题的缩略图裁剪哦! location ~ ^/wp\-content/themes/.*\.(?:php[1-7]?|pht|phtml?|phps)$ { deny all; } # 不记录 favicon.ico 请求 location = /favicon.ico { log_not_found off; access_log off;} # 不记录 robots.txt 请求 location = /robots.txt { log_not_found off; access_log off;} location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ {expires 30d;} location ~ .*\.(js|css)?$ { expires 30d;} location ~ /\. {deny all;} location ~ /\.ht { deny all; access_log off; log_not_found off;} location ~ /\.user.ini { deny all; access_log off;log_not_found off;}