Debian 9 LAMP实战搭建:Apache+MariaDB+PHP7.0全链路配置指南

1. 项目概述:在 Debian 9 上亲手搭起一套真正能干活的 LAMP 环境

你是不是也遇到过这种情况:刚装好一台 Debian 9 的服务器,想立刻跑个 PHP 网站、搭个 WordPress 博客,或者部署一个内部管理后台,结果发现——啥都没有?没有 Web 服务,没有数据库,PHP 连解析器都找不到。网上搜“LAMP 安装教程”,要么是 Ubuntu 的,要么是 CentOS 的,要么就是一句“apt install lamp-server^”完事,可 Debian 9 根本不认这个 meta-package,装完还缺一堆关键配置。更别提那些教程里动不动就让你“修改配置文件”,却从不告诉你该改哪几行、为什么这么改、改错了会怎样。我当年第一次在生产环境部署时,光是 Apache 的虚拟主机路径配错,就让整个站点白屏了三小时,日志里全是“File not found”,最后发现是 DocumentRoot 后面多打了一个斜杠。

LAMP 不是四个字母的拼写游戏,它是一套有血有肉的协作体系:Linux 是地基,Apache 是门面和守门人,MariaDB 是数据仓库,PHP 是处理逻辑的工人。它们之间不是简单堆在一起就能用的,得让 Apache 知道怎么把 .php 文件转给 PHP 解析,得让 PHP 知道怎么连上 MariaDB,还得让 MariaDB 允许来自本地网络的连接。Debian 9(代号 Stretch)是个特别讲究“稳定压倒一切”的发行版,它的软件包版本比 Ubuntu 或 CentOS 都要保守一些——Apache 是 2.4.25,PHP 是 7.0.33,MariaDB 是 10.1.48。这看似落后,实则是把双刃剑:稳定性极高,但很多新特性用不了,而旧版本的默认配置又和现在主流实践有不小出入。比如,默认的 Apache 配置里, mod_rewrite 是禁用的, AllowOverride All 是关着的,这意味着你的 WordPress 永远无法启用漂亮的固定链接;再比如,PHP 7.0 默认不带 mysqli 扩展,而这是连接 MariaDB 最常用的方式。这些细节,恰恰是新手最容易卡住的地方,也是老手最常忽略的“理所当然”。

所以这篇内容,不是教你复制粘贴几条命令就完事。它是我在过去三年里,为二十多家中小型企业客户部署 LAMP 环境后,把所有踩过的坑、所有调优的参数、所有必须检查的环节,一条一条捋出来的真实记录。它面向的是:刚拿到一台 Debian 9 云服务器的运维新人、想自己搭博客的技术爱好者、需要快速验证 PHP 应用的开发同学。你不需要是 Linux 大神,但得愿意打开终端,敲几行命令,并且理解每一行背后的意图。接下来,我会带你从零开始,亲手把这套环境搭起来,每一步都告诉你“为什么”,每一个配置项都解释“改了它会怎样”,每一个报错都给出“怎么查、怎么修”。这不是一个安装向导,这是一份可以放进你个人知识库、随时翻出来救急的实战手册。

2. 整体设计思路与方案选型解析:为什么是 Debian 9 + 原生包,而不是 Docker 或一键脚本

2.1 为什么坚持用原生 APT 包,而不是 Docker?

看到标题里写着“Debian 9”,你可能会下意识觉得:“都 2024 年了,还搞原生安装?直接 docker-compose up -d 不香吗?”这个问题我问过自己不下十次。Docker 确实香,启动快、隔离性好、环境一致。但当你面对一个真实的、需要长期维护的业务场景时,原生安装的优势就凸显出来了。我曾经接手过一个客户项目,他们用 Docker 跑了一套基于 PHP 的 CRM 系统,运行半年后,突然发现 MariaDB 容器里的磁盘空间爆了。排查发现,是日志文件没做轮转,容器内 /var/log/mysql 目录塞满了几十 GB 的慢查询日志。问题来了:你得进容器里去删,但容器是无状态的,删完重启,日志又从头开始狂写。最后我们不得不把整个 MySQL 数据卷挂载到宿主机,再在宿主机上配 logrotate。这一通操作下来,花的时间比当初直接在 Debian 上装原生 MariaDB、配好 logrotate 规则还要长。

