LNMP 环境搭建完全指南:Linux + Nginx + MySQL + PHP 从零配置

LNMP(Linux + Nginx + MySQL + PHP)是 PHP 网站最经典的服务器架构,WordPress、Laravel、ThinkPHP 这些主流应用都是跑在它上面的。它和 LAMP 的最大区别是:Nginx 用事件驱动模型处理静态文件和反向代理,比 Apache 更省内存、扛并发更好,PHP 再通过 FastCGI 交给 php-fpm 进程池执行。

一、系统初始化

选择操作系统

推荐 Ubuntu 22.04 LTS 或 24.04 LTS。生产环境选 LTS,能拿到 5 年以上的安全更新;Ubuntu 24.04 默认自带 PHP 8.3,省去不少升级麻烦。Debian 12 也是稳妥选择,但官方文档示例更多围绕 Ubuntu,新手建议跟着 Ubuntu 走。内存方面,只跑个人站 2G 起步足够,要跑电商或高并发,起步就上 4G,省得后面折腾迁移。

初始安全配置

一台裸机到手,先做三件事:更新系统、建普通用户、关掉 root 远程登录。

# 更新系统
apt update && apt upgrade -y

# 创建普通用户
adduser deploy
usermod -aG sudo deploy

# 配置 SSH 密钥登录
ssh-keygen -t ed25519 -C "[email protected]"
# 将公钥添加到 ~/.ssh/authorized_keys

# 禁止 root 登录
sed -i 's/PermitRootLogin yes/PermitRootLogin no/' /etc/ssh/sshd_config
systemctl restart sshd

# 配置防火墙
ufw allow OpenSSH
ufw allow 'Nginx Full'
ufw enable

参考:Ubuntu 服务器安全加固 https://ubuntu.com/server/docs/security-hardening;OpenSSH 手册 https://www.openssh.com/manual.html

注意顺序:先确认密钥能登录,再执行最后一条 PermitRootLogin no,否则把自己锁在外面就只能靠服务商的控制台救场了。

再补两件小事:一是配置 swap,1-2G 内存的小机器没有 swap,遇到内存峰值会被 OOM 杀掉进程,fallocate -l 2G /swapfile && mkswap /swapfile && swapon /swapfile 就能建好(记得写进 /etc/fstab 开机自动挂载);二是顺手把时区设对,timedatectl set-timezone Asia/Shanghai,否则日志和定时任务的时区对不上,排查问题很痛苦。

二、安装 Nginx

# 安装 Nginx
apt install nginx -y

# 验证安装
nginx -v
systemctl status nginx

装完顺手做基础优化,写进 /etc/nginx/nginx.conf

cat > /etc/nginx/nginx.conf << 'EOF'
user www-data;
worker_processes auto;
worker_rlimit_nofile 65535;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;
    
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    server_tokens off;
    
    # Gzip 压缩
    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/x-component;
    gzip_min_length 256;
    gzip_comp_level 5;
    gzip_vary on;
    
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}
EOF

worker_processes auto 让 Nginx 按 CPU 核数启动进程,sendfile on 开启零拷贝,静态文件吞吐能差出一截。接着创建站点配置,把 PHP 请求转发给 php-fpm:

cat > /etc/nginx/sites-available/example.com << 'EOF'
server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com/public;
    index index.php index.html;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }
    
    location ~ /\.ht {
        deny all;
    }
}
EOF

# 启用站点
ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx

参考:Nginx 官方文档 https://nginx.org/en/docs/;nginx beginners guide https://nginx.org/en/docs/beginners_guide.html

三、安装 MySQL

# 安装 MySQL 8.0
apt install mysql-server -y

# 安全配置
mysql_secure_installation
# 按提示设置 root 密码、移除匿名用户、禁止远程 root 登录、移除测试数据库

然后建库建用户,注意字符集统一用 utf8mb4,别再用 utf8——emoji 和生僻字全靠它。另外密码别用常见弱口令,最好用 openssl rand -base64 24 生成一段随机串,避免被字典爆破。

mysql -u root -p
CREATE DATABASE example_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'example_user'@'localhost' IDENTIFIED BY 'strong_password';
GRANT ALL PRIVILEGES ON example_db.* TO 'example_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

MySQL 的默认配置偏保守,生产环境至少改这几项:

# /etc/mysql/mysql.conf.d/optimize.cnf
[mysqld]
# InnoDB 设置
innodb_buffer_pool_size = 1G    # 设为可用内存的 60-70%
innodb_log_file_size = 256M
innodb_flush_log_at_trx_commit = 2
innodb_file_per_table = 1

# 连接设置
max_connections = 150
max_allowed_packet = 64M

