web服务
Linux Web 服务器
目录
- 软件包安装
- 认识 Web 服务器:它到底在做什么
- 三大主流 Web 服务器总览
- Nginx 架构:为什么它快
- Nginx 基本配置:server / location / 静态站点
- Nginx 托管动态应用
- Nginx 反向代理与负载均衡
- HTTPS:让网站更安全
- 性能优化与缓存
- 安全加固要点
- Apache httpd:经典之选(对比补充)
- Caddy:自动 HTTPS 的现代之选(对比补充)
- 从零在 Rocky 部署一个完整网站(整合篇)
- 常见问题排查清单
- 总结与选型对比
- 参考资料
软件包安装
本节安装后面会用到的软件。以 Nginx 为主,Apache 与 Caddy 按需安装。
安装 Nginx(Rocky / RHEL / CentOS)
Rocky 的 AppStream 自带 nginx,直接安装:
sudo dnf install -y nginx
sudo systemctl enable --now nginx
sudo systemctl status nginx
安装 Apache httpd(可选,用于对比)
sudo dnf install -y httpd
sudo systemctl enable --now httpd
提示:Nginx 与 Apache 都监听 80/443 端口,不要在同一台机器上同时启用,以免端口冲突。建议在虚拟机里分别实验,或临时停掉另一个服务。
安装 Caddy(可选,用于对比)
sudo dnf install -y caddy
sudo systemctl enable --now caddy
Ubuntu / Debian 差异
# Nginx / Apache / Caddy 在 Ubuntu 上
sudo apt install -y nginx apache2 caddy
# 服务名:nginx / apache2 / caddy
sudo systemctl enable --now nginx apache2
放行 HTTP/HTTPS 端口(防火墙)
sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --reload
# 确认
firewall-cmd --query-service=http
firewall-cmd --query-service=https
若在云上,还要在安全组放行 80/443 端口。
一、认识 Web 服务器:它到底在做什么
1.1 一句话定义
Web 服务器是一台(或一组)运行在网络上的程序:它监听 HTTP 请求,返回响应。浏览器输入网址发出请求,Web 服务器把网页(HTML、图片、脚本等)发回给浏览器。
1.2 一次完整的访问流程
浏览器 --HTTP请求--> Web 服务器(Nginx/Apache/Caddy) --读取--> 网站文件/程序
浏览器 <--HTTP响应-- Web 服务器 <--返回--> 内容
- 你访问
http://example.com,浏览器向服务器 80 端口 发一个 HTTP 请求(如GET /index.html)。 - Web 服务器找到对应的文件(或调用程序生成内容),组装成 HTTP 响应(含状态码、响应头、正文)返回。
- 状态码常见:
200 OK(成功)、301/302(重定向)、404(找不到)、403(禁止)、500(服务器内部错误)。
1.3 静态与动态
- 静态内容:文件本来就在磁盘上(HTML、CSS、JS、图片),Web 服务器直接读文件返回,快。
- 动态内容:内容由程序实时生成(PHP、Python、Java、Node 等),Web 服务器要把请求转发给后端程序,再把结果返回。
静态内容 Web 服务器自己就能搞定;动态内容需要 Web 服务器 + 后端解释器/应用配合(见第五章)。
1.4 为什么有 80 和 443 两个端口
- 80:HTTP(明文)。
- 443:HTTPS(加密,TLS)。
- 现在主流网站都走 HTTPS(443),80 通常用来跳转到 443。
参考:phoenixNAP - What Is a Web Server?
二、三大主流 Web 服务器总览
Linux 上最常用的三类 Web 服务器:Nginx、Apache httpd、Caddy。它们各有侧重:
| 对比项 | Nginx | Apache httpd | Caddy |
|---|---|---|---|
| 出身 | 高性能、高并发 | 老牌、功能全面 | 现代、开箱即用 |
| 处理模型 | 事件驱动、异步 | 每请求一线程/进程 | 事件驱动(Go) |
| 静态文件 | 很快 | 快 | 快 |
| 动态支持 | 配合 PHP-FPM/FastCGI | 内置 mod_php 等模块 | 配合 FastCGI/代理 |
| 配置 | 清晰、较简洁 | 灵活但常较冗长 | 极简(Caddyfile) |
| 自动 HTTPS | 需手动或 certbot | 需手动或 certbot | 内置自动 HTTPS |
| 生态 | 现代网站主流 | 传统托管广泛 | 个人/快速部署 |
| 适合 | 高并发、反向代理 | 传统应用、.htaccess | 个人站点、快速上手 |
Nginx 目前是互联网上占有率最高的 Web 服务器之一,也是本文主线。Apache 经典稳定,Caddy 以自动 HTTPS 闻名。
三、Nginx 架构:为什么它快
要"讲透"Nginx,先理解它的架构——这是它与 Apache 最本质的区别。
3.1 事件驱动、异步、非阻塞
- Nginx 采用 事件驱动(event-driven)+ 异步非阻塞 模型:一个 worker 进程可以同时处理成千上万个连接,而不是"一个请求占一个进程"。
- 这让 Nginx 能用很少的内存支撑很高的并发,尤其擅长静态文件和反向代理。
3.2 master / worker 进程模型
Nginx 运行时有 master 进程 和多个 worker 进程:
master 进程(root) -> 负责管理、读配置、绑定特权端口
worker 进程(nginx 用户)-> 真正处理请求,可配置多个
- master 以 root 运行:为了能绑定特权端口 80/443(<1024),也为了读配置、管理 worker。
- worker 以普通用户(nginx)运行:负责处理请求,降权以增强安全,即使被攻破也拿不到 root。
- worker 数量通常设为 CPU 核心数(
worker_processes auto;)。
3.3 这也解释了端口 80 权限坑
- Linux 中 0–1023 是特权端口,只有 root(或具备
CAP_NET_BIND_SERVICE能力的进程)能监听。 - 普通用户直接监听 80 会报:
bind() to 0.0.0.0:80 failed (13: Permission denied)。 - Nginx 靠 master 进程的 root 权限绑定 80/443,再由 worker 降权干活——这就是它"能监听 80 又相对安全"的原因。
参考:nginx.org - Beginner's Guide
四、Nginx 基本配置:server / location / 静态站点
4.1 配置文件的组织
/etc/nginx/nginx.conf # 主配置
/etc/nginx/conf.d/*.conf # 站点/server 配置(推荐放这里)
/etc/nginx/default.d/ # 默认站点的补充
- 通常做法:在
conf.d/下新建mysite.conf写自己的站点。 - 改完先
nginx -t测试语法,再systemctl reload nginx热加载。
4.2 server 块:定义一个站点
server {
listen 80;
server_name mysite.example.com;
root /var/www/mysite;
index index.html;
}
listen 80;:监听端口。server_name:匹配哪个域名(多个用空格隔开)。root:站点文件根目录。index:访问目录时默认加载的文件。
4.3 location 块:按路径匹配
server {
listen 80;
server_name mysite.example.com;
root /var/www/mysite;
location /images/ {
# 前缀匹配:/images/ 开头的请求
}
location = /favicon.ico {
log_not_found off;
}
location / {
try_files $uri $uri/ =404;
}
}
location /:默认处理所有未命中的路径。try_files $uri $uri/ =404:先找文件、再找目录,都没有返回 404。- location 匹配优先级:精确(=)> 前缀(^
)> 正则()> 普通前缀。
4.4 静态站点验证
sudo mkdir -p /var/www/mysite
sudo tee /var/www/mysite/index.html >/dev/null <<'EOF'
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>我的站点</title></head>
<body><h1>Hello Linux Web Server</h1></body></html>
EOF
# 配置权限(worker 以 nginx 用户运行,需能读这些文件)
sudo chown -R nginx:nginx /var/www/mysite
sudo chmod 755 /var/www/mysite && sudo chmod 644 /var/www/mysite/index.html
# 测试并加载配置
sudo nginx -t
sudo systemctl reload nginx
# 验证
curl -I http://127.0.0.1/
参考:docs.nginx.com - Serving Static Content
五、Nginx 托管动态应用
静态内容 Nginx 直接返回;动态内容(如 PHP、Python、Node)需要把请求交给后端程序处理。
5.1 动态内容的常见做法
- PHP:Nginx 本身不解析 PHP,需要配合 PHP-FPM(FastCGI 进程管理器),用
fastcgi_pass转发。 - Python/Node/Java 等:应用自己监听一个高位端口(如 8080),Nginx 用
proxy_pass反向代理(见第六章)。
5.2 Nginx + PHP-FPM 示例
server {
listen 80;
server_name mysite.example.com;
root /var/www/mysite;
index index.php index.html;
location / {
try_files $uri $uri/ =404;
}
# 把 .php 请求交给 PHP-FPM 处理
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
include fastcgi_params;
}
}
# 安装 PHP-FPM(Rocky)
sudo dnf install -y php-fpm
sudo systemctl enable --now php-fpm
对比:Apache 通常用
mod_php(直接嵌入 PHP)或 PHP-FPM,配置上 Nginx 走fastcgi_pass,Apache 走ProxyPass或 mod_php——这是两者托管动态应用的主要差异。
六、Nginx 反向代理与负载均衡
反向代理(reverse proxy) 是 Nginx 最常用的场景之一:浏览器访问 Nginx(80/443),Nginx 把请求转发给后端应用(跑在高位端口的内网服务),再把响应返回。
6.1 一个最简单的反向代理
假设后端应用监听 127.0.0.1:8080:
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://127.0.0.1:8080;
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_pass:把请求转发给后端。proxy_set_header Host $host;:把原始 Host 传给后端(后端才知道访问的是哪个域名)。X-Real-IP/X-Forwarded-For:把客户端真实 IP 传给后端(否则后端只看到 127.0.0.1)。
6.2 负载均衡(upstream)
后端有多个实例时,用 upstream 定义一组服务器,Nginx 自动分配请求:
upstream backend {
server 127.0.0.1:8080;
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}
server {
listen 80;
server_name app.example.com;
location / {
proxy_pass http://backend;
proxy_set_header Host $host;
}
}
- 默认轮询(round-robin) 分配;也可配
weight、least_conn等策略。 - 一台后端挂掉,Nginx 会自动把请求分给其他正常实例。
6.3 SELinux:反向代理要额外放行(Rocky 特有)
# Rocky 上 Nginx 默认被 SELinux 限制,转发到后端需要开启:
sudo setsebool -P httpd_can_network_connect 1
不加这步,反向代理会报
(13: Permission denied) while connecting to upstream。
参考:docs.nginx.com - NGINX Reverse Proxy
七、HTTPS:让网站更安全
HTTPS 就是在 HTTP 外面加一层 TLS 加密,运行在 443 端口。要让网站走 HTTPS,需要一张 SSL/TLS 证书。
7.1 证书从哪来
- Let's Encrypt:免费、自动化的证书颁发机构,配合 certbot 工具自动申请和续期,最常用。
- 云厂商/商业 CA:付费证书,用于企业场景。
7.2 Nginx 配置 HTTPS
手动配置(假设已有证书 example.com.crt 和私钥 example.com.key):
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/example.com.crt;
ssl_certificate_key /etc/ssl/example.com.key;
root /var/www/mysite;
index index.html;
}
# 把 80 端口的 HTTP 请求跳转到 HTTPS
server {
listen 80;
server_name example.com;
return 301 https://$host$request_uri;
}
7.3 用 certbot 自动申请证书
# 安装 certbot(Rocky)
sudo dnf install -y certbot python3-certbot-nginx
# 自动申请并配置 Nginx(需域名已解析到本机,且 80 端口可达)
sudo certbot --nginx -d example.com -d www.example.com
# 自动续期(certbot 会装 timer)
sudo certbot renew --dry-run
- certbot 会自动改写 Nginx 配置加上证书,并设置续期。
- Let's Encrypt 证书有效期 90 天,certbot 的 timer 会自动续期。
7.4 Apache 与 Caddy 的 HTTPS 对比
| Web 服务器 | 配置 HTTPS 方式 |
|---|---|
| Nginx | 手写 ssl_certificate,或用 certbot --nginx |
| Apache | 手写 SSLCertificateFile,或用 certbot --apache |
| Caddy | 无需配置,有域名就自动申请并启用 HTTPS |
# Apache 的 HTTPS 配置示例
<VirtualHost *:443>
ServerName example.com
SSLEngine on
SSLCertificateFile /etc/ssl/example.com.crt
SSLCertificateKeyFile /etc/ssl/example.com.key
</VirtualHost>
参考:nginx.org - Configuring HTTPS servers、Caddy - Automatic HTTPS
八、性能优化与缓存
Nginx 的常见性能优化点:
8.1 worker 进程数
# 通常设为 CPU 核心数;auto 表示自动检测
worker_processes auto;
events {
worker_connections 1024; # 每个 worker 的最大连接数
}
8.2 gzip 压缩
对文本类内容(HTML/CSS/JS/JSON)启用 gzip,能显著减小传输体积:
http {
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml;
}
8.3 静态资源缓存(expires)
对图片、CSS、JS 等静态资源设置缓存头,减少重复请求:
location ~* \.(css|js|png|jpg|jpeg|gif|ico)$ {
expires 7d;
add_header Cache-Control "public";
}
8.4 静态文件开启 sendfile
sendfile on; # 用内核 sendfile 高效发送文件
tcp_nopush on;
参考:docs.nginx.com - Compression and Decompression、nginx.org - ngx_http_gzip_module
九、安全加固要点
9.1 隐藏服务器版本
server_tokens off; # 隐藏响应头里的 Nginx 版本号
9.2 限制请求体大小
client_max_body_size 10m; # 限制上传体积,防止超大请求
9.3 关闭目录列表
Nginx 默认不列目录;若开启了 autoindex on 记得关掉或仅用于内网:
autoindex off;
9.4 系统层安全(配合前面学的)
- 防火墙只放行必要的端口(80/443/22)。
- 文件权限:网站文件只给
nginx用户读权限,不给写权限(除非确实需要)。 - SELinux(Rocky):保持 Enforcing,用
restorecon/setsebool正确处理上下文和网络布尔值。
安全是系统工程:Web 服务器配置 + 系统防火墙 + 文件权限 + SELinux 缺一不可,正好呼应本系列前面讲过的防火墙与权限模块。
十、Apache httpd:经典之选(对比补充)
Apache httpd 是历史最悠久的 Web 服务器之一,功能全面、稳定,传统虚拟主机托管大量使用。
10.1 与 Nginx 的核心差异
- 处理模型:Apache 传统上是每请求一线程/进程(MPM 模型),并发高时内存开销比 Nginx 大。
- 模块化:Apache 功能靠模块(如
mod_php、mod_rewrite、mod_ssl),灵活但配置较分散。 - .htaccess:Apache 支持在每个目录放
.htaccess做目录级配置(需开启AllowOverride),Nginx 没有对应机制。
10.2 配置文件位置
# Rocky/RHEL: /etc/httpd/conf/httpd.conf 主配置
# /etc/httpd/conf.d/*.conf 站点配置
# Ubuntu: /etc/apache2/apache2.conf 主配置
# /etc/apache2/sites-available/ 站点(用 a2ensite 启用)
10.3 一个 Apache 静态站点
<VirtualHost *:80>
ServerName mysite.example.com
DocumentRoot /var/www/mysite
<Directory /var/www/mysite>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
DocumentRoot类似 Nginx 的root。Require all granted放行访问(Apache 2.4 语法)。AllowOverride All允许.htaccess生效。
10.4 何时选 Apache
- 需要 .htaccess 做灵活的目录级配置(很多传统 CMS/虚拟主机依赖)。
- 依赖 Apache 丰富的模块(如
mod_php、mod_rewrite)。 - 老项目、托管环境兼容性要求高。
参考:Apache - httpd 官方文档
十一、Caddy:自动 HTTPS 的现代之选(对比补充)
Caddy 是一个用 Go 写的现代化 Web 服务器,最大亮点是开箱即用的自动 HTTPS 和极简的 Caddyfile。
11.1 Caddyfile:静态站点
mysite.example.com {
root * /var/www/mysite
file_server
}
11.2 Caddyfile:反向代理
app.example.com {
reverse_proxy localhost:8080
}
11.3 自动 HTTPS
- 只要配了真实域名且解析指向本机,Caddy 会自动向 Let's Encrypt 申请证书并配置 HTTPS,无需手动配证书、无需续期。
- 用纯 IP 或本机测试时,Caddy 走 HTTP 或内部自签证书。
sudo systemctl restart caddy
sudo journalctl -u caddy -n 50 # 看日志
11.4 何时选 Caddy
- 想几行配置就上线一个带 HTTPS 的站点。
- 个人博客、内网工具、快速原型。
- 不想折腾证书申请与续期。
参考:Caddy - Caddyfile Concepts、Rocky Linux - Caddy Web Server
十二、从零在 Rocky 部署一个完整网站(整合篇)
把本系列学到的文件、权限、网络、服务、安全全部串起来,用 Nginx 部署一个带静态站点 + 反向代理的完整网站。
12.1 准备文件与权限
sudo mkdir -p /var/www/mysite
sudo tee /var/www/mysite/index.html >/dev/null <<'EOF'
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>部署测试</title></head>
<body><h1>部署成功!</h1></body></html>
EOF
# worker 以 nginx 用户运行,需能读这些文件
sudo chown -R nginx:nginx /var/www/mysite
sudo chmod 755 /var/www/mysite && sudo chmod 644 /var/www/mysite/index.html
12.2 配置站点
server {
listen 80;
server_name _;
root /var/www/mysite;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
保存到 /etc/nginx/conf.d/mysite.conf:
sudo nginx -t
sudo systemctl reload nginx
12.3 放行网络
sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --reload
12.4 SELinux 检查
sudo restorecon -Rv /var/www/mysite # 恢复默认上下文
getenforce # 确认 Enforcing
12.5 验证
curl -I http://127.0.0.1/ # 应返回 200
curl http://127.0.0.1/ # 应看到"部署成功!"
tail -f /var/log/nginx/access.log # 看访问日志
- 浏览器访问服务器 IP 即可看到网站。
- 若想上 HTTPS,装 certbot 申请证书(见 7.3)。
到这里,文件(/var/www/mysite)、权限(nginx 用户可读)、网络(防火墙放行)、服务(nginx 加载配置)、安全(SELinux/权限) 五个环节全部打通,一个网站就完整上线了。
十三、常见问题排查清单
- 浏览器打不开 → 本机
curl -I http://localhost;本机通外部不通,查防火墙和云安全组 80/443。 bind() ... Permission denied绑定 80 → 非 root 不能监听 <1024 端口;用系统服务让 root 启动。13: Permission denied读文件 → worker 是nginx用户,检查文件权限(chown nginx:nginx)。- SELinux 拦截静态文件 →
restorecon -Rv /var/www/...。 - 反向代理
Permission denied while connecting to upstream→setsebool -P httpd_can_network_connect 1。 - 改配置不生效 →
nginx -t后systemctl reload nginx。 - Nginx 与 Apache 端口冲突 → 两者都监听 80,只能启用其一。
- HTTPS 打不开 → 确认 443 端口放行、证书路径正确、域名已解析。
十四、总结与选型对比
14.1 核心速查
| 需求 | Nginx 命令 |
|---|---|
| 安装 | sudo dnf install -y nginx |
| 启动/自启 | sudo systemctl enable --now nginx |
| 测试配置 | sudo nginx -t |
| 热加载 | sudo systemctl reload nginx |
| 放行端口 | sudo firewall-cmd --permanent --add-service=http --add-service=https; sudo firewall-cmd --reload |
| 看日志 | tail -f /var/log/nginx/access.log |
| 自动证书 | sudo certbot --nginx -d example.com |
14.2 三大 Web 服务器选型
| 场景 | 选择 |
|---|---|
| 高并发、反向代理、现代网站 | Nginx |
| 传统托管、需要 .htaccess、模块丰富 | Apache httpd |
| 快速上线、自动 HTTPS、个人站点 | Caddy |
14.3 动手练习建议
# 1. 装 Nginx 并跑起来
sudo dnf install -y nginx && sudo systemctl enable --now nginx
curl -I http://localhost
# 2. 部署一个静态站点(见第四章/十二章)
# 3. 起一个 8080 的服务,配一个反向代理(见第六章)
# 4. 配 HTTPS(见第七章,需域名)
# 5. 对比:在另一台虚拟机装 Apache / Caddy,体验配置差异
提示:练习在虚拟机进行。改配置前先
nginx -t验证;Nginx 与 Apache/Caddy 不要同时占用 80 端口。
参考资料
- nginx.org - Beginner's Guide:https://nginx.org/en/docs/beginners_guide.html
- nginx.org - Configuring HTTPS servers:https://nginx.org/en/docs/http/configuring_https_servers.html
- nginx.org - ngx_http_gzip_module:https://nginx.org/en/docs/http/ngx_http_gzip_module.html
- docs.nginx.com - Serving Static Content:https://docs.nginx.com/nginx/admin-guide/web-server/serving-static-content/
- docs.nginx.com - NGINX Reverse Proxy:https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/
- docs.nginx.com - Compression and Decompression:https://docs.nginx.com/nginx/admin-guide/web-server/compression/
- Apache - httpd 官方文档:https://httpd.apache.org/docs/2.4/
- Rocky Linux - Web Servers Nginx:https://docs.rockylinux.org/books/web_services/022-web-servers-nginx/
- Caddy - Caddyfile Concepts:https://caddyserver.com/docs/caddyfile/concepts
- Caddy - Automatic HTTPS:https://caddyserver.com/docs/automatic-https
- Rocky Linux - Caddy Web Server:https://docs.rockylinux.org/guides/web/caddy/
- 菜鸟教程 - Linux 教程:https://www.runoob.com/linux/linux-tutorial.html