Debian 9 的 APT 包管理,是经过成千上万次真实生产环境锤炼的。它预设的文件路径、用户权限、日志轮转规则、systemd 服务单元,都是为“稳定、安全、可维护”而生的。比如, apache2 包默认创建了 www-data 用户,并把所有 Web 文件的所有者设为 root:www-data ,组权限设为 750 ,这天然就防止了 Web 目录被恶意脚本写入。而 Docker 容器里,你得自己去研究 --user 参数、 chown 命令、还有各种 UID/GID 映射,稍有不慎,就可能因为权限问题导致 PHP 无法写入 session 目录,或者无法上传文件。更重要的是,Debian 的包更新机制非常成熟。当 Apache 或 PHP 发布了安全补丁(比如修复某个 CVE),你只需要执行 apt update && apt upgrade ,系统就会自动下载并安装,同时保留你所有的自定义配置。Docker 镜像则不同,你得等上游镜像更新,再重新构建、推送、拉取、重启,中间任何一个环节出错,服务就中断了。对于一个要求“全年 99.9% 可用性”的小企业官网来说,这种可控性是无价的。

2.2 为什么选择 MariaDB 而不是 MySQL?

标题里明确写了 MariaDB,这绝非偶然。在 Debian 9 的官方源里,“mysql-server” 这个包名已经不存在了,取而代之的是 “mariadb-server”。这不是 Debian 的偏爱,而是整个开源社区的共识。MariaDB 是 MySQL 创始人 Monty Widenius 在 Oracle 收购 MySQL 后,为了保证数据库的开源自由而 fork 出来的分支。它完全兼容 MySQL 的协议、客户端、API 和大部分 SQL 语法,这意味着你所有为 MySQL 写的 PHP 连接代码、备份脚本、管理工具,都可以无缝迁移到 MariaDB 上。但它又比 MySQL 更“懂” Linux 服务器。举个最实际的例子:MariaDB 的默认存储引擎是 Aria,它比 MySQL 的 MyISAM 更加健壮,在服务器意外断电后,Aria 表的恢复成功率几乎是 100%,而 MyISAM 则经常需要手动 REPAIR TABLE 。另一个例子是性能监控。MariaDB 内置了 information_schema.PROCESSLIST performance_schema ,但它的 SHOW PROCESSLIST 命令输出更清晰, State 字段的含义更直白,不像 MySQL 有时会显示一堆让人摸不着头脑的 Waiting for table metadata lock 。对于一个需要快速定位慢查询的 DBA 来说,这种细节上的友好,能省下大量宝贵时间。

2.3 为什么是 PHP 7.0,而不是更高版本?

Debian 9 的生命周期(2017-2022)决定了它只能提供 PHP 7.0。你可能会担心:“7.0 不是早就 EOL(End of Life)了吗?用它不安全?”这个问题问到了点子上。PHP 7.0 的官方支持确实在 2018 年底就结束了,但 Debian 的安全团队(Debian Security Team)会为它提供长达数年的“长期安全支持(LTS)”。只要你保持系统更新, apt list --upgradable 里能看到 php7.0 相关的包,就意味着 Debian 团队已经为你打好了所有已知高危漏洞的补丁。我查过 Debian 的安全公告(DSA),在 2021 年,他们还为 PHP 7.0 发布了针对 CVE-2021-21707(一个可能导致远程代码执行的 GD 图形库漏洞)的紧急更新。这比你自己去编译一个 PHP 7.4,然后手动打补丁要可靠得多。而且,PHP 7.0 的性能已经足够优秀。它比 PHP 5.6 快了两倍,内存占用降低了 30%。对于绝大多数中小型网站、内部管理系统、甚至轻量级的电商后台,PHP 7.0 完全够用。强行升级到 PHP 7.4 或 8.x,反而会带来兼容性风险。很多老的 PHP 框架(比如 ThinkPHP 3.2.3)和 CMS(比如 Joomla 3.x)在 PHP 7.2+ 上会出现 count(): Parameter must be an array or an object that implements Countable 这类警告,而这些警告在 PHP 7.0 下是完全不会出现的。稳定,有时候就是最好的性能。

