Web 服务器搭建完全指南:Nginx / Apache / Caddy

Web 服务器搭建完全指南:Nginx / Apache / Caddy

Web 服务器是网站的引擎。本指南帮您在 Nginx、Apache、Caddy 中做出正确选择,并手把手完成安装、PHP-FPM 集成、反向代理,以及用 Certbot 或 acme.sh 申请 SSL 证书——从零到一个完整的 HTTPS 站点。

⚖️ 选型对比:Nginx / Apache / Caddy

在开始安装前,先了解三位"选手"的核心差异,选对工具能让您事半功倍。

🟢 Nginx 高性能反向代理首选 ✅ 优点 +异步事件驱动,适合高并发连接+资源占用可预测并可按负载调优+反向代理与负载均衡功能完整+静态文件服务成熟 ⚠️ 注意 –配置语法需要一定学习成本–动态配置需要 reload(无 .htaccess) 🎯 最适合 静态网站、反向代理、API 网关、高并发场景

🔴 Apache 老牌生态最完整 ✅ 优点 +.htaccess 支持目录级动态配置+PHP mod_php 深度集成,零配置+模块生态最丰富,文档最完善+兼容大量老旧 PHP 应用 ⚠️ 注意 –高并发下每连接一线程,内存消耗大–默认配置性能不如 Nginx 🎯 最适合 传统 PHP 应用(WordPress/Drupal)、需要 .htaccess 的场景

🔵 Caddy 零配置自动 HTTPS ✅ 优点 +自动申请、配置、续期 SSL 证书+配置文件极简,3行搞定 HTTPS 站点+原生支持 HTTP/2 和 HTTP/3+Go 语言编写,单二进制无依赖 ⚠️ 注意 –生态和社区不如 Nginx/Apache 成熟–高级调优选项较少 🎯 最适合 个人项目、快速原型、不想折腾 SSL 的场景

💡 一句话推荐:不知道选哪个?选 Nginx——它覆盖了 95% 的场景。只有两种例外:① 您的 PHP 应用依赖 .htaccess 动态配置 → 选 Apache;② 您不想碰 SSL 配置,要最省心 → 选 Caddy。

🟢 Nginx:安装、配置与性能调优

Nginx(发音 "engine-x")以异步事件驱动架构著称,单进程可处理数万并发连接,是目前最主流的 Web 服务器,全球市占率超过 35%。

安装与验证 安装 Nginx # ── Ubuntu / Debian ──────────────────────────────────────────────────────────

sudo apt update && sudo apt install nginx -y

# 启动并设置开机自启

sudo systemctl enable --now nginx

# 验证安装:访问 http://服务器IP 应看到 "Welcome to nginx!" 页面

curl -I http://localhost # 应返回 200 OK

# ── CentOS / AlmaLinux / RHEL ─────────────────────────────────────────────────

sudo yum install nginx -y

sudo systemctl enable --now nginx

