云原生运维学习笔记:Nginx进阶实战——SSL、PHP、反向代理与ECshop部署
今天继续深挖Nginx,内容比昨天更偏向实战:配置SSL/TLS证书、让Nginx支持PHP动态站点、深入理解反向代理和Location匹配规则,最后还有一个完整的项目实战——部署ECshop商城。说实话,刚开始看到“反向代理”和“Location匹配优先级”的时候,脑子有点乱,各种符号和规则容易记混。但跟着老师一步步做实验,把本地代理和远端代理都跑了一遍,突然就豁然开朗了。这篇博客就当作我的学习笔记,把操作过程、踩过的坑和自己的理解都记录下来,希望能帮到同样在学云原生运维的朋友。
环境说明:CentOS 7,多台虚拟机模拟代理和后端服务器,所有命令都实际执行过,输出结果也尽量完整呈现。
一、配置SSL/TLS,让网站支持HTTPS
1.1 为什么要用HTTPS?
HTTP是明文传输的,别人在网络上抓包就能看到你提交的密码、个人信息。HTTPS通过SSL/TLS加密,保证数据在传输过程中不被窃听和篡改。现在浏览器对HTTP站点都会标记“不安全”,生产环境基本都上HTTPS了。Nginx配置HTTPS需要证书和私钥,我们可以自己生成自签名证书用于测试。
1.2 生成自签名证书
# 创建存放证书的目录
[root@www ~]# mkdir certs && cd certs
# 生成私钥(2048位RSA)
[root@www certs]# openssl genrsa -out www.key 2048
Generating RSA private key, 2048 bit long modulus
................................................................+++
...................................................+++
e is 65537 (0x10001)
# 生成证书签名请求(CSR),注意CN必须填域名
[root@www certs]# openssl req -new -key www.key -out www.csr -subj "/C=CN/ST=JS/L=NJ/O=LM/OU=DEVOPS/CN=www.laoma.cloud/emailAddress=webadmin@laoma.cloud"
# 使用私钥对CSR签名,生成证书,有效期3650天
[root@www certs]# openssl x509 -req -days 3650 -in www.csr -signkey www.key -out www.crt
Signature ok
subject=/C=CN/ST=JS/L=NJ/O=LM/OU=DEVOPS/CN=www.laoma.cloud/emailAddress=webadmin@laoma.cloud
Getting Private key
这里-subj参数直接指定了证书信息,省去了交互式输入。CN(Common Name)必须和网站域名一致,否则浏览器会报证书不匹配。
1.3 配置Nginx使用HTTPS
把证书放到合适的位置,然后修改Nginx配置:
# 创建证书存放目录并移动文件
[root@www certs]# mkdir -p /etc/ssl/certs/www.laoma.cloud
[root@www certs]# mv www* /etc/ssl/certs/www.laoma.cloud
# 复制默认配置作为模板
[root@www ~]# cp /etc/nginx/nginx.conf /etc/nginx/conf.d/vhost-www.laoma.cloud-ssl.conf
[root@www ~]# vim /etc/nginx/conf.d/vhost-www.laoma.cloud-ssl.conf
配置文件内容如下:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name www.laoma.cloud;
root /usr/share/nginx/html;
ssl_certificate "/etc/ssl/certs/www.laoma.cloud/www.crt";
ssl_certificate_key "/etc/ssl/certs/www.laoma.cloud/www.key";
}
重启Nginx:
[root@www ~]# systemctl restart nginx
1.4 配置HTTP自动跳转HTTPS
为了让用户访问HTTP时自动跳到HTTPS,再加一个server块:
server {
listen 80;
listen [::]:80;
server_name www.laoma.cloud;
root /usr/share/nginx/html;
return 301 https://$host$request_uri;
}
重载Nginx,并放行防火墙的https服务:
[root@www ~]# systemctl restart nginx
[root@www ~]# firewall-cmd –add-service=https –permanent
success
[root@www ~]# firewall-cmd –reload
success
1.5 测试验证
客户端用curl测试:
# 访问HTTP,会返回301重定向
[root@client ~]# curl http://www.laoma.cloud/
<html>
<head><title>301 Moved Permanently</title></head>
<body>
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx/1.20.1</center>
</body>
</html>
# 用-k忽略证书校验,访问HTTPS
[root@client ~]# curl -k https://www.laoma.cloud/
Hello World From Nginx
# 用-L跟随重定向,-k忽略证书
[root@client ~]# curl -Lk http://www.laoma.cloud/
Hello World From Nginx
看到内容就说明HTTPS配置成功了。自签名证书浏览器会提示不安全,生产环境需要购买CA签发的证书。
二、动态站点与PHP支持
2.1 静态 vs 动态
之前我们部署的都是静态页面,服务器直接把HTML文件返回给浏览器。静态网站速度快、资源消耗低,但内容固定,无法交互。动态网站则需要后端程序处理请求,查询数据库,实时生成页面。常见的动态技术栈有PHP+MySQL+Nginx、Java+SpringBoot、Python+Django等。
Nginx本身不能执行PHP,需要配合PHP-FPM(FastCGI进程管理器)。流程是:客户端请求.php文件 → Nginx转发给PHP-FPM → PHP-FPM调用PHP解析器执行 → 结果返回给Nginx → Nginx返回给客户端。
2.2 安装PHP和PHP-FPM
[root@www ~]# yum install -y php php-fpm
[root@www ~]# yum install -y php-gd php-common php-pear php-mbstring php-mcrypt
# 修改PHP-FPM运行用户为nginx
[root@www ~]# vim /etc/php-fpm.d/www.conf
# 找到 user = apache 改为 user = nginx
# 找到 group = apache 改为 group = nginx
# 启动并设置开机自启
[root@www ~]# systemctl enable php-fpm –now
# 查看PHP版本
[root@www ~]# php -v
PHP 5.4.16 (cli) (built: Apr 1 2020 04:07:17)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2013 Zend Technologies
# 测试PHP解析
[root@www ~]# echo '<?php echo "PHP Test Page\\n"; ?>' > php_test.php
[root@www ~]# php php_test.php
PHP Test Page
2.3 配置Nginx支持PHP
修改虚拟主机配置,添加对.php文件的处理:
[root@www ~]# vim /etc/nginx/conf.d/vhost-www.conf
内容如下:
server {
listen 80;
listen [::]:80;
server_name www.laoma.cloud;
root /usr/share/nginx/html;
location ~ \\.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
也可以把PHP配置单独放到一个文件里,用include引入:
[root@www ~]# vim /etc/nginx/default.d/php.conf
location ~ \\.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
然后在server块中include /etc/nginx/default.d/*.conf;。
重启Nginx:
[root@www ~]# systemctl restart nginx
创建一个phpinfo页面测试:
[root@www ~]# echo "<?php phpinfo(); ?>" > /usr/share/nginx/html/php_info.php
客户端访问http://www.laoma.cloud/php_info.php,应该能看到PHP信息页面,说明PHP解析正常。
踩坑记录:一开始忘了改/etc/php-fpm.d/www.conf里的用户,导致Nginx无法访问PHP-FPM的socket,报502错误。改成nginx用户后就好了。还有try_files $uri =404;很重要,可以防止恶意请求被PHP解析。
三、反向代理深入与Location匹配
3.1 什么是反向代理?

反向代理是站在服务器端的代理,它接收客户端请求,然后转发给后端服务器,再把结果返回给客户端。客户端只知道代理服务器的地址,不知道后端真实服务器。反向代理常用于负载均衡、缓存、动静分离、多站点代理等。
Nginx通过location匹配URL路径,再用proxy_pass转发到后端。location的匹配规则和proxy_pass末尾是否带斜杠,都会影响最终的转发路径,这也是最容易搞混的地方。
3.2 Location匹配规则
Nginx的location匹配按以下优先级:
用表格总结:
| location = /path | 精确匹配 | 最高 |
| location ^~ /path | 前缀匹配,忽略正则 | 高 |
| location ~ /regex | 正则匹配,区分大小写 | 中 |
| location ~* /regex | 正则匹配,不区分大小写 | 中 |
| location /path | 普通前缀匹配 | 低 |
| location / | 通用匹配 | 最低 |
3.3 proxy_pass末尾斜杠的玄机
proxy_pass末尾有没有/,转发路径完全不同:
-
末尾带 /:会剔除location匹配的路径前缀。例如:
location /api/ {
proxy_pass http://backend:9090/;
}访问/api/user,转发到http://backend:9090/user。
-
末尾不带 /:保留完整路径。例如:
location /api/ {
proxy_pass http://backend:9090;
}访问/api/user,转发到http://backend:9090/api/user。
这个细节在做反向代理时一定要搞清楚,否则后端可能收不到正确的路径。
3.4 反向代理实践环境搭建
我们用4台虚拟机模拟:客户端、代理服务器(proxy)、后端Web服务器(nginx1、nginx2、nginx3)。IP规划如下:
| client | 10.1.8.11 | 测试 |
| proxy | 10.1.8.20 | 代理 |
| nginx1 | 10.1.8.21 | 后端 |
| nginx2 | 10.1.8.22 | 后端 |
| nginx3 | 10.1.8.23 | 后端 |
所有节点配置hosts文件,确保能互相解析。
后端服务器安装Nginx,准备不同的首页内容:
[root@nginx1 ~]# yum install -y nginx
[root@nginx1 ~]# systemctl enable nginx –now
[root@nginx1 ~]# echo "Welcome to nginx1.laoma.cloud" > /usr/share/nginx/html/index.html
# nginx2、nginx3类似
代理服务器也安装Nginx,并准备本地站点目录:
[root@proxy ~]# mkdir -p /var/nginx
[root@proxy ~]# echo "Hello, Nginx" > /var/nginx/index.html
[root@proxy ~]# echo "Hello, Laoma" > /var/nginx/test.txt
配置代理虚拟主机:
[root@proxy ~]# vim /etc/nginx/conf.d/proxy.conf
server {
listen 80;
server_name www.laoma.cloud;
location / {
root /var/nginx;
index index.html;
}
}
[root@proxy ~]# nginx -s reload
客户端测试:

[root@client ~]# curl http://www.laoma.cloud/
Hello, Nginx
[root@client ~]# curl http://www.laoma.cloud/test.txt
Hello, Laoma
3.5 代理本地实验:验证匹配优先级
我们在代理服务器上创建多个目录,模拟不同location匹配效果。
[root@proxy ~]# mkdir -p /var/nginx/nginx1 /var/nginx/nginx2
[root@proxy ~]# echo "Hello, I'm here /var/nginx/nginx1" > /var/nginx/nginx1/index.html
[root@proxy ~]# echo "Hello, I'm here /var/nginx/nginx2" > /var/nginx/nginx2/index.html
[root@proxy ~]# mkdir -p /var/nginx1 /var/nginx2
[root@proxy ~]# echo "Hello, Nginx1" > /var/nginx1/index.html
[root@proxy ~]# echo "Hello, Nginx2" > /var/nginx2/index.html
# 再创建 /var/www1/nginx1, /var/www1/nginx2, /var/www2/nginx1, /var/www2/nginx2
[root@proxy ~]# for path1 in www{1..2}; do
for path2 in nginx{1..2}; do
mkdir -p /var/$path1/$path2
echo "Hello, I'm here /var/$path1/$path2" > /var/$path1/$path2/index.html
done
done
实验1:无符号匹配
location / {
root /var/nginx;
index index.html;
}
location /nginx1 {
root /var;
index index.html;
}
访问/nginx1/,会匹配到location /nginx1,实际路径是/var/nginx1,返回Hello, Nginx1。而/nginx2/会匹配到location /,实际路径/var/nginx/nginx2,返回Hello, I'm here /var/nginx/nginx2。说明普通前缀匹配优先于通用匹配。
实验2:正则匹配
加上location ~ /nginx.* { root /var/www1; },访问/nginx1/和/nginx2/都会匹配正则,返回/var/www1/nginx1和/var/www1/nginx2的内容。说明正则优先级高于普通前缀。
实验3:精确匹配
再加上location = /nginx2/index.html { root /var/www2; },访问/nginx2/时,因为精确匹配优先级最高,会直接命中,返回/var/www2/nginx2的内容。说明精确匹配优先级最高。
通过这三个实验,我彻底搞清楚了location的优先级顺序。
3.6 代理远端实验:反向代理到后端服务器
实验1:无符号匹配,代理到远端
location /nginx1/ {
proxy_pass http://nginx1.laoma.cloud/;
index index.html;
}
访问http://www.laoma.cloud/nginx1/,会被代理到http://nginx1.laoma.cloud/,返回Welcome to nginx1.laoma.cloud。注意proxy_pass末尾有斜杠,所以/nginx1/被剔除。
实验2:正则匹配,代理到远端
location ~ /nginx[123].* {
rewrite ^/nginx[123](.*)$ $1 break;
proxy_pass http://nginx2.laoma.cloud;
index index.html;
}
访问/nginx1/、/nginx2/、/nginx3/,都会匹配正则,经过rewrite去掉前缀,转发到nginx2。返回的都是Welcome to nginx2.laoma.cloud。说明正则优先级高,且rewrite可以灵活改写路径。
实验3:精确匹配,代理到远端
location = /nginx3/ {
proxy_pass http://nginx3.laoma.cloud/;
index index.html;
}
访问/nginx3/时,精确匹配命中,直接代理到nginx3,返回Welcome to nginx3.laoma.cloud。
这些实验把location匹配和proxy_pass的路径处理讲透了,以后做反向代理时,心里就有谱了。
四、项目实战:部署ECshop商城
ECshop是一个开源的PHP商城系统,我们用它来练习完整的LNMP环境部署。
4.1 准备LNMP环境
安装Nginx:
[root@ecshop ~]# yum install -y nginx
[root@ecshop ~]# systemctl enable nginx –now
[root@ecshop ~]# echo "Nginx Test Page" > /usr/share/nginx/html/index.html
[root@ecshop ~]# curl http://shop.laoma.cloud/
Nginx Test Page
安装MariaDB:
[root@ecshop ~]# yum install -y mariadb-server
[root@ecshop ~]# systemctl enable mariadb –now
[root@ecshop ~]# mysql_secure_installation
# 按照提示设置root密码、删除匿名用户、删除测试库等
安装PHP:
[root@ecshop ~]# yum install -y php php-fpm
[root@ecshop ~]# vim /etc/php-fpm.d/www.conf
# 修改 user = nginx, group = nginx
[root@ecshop ~]# systemctl enable php-fpm –now
配置Nginx虚拟主机支持PHP:
[root@ecshop ~]# vim /etc/nginx/conf.d/vhost-shop.laoma.cloud.conf
server {
listen 80;
listen [::]:80;
server_name shop.laoma.cloud;
root /usr/share/nginx/html;
index index.php;
location ~ \\.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
[root@ecshop ~]# systemctl restart nginx
# 测试PHP
[root@ecshop ~]# echo '<?php echo "PHP Test Page\\n"; ?>' > /usr/share/nginx/html/test.php
[root@client ~]# curl http://shop.laoma.cloud/test.php
PHP Test Page
4.2 准备数据库
[root@ecshop ~]# mysql -u root -predhat
MariaDB [(none)]> CREATE DATABASE ecshop;
MariaDB [(none)]> CREATE USER ecshop@localhost IDENTIFIED BY 'redhat';
MariaDB [(none)]> GRANT ALL PRIVILEGES ON ecshop.* TO ecshop@localhost;
MariaDB [(none)]> FLUSH PRIVILEGES;
MariaDB [(none)]> exit
4.3 部署ECshop代码
[root@ecshop ~]# wget http://192.168.49.200/class/course-materials/softwares/stage01/ECShop_V4.1.20_UTF8.zip
[root@ecshop ~]# unzip ECShop_V4.1.20_UTF8.zip
[root@ecshop ~]# mv /usr/share/nginx/html /usr/share/nginx/html.ori
[root@ecshop ~]# cp -a ECShop_V4.1.20_UTF8_release20250416/source/ecshop /usr/share/nginx/html
[root@ecshop ~]# chown -R nginx:nginx /usr/share/nginx/html
# 安装PHP扩展
[root@ecshop ~]# yum install -y php-gd php-mysqlnd
[root@ecshop ~]# chown -R nginx:nginx /var/lib/php/
# 设置时区
[root@ecshop ~]# vim /etc/php.ini
date.timezone = Asia/Shanghai
[root@ecshop ~]# systemctl restart nginx php-fpm
4.4 安装ECshop
浏览器访问http://shop.laoma.cloud,进入安装向导。按照提示:
客户端登录 http://shop.laoma.cloud

点击下一步:配置系统

输入数据库账户信息后,点击搜,选中搜索到的数据库。

在弹出的界面,点击确定。

继续完成其他配置,点击立即安装。

关闭该窗口,重新点击立即安装。

激活系统,享受更多服务。不激活也可以使用。关闭网页。

ECshop 访问
商城首页 http://shop.laoma.cloud

商城管理后台 http://shop.laoma.cloud/admin

使用ecshop账户登录

登录后界面如下:

4.5 访问商城
前台首页:http://shop.laoma.cloud
后台管理:http://shop.laoma.cloud/admin,用设置的管理员账号登录。
登录后可以看到商城管理界面,商品管理、订单管理等功能都正常。
踩坑记录:安装过程中提示“无法连接数据库”,检查发现是PHP缺少php-mysqlnd扩展,装上就好了。还有时区问题,不改php.ini会报警告。权限问题也要注意,/usr/share/nginx/html和/var/lib/php/都要改成nginx用户。
五、总结与心得
今天的内容非常充实,从SSL证书到PHP动态站点,再到反向代理和Location匹配,最后完整部署了一个ECshop商城。收获最大的有几点:
学习中踩的坑:PHP-FPM用户没改导致502、try_files漏写导致安全问题、proxy_pass斜杠搞混导致路径错误、ECshop缺少扩展等。这些坑踩过之后,记忆特别深刻。
反向代理和Location匹配是Nginx最核心也最容易出错的部分,建议多动手做实验,把各种情况都试一遍。ECshop部署则是一个很好的综合练习,把之前学的Nginx、PHP、MariaDB都串起来了。
希望这篇笔记能帮到同样在学云原生运维的朋友。Nginx功能强大,配置灵活,学好它,以后做Web服务、负载均衡、API网关都会轻松很多。
网硕互联帮助中心


评论前必须登录!
注册