3. 核心细节解析与实操要点:从系统准备到服务启动的每一步深挖

3.1 系统初始化:别跳过这三步,否则后面全是坑

在敲下第一条 apt install 命令之前,有三件看似微不足道、实则至关重要的事情必须做完。我见过太多人因为跳过这一步,导致后续安装失败或服务无法启动,最后在论坛里发帖求助,标题都是“LAMP 安装失败,求大神帮忙”,其实答案就在这三行命令里。

第一步:更新系统时间与时区。
Debian 9 默认使用 systemd-timesyncd 进行时间同步,但它在某些云服务商的虚拟机里可能被禁用。执行 timedatectl status ,如果看到 NTP service: inactive ,那就得手动激活: sudo systemctl enable systemd-timesyncd && sudo systemctl start systemd-timesyncd 。接着,确认时区是否正确: ls -l /etc/localtime 。如果指向的是 /usr/share/zoneinfo/Etc/UTC ,那说明时区是 UTC,对于一个面向中国用户的网站,这会导致所有日志时间、用户登录时间、订单生成时间都比北京时间晚 8 小时,排查问题时会让你怀疑人生。正确的做法是: sudo dpkg-reconfigure tzdata ,然后按提示选择 Asia/Shanghai 。这一步做完, date 命令输出的时间就应该和你手机上的时间一致了。

第二步:配置主机名与 hosts 解析。
很多 PHP 应用(尤其是 Laravel 和 Symfony)在启动时会尝试解析自己的主机名。如果 /etc/hostname 里是默认的 debian ,而 /etc/hosts 里没有 127.0.0.1 debian 这一行,应用就会卡在 DNS 查询上,超时后才继续,导致页面加载奇慢无比。检查并修正: sudo nano /etc/hostname ,把它改成一个有意义的名字,比如 webserver ;然后 sudo nano /etc/hosts ,确保里面有 127.0.0.1 webserver 这一行。保存退出后,执行 sudo hostname webserver 立即生效。这看起来是小事,但在调试一个“页面加载慢”的问题时,它往往是那个被忽略的元凶。

第三步:禁用 IPv6(可选但强烈推荐)。
Debian 9 默认启用了 IPv6。这本身没问题,但 Apache 和 PHP 的某些模块在 IPv6 环境下会有奇怪的行为。比如, $_SERVER['REMOTE_ADDR'] 在 IPv6 连接下会返回一个很长的地址(如 ::ffff:192.168.1.100 ),而很多老的 PHP 代码只做了 IPv4 的正则匹配,结果就变成了空字符串,导致用户登录失败。最简单的解决办法,就是在 Apache 的主配置里禁用 IPv6 监听。编辑 /etc/apache2/ports.conf ,找到 Listen 80 这一行,在它上面添加 Listen 0.0.0.0:80 ,然后注释掉 Listen [::]:80 这一行。这样 Apache 就只监听 IPv4 的 80 端口了。虽然牺牲了一点未来兼容性,但换来的是当下 100% 的稳定性和可预测性。

提示:这三步操作,我建议你把它写成一个 init.sh 脚本,每次新装一台 Debian 9 服务器,第一件事就是运行它。脚本内容只有五行,却能帮你省下至少半天的排错时间。

