云计算百科
云计算领域专业知识百科平台

云原生运维学习笔记:Nginx进阶实战——SSL、PHP、反向代理与ECshop部署

云原生运维学习笔记: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匹配按以下优先级:

  • 精确匹配 =:完全匹配URL,优先级最高。
  • 前缀匹配 ^~:匹配URL开头,且不再匹配正则。
  • 正则匹配 ~ 或 ~*:按顺序匹配,匹配到就停止。
  • 普通前缀匹配:匹配开头,选最长匹配。
  • 通用匹配 /:兜底。
  • 用表格总结:

    语法说明优先级
    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规划如下:

    主机名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商城。收获最大的有几点:

  • HTTPS配置:自签名证书的生成和Nginx配置,以及HTTP自动跳转HTTPS。
  • PHP-FPM:理解了Nginx和PHP-FPM的协作流程,以及try_files的安全作用。
  • Location匹配:通过实验彻底搞清了精确匹配、前缀匹配、正则匹配的优先级。
  • proxy_pass:末尾斜杠对路径的影响,这个细节非常关键。
  • 完整项目部署:LNMP环境搭建、数据库创建、代码部署、安装向导,走了一遍完整的流程。
  • 学习中踩的坑:PHP-FPM用户没改导致502、try_files漏写导致安全问题、proxy_pass斜杠搞混导致路径错误、ECshop缺少扩展等。这些坑踩过之后,记忆特别深刻。

    反向代理和Location匹配是Nginx最核心也最容易出错的部分,建议多动手做实验,把各种情况都试一遍。ECshop部署则是一个很好的综合练习,把之前学的Nginx、PHP、MariaDB都串起来了。

    希望这篇笔记能帮到同样在学云原生运维的朋友。Nginx功能强大,配置灵活,学好它,以后做Web服务、负载均衡、API网关都会轻松很多。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 云原生运维学习笔记:Nginx进阶实战——SSL、PHP、反向代理与ECshop部署
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!