📁 Nginx 核心目录速查 /etc/nginx/nginx.conf 主配置文件:全局 worker、日志、http 块 /etc/nginx/conf.d/*.conf 站点配置目录(CentOS 直接生效) /etc/nginx/sites-available/ 站点配置存放目录(Ubuntu/Debian) /etc/nginx/sites-enabled/ 已激活的站点(软链接到 sites-available) /var/log/nginx/access.log 访问日志(每条请求) /var/log/nginx/error.log 错误日志(排查问题首选) 静态网站配置 /etc/nginx/conf.d/mysite.conf # 文件路径:/etc/nginx/conf.d/mysite.conf

# Ubuntu/Debian 也可放到 /etc/nginx/sites-available/mysite.conf(需创建软链接激活)

server {

listen 80;

listen [::]:80; # 同时监听 IPv6

server_name example.com www.example.com; # 您的域名

root /var/www/mysite; # 网站根目录

index index.html index.htm index.php; # 默认首页文件顺序

# 日志(每个站点独立日志,便于排查)

access_log /var/log/nginx/mysite_access.log;

error_log /var/log/nginx/mysite_error.log warn;

# 静态文件请求处理:先找文件,再找目录,最后返回 404

location / {

try_files $uri $uri/ =404;

}

# 静态资源长期缓存(图片/CSS/JS/字体)

location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff2|svg)$ {

expires 30d;

add_header Cache-Control "public, immutable";

}

# 禁止访问隐藏文件(.git/.env 等)

location ~ /\. {

deny all;

access_log off;

log_not_found off;

}

}

性能调优:nginx.conf 全局优化 /etc/nginx/nginx.conf(性能调优版) # 文件路径:/etc/nginx/nginx.conf

# 以下配置针对 2核4GB 服务器调优,根据实际硬件调整数值

# ── 全局块 ────────────────────────────────────────────────────────────────────

worker_processes auto; # 自动匹配 CPU 核心数(推荐)

worker_rlimit_nofile 65535; # 每个 worker 进程最大打开文件数

events {

worker_connections 4096; # 每个 worker 的最大并发连接数

multi_accept on; # 一次接受所有新连接(提升突发连接效率)

use epoll; # Linux 最高效的 I/O 事件模型

}

http {

# ── 基础安全 ──────────────────────────────────────────────────────────────

server_tokens off; # 隐藏 Nginx 版本号(防止版本探测)

# ── 连接优化 ──────────────────────────────────────────────────────────────

keepalive_timeout 65; # 保持 HTTP 长连接 65 秒

keepalive_requests 1000; # 单个长连接最多处理 1000 个请求

client_header_timeout 15; # 读取请求头超时(防慢速攻击)

client_body_timeout 15;

send_timeout 15;

# ── Gzip 压缩(减少 60-80% 传输体积)────────────────────────────────────

gzip on;

gzip_vary on; # 告知代理服务器缓存 gzip 版本

gzip_proxied any; # 对代理请求也压缩

gzip_comp_level 6; # 压缩级别 1-9,6 是性能与压缩率的最佳平衡点

gzip_min_length 1000; # 小于 1KB 的响应不压缩

gzip_types

text/plain text/css text/xml text/javascript

application/json application/javascript application/xml

application/x-font-ttf font/opentype image/svg+xml;

# ── 文件缓存(减少磁盘 I/O)───────────────────────────────────────────────

open_file_cache max=10000 inactive=30s; # 缓存最多 10000 个文件描述符

open_file_cache_valid 60s;

open_file_cache_min_uses 2; # 至少访问 2 次才缓存

open_file_cache_errors on;

# ── 请求限速(防 CC 攻击,从第12篇 security-advanced 引入)────────────────

limit_req_zone $binary_remote_addr zone=perip:10m rate=30r/s;

limit_conn_zone $binary_remote_addr zone=addr:10m;

include /etc/nginx/conf.d/*.conf;

}

反向代理配置 /etc/nginx/conf.d/api.conf(反向代理) # 反向代理:将域名请求转发到后端应用(Node.js/Python/Go 等)

# 文件路径:/etc/nginx/conf.d/api.conf

upstream backend_app {

# keepalive 保持与后端的持久连接,减少 TCP 握手开销

keepalive 32;

server 127.0.0.1:3000; # 后端应用地址和端口

# server 127.0.0.1:3001; # 可以添加多个后端实现负载均衡

}

server {

listen 80;

server_name api.example.com;

# 应用连接限速规则

limit_req zone=perip burst=50 nodelay;

location / {

proxy_pass http://backend_app;

proxy_http_version 1.1;

# WebSocket 支持(如果后端有 WS 连接需要这两行)

proxy_set_header Upgrade $http_upgrade;

proxy_set_header Connection "upgrade";

# 传递真实客户端信息到后端

proxy_set_header Host $host;

proxy_set_header X-Real-IP $remote_addr;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_set_header X-Forwarded-Proto $scheme;

# 超时配置(后端响应超过此时间返回 504)

proxy_connect_timeout 10s;

proxy_send_timeout 60s;

proxy_read_timeout 60s;

# 缓冲区(防止后端慢速导致 worker 阻塞)

proxy_buffering on;

proxy_buffer_size 8k;

proxy_buffers 16 8k;

}

}

负载均衡配置 upstream 负载均衡配置 # 负载均衡:将流量分散到多台后端服务器

upstream web_cluster {

# least_conn:将请求发到当前连接数最少的服务器(适合耗时不均的请求)

least_conn;

server backend1.example.com:8080 weight=3; # weight 越大获得越多流量

server backend2.example.com:8080 weight=2;

server backend3.example.com:8080 weight=1;

# backup:仅在其他服务器全部不可用时启用

# server backup.example.com:8080 backup;

keepalive 64;

}

# 其他负载均衡策略:

# round_robin(默认):轮询,最简单

# ip_hash:同一 IP 始终路由到同一后端(适合 Session 不共享的场景)

# hash $request_uri consistent:按 URL 哈希(适合缓存命中率优化)

🐘 实战:Nginx + PHP-FPM 完整部署

PHP-FPM(FastCGI Process Manager)是 Nginx 处理 PHP 的标准方案。与 Apache 的 mod_php 不同,PHP-FPM 作为独立进程运行,Nginx 通过 Unix Socket 与其通信,资源占用更低,性能更好。

安装发行版支持的 PHP-FPM 安装 PHP-FPM + 常用扩展 # ── 使用发行版仓库安装受支持的 PHP-FPM ─────────────────────────────────────

sudo apt update

sudo apt install -y php-fpm php-mysql php-curl php-gd php-intl php-mbstring php-xml php-zip php-bcmath php-imagick

# 先查实际服务名、版本与 socket,再写 Nginx/Caddy 配置

systemctl list-unit-files 'php*-fpm.service'

# 将 X.Y 替换成上一步显示的实际版本

sudo systemctl enable --now phpX.Y-fpm.service

php -v

find /run/php -maxdepth 1 -type s -name 'php*-fpm.sock' -print

# 若应用要求发行版仓库之外的 PHP 版本,先核对应用支持矩阵、

# 第三方仓库签名、升级和回退路径,不要直接套用其他发行版的 PPA。

Nginx 配置 PHP-FPM(WordPress 完整示例) /etc/nginx/conf.d/wordpress.conf # 文件路径:/etc/nginx/conf.d/wordpress.conf

# WordPress + Nginx + PHP-FPM 完整配置

server {

listen 80;

server_name yourblog.com www.yourblog.com;

root /var/www/wordpress;

index index.php index.html;

# WordPress 固定链接支持

location / {

try_files $uri $uri/ /index.php?$args;

}

# PHP 文件通过 FastCGI 交给 PHP-FPM 处理

location ~ \.php$ {

# 防止 Nginx 处理不存在的 PHP 文件(安全)

try_files $uri =404;

fastcgi_split_path_info ^(.+\.php)(/.+)$;

# 替换 X.Y:以 find /run/php 查到的实际 socket 为准

fastcgi_pass unix:/run/php/phpX.Y-fpm.sock;

fastcgi_index index.php;

# 传递标准 FastCGI 参数

include fastcgi_params;

fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

fastcgi_param PATH_INFO $fastcgi_path_info;

# FastCGI 缓冲(减少 PHP-FPM 进程等待时间)

fastcgi_buffering on;

fastcgi_buffer_size 16k;

fastcgi_buffers 16 16k;

fastcgi_read_timeout 120s;

}

# WordPress 上传文件大小限制

client_max_body_size 64M;

# 禁止访问 WordPress 敏感文件

location ~* /wp-config\.php { deny all; }

location ~* /xmlrpc\.php { deny all; } # 禁用 XML-RPC 防暴力破解

location ~* /\. { deny all; } # 禁止访问隐藏文件

}

PHP-FPM 进程池调优 /etc/php/8.3/fpm/pool.d/www.conf # 文件路径:/etc/php/X.Y/fpm/pool.d/www.conf(替换实际版本)

# PHP-FPM 进程池配置(根据服务器内存调整)

[www]

user = www-data

group = www-data

# ── 进程管理模式 ──────────────────────────────────────────────────────────────

# dynamic(推荐):根据负载动态调整进程数,平衡性能与内存

pm = dynamic

# 进程数参考公式(以每个 PHP 进程占 50MB 内存为例):

# pm.max_children = 可用内存(MB) / 50

pm.max_children = 20 # 1GB 内存约设 20

pm.start_servers = 5 # 启动时初始化 5 个进程

pm.min_spare_servers = 3 # 最少保留 3 个空闲进程

pm.max_spare_servers = 8 # 最多保留 8 个空闲进程

# 每个进程处理 500 个请求后重启(防内存泄漏)

pm.max_requests = 500

# ── PHP 运行时配置(覆盖 php.ini)────────────────────────────────────────────

php_value[memory_limit] = 256M

php_value[upload_max_filesize] = 64M

php_value[post_max_size] = 64M

php_value[max_execution_time] = 120

# 开启 PHP-FPM 慢日志(记录超过 5 秒的请求,性能调优利器)

slowlog = /var/log/php-fpm-slow.log

request_slowlog_timeout = 5s

🔴 Apache:安装、虚拟主机与 PHP 集成

Apache 拥有 30 年历史,其 mod_php 深度集成让 PHP 应用的部署极其简单,.htaccess 的目录级动态配置也让它在共享主机环境中无可替代。

安装 Apache 安装 Apache # ── Ubuntu / Debian ──────────────────────────────────────────────────────────

sudo apt update && sudo apt install apache2 -y

sudo systemctl enable --now apache2

# ── CentOS / RHEL(软件包名为 httpd)─────────────────────────────────────────

sudo yum install httpd -y

sudo systemctl enable --now httpd

# 验证:访问 http://服务器IP 应看到 Apache 欢迎页

curl -I http://localhost

虚拟主机配置 /etc/apache2/sites-available/mysite.conf # 文件路径:/etc/apache2/sites-available/mysite.conf(Ubuntu)

# CentOS:/etc/httpd/conf.d/mysite.conf

ServerName example.com

ServerAlias www.example.com

DocumentRoot /var/www/mysite

Options -Indexes +FollowSymLinks # 禁止目录浏览,允许符号链接

AllowOverride All # 允许 .htaccess(如不需要改 None 提升性能)

Require all granted

# 日志(每站点独立)

ErrorLog ${APACHE_LOG_DIR}/mysite_error.log

CustomLog ${APACHE_LOG_DIR}/mysite_access.log combined

# ── Ubuntu 激活站点 ───────────────────────────────────────────────────────────

# sudo a2ensite mysite.conf

# sudo a2enmod rewrite # 启用 URL 重写模块(WordPress 必需)

# sudo systemctl reload apache2

.htaccess 配置(URL 重写与安全规则) /var/www/mysite/.htaccess # 文件路径:/var/www/mysite/.htaccess

# 注意:AllowOverride All 时 Apache 才会读取此文件

# ── 开启 URL 重写 ─────────────────────────────────────────────────────────────

RewriteEngine On

# 强制 HTTPS(HTTP 全部跳转到 HTTPS)

RewriteCond %{HTTPS} off

RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]

# 去除 www 前缀(统一规范 URL)

RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]

RewriteRule ^(.*)$ https://%1/$1 [R=301,L]

# WordPress 固定链接(所有 PHP 不存在的路径交给 index.php)

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule ^(.*)$ index.php?route=$1 [L,QSA]

# 禁止访问敏感文件

Require all denied

常用模块管理与 PHP 集成 sudo a2enmod rewrite URL 重写(WordPress/Laravel 必需)

sudo a2enmod ssl SSL/HTTPS 支持

sudo a2enmod headers 自定义 HTTP 响应头

sudo a2enmod deflate Gzip 压缩

sudo a2enmod expires 浏览器缓存控制

sudo a2ensite mysite 激活站点配置

模块变更后执行 sudo systemctl restart apache2 生效。PHP 集成:sudo apt install php libapache2-mod-php php-mysql -y,安装后 Apache 自动加载 PHP 模块,无需额外配置。

🔵 Caddy:零配置自动 HTTPS

Caddy 是最省心的 Web 服务器——它会自动申请 Let's Encrypt 证书、自动续期、自动将 HTTP 跳转到 HTTPS,您只需写几行配置文件。

安装 Caddy 安装 Caddy(官方 APT 源) # ── Ubuntu / Debian ──────────────────────────────────────────────────────────

# 添加 Caddy 官方 APT 源

apt install -y debian-keyring debian-archive-keyring apt-transport-https curl

curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg

curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list

apt update && apt install caddy -y

# ── CentOS / RHEL ─────────────────────────────────────────────────────────────

# 参考官方文档:https://caddyserver.com/docs/install#fedora-redhat-centos

# 验证安装

systemctl status caddy

caddy version

最简 Caddyfile(3行搞定 HTTPS 站点) /etc/caddy/Caddyfile # 文件路径:/etc/caddy/Caddyfile

# 这 3 行就是一个完整的 HTTPS 静态网站!

example.com {

root * /var/www/mysite # 网站根目录

file_server # 开启文件服务器(自动处理静态文件)

# Caddy 自动为 example.com 申请 Let's Encrypt 证书,自动续期,自动 HTTP→HTTPS 跳转

}

✨ Caddy 的自动化魔法: 只要域名已解析到本服务器,Caddy 就会自动完成:① 向 Let's Encrypt 申请证书 → ② 配置 HTTPS → ③ 设置 HTTP 自动跳转 → ④ 90 天后自动续期。前提:80 和 443 端口对外开放,且服务器能访问公网。

高级 Caddyfile(多域名、反代、PHP-FPM) /etc/caddy/Caddyfile(高级版) # 文件路径:/etc/caddy/Caddyfile

# 完整的高级配置示例

# 主站:静态 + PHP 博客

example.com {

root * /var/www/mysite

file_server

encode gzip # 启用 Gzip 压缩

# 反向代理特定路径到后端 API

reverse_proxy /api/* localhost:3000

# PHP-FPM 集成

php_fastcgi unix//run/php/phpX.Y-fpm.sock

# 安全响应头

header {

X-Content-Type-Options "nosniff"

X-Frame-Options "DENY"

Referrer-Policy "strict-origin-when-cross-origin"

-Server # 删除 Server 响应头

}

# 自定义日志格式

log {

output file /var/log/caddy/example.log {

roll_size 100mb

roll_keep 10

}

format console

}

}

# API 子域名:纯反向代理

api.example.com {

reverse_proxy localhost:8080

}

# 图床子域名:静态文件服务

cdn.example.com {

root * /var/www/uploads

file_server browse # browse 显示目录列表(内部使用)

}

# 重载配置(不中断现有连接)

# sudo systemctl reload caddy

🔒 SSL 证书:Certbot 与 acme.sh 双方案

HTTPS 已是现代网站的标配,对 SEO 和用户信任都有直接影响。以下提供两套证书申请方案:Certbot(官方工具,自动修改 Nginx/Apache 配置)和 acme.sh(纯 Shell 脚本,支持泛域名和 DNS 验证,无需开放 80 端口)。

🤖Certbot 官方 EFF 维护,文档最全自动修改 Nginx/Apache 配置新手最友好 适合:首次配置 SSL,单一域名场景

⚡acme.sh 支持 *.example.com 泛域名DNS 验证无需开放 80 端口支持多个 CA(Let's Encrypt/ZeroSSL) 适合:泛域名证书、CDN 场景、无 80 端口

方案一:Certbot(推荐新手) Certbot 安装与申请证书 # ── Ubuntu / Debian ──────────────────────────────────────────────────────────

sudo apt install certbot python3-certbot-nginx python3-certbot-apache -y

# ── CentOS / RHEL(需要 EPEL)─────────────────────────────────────────────────

sudo dnf install epel-release -y

sudo dnf install certbot python3-certbot-nginx python3-certbot-apache -y

# ── 方式一:自动模式(推荐,Certbot 自动修改 Nginx/Apache 配置)─────────────

# Nginx:

sudo certbot --nginx -d example.com -d www.example.com

# 按提示:输入邮箱 → 同意条款 → 选择是否跳转 HTTPS → 完成

# Apache:

sudo certbot --apache -d example.com -d www.example.com

# ── 方式二:certonly 模式(只获取证书,手动配置)──────────────────────────────

# 适合:使用 Docker 或非标准路径的场景

sudo certbot certonly --webroot -w /var/www/mysite -d example.com -d www.example.com --email admin@example.com --agree-tos

# 证书文件位置:

# 证书:/etc/letsencrypt/live/example.com/fullchain.pem

# 私钥:/etc/letsencrypt/live/example.com/privkey.pem

# ── 验证自动续期 ──────────────────────────────────────────────────────────────

sudo certbot renew --dry-run # 模拟续期(不实际执行)

sudo certbot certificates # 查看所有证书及到期时间

方案二:acme.sh 申请泛域名证书(进阶推荐) acme.sh + Cloudflare DNS API 申请 *.example.com # ── acme.sh 申请泛域名证书(DNS-01 场景)──────────────────────────────────

# 1. 从官方仓库下载到本地,核对来源并审阅安装脚本

git clone --depth 1 https://github.com/acmesh-official/acme.sh.git /tmp/acme.sh

cd /tmp/acme.sh

less acme.sh

./acme.sh --install -m admin@example.com

# 2. 在权限为 600 的文件中提供最小权限 DNS API Token

# /etc/vpsknow/acme-dns.env 仅允许证书任务用户读取,不提交到 Git

set -a

. /etc/vpsknow/acme-dns.env

set +a

# 3. 申请泛域名证书(* 号匹配所有子域名)

"$HOME/.acme.sh/acme.sh" --issue --dns dns_cf -d example.com -d "*.example.com" --server letsencrypt

# 4. 把证书部署到稳定路径;不要让 Nginx 直接读取 acme.sh 内部目录

"$HOME/.acme.sh/acme.sh" --install-cert -d example.com -d "*.example.com" --cert-file /etc/nginx/ssl/example.com/cert.pem --key-file /etc/nginx/ssl/example.com/key.pem --fullchain-file /etc/nginx/ssl/example.com/fullchain.pem --reloadcmd "systemctl reload nginx" # 安装后自动 reload

# 5. 检查安装程序创建的定时任务,并执行一次续期演练

crontab -l | grep acme

"$HOME/.acme.sh/acme.sh" --cron --home "$HOME/.acme.sh"

unset CF_Token CF_Zone_ID

Nginx HTTPS 完整配置(含 HTTP/2 和安全响应头) /etc/nginx/conf.d/mysite.conf(HTTPS 完整版) # 申请证书后,将 HTTP server 块升级为 HTTPS

# 文件路径:/etc/nginx/conf.d/mysite.conf

# HTTP → HTTPS 跳转

server {

listen 80;

listen [::]:80;

server_name example.com www.example.com;

return 301 https://$host$request_uri;

}

# HTTPS 主配置

server {

listen 443 ssl;

listen [::]:443 ssl;

http2 on; # 需当前 Nginx 构建包含 HTTP/2 模块

server_name example.com www.example.com;

# 证书路径(Certbot 自动填充 / acme.sh 手动指定)

ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;

ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

# ── SSL 安全配置(Mozilla 现代级别)──────────────────────────────────────

ssl_protocols TLSv1.2 TLSv1.3; # 只允许 TLS 1.2/1.3,禁用旧版

ssl_prefer_server_ciphers off; # 让客户端选择最佳密码套件

ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;

# SSL Session 复用(减少重复握手开销)

ssl_session_cache shared:SSL:10m;

ssl_session_timeout 1d;

# HSTS:强制浏览器永远使用 HTTPS(慎用,设置后很难撤销)

add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;

# 安全响应头

add_header X-Frame-Options "SAMEORIGIN" always;

add_header X-Content-Type-Options "nosniff" always;

add_header X-XSS-Protection "1; mode=block" always;

server_tokens off;

root /var/www/mysite;

index index.html;

location / {

try_files $uri $uri/ =404;

}

}

💡 SSL 配置质量检测: 配置完成后,访问 SSL Labs 在线测试,输入您的域名,目标是获得 A+ 评级。本文的配置模板已经达到 Mozilla 现代级别安全标准,正确配置后应直接获得 A+。

🔧 故障排查速查手册

故障排查通用命令 # ════════════════════════════════════════════════════════════════════

# Web 服务器故障排查速查手册

# ════════════════════════════════════════════════════════════════════

# ── 通用:查看服务状态与日志 ──────────────────────────────────────────────────

systemctl status nginx # 服务是否运行

journalctl -u nginx -n 50 -p err # 最近 50 条 error 日志

tail -f /var/log/nginx/error.log # 实时错误日志

# ── Nginx:配置语法检查与重载 ─────────────────────────────────────────────────

nginx -t # 测试配置文件语法(出错显示具体位置)

systemctl reload nginx # 语法无误后优雅重载(不中断连接)

# !永远不要跳过 nginx -t 直接 reload,语法错误会导致 Nginx 完全停止

# ── 端口占用检查 ──────────────────────────────────────────────────────────────

ss -tlnp | grep ':80|:443' # 查看 80/443 端口被哪个进程占用

lsof -i :80 # 同上,另一种方式

# ── 权限问题(403 Forbidden)─────────────────────────────────────────────────

# Nginx 以 www-data 用户运行,网站目录必须对其可读

chown -R www-data:www-data /var/www/mysite

chmod -R 755 /var/www/mysite # 目录 755,文件 644

chmod 644 /var/www/mysite/index.html

# ── PHP-FPM 连接问题 ──────────────────────────────────────────────────────────

systemctl status 'php*-fpm.service' # FPM 是否运行

find /run/php -type s -name 'php*-fpm.sock' -print # 实际 socket

# 若 socket 不存在,检查 /etc/php/8.3/fpm/pool.d/www.conf 中的 listen 配置

# ── SSL 证书问题 ──────────────────────────────────────────────────────────────

openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates

# 输出 notAfter 即到期时间

certbot certificates # 查看所有证书状态

启动 Nginx 报错"端口已被占用"(Address already in use)

80/443 端口被其他进程占用。排查步骤:① ss -tlnp | grep ':80' 查看占用进程;② 常见"凶手":Apache(systemctl stop apache2)、面板安装的 Nginx(systemctl stop openresty)、Python 测试服务器;③ 若需要两个服务共存,给其中一个改端口,前面用 Nginx 做反向代理统一出口。

访问网站显示 403 Forbidden

三种常见原因:① 权限问题:chown -R www-data:www-data /var/www/mysite && chmod -R 755 /var/www/mysite;② 缺少索引文件:目录下没有 index.html/index.php,且配置了 try_files ... =404;③ SELinux 拦截(CentOS):chcon -Rt httpd_sys_content_t /var/www/mysite 或临时 setenforce 0 测试是否是 SELinux 原因。

502 Bad Gateway(反向代理场景)

Nginx 无法连接后端服务。检查顺序:① curl http://localhost:3000 直接测试后端是否响应;② systemctl status 后端服务名 确认服务在运行;③ 检查 proxy_pass 中的端口与后端实际监听端口是否一致;④ 查看 tail -f /var/log/nginx/error.log 获取具体错误原因——"connection refused" 表示后端没运行,"timeout" 表示后端运行但响应太慢。

Certbot 申请证书失败

按可能性从高到低排查:① DNS 未生效:dig example.com 确认解析到当前服务器 IP;② 80 端口被防火墙拦截:ufw allow 80/tcp,Let's Encrypt 的 HTTP-01 验证必须能访问 80 端口;③ Nginx/Apache 未运行:Certbot 需要 Web 服务器配合完成验证;④ 频率限制:同一域名每周最多申请 5 次,超限需等 7 天,可用 --staging 参数测试(不消耗配额);⑤ 备选:改用 acme.sh + DNS API 验证,完全绕开 80 端口问题。

PHP 文件直接下载而不执行(显示代码而不是网页)

Nginx 没有配置 PHP-FPM 处理 .php 文件。确认配置中有正确的 location ~ \.php$ 块,并且 fastcgi_pass 指向 find /run/php -type s -name 'php*-fpm.sock' 查到的实际 socket。Apache 可按发行版方式使用 PHP-FPM 或对应模块,但不要把其他系统、其他 PHP 版本的模块名直接照搬。

修改配置后不生效

修改配置后必须重载服务:Nginx → nginx -t && systemctl reload nginx(先测试语法);Apache → apachectl configtest && systemctl reload apache2;Caddy → systemctl reload caddy。浏览器缓存也是常见"元凶"——用 Chrome 按 Ctrl+Shift+R 强制刷新,或开无痕窗口测试。Ubuntu 的 sites-available 配置还需要 a2ensite/ln -s 创建软链接激活,否则修改不会被读取。

如何查看 Web 服务器实时日志?

Nginx 错误日志:tail -f /var/log/nginx/error.log;访问日志:tail -f /var/log/nginx/access.log。Apache:tail -f /var/log/apache2/error.log。Caddy:journalctl -u caddy -f。用 grep " 500 \| 502 \| 503 " /var/log/nginx/access.log | tail -20 快速过滤错误请求。详细的日志分析方法参见第 12 篇日志分析指南。

Nginx 性能测试显示并发很低,如何优化?

不要先批量放大连接数和文件描述符。先用访问日志、stub_status 或指标系统确认排队位置,再对比静态文件、上游应用和数据库耗时;同时检查 CPU、内存、磁盘等待、上游连接池和 499/502/504。只有证据指向连接或描述符上限时,才同步核算 systemd unit、操作系统与 Nginx 的有效限制,单变量调整并压测验收。压测必须针对自有或已授权目标,从低并发逐步增加,并保留配置备份与回退。

❓ 常见问题解答 Nginx 和 Apache 可以同时安装在一台服务器上吗?

可以安装,但不能同时监听 80/443 端口。经典方案:让 Nginx 监听 80/443 对外,Apache 监听 8080/8888 对内,Nginx 将动态 PHP 请求反代到 Apache(proxy_pass http://127.0.0.1:8080)。但这种架构增加了复杂度,现代方案推荐 Nginx + PHP-FPM 的组合,比 Nginx + Apache 性能更好,资源占用更低。只有当您有无法去掉 .htaccess 的老 PHP 应用时,才值得考虑双服务器方案。

Let's Encrypt 的免费证书和付费证书有什么区别?值得买付费证书吗?

对于绝大多数个人站长和中小企业,Let's Encrypt 免费证书完全够用——它提供的加密强度与付费证书完全相同,浏览器显示的"🔒"小锁也没有区别。付费证书主要差异:① OV(组织验证)证书:CA 会验证公司真实性,证书信息中显示公司名称,适合有公信力要求的企业;② EV(扩展验证)证书:最高级别验证,以前浏览器会显示绿色地址栏(现代浏览器已取消),金融/政府机构使用;③ 通配符付费证书:一次购买可用于所有子域名,而 Let's Encrypt 的泛域名证书通过 acme.sh 可以免费获得。结论:个人博客/企业官网/API 服务用 Let's Encrypt 完全足够;只有银行/证券/政府类网站才需要考虑 OV/EV 付费证书。

服务器已经用了 1Panel 面板管理 Nginx,还需要学手动配置吗?

强烈建议学。原因:① 面板出问题时需要手动排查:当面板显示 "Nginx 配置错误" 时,您需要能读懂 /etc/nginx/conf.d/ 下的具体配置文件来定位问题;② 面板的"自定义配置"框需要你写 Nginx 语法:实现复杂的 location 规则、特殊 Header 配置时,面板只提供了输入框,内容要您自己写;③ 理解底层让您更有掌控感:知道面板的"反向代理"按钮背后生成了什么配置,出了问题才能从容应对。第 13 篇的面板是加速器,本篇是理解地基——两者互为补充,不是替代关系。

HTTP/2 和 HTTP/3 有什么区别?应该开哪个?

HTTP/2 在一条 TCP 连接中复用多个流,HTTP/3 则基于 QUIC/UDP;两者的实际收益取决于页面结构、缓存、网络和客户端,不能承诺固定百分比。启用 HTTP/2 前用 nginx -V 核对模块与 TLS/ALPN 支持,修改后先运行 nginx -t,再以真实浏览器和回退到 HTTP/1.1 的客户端验收。Nginx 官方自 1.25.0 提供 QUIC/HTTP/3 支持,但仍需核对当前软件包、TLS 库、UDP 443、防火墙和客户端;应灰度启用并保留 HTTP/2 回退,观察错误率、握手和响应指标后再扩大范围。参见 HTTP/2 模块 与 QUIC 官方文档。

WordPress 部署在 Nginx 上,固定链接 404,是什么原因?

WordPress 的固定链接(如 /2026/03/my-post/)依赖 URL 重写,Nginx 需要正确配置 try_files。在 Nginx 的 server 块 location / 中添加:try_files $uri $uri/ /index.php?$args;——这行的含义是:先找文件,再找目录,都不存在就交给 index.php 处理(WordPress 的路由入口)。缺少这行就会导致固定链接 404。如果是 Apache,则需要确认已启用 mod_rewrite 并且 AllowOverride All,WordPress 会通过 .htaccess 自动添加重写规则。

一台 Nginx 服务器能托管多少个网站?有数量限制吗?

Nginx 配置本身通常不是首先触顶的限制,容量取决于每个站点的请求率、缓存命中、PHP-FPM 进程、数据库、磁盘 I/O、备份窗口和故障隔离。不要按“2GB 能放几个 WordPress”的固定经验上线:先测单站峰值内存和请求耗时,给系统、数据库及突发流量保留余量,再用监控逐步增加站点。不同信任边界或不同客户的站点还应考虑账号、进程、数据库和备份隔离,避免一个站点拖垮全部业务。

Caddy 的自动证书存储在哪里?能导出给 Nginx 用吗?

Caddy 将证书存储在 /var/lib/caddy/.local/share/caddy/certificates/acme-v02.api.letsencrypt.org-directory/(或 ~/.local/share/caddy/,取决于运行用户)。证书文件是标准的 PEM 格式,技术上可以复制给 Nginx 用,但不推荐这种做法——Caddy 自动续期后文件路径不变,但 Nginx 不会自动 reload,导致 Nginx 仍用旧证书。更好的做法:如果您需要 Nginx,直接用 Certbot 或 acme.sh 为 Nginx 申请证书;或者让 Caddy 作为前端代理,Nginx 在后端只处理逻辑,不直接面向公网。

学完 Web 服务器后,下一步应该怎么进阶?

按本站 30 篇路径,第 14 篇(本篇)→ 第 15 篇(docker-deployment)→ 第 16 篇(database-setup)是最紧密的进阶链条。关联逻辑:Docker 和 Nginx 是目前最流行的部署组合——Docker 管理应用容器,Nginx 作为前端反向代理统一对外服务;掌握了本篇的反向代理配置,在第 15 篇中把 proxy_pass 指向 Docker 容器就能实现完整的容器化部署。第 16 篇的数据库搭建则为您的 Web 应用提供数据存储能力,Nginx + PHP-FPM + MySQL 三件套构成了传统 LEMP 栈的全部组件。

PHP-FPM 的 pm.max_children 设置太小会有什么表现?如何判断需要调大?

达到 pm.max_children 时请求可能排队,PHP-FPM 日志通常会出现相应警告,但 499、502 或响应变慢也可能来自其他上游故障。先在真实峰值期间测量 PHP 进程 RSS 分布、队列、请求时长和服务器可用内存,再为系统、缓存、数据库及突发流量保留余量。计算结果只能作为压测起点;逐步调整后要观察 OOM、交换、尾延迟和错误率,不能用固定的“每进程内存”或“1GB 应设多少”作为通用答案。

🚀 下一步行动

Web 服务器搭建完毕,接下来进入容器化与数据库部署:

🐳 Docker 容器化部署 Nginx 反代 + Docker 是最流行的组合,掌握容器编排实现秒级迁移和环境隔离。

开始学习 💾 数据库服务搭建 MySQL / PostgreSQL / Redis 安装配置,为 Web 应用提供完整的数据存储支持。

开始学习 ⭐ VPS 推荐榜单 查看已测评和待测候选 VPS 商家,先看结论再去官网。

查看推荐 📚 浏览更多教程 继续探索服务器安全、网站搭建、性能优化和 AI 环境主题。

探索教程

读完后建议

先验证,再选择 把判断落到具体选择 准备购买 VPS 时,先对照推荐榜单和真实测评确认线路、价格、用途与风险;只是继续学习,可以回到教程索引按主题往下看。

查看推荐榜单 回到教程索引

相关推荐

365平台提现审核未通过 现任中国共产党省级行政区委员会书记列表

现任中国共产党省级行政区委员会书记列表

📅 07-22 👁️ 1522
office365人工客服电话 2.3尺等于多少米

2.3尺等于多少米

📅 11-13 👁️ 8711