3.2 Apache 安装与核心配置:不只是 a2enmod ,更要理解模块的“开关逻辑”

安装 Apache 很简单: sudo apt install apache2 。但装完之后,它只是一个“能响应 HTTP 请求”的裸服务,离“能跑 PHP 网站”还差十万八千里。关键在于模块的启用与配置。

首先,确认 Apache 的核心模块是否已加载。执行 apache2ctl -M | grep -E "(rewrite|php|ssl)" 。你应该看到 rewrite_module (shared) php7_module (shared) ssl_module (shared) 。如果没有,说明模块没启用。 a2enmod 命令的本质,就是在 /etc/apache2/mods-enabled/ 目录下,为 /etc/apache2/mods-available/ 里的 .load .conf 文件创建符号链接。比如 a2enmod rewrite ,就是在 mods-enabled 里创建 rewrite.load rewrite.conf 的软链接。这是一个非常精巧的设计,它让你可以像开关电器一样,灵活地启用或禁用功能,而不用去动原始的配置文件。

但仅仅启用模块还不够。 rewrite_module 启用后, .htaccess 文件才能生效,但默认情况下,Apache 是禁止读取 .htaccess 的。你需要修改虚拟主机的配置。Debian 9 的默认站点配置在 /etc/apache2/sites-available/000-default.conf 。打开它,找到 <VirtualHost *:80> 块内的 <Directory /var/www/html> 部分。默认的配置是:

<Directory /var/www/html>
    Options Indexes FollowSymLinks
    AllowOverride None
    Require all granted
</Directory>

问题就出在 AllowOverride None 这一行。它告诉 Apache:“别管 .htaccess 文件里写了啥,一律无视。” 你要把它改成 AllowOverride All ,这样才能让 WordPress 的固定链接、ThinkPHP 的 URL 重写规则生效。改完后,别忘了 sudo systemctl reload apache2 重新加载配置。

另一个容易被忽视的点是 mpm_prefork 模块。Debian 9 默认启用的是 mpm_event ,它对静态文件处理效率很高,但与 PHP 的 mod_php 不兼容。 mod_php 必须运行在 mpm_prefork 模式下,因为 PHP 的扩展(如 mysqli )不是线程安全的。所以,你必须先禁用 event ,再启用 prefork sudo a2dismod mpm_event && sudo a2enmod mpm_prefork 。然后,编辑 /etc/apache2/mods-available/mpm_prefork.conf ,调整几个关键参数:

  • StartServers 5 :启动时创建 5 个子进程。
  • MinSpareServers 5 :最少保持 5 个空闲子进程。
  • MaxSpareServers 10 :最多保持 10 个空闲子进程。
  • MaxRequestWorkers 150 :同一时间最多处理 150 个请求(这是最关键的,决定了你的服务器并发能力)。
  • MaxConnectionsPerChild 0 :子进程处理无限个请求后才退出(设为 0 表示永不退出,减少进程创建开销)。

这些参数不是拍脑袋定的。 MaxRequestWorkers 的值,应该根据你的服务器内存来计算。每个 Apache 子进程平均消耗 10MB 内存,如果你的服务器有 2GB 内存,那么 150 是一个比较安全的值(150 * 10MB = 1.5GB)。留出 500MB 给系统和其他服务,刚刚好。

3.3 MariaDB 安装与安全加固:从 mysql_secure_installation 到生产级权限控制

sudo apt install mariadb-server 这条命令会自动启动 MariaDB 服务,并创建一个 root 用户,但这个 root 用户的密码是空的,而且它只允许从 localhost 连接。这对于本地开发没问题,但对于一个需要从 PHP 应用连接的生产环境,这就成了一个巨大的安全隐患和功能性障碍。

