跳转至

20 - Web 服务配置(Apache2 / Nginx)

前提条件

  • 已完成第三阶段存储与日志配置(/data 可用于 Web 站点目录)
  • 以 root 身份登录,或 ops 用户执行 sudo -i 切换至 root 环境
  • 系统运行在 Debian 12 Bookworm
  • 防火墙已放行 80/tcp443/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(修改 ServerNameDocumentRoot)。

启用站点并验证:

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 oktest 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

实践任务

  1. 安装 Apache2,创建 site1 / site2 两个虚拟主机,浏览器访问确认显示不同页面
  2. 安装 Nginx(先停止 Apache2),创建 site1 虚拟主机,确认可正常访问
  3. 用自签名证书配置 HTTPS,访问 https://192.168.1.100 确认 TLS 握手成功(浏览器会提示证书不受信任,属正常现象)
  4. 查看 /var/log/nginx/site1.access.log,找出最近的访问记录

自测问题

1. Apache2 的 a2ensitea2dissite 命令的作用是什么?

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 基础,将在后续数据库联动、容器部署章节中作为前端接入层。