本文整理一份在 Debian / Ubuntu 上可直接落地的 Nginx + PHP-FPM 站点模板,适合 WordPress、Laravel、Symfony、ThinkPHP 以及自定义 PHP 项目。目标不是只给一段能跑的配置,而是把目录结构、PHP-FPM 对接、HTTPS、缓存、安全头、常见限制和排障一起整理出来,形成一份完整站点模板。
适用场景
- 部署 PHP 动态站点
- 使用 Nginx 作为前端入口
- 使用 PHP-FPM 处理 PHP 请求
- 需要静态资源缓存和基础安全头
- 需要同时兼顾 SEO、HTTPS 和上传
推荐架构
典型结构如下:
- Nginx:处理静态资源、HTTPS、反向代理、FastCGI 转发
- PHP-FPM:执行 PHP 脚本
- MariaDB / MySQL:保存业务数据
- 可选 Redis:缓存和会话
如果是 WordPress:
- Nginx 负责路由和静态文件
- PHP-FPM 负责 WordPress PHP 执行
- 数据库负责文章、用户、配置
目录规划
建议采用清晰的目录布局:
/var/www/example.com
/var/www/example.com/public
/var/www/example.com/storage
/var/log/nginx/example.com
/var/log/php/example.com建议:
- Web 根目录尽量指向 public
- 业务私有文件不要放到可直接下载的位置
- 日志单独按站点拆分
PHP-FPM 对接前提
先确保 PHP-FPM 已安装并运行,例如:
sudo systemctl status php8.2-fpm确认 socket 路径,例如:
ls -l /run/php/常见 socket:
- /run/php/php8.2-fpm.sock
- /run/php/php8.3-fpm.sock
完整 Nginx 站点模板
下面是一个适合多数 PHP 站点的基础模板:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
root /var/www/example.com/public;
index index.php index.html;
access_log /var/log/nginx/example.com/access.log;
error_log /var/log/nginx/example.com/error.log;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
client_max_body_size 64m;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header X-XSS-Protection "0" always;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $document_root;
}
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|webp|woff|woff2)$ {
expires 30d;
access_log off;
add_header Cache-Control "public, max-age=2592000, immutable";
}
location ~ /\.(?!well-known).* {
deny all;
}
}模板说明
HTTP 强制跳转 HTTPS
第一个 server 块负责把 80 端口统一跳转到 HTTPS。
建议:
- 生产环境不要同时开放 HTTP 和 HTTPS 作为主入口
- 统一一个规范主域名
根目录
root /var/www/example.com/public;这是很多现代 PHP 框架的推荐做法,因为:
- public 之外的文件不会被直接暴露
- 路由入口统一到 index.php
PHP 请求转发
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}这部分是 Nginx 和 PHP-FPM 的核心连接点。注意:
- fastcgi_pass 的 socket 必须和 FPM 池配置一致
- PHP 版本不同,socket 路径通常不同
静态资源缓存
静态资源建议设置较长缓存:
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|webp|woff|woff2)$ {
expires 30d;
access_log off;
}如果你的资源文件名带 hash,可以考虑更长缓存。
目录保护
location ~ /\.(?!well-known).* {
deny all;
}用于阻止访问隐藏文件,例如 .env、.git 等。
WordPress 兼容模板
如果站点是 WordPress,可以使用更贴合 WordPress 的路由:
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
root /var/www/example.com;
index index.php index.html;
access_log /var/log/nginx/example.com/access.log;
error_log /var/log/nginx/example.com/error.log;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
client_max_body_size 64m;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|webp)$ {
expires 30d;
access_log off;
}
location ~ /\. {
deny all;
}
}Laravel 兼容模板
Laravel 通常使用 public 目录作为入口:
location / {
try_files $uri $uri/ /index.php?$query_string;
}如果你是 Laravel 或类似框架,这种模板更适合。
PHP.ini 和上传限制
站点上线时,常见还需要配合 PHP 的配置:
upload_max_filesize = 64M
post_max_size = 64M
memory_limit = 256M
max_execution_time = 60
date.timezone = Asia/Shanghai此外,Nginx 也要放宽上传:
client_max_body_size 64m;权限建议
站点目录权限要和 PHP-FPM 用户一致。
常见做法:
sudo chown -R www-data:www-data /var/www/example.com
sudo find /var/www/example.com -type d -exec chmod 755 {} \;
sudo find /var/www/example.com -type f -exec chmod 644 {} \;建议:
- 可写目录只放到必要路径
- 不要给整个站点 777
- 不要让 Web 用户拥有不必要的源码写权限
配置检查与重载
修改后先检查:
sudo nginx -t
sudo php-fpm8.2 -t重载:
sudo systemctl reload nginx
sudo systemctl reload php8.2-fpm如果改动较大,可以重启:
sudo systemctl restart nginx
sudo systemctl restart php8.2-fpm日志排查
Nginx 日志
sudo tail -f /var/log/nginx/example.com/error.log
sudo tail -f /var/log/nginx/example.com/access.logPHP-FPM 日志
sudo journalctl -u php8.2-fpm -xe常见排障顺序
- 看 Nginx error log
- 看 PHP-FPM 服务日志
- 检查 socket 是否存在
- 检查权限
- 检查 fastcgi_pass
常见问题
1. 502 Bad Gateway
通常原因:
- PHP-FPM 没启动
- socket 路径错误
- socket 权限不对
- PHP 版本不一致
2. 404 或路由失效
常见于:
- try_files 写错
- 站点根目录不对
- 框架入口文件路径不对
3. 上传失败
检查:
- client_max_body_size
- upload_max_filesize
- post_max_size
- 目录权限
4. 证书路径错误
检查:
- Let’s Encrypt 证书路径是否存在
- 域名是否与证书一致
- ssl_certificate 和 ssl_certificate_key 是否配对
5. 页面空白
检查 PHP 错误日志、FPM 日志和业务日志。
最小可用流程
sudo apt update
sudo apt install -y nginx php8.2-fpm php8.2-mysql php8.2-xml php8.2-curl php8.2-mbstring php8.2-zip php8.2-gd
sudo systemctl enable nginx php8.2-fpm
sudo systemctl start nginx php8.2-fpm
sudo mkdir -p /var/www/example.com/public然后:
- 写入 Nginx 站点配置
- 放置 PHP 应用文件
- 检查 nginx -t
- 检查 php-fpm8.2 -t
- 重载服务
结论
Nginx + PHP-FPM 的核心是“站点模板统一、PHP 版本明确、socket 对齐、HTTPS 可用、日志可查”。
真正可用的模板应该同时处理:
- HTTP 到 HTTPS 跳转
- 静态资源缓存
- PHP 转发
- 目录保护
- 上传限制
- 错误日志
- 权限
如果你要,我可以继续把这篇文档扩成更深入的版本,例如:
- WordPress 专用 Nginx + PHP-FPM 模板
- Laravel / Symfony 专用模板
- 多站点多池隔离方案
- HTTPS + acme.sh 自动续期联动
- 高并发与缓存优化模板