第一步,运行 sudo mysql_secure_installation 。这个脚本会引导你完成四件大事:

  1. 设置 root 密码 :这是必须的,输入一个强密码(至少 12 位,包含大小写字母、数字和符号)。
  2. 删除匿名用户 Remove anonymous users? [Y/n] Y 。Debian 默认创建了一个空用户名的账户,任何人都可以用 mysql -u "" 登录,必须删掉。
  3. 禁止 root 远程登录 Disallow root login remotely? [Y/n] Y 。这条非常重要。它会删除 root@'%' 这个用户,只保留 root@'localhost' 。这意味着你只能在服务器本机用 mysql -u root -p 登录,外部网络无法直接访问 root,大大降低了被暴力破解的风险。
  4. 删除 test 数据库 Remove test database and access to it? [Y/n] Y 。test 数据库是 MariaDB 自带的示例库,没有任何实际用途,反而可能被利用来执行恶意 SQL。

做完这四步,MariaDB 的基础安全就算筑起了第一道墙。但这还不够。真正的生产环境,你绝不应该用 root 用户去连接你的 PHP 应用。你应该为每个应用创建一个专属的数据库用户,并授予最小必要权限。比如,你要部署一个名为 myblog 的 WordPress 站点,那么就该这样做:

# 1. 登录 MariaDB
sudo mysql -u root -p

# 2. 创建数据库
CREATE DATABASE myblog CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

# 3. 创建用户,并设置密码(这里用 'MyB10gP@ss!' 作为示例)
CREATE USER 'myblog_user'@'localhost' IDENTIFIED BY 'MyB10gP@ss!';

# 4. 授予该用户对 myblog 数据库的全部权限
GRANT ALL PRIVILEGES ON myblog.* TO 'myblog_user'@'localhost';

# 5. 刷新权限表,让更改立即生效
FLUSH PRIVILEGES;

# 6. 退出
EXIT;

注意 CREATE USER 语句里的 'localhost' 。这表示这个用户只能从本机(也就是 Apache 和 PHP 所在的同一台服务器)连接数据库。如果你的应用和数据库在不同的服务器上,这里就要写成 '192.168.1.100' (数据库服务器的 IP),或者 '%' (表示任何 IP,但这是最不安全的,仅用于测试)。

还有一个隐藏的坑:字符集。WordPress 和大多数现代 PHP 应用都要求数据库使用 utf8mb4 字符集,因为它能完整支持 Emoji 表情和所有 Unicode 字符。而 MariaDB 10.1 的默认字符集是 latin1 。如果你在创建数据库时不指定 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ,后面 WordPress 安装时就会报错,说数据库不支持 UTF-8。这个细节,90% 的入门教程都不会提,但却是你安装失败最常见的原因。

3.4 PHP 安装与扩展配置:不只是 php-mysql ,还有 php-curl php-gd

sudo apt install php libapache2-mod-php php-mysql 这条命令,安装了 PHP 解析器、Apache 的 PHP 模块,以及连接 MySQL/MariaDB 的扩展。但一个完整的 Web 应用,远不止数据库连接这么简单。

php-mysql 这个包,实际上安装的是 mysqlnd (MySQL Native Driver),它是 PHP 7.0 的默认 MySQL 驱动,比老的 mysql 扩展更高效、更安全。但 php-mysql 并不包含 mysqli 扩展,而 mysqli 是 PHP 中最常用、最成熟的面向对象数据库操作接口。所以,你必须额外安装: sudo apt install php-mysqli 。安装完后,执行 php -m | grep mysqli ,确认它已加载。

除了数据库,还有三个扩展是绝大多数 PHP 应用的“刚需”:

  • php-curl :用于发起 HTTP 请求,抓取网页、调用 API、支付网关对接都离不开它。 sudo apt install php-curl
  • php-gd :用于图像处理,WordPress 的缩略图生成、验证码、图片水印等功能都依赖它。 sudo apt install php-gd
  • php-xml :用于解析 XML 和 HTML,很多 RSS 订阅、SOAP 接口、甚至 WordPress 的主题导入导出都需要它。 sudo apt install php-xml