# 缓存设置
query_cache_type = 0            # MySQL 8.0 已移除查询缓存
tmp_table_size = 64M
max_heap_table_size = 64M

# 字符集
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

innodb_buffer_pool_size 是重中之重,官方建议占可用内存的 60-70%,太小了热点数据全走磁盘。

参考:MySQL 文档 https://dev.mysql.com/doc/refman/8.0/en/;InnoDB 缓冲区池 https://dev.mysql.com/doc/refman/8.0/en/innodb-buffer-pool.html

四、安装 PHP

# Ubuntu 24.04 默认 PHP 8.3
apt install php8.3-fpm php8.3-cli php8.3-mysql php8.3-curl \
  php8.3-gd php8.3-mbstring php8.3-xml php8.3-bcmath php8.3-zip \
  php8.3-redis php8.3-opcache -y

# 验证安装
php -v
php -m  # 查看已安装的模块

php8.3-mysql(连数据库)、php8.3-mbstring(多字节字符串)、php8.3-opcache(字节码缓存)是必装项,缺了 WordPress 或 Laravel 会直接报错。php-fpm 进程池按需调整:

# /etc/php/8.3/fpm/pool.d/www.conf
pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 15
pm.max_requests = 500
# /etc/php/8.3/cli/conf.d/99-optimize.ini
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
date.timezone = Asia/Shanghai

pm.max_children 不是越大越好,它乘以单个 PHP 进程的平均内存,最好别超过机器总内存的 70%,否则高峰期直接 OOM。

参考:PHP 手册 https://www.php.net/manual/;php-fpm 配置说明 https://www.php.net/manual/en/install.fpm.configuration.php

五、一键脚本:LNMP.org 与 Oneinstack

不想逐项手敲,可以换一键包。LNMP.org 是国内很老牌的一键包:

wget https://soft.lnmp.com/lnmp/lnmp2.0.tar.gz
tar zxf lnmp2.0.tar.gz
cd lnmp2.0
./install.sh lnmp

Oneinstack 的可选项更多,组件版本能自己挑:

wget https://oneinstack.com/download/oneinstack-full.tar.gz
tar xzf oneinstack-full.tar.gz
cd oneinstack
./install.sh --nginx_option 1 --php_option 9 --mysql_option 2

参考:LNMP.org https://lnmp.org;OneinStack https://oneinstack.com

一键包的优点是省事、目录规范、自带常用安全配置;缺点是版本升级要跟着作者节奏,不透明的编译参数出了问题比较难排查。追求可控的生产环境,还是建议手动装一遍,哪怕只装一次,也能建立对整条链路的理解。

六、安全加固

Fail2Ban 能挡住绝大多数暴力破解:

# 配置 Fail2Ban 防止暴力破解
apt install fail2ban -y
cat > /etc/fail2ban/jail.local << 'EOF'
[sshd]
enabled = true
maxretry = 5
bantime = 3600

[nginx-http-auth]
enabled = true
maxretry = 5
bantime = 3600
EOF
systemctl restart fail2ban

# 设置自动安全更新
apt install unattended-upgrades -y
dpkg-reconfigure --priority=low unattended-upgrades

Fail2Ban 的核心价值是"错五次封一小时"这种自动封禁,配合密钥登录基本能挡住 99% 的脚本扫描。另外记得检查 /etc/ssh/sshd_configPasswordAuthentication 是否已设为 no——只留密钥登录,暴力破解连试的机会都没有。

七、性能测试

# 使用 ab 进行压力测试
apt install apache2-utils -y
ab -n 1000 -c 50 http://example.com/

# PHP 性能测试
cat > /var/www/example.com/public/info.php << 'EOF'
<?php
phpinfo();
EOF

装完最好用 ab -n 1000 -c 50 打一轮,看 QPS 和响应时间;再配合 htop 观察内存占用,确认 php-fpm 的 pm.max_children 没有把内存吃满。

八、方案怎么选

这几种方案的取舍其实一句话就能说清:越省事的方案,出问题时你能控制的东西越少。手动安装前期花的时间最多,但目录、权限、参数全在自己手里,后面排障和调优都更从容。

方案 上手难度 可控性 适用人群
手动安装 生产环境、有运维基础
LNMP.org 想快速上线的个人站
Oneinstack 想选组件版本的开发者
宝塔面板 最低 不想碰命令行的站长

16IDC 提醒

1GB 内存能跑基础 LNMP,但 WordPress 想顺畅至少 2GB,跑 Laravel 建议 2GB 起。装完记得把 example.com 全部替换成真实域名,并尽快接上 HTTPS(Let's Encrypt 免费证书即可)。如果不想自己维护,也可以参考 海外服务器方案 里的托管选项。数据库备份建议用 cron 每天拉一次 mysqldump 到对象存储,别只存在同一台机器上。