20 - Web 服务配置(Apache2 / Nginx)
前提条件
- 已完成第三阶段存储与日志配置(
/data可用于 Web 站点目录) - 以 root 身份登录,或 ops 用户执行
sudo -i切换至 root 环境 - 系统运行在 Debian 12 Bookworm
- 防火墙已放行
80/tcp和443/tcp - 虚拟机环境:VMware Workstation Pro(建议从宿主机浏览器访问测试)
全局参数
主机名 linuxdc,IP 192.168.1.100/24,SSH 端口 2222,运维用户 ops
Apache2 与 Nginx 对比
| 维度 | Apache2 | Nginx |
|---|---|---|
| 架构模型 | 多进程 / 多线程(MPM) | 事件驱动异步非阻塞 |
| 并发性能 | 中等 | 高并发低内存占用 |
.htaccess 支持 |
原生支持(逐目录配置) | 不支持 |
| 动态内容处理 | 内置 mod_php / mod_wsgi | 依赖外部 FastCGI(php-fpm 等) |
| 反向代理 | 支持(mod_proxy) | 原生高性能反向代理 |
| 推荐场景 | 传统 PHP 应用、WordPress | 高并发静态服务、反向代理、容器前端 |
详细步骤
1. 安装 Apache2
apt update
apt install -y apache2 apache2-utils
systemctl enable --now apache2
systemctl status apache2
防火墙放行(nftables 示例):
nft add rule inet filter input tcp dport { 80, 443 } ct state new accept
nft list ruleset > /etc/nftables.conf
若使用 ufw:
ufw allow 'Apache Full'
ufw reload
检查点
浏览器访问 http://192.168.1.100 显示 Apache2 Debian Default Page。
2. Apache2 虚拟主机配置
创建站点目录与测试页面:
mkdir -p /var/www/site1 /var/www/site2
echo "<h1>Site 1 - linuxdc</h1>" > /var/www/site1/index.html
echo "<h1>Site 2 - Test</h1>" > /var/www/site2/index.html
chown -R www-data:www-data /var/www
创建虚拟主机配置文件:
vim /etc/apache2/sites-available/site1.conf
<VirtualHost *:80>
ServerName site1.local
ServerAlias www.site1.local
DocumentRoot /var/www/site1
<Directory /var/www/site1>
Options -Indexes +FollowSymLinks
AllowOverride All
Require all granted
</Directory>
ErrorLog ${APACHE_LOG_DIR}/site1_error.log
CustomLog ${APACHE_LOG_DIR}/site1_access.log combined
</VirtualHost>
参照以上模板创建 site2.conf(修改 ServerName 和 DocumentRoot)。
启用站点并验证:
a2ensite site1.conf site2.conf
a2dissite 000-default.conf # 禁用默认站点
apache2ctl configtest # 语法检查,输出 Syntax OK 才继续
systemctl reload apache2
检查点
apache2ctl configtest 输出 Syntax OK。在 /etc/hosts 添加 192.168.1.100 site1.local 后,浏览器访问 http://site1.local 显示对应页面。
3. 安装 Nginx
与 Apache2 的冲突
Apache2 和 Nginx 默认都监听 80 端口,不可同时启用。生产中通常二选一,或将 Apache2 改为监听 8080 后由 Nginx 反代。
apt install -y nginx
systemctl enable --now nginx
检查点
浏览器访问 http://192.168.1.100 显示 Welcome to nginx!。
4. Nginx 虚拟主机配置
vim /etc/nginx/sites-available/site1
server {
listen 80;
server_name site1.local www.site1.local;
root /var/www/site1;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
access_log /var/log/nginx/site1.access.log;
error_log /var/log/nginx/site1.error.log;
}
启用并验证:
ln -s /etc/nginx/sites-available/site1 /etc/nginx/sites-enabled/
nginx -t # 语法检查
systemctl reload nginx
检查点
nginx -t 输出 syntax is ok 和 test is successful。
5. HTTPS 配置(Let's Encrypt)
适用条件
Let's Encrypt 证书需要域名能被公网解析,且服务器 80 端口对外可达。本地实验环境(192.168.1.x)无法使用此方式获取证书,可改用自签名证书测试 TLS 流程(见下方说明)。
安装 certbot:
apt install -y certbot python3-certbot-nginx
# Apache 使用:python3-certbot-apache
申请证书(需要真实可解析域名):
certbot --nginx -d yourdomain.com -d www.yourdomain.com
本地实验环境:使用自签名证书
# 生成自签名证书(有效期 365 天)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/ssl/private/linuxdc-selfsigned.key \
-out /etc/ssl/certs/linuxdc-selfsigned.crt \
-subj "/C=CN/ST=Beijing/L=Beijing/O=linuxdc/CN=192.168.1.100"
在 Nginx 站点配置中添加 HTTPS 块:
server {
listen 443 ssl;
server_name site1.local;
ssl_certificate /etc/ssl/certs/linuxdc-selfsigned.crt;
ssl_certificate_key /etc/ssl/private/linuxdc-selfsigned.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
root /var/www/site1;
index index.html;
}
nginx -t && systemctl reload nginx
6. 关键配置参数说明
Apache2 目录选项:
| 选项 | 说明 |
|---|---|
Options -Indexes |
禁止目录列表(安全推荐) |
Options +FollowSymLinks |
允许跟随符号链接 |
AllowOverride All |
允许 .htaccess 覆盖配置 |
Require all granted |
允许所有客户端访问 |
Nginx try_files 逻辑:
| 参数 | 说明 |
|---|---|
$uri |
尝试匹配请求路径对应的文件 |
$uri/ |
尝试匹配请求路径对应的目录(含 index) |
=404 |
以上均不存在时返回 404 |
实践任务
- 安装 Apache2,创建
site1/site2两个虚拟主机,浏览器访问确认显示不同页面 - 安装 Nginx(先停止 Apache2),创建
site1虚拟主机,确认可正常访问 - 用自签名证书配置 HTTPS,访问
https://192.168.1.100确认 TLS 握手成功(浏览器会提示证书不受信任,属正常现象) - 查看
/var/log/nginx/site1.access.log,找出最近的访问记录
自测问题
1. Apache2 的 a2ensite 和 a2dissite 命令的作用是什么?
a2ensite 在 /etc/apache2/sites-enabled/ 目录下创建指向 sites-available/ 中对应配置文件的符号链接,使该虚拟主机生效。a2dissite 删除该符号链接,使虚拟主机停用。Apache2 启动时只加载 sites-enabled/ 中的配置,sites-available/ 仅作为配置文件存储库,不直接生效。执行变更后需 systemctl reload apache2 使配置生效。
2. Nginx 配置中 try_files $uri $uri/ =404 的含义是什么?
按顺序尝试以下三个候选项:首先在 root 指定的目录下查找与请求 URI 完全匹配的文件;若不存在则查找同名目录(并尝试读取其 index 文件);前两者均不存在时直接返回 HTTP 404。这是 Nginx 中处理静态文件请求的标准写法,SPA 应用通常改为 try_files $uri $uri/ /index.html 以支持前端路由。
3. 为什么生产环境优先使用 HTTPS 而不是 HTTP?
HTTP 明文传输,链路上任意中间节点均可读取和篡改内容,包括用户凭据、Session Cookie、表单数据。HTTPS 通过 TLS 提供三重保障:加密(防窃听)、完整性(防篡改)、身份验证(防伪造服务端)。现代浏览器将 HTTP 站点标记为"不安全",搜索引擎也对 HTTPS 站点给予更高排名权重。Let's Encrypt 提供免费 DV 证书,已无成本障碍。
4. certbot 自动续期默认通过什么方式实现?
certbot 安装后会在 /etc/cron.d/certbot 创建 cron 任务,每天运行两次 certbot renew。该命令检查所有证书的到期时间,仅对距到期不足 30 天的证书执行续期操作,续期成功后自动重载 Web 服务器配置。Debian 12 上也可能通过 systemd timer(certbot.timer)实现,两者效果相同。
总结
Apache2 配置友好、模块丰富,适合传统 PHP 应用;Nginx 高并发低开销,适合反向代理与高流量静态服务。本章建立的虚拟主机 + TLS 基础,将在后续数据库联动、容器部署章节中作为前端接入层。