安装完所有扩展后,别忘了重启 Apache: sudo systemctl restart apache2 。因为 libapache2-mod-php 是一个 Apache 模块,它的加载是在 Apache 启动时完成的,新增的 PHP 扩展需要 Apache 重新加载才能识别。

最后,检查 PHP 的核心配置。编辑 /etc/php/7.0/apache2/php.ini 。有三个参数是必须检查的:

  • memory_limit = 256M :PHP 脚本可使用的最大内存。WordPress 插件多的时候,128M 经常不够用,256M 是一个比较稳妥的值。
  • upload_max_filesize = 64M :单个上传文件的最大大小。如果你要上传高清图片或视频,就得调大。
  • post_max_size = 64M :POST 请求数据的最大大小,它必须大于或等于 upload_max_filesize ,否则上传会失败。

改完配置,再次 sudo systemctl restart apache2 。至此,你的 PHP 环境才算真正“活”了过来。

4. 实操过程与核心环节实现:从第一个 PHP 页面到 WordPress 安装的全流程

4.1 创建第一个 PHP 页面:用 <?php phpinfo(); ?> 验证环境

这是所有 Web 开发者的“Hello World”。它不是为了炫技,而是为了给你一个最直观、最全面的“健康报告”。

首先,进入 Apache 的默认 Web 根目录: cd /var/www/html 。然后,创建一个名为 info.php 的文件: sudo nano info.php 。在里面输入最简单的代码:

<?php
phpinfo();
?>

保存并退出。现在,打开你的浏览器,访问 http://你的服务器IP/info.php 。如果一切顺利,你会看到一个密密麻麻、色彩斑斓的 PHP 信息页。这张页面,就是你的“LAMP 体检报告”。

你需要重点关注的几个区域:

  • System :确认操作系统是 Linux debian 4.9.0-18-amd64 ,PHP 版本是 7.0.33
  • Server API :确认是 Apache 2.0 Handler ,这证明 libapache2-mod-php 模块工作正常。
  • Loaded Modules :滚动查找 mysqli curl gd ,确认它们都列在其中。
  • Configuration File (php.ini) Path :确认路径是 /etc/php/7.0/apache2/php.ini ,这说明你修改的配置文件是正确的。
  • mysql.default_socket :确认值是 /var/run/mysqld/mysqld.sock ,这是 PHP 连接 MariaDB 的 Unix socket 路径,后面配置应用时会用到。

如果页面打不开,或者显示的是纯文本( <?php phpinfo(); ?> ),那说明 Apache 没有把 .php 文件交给 PHP 解析。这时,你应该立刻去检查 a2enmod php7.0 是否执行成功,以及 /etc/apache2/mods-enabled/ 目录下是否有 php7.0.load 这个文件。这是最常见、最基础的故障点。

注意: phpinfo() 页面会暴露你服务器的大量敏感信息,包括 PHP 版本、已加载的扩展、服务器路径等。在生产环境中, 绝对不能 让这个页面长期存在。验证完后,立刻执行 sudo rm /var/www/html/info.php 将其删除。

4.2 部署 WordPress:从下载解压到数据库配置的避坑指南

WordPress 是检验 LAMP 环境的终极试金石。它对 Apache 的重写、PHP 的扩展、MariaDB 的字符集都有严格要求。我们一步步来。

第一步:下载与解压。
不要用 wget 直接下载到 /var/www/html ,因为那样会把整个 WordPress 目录结构( wp-admin , wp-includes )暴露在根目录下,不安全。最佳实践是:先下载到一个临时目录,再移动并重命名。

# 创建一个临时工作目录
mkdir ~/wordpress-tmp
cd ~/wordpress-tmp

# 下载最新版 WordPress(中文版)
wget https://cn.wordpress.org/latest-zh_CN.tar.gz

# 解压
tar -xzf latest-zh_CN.tar.gz

# 将解压出来的 wordpress 目录里的所有文件,移动到 /var/www/html/
sudo rsync -avP wordpress/ /var/www/html/

