说实话,2025年了,还在问“服务器崩了怎么办”的人,通常不是技术不行,而是步骤没记牢,或者被网上那些过时的博客坑惨了。
前两天帮朋友救火,他的网站死活打不开,报错502 Bad Gateway。我去看了一眼,发现他照着2018年的教程装Nginx,连SELinux都没关,防火墙配置也是乱的,php-fpm进程都起不来。那一刻我真的想叹气:有些坑,真的不需要再踩第二遍。
今天这篇指南,不是那种干巴巴的官方文档翻译,而是我这些年“填坑”填出来的实战经验。我们用的是 AlmaLinux 9——这是目前CentOS的完美继任者,稳定性和RHEL完全一致,但比CentOS 7更现代,比Ubuntu更适合那些习惯了RedHat系操作逻辑的运维同学。
准备好了吗?咱们从零开始,一步步把LNMP(Linux + Nginx + MySQL/MariaDB + PHP)环境搭建起来,顺便教你怎么在出问题时冷静排查。
第一步:别急着装软件,先搞定“地基”
很多新手一上来就yum install nginx,结果后续一堆依赖报错。其实,真正的坑往往在系统层面。
1.1 为什么选AlmaLinux 9?
首先你得明白,CentOS 7已经停止维护了,CentOS Stream虽然可用但偏向开发测试。如果你需要的是生产环境的稳定性,AlmaLinux 9或者Rocky Linux 9是首选。它们二进制兼容RHEL 9,意味着你在CentOS 7上学的那些systemctl、firewalld、SELinux操作逻辑,在这里完全通用,甚至更规范。
1.2 初始安全设置:最小化原则
服务器上线前,做这几件事,能挡住90%的自动化脚本攻击。
更新系统到最新:
sudo dnf update -y
sudo dnf upgrade -y
创建普通用户并赋予sudo权限(永远不要用root干所有事):
sudo useradd -m -s /bin/bash linuxowner
sudo usermod -aG wheel linuxowner
解释:
-m是创建家目录,-s指定shell,wheel组在AlmaLinux里默认拥有sudo权限。
配置SSH密钥登录(替代密码登录): 这一步至关重要。密码登录容易被暴力破解,密钥登录几乎不可能被猜中。
# 在你本地电脑上生成密钥(如果还没有)
ssh-keygen -t ed25519 -C "your_email@example.com"
# 把公钥复制到服务器
ssh-copy-id linuxowner@你的服务器IP
复制完后,测试能否登录。成功后,去服务器编辑SSH配置,禁止密码登录:
sudo vi /etc/ssh/sshd_config
找到以下行并修改:
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes
重启SSH服务:
sudo systemctl restart sshd
配置防火墙(firewalld): AlmaLinux默认开启firewalld,我们只开放必要的端口(22是SSH,80和443是Web)。
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
注意:如果你用了云厂商(如阿里云、腾讯云、AWS),记得同时去控制台的安全组里开放这些端口,否则内层防火墙开了也没用。
第二步:Nginx —— 别让它是“摆设”
Nginx安装简单,但配置才是关键。很多新人装完Nginx,发现访问http://IP只显示默认页,或者静态资源加载不出来。
2.1 安装与启动
sudo dnf install nginx -y
sudo systemctl enable nginx --now
2.2 目录结构认知(这是理解配置的基础)
# 配置文件主目录
/etc/nginx/
├── nginx.conf # 主配置,别乱改,通常include其他
├── conf.d/ # 你的网站配置放这里
└── sites-available/ # 备用配置(可选)
# 网站根目录
/var/www/html/ # 默认位置,建议自定义
# 日志
/var/log/nginx/
├── access.log
└── error.log
2.3 实战:部署一个简单站点
假设我们要部署example.com,域名指向服务器IP。
- 创建网站目录:
sudo mkdir -p /var/www/example.com/public_html
sudo chown -R $USER:$USER /var/www/example.com/public_html
sudo chmod -R 755 /var/www
- 创建测试页面:
echo "<h1>Hello from Nginx!</h1>" | sudo tee /var/www/example.com/public_html/index.html
- 创建Nginx配置文件:
sudo vi /etc/nginx/conf.d/example.com.conf
内容如下:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/public_html;
index index.html index.htm;
# 日志建议开启,出问题第一时间看这里
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
try_files $uri $uri/ =404;
}
# 静态资源缓存,提升性能
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}
- 测试配置并重载:
sudo nginx -t
sudo systemctl reload nginx
坑点提醒: 如果访问还是403 Forbidden,99%是权限问题或SELinux拦住了。先检查ls -l /var/www/的权限,再往下看SELinux。
第三步:MariaDB —— MySQL的完美替代
AlmaLinux 9默认用MariaDB 10.5+,它和MySQL完全兼容,而且性能在某些场景下更好。
3.1 安装
sudo dnf install mariadb-server mariadb -y
sudo systemctl enable mariadb --now
3.2 安全初始化
安装完后,务必运行安全脚本:
sudo mysql_secure_installation
它会引导你:
- 设置root密码
- 删除匿名用户
- 禁止root远程登录
- 删除测试数据库
- 重载权限表
重要: 在生产环境中,永远不要让数据库root从远程IP登录。你的Web应用应该用单独创建的数据库用户。
3.3 创建数据库和用户(示例)
sudo mysql -u root -p
CREATE DATABASE myapp_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'myapp_user'@'localhost' IDENTIFIED BY 'StrongPassword123!';
GRANT ALL PRIVILEGES ON myapp_db.* TO 'myapp_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
utf8mb4是支持Emoji的正确编码,别用utf8,那是MySQL的伪UTF-8。
第四步:PHP 8.x —— 让动态内容跑起来
AlmaLinux 9默认仓库里的PHP版本可能较旧(PHP 8.0)。如果你想要更新的PHP 8.2或8.3,需要启用Remi仓库。
4.1 启用Remi仓库
sudo dnf install epel-release -y
sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm -y
4.2 安装PHP及常用扩展
# 先重置模块流,确保安装最新版
sudo dnf module reset php -y
sudo dnf module enable php:remi-8.3 -y
sudo dnf install php php-fpm php-mysqlnd php-gd php-curl php-mbstring php-xml php-redis php-opcache -y
4.3 配置PHP-FPM
PHP-FPM是PHP的FastCGI进程管理器,Nginx通过它来执行PHP。
- 编辑FPM配置,优化性能(根据你的服务器配置调整):
sudo vi /etc/php-fpm.d/www.conf
找到[www]部分,调整:
user = nginx
group = nginx
listen = /run/php-fpm/www.sock ; 用socket比TCP更快
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
; 进程管理
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35
pm.max_children不要设太大,否则内存撑爆。一般每个进程占用30-50MB内存。
- 启动并启用:
sudo systemctl enable php-fpm --now
第五步:打通Nginx与PHP —— 关键连接
现在Nginx和PHP-FPM各自为政,得让它们“对话”。
修改之前创建的example.com.conf,加入PHP处理配置:
server {
listen 80;
server_name example.com www.example.com;
root /var/www/example.com/public_html;
index index.php index.html index.htm;
# ... 之前的日志和缓存配置保持不变 ...
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# PHP处理核心配置
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
# 安全:禁止访问.php以外的文件,防止路径穿越
fastcgi_param PHP_VALUE "open_basedir=$document_root:/tmp";
}
# 禁止访问隐藏文件(如.htaccess, .git)
location ~ /\. {
deny all;
}
}
测试并重载:
sudo nginx -t
sudo systemctl reload nginx
4.4 测试PHP是否工作
在网站上创建一个info.php:
echo "<?php phpinfo(); ?>" | sudo tee /var/www/example.com/public_html/info.php
访问http://example.com/info.php。如果看到PHP信息页面,恭喜你,LNMP跑通了!
最后记得删除info.php! 别留这个后门。
第六步:SSL证书 —— HTTPS是标配
2025年了,没有HTTPS的网站几乎没人信任。我们用Certbot申请免费的Let’s Encrypt证书。
sudo dnf install certbot python3-certbot-nginx -y
申请证书(Nginx插件会自动帮你配置):
sudo certbot --nginx -d example.com -d www.example.com
按提示输入邮箱,同意条款,选择是否重定向HTTP到HTTPS(选2,强制HTTPS)。
完成后,Certbot会自动修改Nginx配置,并设置定时任务自动续期。你可以测试续期:
sudo certbot renew --dry-run
第七步:排错实战 —— 服务器崩了怎么办?
这是你最关心的部分。当网站访问失败时,不要慌,按以下顺序排查。
7.1 症状:502 Bad Gateway
含义: Nginx收到了无效的响应,通常是因为后端PHP-FPM挂了。
排查步骤:
- 检查PHP-FPM状态:
如果没运行,sudo systemctl status php-fpmsudo systemctl start php-fpm。 - 查看错误日志:
常见原因:tail -n 20 /var/log/nginx/error.log tail -n 20 /var/log/php-fpm/www-error.logconnection refused:PHP-FPM进程不存在。upstream timed out:PHP脚本执行时间太长,需要调整fastcgi_read_timeout或优化PHP代码。permission denied:PHP-FPM用户(nginx)没有权限访问socket文件,检查www.conf中的listen.owner和listen.group。
7.2 症状:504 Gateway Timeout
含义: 后端处理超时。可能是数据库查询慢,或者PHP脚本死循环。
排查步骤:
- 检查数据库连接:
看是否有长时间运行的查询。sudo systemctl status mariadb sudo mysql -u root -p -e "SHOW PROCESSLIST;" - 增加Nginx超时时间:
在
location ~ \.php$块中添加:fastcgi_read_timeout 300s; fastcgi_send_timeout 300s; - 检查PHP执行时间:
在
php.ini中检查max_execution_time和memory_limit。
7.3 症状:403 Forbidden
含义: 权限问题或索引缺失。
排查步骤:
- 检查目录权限:
确保ls -lZ /var/www/example.com/public_html/nginx用户可以读取。通常所有者是nginx:nginx,权限是755。 - 检查SELinux:
这是最容易忽略的!运行:
如果有大量拒绝记录,可能需要设置上下文:sudo ausearch -m avc -ts recent
或者临时禁用SELinux测试(生产环境不建议长期禁用):sudo restorecon -Rv /var/www/example.com
如果禁用后正常,说明是SELinux策略问题,需调整。sudo setenforce 0
7.4 症状:500 Internal Server Error
含义: PHP代码错误或配置错误。
排查步骤:
- 查看PHP错误日志:
通常会显示具体的PHP Fatal error。tail -n 50 /var/log/php-fpm/www-error.log - 启用PHP错误显示(仅测试环境):
在
php.ini中设置:display_errors = On error_reporting = E_ALL - 检查Nginx错误日志:
tail -n 20 /var/log/nginx/error.log
7.5 通用排查工具
- 网络连通性:
ping、telnet IP端口、curl -I http://localhost - 进程状态:
ps aux | grep nginx、ps aux | grep php-fpm - 端口监听:
ss -tlnp或netstat -tlnp - 磁盘空间:
df -h,磁盘满了会导致数据库和日志写入失败 - 内存使用:
free -h,OOM(内存溢出)会杀死进程
第八步:一键部署脚本(懒人福音)
如果你觉得手动敲命令太麻烦,或者需要频繁重置环境,可以写个简单的Shell脚本。以下是一个基础版本,仅供参考,生产环境请自行调整:
#!/bin/bash
# AlmaLinux 9 LNMP一键部署脚本
set -e
echo "更新系统..."
sudo dnf update -y
echo "安装EPEL和Remi仓库..."
sudo dnf install epel-release -y
sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm -y
echo "安装Nginx, MariaDB, PHP..."
sudo dnf install nginx mariadb-server php php-fpm php-mysqlnd php-gd php-curl php-mbstring php-xml php-opcache -y
echo "启动并启用服务..."
sudo systemctl enable nginx mariadb php-fpm --now
sudo systemctl start nginx mariadb php-fpm
echo "配置防火墙..."
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --reload
echo "安全初始化MariaDB..."
sudo mysql_secure_installation
echo "安装Certbot..."
sudo dnf install certbot python3-certbot-nginx -y
echo "LNMP基础环境部署完成!"
echo "请手动配置您的站点和SSL证书。"
保存为setup_lnmp.sh,赋予执行权限chmod +x setup_lnmp.sh,然后运行。
最后一点心得
部署服务器不是一劳永逸的事。建完环境后,记得:
- 定期备份:数据库和网站文件,最好异地备份。
- 监控告警:用Prometheus + Grafana,或者简单的第三方监控,关注CPU、内存、磁盘。
- 日志轮转:确保Nginx和PHP的日志不会占满磁盘。
- 保持更新:
sudo dnf update定期跑一跑,修复安全漏洞。
服务器崩了不可怕,可怕的是乱了阵脚。按照这个指南,一步步来,你一定能搭建出一个稳定、安全的LNMP环境。如果在某个步骤卡住了,记得看日志,日志是程序员最好的朋友。
希望这篇指南能帮到你,祝你的服务器永远在线!
