前言
在 Ubuntu 或 Debian 上装 Apache HTTP Server,网上能搜到的教程有一大半是从 RHEL/CentOS 抄过来的:包名写httpd、服务名写httpd、配置文件写/etc/httpd/conf/httpd.conf。这些写法在 Ubuntu 上一条都对不上——apt 仓库里的包叫apache2,服务名是apache2,配置目录是/etc/apache2/,而且整体布局被 Debian 拆成了sites-available、mods-available这一套目录加a2ensite、a2enmod工具。
本文只讲 Ubuntu/Debian 这条线,覆盖:安装前的检查、apt install的完整过程、安装后的目录布局、启停与自启、虚拟主机与模块的启用方式、以及卸载。示例基于 Ubuntu 22.04 LTS(仓库提供 Apache 2.4.52 系列)和 Debian 12(2.4.57 系列),实际版本以apt policy apache2的输出为准。文中命令均以具备sudo权限的普通用户执行,sudo不可省略。
一、安装前的三件事
第一,更新软件索引。apt install装的是索引里记录的版本,索引过期会导致「找不到包」或装到旧版本:
sudo apt update第二,确认没有别的服务占着 80 端口。这是最容易被忽略、装完才发现的一步。如果机器上已经跑了 Nginx 或另一个 Web 服务,Apache 装完能启动但会绑定失败或抢不到端口:
sudo ss -lntp | grep -E ':80|:443'有输出就说明 80/443 已被占用,先决定是停掉占用方、还是给 Apache 换端口(改/etc/apache2/ports.conf里的Listen)。
第三,看一眼这个包在仓库里到底叫什么、什么版本。
apt policy apache2 apt search --names-only '^apache2$'apt policy会列出已安装版本、候选(candidate)版本和它们来自哪个仓库。确认包名是apache2而不是httpd——在 Debian 系里httpd这个名字根本不存在,apt install httpd会报Unable to locate package httpd。
二、安装与验证
sudo apt install -y apache2这一条会连带装上apache2-bin(实际的可执行文件和模块)、apache2-utils(ab、htpasswd等辅助工具)、apache2-data等依赖包。安装过程中 apt 会自动创建www-data用户和组、初始化/var/www/html目录、并把apache2.service设为开机自启。
安装完成后依次做四项验证。
# 1. 版本与编译参数 apache2 -v # 2. 服务状态(active (running) 才算正常) systemctl status apache2 --no-pager # 3. 语法检查 sudo apache2ctl configtest # 4. 本机发起一次真实请求 curl -sI http://127.0.0.1/ | head -n 1apache2 -v的输出形如:
Server version: Apache/2.4.52 (Ubuntu) Server built: 2023-10-26T13:20:00带(Ubuntu)后缀说明是发行版打包版本,与 apache.org 上的同名版本在模块和补丁上有差异。
curl -sI应当返回HTTP/1.1 200 OK,此时/var/www/html/index.html是那个 "Apache2 Ubuntu Default Page"。如果本机通、外网不通,先看防火墙:
# Ubuntu 上若有 ufw sudo ufw status sudo ufw allow 'Apache' # ufw 内置的应用配置,等价于放行 80/443Debian 默认没有启用 ufw,通常不需要这一步。
三、Ubuntu/Debian 特有的目录布局
这是和 RHEL 系差别最大的地方,也是新手最容易迷路的地方。
| 用途 | Ubuntu / Debian | RHEL / CentOS |
|---|---|---|
| 包名 | apache2 | httpd |
| 服务名 | apache2 | httpd |
| 主配置 | /etc/apache2/apache2.conf | /etc/httpd/conf/httpd.conf |
| 监听端口 | /etc/apache2/ports.conf | 写在主配置里 |
| 站点配置 | /etc/apache2/sites-available/+sites-enabled/ | /etc/httpd/conf.d/ |
| 模块配置 | /etc/apache2/mods-available/+mods-enabled/ | /etc/httpd/conf.modules.d/ |
| 默认站点根目录 | /var/www/html | /var/www/html |
| 日志 | /var/log/apache2/ | /var/log/httpd/ |
| 运行用户 | www-data | apache |
apache2.conf的末尾通常是这样几行,把其他目录串进来:
# /etc/apache2/apache2.conf 中的片段 IncludeOptional mods-enabled/*.load IncludeOptional mods-enabled/*.conf IncludeOptional conf-enabled/*.conf IncludeOptional sites-enabled/*.conf所以sites-enabled/里的文件才是真正生效的,sites-available/只是一个「备选库」。这两个目录里的文件通常是符号链接,由工具创建,不要手工复制。
配套的管理工具:
| 工具 | 作用 |
|---|---|
a2ensite 站点名 | 在sites-enabled/里创建指向sites-available/站点名的链接(启用) |
a2dissite 站点名 | 删除该链接(停用) |
a2enmod 模块名 | 启用模块,同时把对应的.load/.conf链接到mods-enabled/ |
a2dismod 模块名 | 停用模块 |
a2enconf/a2disconf | 启用/停用conf-available/里的全局片段 |
apache2ctl -S | 列出所有虚拟主机及其匹配的ServerName,排查域名分流最有用 |
apache2ctl -M | 列出当前已加载的模块 |
apache2ctl configtest | 语法检查,作用同apache2 -t |
a2*这一组工具干的事就是创建/删除符号链接,然后提示你重启或重载 Apache。它们必须用sudo运行,否则会因为没权限写sites-enabled/而失败。
四、实战:加一个站点并启用 HTTPS
目标:给example.com建一个虚拟主机,并在同一台机器上启用 TLS。
第 1 步,写站点配置。从默认站点复制一份再改,比从零写省事:
sudo cp /etc/apache2/sites-available/000-default.conf \ /etc/apache2/sites-available/example.com.conf sudo editor /etc/apache2/sites-available/example.com.conf内容改为:
<VirtualHost *:80> ServerName example.com ServerAlias www.example.com DocumentRoot /var/www/example.com/public ErrorLog ${APACHE_LOG_DIR}/example.com_error.log CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined <Directory /var/www/example.com/public> Options -Indexes +FollowSymLinks AllowOverride None Require all granted </Directory> </VirtualHost>${APACHE_LOG_DIR}是 Ubuntu/Debian 在/etc/apache2/envvars里预设的变量,展开为/var/log/apache2。注意Require all granted是 Apache 2.4 的写法,网上大量 2.2 时代的Order allow,deny写法在 2.4 上会直接报语法错误。
第 2 步,建目录和首页,注意属主。
sudo mkdir -p /var/www/example.com/public echo 'hello from example.com' | sudo tee /var/www/example.com/public/index.html sudo chown -R www-data:www-data /var/www/example.com第 3 步,启用站点、检查语法、平滑重载。
sudo a2ensite example.com sudo apache2ctl configtest # 必须看到 Syntax OK sudo systemctl reload apache2 sudo apache2ctl -S # 确认 example.com 已挂到 *:80用reload而不是restart:reload 是平滑加载,已建立的连接不会被掐断;只有在配置改错了改出语法问题、或者换了 MPM 模块时,才需要restart。
第 4 步,本机带上 Host 头验证分流。
curl -s -H 'Host: example.com' http://127.0.0.1/第 5 步,启用 TLS。先在ports.conf里确认有Listen 443(Ubuntu 的ports.conf默认带一段被IfModule ssl_module包裹的Listen 443),然后:
sudo a2enmod ssl # 加载 mod_ssl sudo a2ensite default-ssl # 启用自签名证书的示例站点 sudo apache2ctl configtest sudo systemctl reload apache2a2enmod ssl会在mods-enabled/下建立ssl.load和ssl.conf的链接。真正的生产证书配置要改SSLCertificateFile和SSLCertificateKeyFile指向你的证书和私钥路径。证书路径和签发流程不在本文范围,用certbot --apache之类的工具会由它自动改写虚拟主机配置。
顺带一提 PHP 的坑:装libapache2-mod-php时,它的维护脚本会自动把 Apache 切到mpm_prefork。切换 MPM 意味着必须restart而不是reload,而且切换后mod_php与mpm_event不能共存。用apache2ctl -M | grep mpm可以看到当前生效的是哪一个。
卸载(想彻底清干净时):
sudo apt remove --purge -y apache2 apache2-utils apache2-bin sudo apt autoremove -y sudo rm -rf /etc/apache2 /var/www/html--purge会连配置文件一起删掉;不加它,/etc/apache2下的配置会作为「用户改过的文件」保留下来,下次重装时又被带回来。
常见坑点
❌ 照着 CentOS 教程执行sudo yum install httpd或sudo apt install httpd✅ Debian/Ubuntu 的包名是apache2,apt install apache2;httpd只存在于 RHEL 系
❌ 改完配置直接sudo systemctl restart apache2,一次语法错误就让整个站点下线 ✅ 先sudo apache2ctl configtest看到Syntax OK再reload;只有换 MPM 或端口这类结构性改动才用restart
❌ 把站点配置写进/etc/apache2/apache2.conf,越改越长,升级时被覆盖 ✅ 放在sites-available/里用a2ensite启用;apache2.conf只放全局设置
❌ 手工cp一份配置到sites-enabled/,改的时候改的是副本,改完发现不生效 ✅ 只改sites-available/里的原件,sites-enabled/交给a2ensite管理链接
❌ 用 2.2 时代的Order allow,deny/Allow from all授权写法 ✅ Apache 2.4 用Require all granted、Require ip 10.0.0.0/8;两套写法不能混在同一段<Directory>里
❌ 站点目录权限设成chown -R root:root之后只chmod 755,结果动态站点写不了缓存目录报 500 ✅ 文档根目录属主给www-data(chown -R www-data:www-data),可写目录再单独放开;Apache 默认以www-data身份运行
❌ 装完发现外网访问不了就反复改配置,其实是防火墙没放行 ✅ 先sudo ss -lntp | grep :80确认绑定成功,再sudo ufw allow 'Apache'(Ubuntu)确认放行,最后才怀疑配置
❌ 用apt remove apache2卸载后重装,旧配置又生效了,以为卸载没干净 ✅ 彻底清除加--purge:sudo apt remove --purge apache2 apache2-utils apache2-bin,之后手动确认/etc/apache2是否还有残留
❌sudo a2enmod rewrite之后没重载就测试,以为模块没加载 ✅a2ensite/a2enmod只改链接,必须systemctl reload apache2才生效;用apache2ctl -M | grep rewrite确认已加载
总结
| 环节 | 命令 / 路径 |
|---|---|
| 装包 | sudo apt update && sudo apt install -y apache2 |
| 服务控制 | systemctl status/reload/restart apache2,开机自启由安装时自动设置 |
| 语法检查 | sudo apache2ctl configtest |
| 看已加载模块 | apache2ctl -M |
| 看虚拟主机分流 | apache2ctl -S |
| 主配置 | /etc/apache2/apache2.conf、ports.conf |
| 站点 | /etc/apache2/sites-available/,用a2ensite启用 |
| 模块 | /etc/apache2/mods-available/,用a2enmod启用 |
| 默认根目录 | /var/www/html,属主www-data |
| 日志 | /var/log/apache2/ |
| 防火墙 | sudo ufw allow 'Apache'(Ubuntu) |
| 卸载 | sudo apt remove --purge apache2 apache2-utils apache2-bin |
在 Ubuntu/Debian 上装 Apache,摸清两件事就顺了:一是包名和服务名都是apache2,别被 RHEL 的httpd教程带偏;二是配置靠a2*工具在available和enabled两个目录之间建链接来启用,永远只改available里的原件。改完配置先configtest再reload,这个习惯能省下无数次站点意外下线。