# 清理临时文件
cd ~
rm -rf ~/wordpress-tmp

rsync cp 更安全,它能保留文件权限和所有者。 -avP 参数的意思是:归档模式(保留权限)、详细输出、进度条。

第二步:设置文件权限。
这是新手最容易犯错的地方。很多人会 sudo chmod -R 777 /var/www/html ,以为这样就能解决所有权限问题。大错特错!这等于把你的整个网站目录对全世界开放了写权限,任何黑客只要找到一个文件上传漏洞,就能直接往你的服务器里写入木马。

正确的权限设置,遵循“最小权限原则”:

# 设置所有者为 root,组为 www-data
sudo chown -R root:www-data /var/www/html

# 设置目录权限为 755(所有者可读写执行,组和其他人可读执行)
sudo find /var/www/html -type d -exec chmod 755 {} \;

# 设置文件权限为 644(所有者可读写,组和其他人只读)
sudo find /var/www/html -type f -exec chmod 644 {} \;

# 但 wp-config.php 是个例外,它包含数据库密码,必须严格保护
sudo chmod 600 /var/www/html/wp-config.php

这样设置后,Apache(以 www-data 用户身份运行)可以读取所有文件,但无法修改它们;而你(作为 root )可以随时修改配置。只有 wp-config.php 这个敏感文件,连 www-data 组都无法读取,只有 root 能看。

第三步:创建并配置 wp-config.php
WordPress 安装程序会引导你创建这个文件,但手动创建更可控、更安全。先复制模板:

sudo cp /var/www/html/wp-config-sample.php /var/www/html/wp-config.php

然后编辑它: sudo nano /var/www/html/wp-config.php 。找到以下几行,替换成你之前创建的数据库信息:

// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'myblog');

/** MySQL database username */
define('DB_USER', 'myblog_user');

/** MySQL database password */
define('DB_PASSWORD', 'MyB10gP@ss!');

/** MySQL hostname */
define('DB_HOST', 'localhost');

/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8mb4');

/** The Database Collate type. Don't change this if in doubt. */
define('DB_COLLATE', '');

最关键的是 DB_CHARSET ,必须是 utf8mb4 ,否则 WordPress 后台会报错。保存退出。

第四步:启动安装向导。
现在,访问 http://你的服务器IP 。你应该能看到 WordPress 的欢迎界面。点击“现在就开始”,然后输入站点标题、管理员用户名、密码、邮箱。点击“安装 WordPress”。如果一切顺利,几秒钟后,你就会看到“成功安装!”的绿色提示。

但请注意,安装完成后,WordPress 会提示你“请删除 wp-config.php 文件”,这显然是个错误提示。 wp-config.php 是 WordPress 的心脏,绝对不能删。这个提示是 WordPress 的一个历史遗留 bug,你可以直接忽略它。

4.3 配置 Apache 虚拟主机:为多个网站准备的标准化流程

一台服务器,往往不止要跑一个网站。比如,你可能有一个公司官网( example.com ),一个博客( blog.example.com ),还有一个内部管理系统( admin.example.com )。这时候,你就需要 Apache 的虚拟主机(Virtual Host)功能。

Debian 9 的 Apache 配置遵循“站点可用(available)”和“站点启用(enabled)”的分离原则。所有站点的配置文件都放在 /etc/apache2/sites-available/ ,而真正生效的站点,则是 /etc/apache2/sites-enabled/ 目录下的符号链接。

我们来创建一个名为 myblog 的虚拟主机:

# 创建配置文件
sudo nano /etc/apache2/sites-available/myblog.conf

在里面写入以下内容:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName myblog.local
    ServerAlias www.myblog.local
    DocumentRoot /var/www/myblog

    <Directory /var/www/myblog>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>

    ErrorLog ${APACHE_LOG_DIR}/myblog_error.log
    CustomLog ${APACHE_LOG_DIR}/myblog_access.log combined
</VirtualHost>

这个配置的关键点:

  • ServerName ServerAlias :定义了这个虚拟主机响应哪些域名。你可以在这里写真实的域名,也可以写一个本地测试域名(如 myblog.local )。
  • DocumentRoot :指定了这个网站的根目录。我们把它从默认的 /var/www/html 换成了 /var/www/myblog ,实现了物理隔离。
  • ErrorLog CustomLog :为这个站点单独创建了错误日志和访问日志,方便日后排查问题,而不会和默认站点的日志混在一起。

保存后,启用这个站点: sudo a2ensite myblog.conf 。这个命令会在 /etc/apache2/sites-enabled/ 下创建一个指向 myblog.conf 的软链接。最后,重启 Apache: sudo systemctl restart apache2

为了让 myblog.local 这个域名能在你的本地电脑上解析,你还需要修改本地电脑的 hosts 文件(Windows 在 C:\Windows\System32\drivers\etc\hosts ,macOS/Linux 在 /etc/hosts ),添加一行: 192.168.1.100 myblog.local (把 192.168.1.100 替换成你的服务器 IP)。这样,你在浏览器里访问 http://myblog.local ,流量就会被导向你的服务器,Apache 会根据 ServerName 找到对应的虚拟主机配置,把请求交给 /var/www/myblog 目录处理。

5. 常见问题与排查技巧实录:一份来自真实战场的故障速查手册

5.1 Apache 启动失败: Address already in use: AH00072: make_sock: could not bind to address [::]:80

这个错误意味着 80 端口已经被占用了。最常见的情况是,你之前已经运行了一个 Nginx 或其他 Web 服务,或者你安装了 apache2 两次,导致两个实例都在抢端口。

排查步骤:

  1. 查看哪个进程占用了 80 端口: sudo ss -tulpn | grep ':80' ss 命令比 netstat 更快、更现代。输出会类似:
    tcp LISTEN 0 128 *:80 *:* users:(("nginx",pid=1234,fd=6))
    
    这说明是 nginx 进程(PID 1234)占用了 80 端口。
  2. 如果是 nginx ,你可以选择停止它: sudo systemctl stop nginx ,或者卸载它: sudo apt remove nginx
  3. 如果是另一个 apache2 进程,用 sudo kill -9 1234 强制杀死它(把 1234 替换成实际的 PID)。
  4. 然后,再尝试启动 Apache: sudo systemctl start apache2

实操心得:我习惯在安装任何新服务前,先执行 sudo ss -tulpn | grep ':80\|:443' ,看看端口是否干净。这能避免 90% 的“启动失败”问题。

5.2 PHP 页面显示空白,但 Apache 日志里没有错误

这是一个经典的“静默失败”。PHP 脚本执行过程中发生了致命错误(Fatal Error),但 PHP 的错误报告被关闭了,所以页面什么也不显示,只有一片空白。

解决方法:

  1. 编辑 PHP 配置文件: sudo nano /etc/php/7.0/apache2/php.ini
  2. 找到 display_errors 这一行,把它改为 On
  3. 找到 error_reporting 这一行,把它改为 E_ALL
  4. 重启 Apache: sudo systemctl restart apache2
  5. 刷新你的 PHP 页面,错误信息就会直接显示在浏览器上了。

常见的错误类型包括:

  • Fatal error: Uncaught Error: Call to undefined function mysqli_connect() :说明 php-mysqli 扩展没安装或没加载。
  • Warning: mysqli_connect(): (HY000/1045): Access denied for user... :说明数据库用户名或密码错了。
  • Parse error: syntax error, unexpected end of file :说明 PHP 代码里少了一个 } ;

一旦问题解决, 务必 display_errors 改回 Off ,并把 error_log 设置为一个文件路径(如 /var/log/php_errors.log ),这样错误信息会记录在日志里,而不是暴露给用户。

5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值